2
votes

I've been trying for a while to use auto dependencies in my makefile, but i struggle a lot to make it work, as i use a more complex structure for my project than just putting every files in a root folder.

I've tried using this piece of code in my makefile :

OBJECTS_DIR = obj/
SRCS_DIR = src/
#source files list, i.e : src/foo.cpp src/bar/foo2.cpp
SOURCES = $(shell find $(SRCS_DIR) -name \*.cpp | xargs -d '\n')
#object files list, i.e : obj/foo.o obj/foo2.o
OBJECTS = $(addprefix $(OBJECTS_DIR), $(notdir $(SOURCES:.cpp=.o)))
DEPS = $(OBJECTS_DIR)make.dep

myproject : $(OBJECTS)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^

$(OBJECTS) : $(SOURCES)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $@ -c $(filter %/$(notdir $(@:.o=.cpp)), $(SOURCES))

$(DEPS): $(SOURCES)
    $(CC) -MM  $(SOURCES) > $(DEPS)

-include $(DEPS)

all : myproject

clean :
    @-rm -f $(RELEASE_DIR)* $(OBJECTS_DIR)*

I would like to store all the dependencies in the obj/make.dep file. This gives me the following output (here foo includes foo2) :

foo2.o: src/bar/foo2.cpp src/bar/headers/foo2.h
foo.o: src/foo.cpp src/bar/headers/foo2.h

I would like to rename each of the object files in order to have the following output : obj/foo2.o: src/bar/foo2.cpp src/bar/headers/foo2.h obj/foo.o: src/foo.cpp src/bar/headers/foo2.h

I've tried with the -MT option with no result... Furthermore, is the -include $(DEPS) enough to include the dependencies i created? Shouldn't I replace $(filter %/$(notdir $(@:.o=.cpp)), $(SOURCES)) in the OBJECT rule by the line written in the make.dep file?

Thanks in advance for your insight, please tell me if there is any other way to enhance my makefile !

2

2 Answers

1
votes

What is your reasoning for storing all the dependencies in 1 file? Conventionally each object file will have it's own .d file that is created during the compile and that is what you -include. When that is the case it is much simpler to add -MT flags etc into the same command as your initial compile to get the object dir's and names correct.

I would do something more along the lines of the answer to this question:

make include directive and dependency generation with -MM

The good thing is that all the dependency generation will happen in the compile step so you're not having to make additional calls to gcc. Having all the dependencies in one file is probably OK for a small file but if you want your makefile to scale its probably best to do something like the above.

1
votes

You should use a pattern rule to generate your .o files.

$(OBJECTS_DIR)/%.o : %.c 
        $(CC) $(CFLAGS) -c -o $@ $^ 

You have to process the dependency file to add OBJECTS_DIR to the target path. sed makes this simple. You probably also want it to depend on the .h files.

$(DEPS): $(SOURCES) $(shell find . -name '*.h')
        $(CC) -MM  $(SOURCES) | sed 's#^\(.*:\)#$(OBJECTS_DIR)\1#' > $(DEPS)