Makefile:声明包含文件之间的依赖关系
使用make的“重新生成生成文件”功能,我使用Makefile:声明包含文件之间的依赖关系,makefile,gnu-make,Makefile,Gnu Make,使用make的“重新生成生成文件”功能,我使用include指令生成生成生成文件的一部分(请参阅)。现在,我无法理解如何表达包含的makefile之间的依赖关系。它们似乎都是一次评估出来的 考虑以下说明我的问题的最小生成文件: all: -include foo.make -include bar.make foo.make: Makefile echo FOO:=blub bla baz > foo.make bar.make: Makefile foo.make
include
指令生成生成生成文件的一部分(请参阅)。现在,我无法理解如何表达包含的makefile之间的依赖关系。它们似乎都是一次评估出来的
考虑以下说明我的问题的最小生成文件:
all:
-include foo.make
-include bar.make
foo.make: Makefile
echo FOO:=blub bla baz > foo.make
bar.make: Makefile foo.make
echo BAR:=$(FOO) > bar.make
如果我现在运行make
,我将获得:
$ cat foo.make
FOO:=blub bla baz
$ cat bar.make
BAR:=
为什么??既然bar.make
依赖于foo.make
,那么bar.make
的评估不应该等到它成功包含foo.make
我如何解决这个问题,并确保bar.make
在以后重新计算,或者只在foo.make
存在时计算一次。make包括在内,并且可以定义变量bar
我无法将foo.make
和bar.make
合并到单个makefile中的原因有两个:
首先,在我的实际设置中,bar.make
依赖于更多的中间目标,而这些中间目标反过来又依赖于foo.make
。因此,在创建foo.make
时,还不能创建bar.make
的内容
其次,在我的实际设置中,foo.make
和bar.make
不仅定义变量,而且定义/endef块。所以我必须写:
-include makefile_with_prerequisite_variables
define MYDEF
sometarget-$1: $(TARGET_$1_PREREQUISITES)
[...]
endf
-include makefile_with_eval_call_statements
带有前提条件变量的makefile\u和带有eval\u call\u语句的makefile\u的内容不能包含在单个makefile片段中:
- 如果我在
MYDEF
上面放置makefile\u和
以及makefile\u和前提变量
,那么$eval($call(MYDEF))
语句将无法工作,因为MYDEF
只是在后面声明的
- 如果我将
makefile\u和前提条件变量
放在MYDEF
下面,再加上makefile\u和评估调用语句
,那么MYDEF
中定义的配方将没有适当的前提条件,因为$(目标条件1)
变量随后将由makefile\u和前提条件变量声明
总之,我需要包含两个不同的makefile,其中一个依赖于另一个。我不知道如何表达这种关系,这样一个makefile的内容只能在另一个makefile更新并包含在主makefile中之后才能创建。首先,在这个简单的示例中,您的makefile创建可以通过转义$(FOO)的值轻松修复
这样,在创建bar.make
时,它不会被展开,而是推迟到读入时。因此:
bar.make: Makefile foo.make
echo 'BAR:=$$(FOO)' > $@
但是,在更复杂的实际makefile中,这可能还不够
gnumake的工作原理如下:首先解析所有makefile。然后,对于每个包含的makefile,将其视为目标并尝试构建它(例如,就像用户调用了makeinclude1.mk include2.mk include3.mk…
)。最后,如果重建了包含的任何makefile,请重新执行我们自己,从头开始整个过程
GNU make不是这样工作的:解析makefiles,尝试重建包含的第一个makefile,如果重建了,则重新执行;如果它没有被重建,继续下一个包含的makefile,等等
如果您必须拥有这种类型的订单,您可以使用的一个简单技巧是将包含的bar.make
放入foo.make
:
all:
-include foo.make
foo.make: Makefile
printf -- '-include bar.make' > $@
echo FOO:=blub bla baz >> $@
bar.make: Makefile foo.make
echo 'BAR:=$$(FOO)' > $@
这样做可以确保如果foo.make
不存在,make就看不到bar.make
的包含,因此它不会尝试构建它。只有在第一次重新执行后,才会看到包含的条。制作并尝试构建它
有一件事:如果你得到了最新版本的GNU,你就不再需要使用-include
技巧了。即使生成了makefiles,您也可以使用include
。您又一次保存了我的一天!如果我能给你更多的选票,我会的。你的两个建议都很有价值。谢谢!