Reputation: 2484
I'm not sure what I'm doing wrong here. I'm trying to get make to figure out what dependencies my project has for, not only source files, but non-system included header files. I've many resources from this very site related to this subject.
Such as: Makefile header dependencies and Makefile, header dependencies
However, when I do
touch MyHeader.h
as a test to see if this works, my make process fails to rebuild the source files that include this header. So, here's what I have in my makefile (of relevance that is)
CPP=g++
CPPFLAGS=-Iadditional/includes -MMD
CXXFLAGS=-std=c++0x -c
# not every source file in this directory needs to be included in this build
# this is because of shared code with Windows
SOURCESFILTER = File1.cpp File2.cpp
OBJ_DIR=obj
SOURCES = $(filter-out $(SOURCEFILTER),$(wildcard *.cpp))
OBJECTS = $(addprefix $(OBJ_DIR)/,$(SOURCES:.cpp=.o))
DEPENDENCIES = $(OBJECTS:.o=.d)
.PHONY: archive
archive : $(OBJECTS)
ar mylib.a obj/*.o
-include $(DEPENDENCIES)
$(OBJ_DIR)/%.o: $(SOURCES) $(DEPENDENCIES)
$(CPP) $(CPPFLAGS) $(CXXFLAGS) $< -o $@
I've verified that the above process does indeed generate the expected *.d files. I assume that I'm including them correctly. However, as mentioned, as a test I do: touch MyHeader.h
which is in the same directory as the sources, and rerun the make, none of the source files which include this header are remade. What am I missing?
Andy
Upvotes: 2
Views: 6449
Reputation: 100781
First, you cannot include prerequisites in a suffix rule. Even if you could, you certainly would not want to include $(SOURCES)
or $(DEPENDENCIES)
, because that would cause every object to rebuild whenever any source or dependency file changed.
Second, you cannot create the target file in a different directory from where make expects it to be. Make will put the place where it wants to find the target in the variable $@
, and you must write the output into that location exactly. If you ever see a rule that modifies the target, such as above where you use obj/$@
, that won't work.
Most likely GCC is writing the files as obj/foo.d
, but your include
is trying to include foo.d
but that doesn't exist... but since you used -include
make doesn't complain.
I recommend you first write the object files into the local directory and get that working with dependencies. Once that works, then read up on how to write targets to a different directory and/or ask again.
ETA:
Try something like this:
CXX := g++
CPPFLAGS := -Iadditional/includes -MMD
CXXFLAGS := -std=c++0x
# not every source file in this directory needs to be included in this build
# this is because of shared code with Windows
SOURCESFILTER := File1.cpp File2.cpp
OBJ_DIR := obj
SOURCES := $(filter-out $(SOURCEFILTER),$(wildcard *.cpp))
OBJECTS := $(addprefix $(OBJ_DIR)/,$(SOURCES:.cpp=.o))
DEPENDENCIES := $(OBJECTS:.o=.d)
.PHONY: archive
archive: mylib.a
mylib.a: $(OBJECTS)
$(AR) $@ $^
-include $(DEPENDENCIES)
$(OBJ_DIR)/%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
Upvotes: 4