3 ms·
GCC has the ability to generate dependencies in the Makefile format using `gcc -MM` which I guess is also for "Make Make" :). It does not create the whole Makef
by p4bl0 3y ago
GCC has the ability to generate dependencies in the Makefile format using `gcc -MM` which I guess is also for "Make Make" :). It does not create the whole Makefile but it's a nice way to have a script (or a Make recipe) that maintains up-to-date dependencies for each targets in a file that can be included from the Makefile (which then declares generic compilation recipes).
E.g.:
force-update-deps::
rm .deps
.deps:
gcc -MM *.c > $@
include .deps
- toast0 3y agoClang's docs say -MM includes only user dependencies, -MD includes user and system dependencies. A better choice if your system includes might change.
- o11c 3y agoSystem includes are generally well-behaved though, so it doesn't matter if they add new things.
- AceJohnny2 3y agoGoing on a tangent here, but properly integrating support for such "discovered" dependencies in GNU Make can get a bit complicated. In particular, you probably want to use `-include` instead of `include`, to continue even a given .dep file doesn't exist (as on the first run). The GNU Make maintainer wrote in-depth about ways to do it here: https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ https://make.mad-scientist.net/papers/advanced-auto-dependen...
- jjgreen 3y agoI think you can get away with 'include' here -- the (Gnu only?) make behaviour on trying to include a non-existent file is to look for a target which creates that file, then running it if found, then to try the include again. This has other applications: if your Common.mk is generated by autoconf (say), then default: all Common.mk: $(error Not configured) include Common.mk gives a nicer error message if you 'make' having not './configure'd
- ralferoo 3y agoIt's also not like this is new - I know I've been using gcc to output dependencies for Makefiles for at least 2 decades, presumably it was around long before then.
- Arch-TK 3y agoThere's generally a much nicer way to handle this so that the dependencies don't have to get generated before the first compile (and are instead generated as a side effect of the first compile, which is sufficient as the first build will always be complete and you only need granular dependency information for proper incremental rebuilds). CFLAGS += -MD -include $(wildcard *.d) I personally like to also pass `-MP` to add phony targets so removing a header doesn't complain about headers which are intentionally removed. You can pass `-MMD` instead of `-MD` to avoid having system includes in the generated depfiles just like the example you wrote does. I also personally prefer to be explicit and avoid wildcards in makefiles wherever possible so I would do something like this: CFLAGS += -MD -MP objs := foo.o bar.o ... baz.o deps = $(objs:.o=.d) ... -include $(deps) That being said, this doesn't solve the "everything should depend on the Makefile" problem as well as the "what if I generate a generate source code" problem or finally "what if I have to compile C to generate C to compile my program" problem. As such, I have personally switched to redo.