4 ms·
POSIX make really does make auto dependencies hard, but GNU make actually solves this fairly cleanly by adding an include directive. As long as you have a scrip
by georgef 13y ago
POSIX make really does make auto dependencies hard, but GNU make actually solves this fairly cleanly by adding an include directive. As long as you have a script or program to process a file and spit out its dependencies in make style (e.g., GCC does this for C and C++ with its -M flags), you can just include the outputs of that process and make will do the rest.
For example, here's how I handle a simple C project.
CSRC := [list .c files here]
DEPS := $(CSRC:.c=.d)
[standard statements for building go here]
%.d: %.c
gcc -MM -MF $@ $<
-include $(DEPS)
Poof. Automatic dependency handling. You can see how any sort of dependency that can be detected by some sort of preprocessor can be plugged in here.
- itayperl 13y agoSome problems I have encountered with this approach: 1. dash before include. It will cause make to ignore any errors when generating the .d files. It can be pretty difficult to figure out what went wrong. Removing the dash will show a (harmless) error message for every .d file generated, which is pretty annoying. 2. At one time a.c includes b.h and you run make. a.d is created with "a.o: a.c b.h". If at this point you add to b.h an include to c.h, the new dependency of a.o on c.h will never be updated in a.d unless you manually delete it. This can cause some pretty nasty bugs! This can be solved by adding -MT $*.o -MT $*.d to the gcc command line, which causes the dep file to regenerate when one of the dependencies changes (in fact the make manual suggests a similar solution using sed). However this creates another problem: if you remove a header a.h included by a.c (and the #include line to it), a.d still depends on a.h, so make will fail looking for it until you manually delete a.d (and any other dep file depending on the removed header). tl;dr: this solution leaves much to be desired, and can be dangerous in some conditions.
- exDM69 13y agoYou can even omit the extra dependency generation rule by using -MMD. CFLAGS+=-MMD -include $(DEPS) That's it.