本文介绍了如何强制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

另一种解决方案是确保ba更新时而不是更新。可能是这样的(同样,未经过测试):

$(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文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 01:05