GNU make: clean target depends on includes
dependencies, gnu-make, makefile
Solution
Just don't provide a rule for generating `.d` files. A good explanation of why it is not so good (including your case too) is available in "Advanced Auto-Dependency Generation" of Paul Smith - a maintainer of GNU Make.
In a nutshell, the following pattern works fine for me for all cases:
CPPFLAGS += -MMD -MP
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
-include $(OBJS:.o=.d)
See also my previous related answers:
- GNU Make. Why this complex syntax to generate dependencies?
- Makefile improvements, dependency generation not functioning
Problem
I'm using gmake and `gcc -MM` to track header dependencies, following the manual. The mechanism relies on a makefile `include` directive to import the computed dependencies. Because the `.d` files are included by the makefile, they must exist for any target to be made, including `clean`. So before `clean` can do the right thing, the dependencies must be generated, and if one fails to build then `clean` just made more mess. Besides `clean`, it wants to make all the dependencies before building any target. Furthermore, if any file is changed to include a nonexistent file, then the dependency resolution breaks and nothing at all will build. If a header is deleted, then the existing dependency files contain still name it as a target, and nothing will build until the offending dependency files are removed… which can't be done with `clean`. Replacing the substitution pattern of the `include` with a wildcard to include all preexisting dependency files solves some of the issues, but it still can't clean out a broken dependency, and stale dependency files are never removed. Is there a better solution? Is the manual's example really intended for real use?