Reputation: 19
I have a directory structure like the following:
bin
main.c
Makefile
lib
lib1.c
lib2.c
Makefile
tst
test1.cc
Makefile
In my Makfile I have code the looks like this:
ALL_OBJECTS = main.o lib1.o lib2.o
BINS = binary
binary,SRCS = main.o lib1.o lib2.o
OBJS = $($(*),SRCS)
all: $(ALL_OBJECTS) $(BINS)
%.o : %.c
${CC} -c $^ -o $@
binary:
${CC} -o $@ $(OBJS)
My question is when I change and of the source files like main.c, lib1.c or lib2.c the *.o file is re-compiled during make but the binary is not recompiled. How can I ensure that the binary is recompiled when one of its dependencies change?
Upvotes: 0
Views: 393
Reputation: 6387
Based on your last comment to @JerryCoffin's answer, you could do something like this:
binary1 : lib1.o lib2.o main1.o
binary2 : lib2.o main2.o
binary3 : lib1.o main3.o
binary1 binary2 binary3:
$(CC) -o $@ $^
The first three lines have no recipe, and thus simply are adding prerequisites to the associated binaries. Then you define a recipe for the binary targets using the automatic variable $^
, which will expand to that target's dependencies.
Upvotes: 1
Reputation: 490218
Some parts of your Makefile don't make much sense to me, and the directory structure you show doesn't really seem to match up well with the Makefile you show. For example, with a directory named lib
that contains a Makefile of its own, I'd expect to see that Makefile create a library that depends on lib1.o and lib2.o. Then binary
would depend on that library.
But right now, it looks like you're just building binary
from a single Makefile, and ignoring the Makefile in the lib
directory. That can work too, but it's going to be different from the previous scenario.
For the moment, let's start with a bit "flatter" directory structure, with main.c
, lib1.c
and lib2.c
all contained in a single directory (and the Makefile in that same directory). For this case, we can build the binary with a really simple Makefile:
binary: lib1.o lib2.o main.o
$(CC) -o binary lib1.o lib2.o main.o
We just make that the binary depends on the object files, and how to create the binary from those object files. Any reasonable modern make utility already has built-in rules for how to compile a .c file to produce a .o file, so we don't have to do any more than that unless we want something fairly unusual in how we build those object files.
That does repeat the names of the object files in two places though. We'd usually prefer to avoid that. We can separate out defining the names of the object files from the rule to make the binary from them, to get something more like this:
OBJS = lib1.o lib2.o main.o
binary: $(OBJS)
$(CC) -o binary $(OBJS)
Now we only have the names of the object files in one place, so if (for one obvious example) we add another object file, we only need to add its name in one place, rather than two.
Upvotes: 1