Makefile auto dependencies with GCC

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)
-include $(DEP)
 
.PHONY: clean
 
foo: foo.o bar.o
 
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.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>