o makefile postado está faltando alguns detalhes
Nota: é (quase) sempre melhor separar a etapa de compilação da etapa do link
O makefile a seguir corrige esses detalhes
Nota: <tab>
significa usar a tecla tab no makefile real
RM := /usr/bin/rm
LFLAGS += 'pkg-config wayland-client --libs'
CFLAGS := -std=c11 -Wall -Werror -O3 -fvisibility=hidden
CFLAGS += 'pkg-config wayland-client --cflags'
OBJS := hello_wayland.o helpers.o
HDRS := helpers.h
TARGET := hello_wayland
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJS) images.bin
<tab>$(CC) -o hello_wayland *.o $(LFLAGS) -lrt
%.o:%.c $(HDRS)
<tab>$(CC) $(CFLAGS)-c $< -o $@ -I.
images.bin: images/convert.py images/window.png images/fish.png
<tab>images/convert.py
<tab>cat window.bin fish.bin > images.bin
.PHONY: clean
clean:
<tab>$(RM) *.o fish.bin window.bin hello_wayland
Você pergunta o que está errado com o makefile original:
aqui estão algumas observações:
-- macros in a make file are of two types:
those evaluated only once using ':='
those evaluated every time they are referenced '='
WAYLAND='pkg-config wayland-client --cflags --libs'
== WAYLAND will be re-evaluated every time referenced
CFLAGS?=-std=c11 -Wall -Werror -O3 -fvisibility=hidden
== invalid format for macro. '?=' should be ':='
== in a makefile, typical usage is 'make all' but this makefile is missing that target (which should be the first target so 'make' by itself, will execute the first target)
== 'targets' for a link step should not be the actual file name
==== but rather a macro name where that macro contains the target name
==== This usage of a macro also makes it easy to set the resulting executable file name at the invocation of 'make'
==== while either way will work, for flexability it is best to create a macro
==== this is expecially true when writing a recursive makefile or multiple different executables
hello_wayland: hello_wayland.o helpers.o helpers.h images.bin
== this is a link step, with hidden compiles, using the default recipe, which knows nothing about any specific header file
==== so the hidden compiles will not be done if the header file changes
== and a header file 'helpers.h' should never be in a link step
== the '*.o' is a 'glob' operation, which should not be used in makefiles
==== instead use the make facilties:
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
== the 'target' is properly referenced by '$@' and there can be no keypunch errors if the '$@' is used.
$(CC) -o hello_wayland *.o $(WAYLAND) -lrt
images.bin: images/convert.py images/window.png images/fish.png
images/convert.py
cat window.bin fish.bin > images.bin
== when a 'target' is not the name of a produced file,
==== especially in older versions of 'make'
==== then the target needs to be preceeded by a
.PHONY: <list of target names that produce no actual output file>
== using a 'glob' operation in a makefile is a bad idea
==== instead use the appropriate macro
==== like the $(OBJS) macro listed above
clean:
$(RM) *.o fish.bin window.bin hello_wayland
Então, por que o makefile original não funcionou? uma combinação de coisas que se acumulam em uma falha de fabricação. Aqui estão as razões mais óbvias:
1) the incorrect setting of the CFLAGS macro
2) the combining of the link operation with the compile operations
3) the missing .PHONY: statement
4) the use of the 'glob' statements