Persistent Makefile Variables
I want my Makefile to be invoked like this:
make x11 oss bin
which should result in compiling the files: main.c x11.c oss.c
and link them into one executable file bin
.
Another way to invoke it would be:
make x11 alsa bin
which should do the same thing 开发者_JS百科but with main.c x11.c alsa.c
This is my Makefile:
bin: $(OBJ) main.o
$(CC) $(LDFLAGS) $(OBJ) main.o $(LDLIBS)
x11:
set OBJ += bsd.o
oss:
set OBJ += oss.o
alsa:
set OBJ += alsa.o
.c.o:
$(CC) $(CFLAGS) -c $<
but it seems that the contents of the OBJ variable isn't persistent throughout the recipes. Any suggestions?
OBJ is persistent, but you have another problem:
- The Makefile first is completely parsed by make. And thus $OBJ still is unset/empty in this stage. Therefore, the bin target only gets
main.o
as dependency since all variables are replaced with their value in this stage. - Next, OBJ is being updated with its content using the given targets on the command line. But OBJ is not used anymore for the bin target, since make is finihed building the dependencies already. (Makefile normally is not parsed a second time)
The trick is to have the OBJ variable filled before the parsing. A simple solution is to call the Makefile using:
make "OBJ=x11 oss" bin
and modify the Makefile a bit to have the .o
-part added (or just add them to the make command):
bin: $(patsubst %,%.o,$(OBJ)) main.o
$(CC) $(LDFLAGS) $(OBJ) main.o $(LDLIBS)
.c.o:
$(CC) $(CFLAGS) -c $<
Note: I said 'Makefile normally is not parsed a second time'. It is possible to recursively use the Makefile multiple times. This is very complicated and probably not required for 99% of all cases. An example of such 'make abuse' is the OpenWRT buildsystem. trunk/Makefile is an example of a Makefile is is called multiple times by itself.
This is somewhat of a hack.
Add this like to the top of your Makefile:
OBJ := $(filter-out bin,${MAKECMDGOALS})
Now when you type make x11 oss bin
make parses this:
OBJ := x11 oss
and for make x11 alsa bin
it will see
OBJ := x11 alsa
You will probably have to remove the shell commands for x11 et. al. as set OBJ += bsd.o
is not valid shell.
精彩评论