同一Makefile中make目标之间的递归依赖关系 [英] Recursive Dependencies Between make Targets in Same Makefile

查看:451
本文介绍了同一Makefile中make目标之间的递归依赖关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个makefile,该文件能够确定何时更改了标头,然后重新编译相应的.cpp文件.为了对此进行测试,我创建了三个文件:main.cppa.hb.h. main.cpp包括s a.ha.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.hb.hmain.cpp的任何组合时,我希望重新编译prog.尽管如此,prog仅在更改a.hmain.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.cppa.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.hb.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.cppa.hb.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆