-include $(OBJS:%.o=%.d)
in your makefile (with -MMD in CFLAGS). -include $(OBJS:%.o=%.d)
in your makefile (with -MMD in CFLAGS).There is a profoundly ugly example here:
https://www.gnu.org/software/make/manual/html_node/Automatic...
%.d: %.c
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
I copied it into a running example here for anyone curious:1) The sed magic is required for adding the dependencies of the .d file itself. For example, if the timestamp of your header changes, it may have acquired new dependencies, and a new .d file has to be generated BEFORE make determines if the .c file is out of date.
See:
https://www.gnu.org/software/make/manual/html_node/Automatic...
The purpose of the sed command is to translate (for example):
main.o : main.c defs.h
into: main.o main.d : main.c defs.h
The first line isn't correct because the .d file itself has no dependencies.2) By the time you are compiling, it's too late to generate .d. The .d files are there to determine IF you need to compile.
EDIT: I am trying to generate a test case that shows this fails, but it seems to actually work.
Hm yes I'm convinced it works, but I have to think about why. I guess one way of saying it is that the previous .d file is always correct. Hm.
If (2) is not correct, then (1) is not needed either. The old .d files from the last compilation pass are sufficient to know which files need to be recompiled in the current compilation pass. Make does not need to know the dependencies of the .d files themselves, it just needs to load all the existing .d files at startup.
EDIT: Yep, I'm fairly confident this works :D. I don't know if whoever wrote that manual page knew about -MD, but I think it might be newer than -M, which would explain it.
This feels hacky, but yes it seems to work. I'll think about it a bit more. (I might clone this feature for a build tool -- since the gcc/Clang support is already there, it seems like any serious build tool needs this. Although some have their own #include scanners which is odd.)
Thanks for the information!
Though, I guess I wasn't quite correct either. See plorkyeran's sibling comment re: generated header files.
I once worked in a place that had its own #include scanner (partially because it used so many different compilers and other tools... suffice it to say that Watcom C++ was in the mix). To make it work, you had to install a custom filesystem driver that intercepted disk reads during compilation and logged them. A rather... bruteforce approach. But it had the advantage of working with everything.
Personally I've never found it too burdensome to just manually specify dependencies on generated files.
Change the target of the rule emitted by
dependency generation... An -MT option will
set the target to be exactly the string you
specify...
So in your example one might do something like -MT "$@ $(basename $@).d"
which would output main.o main.d : main.c defs.h
for the main.o target.Also consider adding -MP to CFLAGS to prevent errors if you delete a .h file.