%.d: %.c
@set -e; rm -f $@; \
$(CC) -MM $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
sinclude $(SOURCES:.c=.d)
above is I saw at someone’s blog, but it does not explain how the code work to create the dependency between .c and .h files in makefile.
is there someone who would explain it for me or supply some materials ?
I would really appreciate for your help!thank you!
Suppose your only new source file is
foo.c, which contains the linesMake determines that
foo.dis out of date (because it doesn’t exist or foo.c is newer), so it executes the rule.Make evaluates the
$$$$as$$and passes that to the shell; the shell interprets this as the value of the$parameter, which is the process ID of the shell, which the rule wants to use to construct a unique file name. This will remain constant only within one command, which is why the rule is written with the line continuations (“\”). This isn’t really a good way to do it; if there are different processes trying to buildfoo.dat the same time, you’re probably hosed anyway. So we can rewrite the rule:We can dispense with the first rule, it doesn’t really bear on the question.
The second command,
$(CC) -MM $< > $@.temp, expands togcc -MM foo.c > foo.d.temp(or some other compiler). The-MMflag tells the compiler to produce a list of dependencies:The next line chews up this list with sed
Which translates roughly as “change
foo.o:tofoo.o foo.d :“:(And the last command removes the temporary file.)
This is not the best way to handle dependencies, since it will rebuild all
%.dfiles every time you run Make, even ones irrelevant to you target. A more polished approach is Advanced Auto-Dependency Generation.