“如何读取文件”的示例

时间:2015-02-03 06:55:49

标签: makefile gnu-make

在GNU-Make手册中如何制作阅读Makefile https://www.gnu.org/software/make/manual/make.html#Reading-Makefiles部分

GNU make在两个不同的阶段开展工作。在第一阶段,它读取所有makefile,包括makefile等,并内化所有变量及其值,隐式和显式规则,并构建所有目标及其先决条件的依赖关系图。在第二阶段,make使用这些内部结构来确定需要重建的目标,并调用必要的规则。

我无法清楚地了解这两个阶段的差异。可能正在寻找一个有助于理解的例子。是否有任何链接或教程阐明了第一阶段和第二阶段到底发生了什么。

1 个答案:

答案 0 :(得分:7)

拿这个琐碎的makefile:

var := some_other_file

some_file: $(var)
  some_command $^ $@

第一阶段后,文件将如下所示

var := some_other_file

some_file: some_other_file
  some_command $^ $@

请注意$^$@尚未展开的方式,只会扩展和调用食谱作为第2阶段的一部分。

在阶段2中,make将使用阶段1产生的规则并确定需要重新制作哪些目标,您可以看到make"如何思考"通过使用-d标志运行make(警告:输出很多)。

在上述案例的第2阶段,在检查了所有some_other_file的依赖关系并在必要时重新生成后,它会考虑some_other_file是否比some_file更新。

如果是这种情况那么(并且只有那时)是食谱'扩展变量,并将每行的内容传递给shell,这里将是some_command some_other_file some_file

因此,除了作为食谱的一部分之外,您无法在任何地方使用$@等,因为自动变量仅在第2阶段设置。

foo: $@bar
  some_command $^

这将在第1阶段扩展为:

foo: bar
  some_command $^

在第2阶段将导致:

foo: bar
  some_command bar

可能不是你想要的。

有些人有办法解决这个限制。例如,GNU make有.SECONDEXPANSION,以下内容将按预期工作:

.SECONDEXPANSION:
foo: $$@bar
  some_command $^

{1}}之后的任何内容都将在第1阶段展开:

.SECONDEXPANSION

和阶段2:

.SECONDEXPANSION:
foo: $@bar
  some_command $^