同一生成文件中的 make 目标之间的递归依赖关系
Recursive Dependencies Between make Targets in Same Makefile
我正在尝试编写一个能够确定何时更改标头的makefile,然后重新编译相应的.cpp文件。为了测试这一点,我创建了三个文件:main.cpp
、a.h
和b.h
。main.cpp
包括 sa.h
,a.h
包括b.h
。
我的生成文件如下所示:
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
时才会重新编译,最后一行似乎被忽略了。
我做错了什么,我怎样才能完成我想要的事情,而无需像这样将完整和完整的标头集添加到每个单独的.cpp文件中(因为对于较大的项目,这可能会变得非常麻烦):
prog: main.cpp a.h b.h
g++ ...
我做错了什么
您的规则:
a.h: b.h
只是告诉make
a.h
取决于b.h
,即a.h
需要 以make
可以从makefile确定的任何方式进行(重新)制作,如果a.h
早于b.h
或不存在。
它没有告诉make
该怎么做才能从b.h
重制a.h
。您的生成文件 不包含从b.h
重制a.h
的食谱。它只包含一个食谱 用于从main.cpp
和a.h
中重制prog
,即:
prog: main.cpp a.h
g++ main.cpp -o prog
此外,make
当然没有内置的制作配方规则a.h
来自b.h
.因此,在没有任何从b.h
制作a.h
的配方的情况下 它假定此依赖项不需要执行任何操作。没有 其他合理的违约。所以即使a.h
比b.h
年长,也没什么 是为了a.h
;虽然prog
取决于a.h
,但什么也不需要做 以prog
该帐户。
这是幸运的,因为事实上你不希望a.h
被翻拍 无论如何,当b.h
发生变化时,你不希望main.cpp
在a.h
或b.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.cpp
,a.h
和b.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
。
- 通过递归进行因子分解
- 递归函数计算序列中的平方和(并输出过程)
- 使用递归的数组的最小值.这是怎么回事
- 递归列出所有目录中的C++与Python与Ruby的性能
- 递归计数给定目录的文件和所有目录
- 如何在BST的这个简单递归实现中消除警告
- C++:正在检查LinkedList中的回文-递归方法-错误
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 递归无序映射
- TSP递归解的迭代形式
- 如何在Elixir中调用递归函数并行
- 返回递归调用和仅递归调用的区别
- 数组元素打印的递归方法
- 使用递归时获取变量的奇怪值
- 我已经建立了递归关系,它找到了两个字符串之间最长的连续公共字符串,我怎么能跳过其中一个字符串中的一个字符
- 递归函数,用于查找 2 个整数之间的最大值
- 同一生成文件中的 make 目标之间的递归依赖关系
- 静态和非静态递归成员之间的差异
- 递归函数参数中前递减和递减后之间的差异
- C++递归函数,可反转数组索引在两个边界之间的顺序