Kanony
Kanony

Reputation: 539

What is -include in GNU Make and how it works?

-include is used to ignore files which does not exist. But can anyone tell me where these files are used in this example?

CXX    := g++
TARGET := exec

SOURCES := $(wildcard *.cpp)
OBJECTS := $(patsubst %.cpp, %.o, $(SOURCES))
DEPENDS := $(patsubst %.cpp, %.d, $(SOURCES))

DEPFLAGS = -MMD -MF $(@:.o=.d)

all: $(TARGET)

-include $(DEPENDS)

$(TARGET): $(OBJECTS)
    $(CXX) -o $@ $^

clean:
    $(RM) $(OBJECTS) $(DEPENDS) $(TARGET)

%.o: %.cpp
    $(CXX) -c $< $(DEPFLAGS)

Upvotes: 0

Views: 4469

Answers (1)

larsks
larsks

Reputation: 312858

The structure of this Makefile is a little questionable.

This is trying performing a variant of the technique discussed in the Automatic Prerequisites section of the Make manual, but it doesn't actually work as intended.

When you have an include statement, make will attempt to build any of the included files if they don't exist. Unfortunately, the Makefile doesn't have rules for generating the dependencies, which is why it has -include instead of just include -- the first time you run make it would fail to find the mentioned files.

Because the Makefile adds $(DEPFLAGS) to the command line used to generate .o files, the first time it compiles a .o file it will do so like this:

g++ -c somefile.c -MMD -MF somefile.d

The arguments in $(DEPFLAGS) ask g++ to generate dependencies in somefile.d, so next time you run make it will use the dependencies file in its calculation.

The dependency information output by -MMD will be a series of make rules that look something like this (assuming that file1.cpp includes file2.h):

file1.o: file1.cpp file2.h

A fixed Makefile might look something like this:

CXX := g++
TARGET := exec

SOURCES := $(wildcard *.cpp)
OBJECTS := $(SOURCES:.cpp=.o)
DEPENDS := $(SOURCES:.cpp=.d)

%.d: %.cpp
    $(CXX) -M -MMD $<

all: $(TARGET)

$(TARGET): $(OBJECTS)
    $(CXX) -o $@ $^

clean:
    $(RM) $(OBJECTS) $(DEPENDS) $(TARGET)

include $(DEPENDS)

Here we're relying on make's implicit rules for compiling .cpp files to .o files, and we introduce a pattern rule for building .d files from .cpp files.

This allows us to remove the - from -include, because when make first runs it will see that the dependency files are missing, and will use the pattern rule to build them.

Upvotes: 3

Related Questions