0

I am trying to create a makefile that automatically compiles and links my .cpp files into an executable via .o files. What I can't get working is automated (or even manual) dependency generation. When i uncomment the below commented code, nothing is recompiled when i run make build. All i get is make: Nothing to be done for 'build'., even if x.h (or any .h file) has changed. I've been trying to learn from this question: Makefile, header dependencies, dmckee's answer, especially. Why isn't this makefile working?

Clarification: I can compile everything, but when I modify any header file, the .cpp files that depend on it aren't updated. So, if I for instance compile my entire source, then I change a #define in the header file, and then run make build, and I get Nothing to be done for 'build'. (when I have uncommented either commented chunks of the below code).

CC=gcc
CFLAGS=-O2 -Wall
LDFLAGS=-lSDL -lstdc++
SOURCES=$(wildcard *.cpp)
OBJECTS=$(patsubst %.cpp, obj/%.o,$(SOURCES))
TARGET=bin/test.bin

# Nothing happens when i uncomment the following. (automated attempt)
#depend: .depend
#
#.depend: $(SOURCES)
#   rm -f ./.depend
#   $(CC) $(CFLAGS) -MM $^ >> ./.depend;
#
#include .depend

# And nothing happens when i uncomment the following. x.cpp and x.h are files in my project. (manual attempt)
#x.o: x.cpp x.h


clean:
    rm -f $(TARGET)
    rm -f $(OBJECTS)

run: build
    ./$(TARGET)

build: $(TARGET)

$(TARGET): $(OBJECTS)
    @mkdir -p $(@D)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

obj/%.o: %.cpp
    @mkdir -p $(@D)
    $(CC) -c $(CFLAGS) $< -o $@
Community
  • 1
  • 1
nijoakim
  • 930
  • 10
  • 25

2 Answers2

2

This may take a few iterations.

1) I can't reproduce your results from your first approach (and you must be clearer than "nothing happens"-- does Make actually produce no output?). This:

depend: .depend

.depend: $(SOURCES)
    rm -f ./.depend
    $(CC) $(CFLAGS) -MM $^ >> ./.depend;

include .depend

seems to work as intended. I suggest you try $(info sources: $(SOURCES)) to verify that that variable contains the filenames you think it does.

2) I can't reproduce your results from your second approach (and you must be clearer than "nothing happens"-- does Make actually produce no output?). You tried x.o: x.cpp x.h when the first approach was commented out, is that right?

EDIT:
Let's concentrate on x.o. Does it contain #include "x.h"? When you uncomment the first section and make x.o, does Make produce (or modify) .depend? Is there a line in .depend that pertains to x.o, and if so what is it? If you then modify x.h and then make x.o, what does Make do?

Beta
  • 96,650
  • 16
  • 149
  • 150
  • I ran `$(info sources: $(SOURCES))` and my sources are what I think they are, that is all the .cpp files and not the header files. And i suppose the header files shouldn't consist the sources since they are should only be compiled when they are called from an `#include` directive. Also, I tried to clarify my question, tell me if you need further clarification. – nijoakim Jul 07 '12 at 09:24
  • I solved it by following this tutorial: http://scottmcpeak.com/autodepend/autodepend.html. I changed the ?`obj/%.o: %.cpp`-rule to what it says in the tutorial. My problem was that the dependency file didn't contain the entire path but missed "obj/" in it. Thanks for all the help! Your latest edit made me find the problem! :D – nijoakim Jul 10 '12 at 18:29
1

You resolve only one kind of dependency with $(CC) -MM. There are various others like changed command options (e.g. -DDO_SOMETHING_ELSE), or a different set of symbols exported by a library. Traditional makes offer you lots of fun debugging inconsistent executables!

That's where makepp comes in. Dependencies are detected automatically. It not only rebuilds targets whenever any kind of dependency warrants this. It even chains everything together and builds what is needed from bottom up. I.e. if your linker has a -lmystuff option and you have a rule to build libmystuff.so or .a, that's all it takes, it will get built in time. Likewise you can include files that don't even exist yet — impossible with your solution.

Daniel
  • 521
  • 1
  • 4
  • 13