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

Community
  • 1
  • 1
Andrew Falanga
  • 2,274
  • 4
  • 26
  • 51

1 Answers1

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 $@ $<
MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • 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???? – Andrew Falanga Apr 25 '13 at 23:20
  • 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. – MadScientist Apr 26 '13 at 00:11
  • 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. – Andrew Falanga Apr 26 '13 at 13:56