There are many ways of having automatic dependencies in a Makefile
. The following, however, is the most clean and complete solution that I know of for modern compilers.
GNU Make has a number of builtin rules and variables for building programs, for example, for C:
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH) OUTPUT_OPTION = -o $@ %.o: %.c $(COMPILE.c) $(OUTPUT_OPTION) $< %: %.o $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ |
Because of these builtins, a basic Makefile
for a C project with gcc
can be quite simple:
CC=gcc LDLIBS=-lm SRC=$(wildcard *.c) OBJ=$(SRC:.c=.o) .PHONY: clean foo: foo.o bar.o clean: rm -f $(OBJ) foo |
This will not track dependencies on headers and other include files, so this will not properly rebuild when these files are updated. With not too much modification, we can ask gcc
to output a dependency file next to each object file that is produced. We ask make
to include these dependency files where available:
CC=gcc OUTPUT_OPTION=-MMD -MP -o $@ LDLIBS=-lm SRC=$(wildcard *.c) OBJ=$(SRC:.c=.o) DEP=$(SRC:.c=.d) .PHONY: clean foo: foo.o bar.o -include $(DEP) clean: rm -f $(OBJ) $(DEP) foo |
The options will generate dependency files alongside compilation (-MMD
instead of -MM
), and with phony targets (-MP
) for dependencies. The rationale for doing this is described in Autodependencies with GNU make, although this article dates from a time when apparently only -MM
was available. The options -MMD -MP
are a modern way of implementing what is proposed in the article.
Besides GCC, also Clang 3.0 and ICC 12.1 seem to support these options.
Interesting, thanks. Looks like the -MP thingie is not so well know… or maybe just one more kinda-dark corner grown to compensate for other dark corners.
The -include line needs to be moved below the first non-phony target. Otherwise, it will override the default target.
Thanks Chris, I’ve updated the article.
Is there a way to implement this without relying on Gmake’s extensions?