同一生成文件中的 make 目标之间的递归依赖关系



我正在尝试编写一个能够确定何时更改标头的makefile,然后重新编译相应的.cpp文件。为了测试这一点,我创建了三个文件:main.cppa.hb.hmain.cpp包括 sa.ha.h包括b.h

我的生成文件如下所示:

prog: main.cpp a.h
g++ main.cpp -o prog
a.h: b.h

a.hb.hmain.cpp的任意组合被更改时,我希望prog被重新编译。尽管如此,prog只有在更改a.hmain.cpp时才会重新编译,最后一行似乎被忽略了。

我做错了什么,我怎样才能完成我想要的事情,而无需像这样将完整和完整的标头集添加到每个单独的.cpp文件中(因为对于较大的项目,这可能会变得非常麻烦):

prog: main.cpp a.h b.h
g++ ...

我做错了什么

您的规则:

a.h: b.h

只是告诉makea.h取决于b.h,即a.h需要 以make可以从makefile确定的任何方式进行(重新)制作,如果a.h早于b.h或不存在。

它没有告诉make怎么做才能从b.h重制a.h。您的生成文件 不包含从b.h重制a.h的食谱。它只包含一个食谱 用于从main.cppa.h中重制prog,即:

prog: main.cpp a.h
g++ main.cpp -o prog

此外,make当然没有内置的制作配方规则a.h来自b.h.因此,在没有任何b.h制作a.h的配方的情况下 它假定此依赖项不需要执行任何操作。没有 其他合理的违约。所以即使a.hb.h年长,也没什么 是为了a.h;虽然prog取决于a.h,但什么也不需要做 以prog该帐户。

这是幸运的,因为事实上你不希望a.h被翻拍 无论如何,当b.h发生变化时,你不希望main.cppa.hb.h发生变化时以任何方式重制。你希望程序是 当它们中的任何一个发生变化时重新制作。你想要的是由任何 以下生成文件:

1

prog: main.cpp a.h b.h
g++ main.cpp -o prog

阿拉伯数字

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

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需要重新制作,即:

g++ main.cpp -o prog

如何在不添加完整和完整的 每个单独的.cpp文件的标头,如下所示 (因为对于较大的项目,这可能会变得非常麻烦)

确实会,因此,海湾合作委员会编译器长期以来一直 用于生成表示依赖关系的迷你生成文件的功能 将在每个头文件上生成的对象文件 读取以创建对象文件。GNU make可以利用这个特性 以生成这些依赖项文件,并将它们包含在用于构建 GCC 目标的生成文件中。这种合作 GCC 和make称为自动依赖关系生成(或类似)。这 如何在makefile中执行此操作的问题与此重复 如果你谷歌,例如"GCC自动生成依赖",你也可以找到大师治疗。

在评论中,你暗示你对GNU还不够专业 对图示的自动依赖关系生成技术充满信心 在这些答案中。好吧,你可以通过简单的基本实现开始掌握它的窍门 因为这样(这也使 makefile 在其他方面更正常):

生成文件

.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的文档

prog.d是一个迷你生成文件:

$ cat prog.d 
prog.o: main.cpp a.h b.h

表达prog.o的所有依赖关系。第一次运行时,include-ed makefileprog.d将不存在,这将是一个致命的make错误,但-前缀告诉make忽略该错误。 所以make收益和一切,包括prog.d都得到了制作,然后 每当任何规则(包括prog.d中的规则)时,都会重新生成prog.d本身 - 需要重新编译prog.o

最新更新