zedxz
zedxz

Reputation: 113

Automatic header dependencies with gmake

EDITED

I'm trying to have source files recompiled without having to specify header files for each CPP in the makefile.

I'm down to :

#CoreObj1.cpp(and .h)
#CoreObj2.cpp(and .h)

#This is the makefile.

CORE_COMPONENT_OBJECTS = \
  obj/CoreObj1.o \
  obj/CoreObj2.o \

# Objects
obj/%.o: %.cpp obj/%.d
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -c $*.cpp -o $@

# Dependencies
obj/%.d: %.cpp
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -MM -MF $@ $<

DEPS = $(CORE_COMPONENT_OBJECTS:.o=.d)

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif   

But modifying a header files does not trigger the source files including it to be recompiled.

NOTE: In fact, it works if my .o, .d and .cpp are in the same folder. But if my .d and .o are in a obj/ folder, it doesn't trigger the recompile.

Upvotes: 2

Views: 1433

Answers (3)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136435

People often have such rules for dependency generation, but they are really unnecessary.

The first time a project is built no dependencies are necessary since it builds all sources anyway. It is only the subsequent builds that require the dependencies from the previous build to detect what needs to be rebuild.

Therefore, the dependencies are really a by-product of compilation. Your rules should look like the following:

#CoreObj1.cpp(and .h)
#CoreObj2.cpp(and .h)

#This is the makefile.

CORE_COMPONENT_OBJECTS = \
  obj/CoreObj1.o \
  obj/CoreObj2.o \

# Objects
obj/%.o: %.cpp
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -c -o $@ -MD -MP -MF ${@:.o=.d} $<

DEPS = $(CORE_COMPONENT_OBJECTS:.o=.d)

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif   

As a side note, mkdir -p is not parallel make friendly. For example, when two or more processes race to create /a/b/c/ and /a/b/cc/ when /a/b/ doesn't exist, one mkdir process may fail with EEXIST trying to create /a/b/.

Upvotes: 4

pmod
pmod

Reputation: 11007

You don't have dependency file as a prerequisite for compilation rule. Should be something like this:

#This is the rule for creating the dependency files
src/%.d: src/%.cpp
    $(CXX) $(CXX_CFLAGS) -MM -MF $(patsubst obj/%.o,obj/%.d,$@) -o $@ $<

obj/%.o: %.cpp %.d
    $(CXX) $(CXXFLAGS) -o $@ -c $<

-include $(SRC:%.cpp=%.d)

The last string adds dependency on headers.

EDIT

I see you have

-include $(DEPS)

but check with $(warning DEPS = $(DEPS)) whether you really include existing files, otherwise make just silently ignore these.

Upvotes: 0

qehgt
qehgt

Reputation: 2990

It's better to use SCons/CMake/bjam to solve "header dependencies problem" than use make

Upvotes: -2

Related Questions