2

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

asked Apr 25, 2013 at 18:14

1 Answer 1

4

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 $@ $<
answered Apr 25, 2013 at 18:23
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the push in the right direction. I understand now that my make file targets were all wrong. I have changed this and will update the text I posted here after submitting this comment. I've copied the the make file to try hacking at building them local to the directory. That works, but I get a strange error at the beginning, "fatal error: opening dependency file obj/*.d.d no such file". Indeed there isn't. This is from the make file where it's being built locally????
That error doesn't look quite like a make error. Did you cut/paste it? Or paraphrase? I recommend you change your = to := in your variable assignments. Also as I mentioned before, having $(SOURCES) and $(DEPENDENCIES) as prerequisites of your pattern rule is really not right. Everything will rebuild all the time. You don't want the dependencies as prerequisites of anything, and you should use just a single %.c as the prerequisite. I'll update my answer.
Thank you for you help. This was what I needed. I was pretty close to the answer, but just wasn't quite there. I wasn't sure how to make filters work on pattern rules, $(OBJ_DIR)/%.o: %.cpp. This seemed that it would compile every source file and clearly I didn't want that. I haven't found in the GNU manual yet how the SOURCES variable affects this but apparently this is what I want. Thanks again.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.