makefiledependenciesgnu

Makefile (Auto-Dependency Generation)


just for quick terminology:

#basic makefile rule
target: dependencies
    recipe

The Problem: I want to generate the dependencies automatically.

For example, I am hoping to turn this:

#one of my targets
file.o: file.cpp 1.h 2.h 3.h 4.h 5.h 6.h 7.h 8.h another.h lots.h evenMore.h
    $(COMPILE)

Into this:

#one of my targets
file.o: $(GENERATE)
    $(COMPILE)

and I'm not too sure if it's possible..

What I do know:

I can use this compiler flag:

g++ -MM file.cpp

and it will return the proper target and dependency.
so from the example, it would return:

file.o: file.cpp 1.h 2.h 3.h 4.h 5.h 6.h 7.h 8.h another.h lots.h evenMore.h  

however, 'make' does NOT allow me to explicitly write shell code in the target or dependency section of a rule :(
I know there is a 'make' function called shell

but I can't quite plug this in as dependency and do parsing magic because it relies on the macro $@ which represents the target.. or at least I think that’s what the problem is

I've even tried just replacing the "file.cpp" dependency with this makefile function and that won't work either..

#it's suppose to turn the $@ (file.o) into file.cpp
THE_CPP := $(addsuffix $(.cpp),$(basename $@))

#one of my targets
file.o: $(THE_CPP) 1.h 2.h 3.h 4.h 5.h 6.h 7.h 8.h another.h lots.h evenMore.h
    $(COMPILE)
#this does not work

So all over google, there appear to be two solutions. both of which I don't fully grasp.
From GNU Make Manual

Some Site that says the GNU Make Manual one is out-of-date

So my ultimate question is: Is it possible to do it the way I want to do it,
and if not, can somebody break down the code from one of these sites and explain to me in detail how they work. I'll implement it one of these ways if I have to, but I'm weary to just paste a chunk of code into my makefile before understanding it


Solution

  • Newer versions of GCC have an -MP option which can be used with -MD. I simply added -MP and -MD to the CPPFLAGS variable for my project (I did not write a custom recipe for compiling C++) and added an "-include $(SRC:.cpp=.d)" line.

    Using -MD and -MP gives a dependency file which includes both the dependencies (without having to use some weird sed) and dummy targets (so that deleting header files will not cause errors).