同一Makefile中make目标之间的递归依赖关系 [英] Recursive Dependencies Between make Targets in Same Makefile
问题描述
我正在尝试编写一个makefile,该文件能够确定何时更改了标头,然后重新编译相应的.cpp文件.为了对此进行测试,我创建了三个文件:main.cpp
,a.h
和b.h
. main.cpp
包括s a.h
,a.h
包括b.h
.
I am attempting to write a makefile that is able to determine when headers were changed and then recompile the corresponding .cpp files. To test this, I created three files: main.cpp
, a.h
, and b.h
. main.cpp
include sa.h
and a.h
includes b.h
.
我的makefile看起来像这样:
My makefile looks like this:
prog: main.cpp a.h
g++ main.cpp -o prog
a.h: b.h
更改a.h
,b.h
和main.cpp
的任何组合时,我希望重新编译prog
.尽管如此,prog
仅在更改a.h
或main.cpp
时才重新编译,而最后一行似乎被忽略.
When any combination of a.h
, b.h
, and main.cpp
is changed, I expect prog
to be recompiled. Despite this, prog
is only recompiled when a.h
or main.cpp
is changed, with the last line seeming to be ignored.
我做错了什么,如何在不向每个单独的.cpp文件中添加完整和完整的标头集的情况下完成我想要的事情(因为对于较大的项目,这可能变得非常繁琐 ):
What am I doing incorrectly and how can I accomplish what I want without adding the full and complete set of headers to each individual .cpp file like this (since for larger projects this could become extremely cumbersome):
prog: main.cpp a.h b.h
g++ ...
推荐答案
我在做什么不正确
What am I doing incorrectly
您的规则:
a.h: b.h
仅告诉make
a.h
取决于b.h
,即a.h
将需要
(重新)以任何方式make
可以从makefile确定,如果
a.h
早于b.h
或不存在.
merely tells make
that a.h
depends on b.h
, i.e. that a.h
will need to
be (re)made, in whatever manner make
can determine from the makefile, if
a.h
is older than b.h
or doesn't exist.
它没有告诉make
该怎么做从b.h
重新制作a.h
.您的makefile
不包含用于从b.h
重构a.h
的食谱.它只包含一个食谱
用于从main.cpp
和a.h
重构prog
,即:
It doesn't tell make
what to do to remake a.h
from b.h
. Your makefile
contains no recipe for remaking a.h
from b.h
. It only contains a recipe
for remaking prog
from main.cpp
and a.h
, namely:
prog: main.cpp a.h
g++ main.cpp -o prog
此外,make
当然也没有内置规则和制作方法
b.h
中的a.h
.因此,在没有任何配方的情况下,用b.h
制成a.h
它假定此依赖项不需要执行任何操作.没有
其他合理的默认值.因此,即使a.h
早于b.h
,也不会
对a.h
完成;尽管prog
依赖于a.h
,但无需执行任何操作
到该帐户上的prog
.
Furthermore make
, of course, has no builtin rule with a recipe for making
a.h
from b.h
. So in the absence of any recipe for making a.h
from b.h
it assumes that this dependency requires nothing to be done. There is no
other reasonable default. So even if a.h
is older than b.h
, nothing
is done to a.h
; and although prog
depends on a.h
, nothing need be done
to prog
on that account.
这很幸运,因为实际上您不想要 a.h
b.h
更改时的任何方式,而您不希望main.cpp
成为
a.h
或b.h
更改时,可以用任何方式进行重新制作.您希望 prog 成为
当它们中的任何一个改变时重新制作.您想要的由任何
以下makefile:
This is fortunate, because in fact you don't want a.h
to be remade in
any manner whatever when b.h
changes, and you don't want main.cpp
to be
remade in any manner whatever when a.h
or b.h
changes. You want prog to be
remade when any of them changes. What you want is expressed by any of the
following makefiles:
1
prog: main.cpp a.h b.h
g++ main.cpp -o prog
2
prog: main.cpp a.h
g++ main.cpp -o prog
prog: b.h
3
prog: main.cpp b.h
g++ main.cpp -o prog
prog: a.h
4
prog: main.cpp
g++ main.cpp -o prog
prog: a.h b.h
5
prog: main.cpp
g++ main.cpp -o prog
prog: a.h
prog: b.h
(还有更多).它们都是等效的.他们都说prog
取决于
在main.cpp
,a.h
和b.h
上,他们都说什么时候该做什么
prog
需要重制,即:
(and some more). They're all equivalent. They all say that prog
depends
on main.cpp
, a.h
and b.h
and they all say what is to be done whenever
prog
needs to remade, namely:
g++ main.cpp -o prog
如何在不添加完整和完整的内容集的情况下完成我想要的工作 像这样的每个.cpp文件的标头 (因为对于较大的项目,这可能变得非常麻烦)
how can I accomplish what I want without adding the full and complete set of headers to each individual .cpp file like this (since for larger projects this could become extremely cumbersome)
的确如此,因此,GCC编译器已经有很长一段时间了
生成迷你makefile的功能,该迷你makefile表示
将在每个头文件上生成的目标文件
读取以制作目标文件. GNU make可以利用此功能
生成这些依赖文件,并将其包含在用于构建GCC目标的makefile中.之间的这种合作
GCC和make
被称为自动依赖项生成(或类似名称).这
如何在Makefile中执行此操作的问题是此的重复项
而如果您是google,例如您还可以在"gcc自动生成依赖项"中找到大师的治疗方法.
Indeed it would, and for that reason GCC compilers have for a very long time had
a feature for generating mini-makefiles that express the dependency of
the object file that is going to be generated upon each of the header files that
are read in order to make the object file. GNU make can exploit this feature
to generate those dependency files and include them in a makefile for building GCC target(s). This co-operation between
GCC and make
is called auto-dependency generation (or similar). The
question of how to do it in a makefile is a duplicate of this one
and if you google, e.g. "gcc auto generate dependencies" you can also find guru treatments.
在评论中,您建议您还不是GNU的专家. 对所示的自动依赖项生成技术充满信心 在这些答案中.好吧,你 可以开始通过简单的基本实现来掌握它 这样(这也使得makefile在其他方面更加正常):
In a comment you suggest that you aren't yet sufficiently expert with GNU make to be confident with the auto-dependency generation techniques illustrated in those answers. Well, you can begin to get the hang of it with a rudimentary implementation as simple as this (which also makes the makefile more normal in other respects):
制作文件
.PHONY: all clean
all: prog
prog: prog.o
prog.o: main.cpp
g++ -MMD -c -o prog.o main.cpp
prog: prog.o
g++ -o prog prog.o
clean:
rm -f prog *.o *.d
-include prog.d
-MMD
是用于生成依赖项文件的GCC预处理程序选项
prog.d
.这是 -MMD
-MMD
is the GCC preprocessor option that generates the dependency file
prog.d
. Here is the documentation of -MMD
prog.d
是一个微型文件:
$ cat prog.d
prog.o: main.cpp a.h b.h
表示prog.o
的所有依赖项.第一次运行,
include
-ed生成文件prog.d
将不存在,这将是致命的make
错误,但因为-
前缀告诉make
忽略该错误.
因此,make
继续进行,包括prog.d
在内的所有内容均制作完毕,之后
每当任何规则-包括prog.d
中的规则时,都会重新生成prog.d
本身-需要重新编译prog.o
.
expressing all of the dependencies of prog.o
. The first time this runs,
the include
-ed makefile prog.d
will not exist, which would be a fatal make
error but for the fact that the -
prefix tells make
to ignore that error.
So make
proceeds and everything, including prog.d
gets made, and thereafter
prog.d
will be regenerated whenever any rule - including the rule in prog.d
itself - requires prog.o
to be recompiled.
这篇关于同一Makefile中make目标之间的递归依赖关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!