本文介绍了如何强制Make重启并重新加载生成的Make文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
手头的任务如下:在食谱中调用的外部工具生成一个Makefile,它应该立即被make包括在内。然后,另一个规则使用包含的数据生成进一步的包含文件。Make应该再次重新启动,然后才能处理进一步的规则。请考虑以下示例:$(info ------- Restart $(MAKE_RESTARTS))
all :
include a
include b
a : p
touch a
b : a
touch b
是这样的:
touch p
make
------- Restart
touch a
touch b
------- Restart 1
make: Nothing to be done for 'all'.
我的问题是,规则b需要a中包含的数据,但b是在包含a的更新版本之前执行的。在执行b之前应该重新启动make。如何实现这一点?我想看看这个: touch p
make
------- Restart
touch a
------- Restart 1
touch b
------- Restart 2
make: Nothing to be done for 'all'.
很容易检测是否包含a,如果不包含a,则可以隐藏b的规则。这对于干净的构建是有效的,但当磁盘上已经存在来自上一次构建的时就不起作用了,并且由于更新了p而触发了规则。只有Make知道规则a:p是否为最新,无法使用条件表达式进行检查。
有解决方案吗?
更新:根据@MadScience的建议,我将其工作方式如下:
$(info ------- Restart $(MAKE_RESTARTS))
all :
include b
include a
a : p
@echo rule A
touch a
$(eval upd=1)
b : a
@echo rule B
$(if $(upd),@echo b skipped,touch b)
和输出:
touch p
make
------- Restart
rule A
touch a
rule B
b skipped
------- Restart 1
rule B
touch b
------- Restart 2
完美!谢谢大家,大家圣诞快乐。
推荐答案
一种解决方案是调用子生成b
。该子制造商将包括较新的a
,因此将是正确的。我相信这样的东西会奏效(未经测试):
$(info ------- Restart $(MAKE_RESTARTS))
all :
include a
include b
a : p
touch a
ifeq ($(filter real_b,$(MAKECMDGOALS)),)
b : a
$(MAKE) real_b
endif
.PHONY: real_b
real_b:
touch b
另一种解决方案是确保b
在a
更新时而不是更新。可能是这样的(同样,未经过测试):
$(info ------- Restart $(MAKE_RESTARTS))
all :
include a
include b
BUILT_A =
a : p
touch a
$(eval BUILT_A = true)
b : a
$(if $(BUILT_A),,touch b)
(在食谱中罕见地合法使用eval
!)在此版本中,如果构建了a
,则不会触及b
。这样,在make re-execs本身之后,它将包括a
和Includeb
,然后看到a
是最新的,但看到b
已过期(因为我们第一次跳过了构建步骤)并重建b
:这次b
将被更新,因为a
在前一遍中被更新,然后make将再次重新执行自己。
这篇关于如何强制Make重启并重新加载生成的Make文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!