Reputation: 8747
Here this tutorial explains it quite beautifully and most of it works fine. The following is the final Makefile from the tutorial which assumes that you have a directory structure like the following:
root-----Makefile
|-----All source files here.
Results of compilation are to be in the root
directory. The following is the Makefile:
OBJS := foo.o bar.o
# link
proggie: $(OBJS)
gcc $(OBJS) -o proggie
# pull in dependency info for *existing* .o files
-include $(OBJS:.o=.d) #NOTE THIS
%.o: %.c #NOTE THIS
gcc -c $(CFLAGS) $*.c -o $*.o
gcc -MM $(CFLAGS) $*.c > $*.d
@cp -f $*.d $*.d.tmp
@sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \
sed -e 's/^ *//' -e 's/$$/:/' >> $*.d
@rm -f $*.d.tmp
# remove compilation products
clean:
rm -f proggie *.o *.dOBJS := foo.o bar.o
I do not understand only one thing in tutorial. It says pull in dependency info for *existing* .o files
and the corresponding .d
files are made but how are these taken care of as no change has been made in the dependency list of the targets which still remain %.o: %.c
.
In fact from what I have noticed it just does not work for me. Can anybody explain what is going on here. If this tutorial is wrong(which I highly doubt) then please mention how can we include dependency from .d
files to the dependency list.
Upvotes: 1
Views: 120
Reputation: 98078
The dependency files created with gcc MM
will contain rules like:
foo.o: stdio.h myinc.h # ...
and this line here includes dependency file for each object in the list:
-include $(OBJS:.o=.d)
just look at the foo.d for example.
One file can be the target of several rules. All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target. If the target is older than any prerequisite from any rule, the recipe is executed.
So even if you have the rule %.o: %.c
, the include statement imports rules that expand this rule with dependencies.
Upvotes: 1