且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Makefile(自动依赖生成)

更新时间:2022-12-13 10:55:38

较新版本的GCC具有-M选项,可用于-MD。我简单地将-MP和-MD添加到我的项目的CPPFLAGS变量(我没有编写用于编译C ++的自定义配方),并添加了一个-include $(SRC:.cpp = .d)行。



使用-MD和-MP给出一个依赖文件,其中包含依赖关系(不必使用一些奇怪的sed)和虚拟目标(以便删除头文件不会导致错误)。


just for quick terminology:

#basic makefile rule
target: dependencies
    recepie

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 appears 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 chuck of code into my makefile before understanding it

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).