强制make从文件中查找过期条件

时间:2012-06-20 13:43:50

标签: makefile gnu-make

(这与GNU make: Execute target but take dependency from file类似,但略有不同)。

当我尝试强制构建目标时,make会自动认为此目标已过期并强制运行所有依赖它的目标。

在我的情况下,目标是一个递归的make调用,它做了很多工作,可能只返回“无所事事”:

 .PHONY: intermediate.dat
 intermediate.dat:
      $(MAKE) expensive_chain_which_finally_creates_intermediate.dat

 step1.dat: intermediate.dat
      sleep 10

 step2.dat: step1.dat
      sleep 15

 step3.dat: step2.dat
      sleep 10

 all: step3.dat
      sleep 5

在这种情况下,“make all”运行40秒,虽然intermediate.dat可能没有更改(递归make返回“没什么可做的”)。但是,如果递归make更新了intermediate.dat,则目标应该是过时的。

真的没办法吗?

此致 DIVB

2 个答案:

答案 0 :(得分:2)

让虚假目标上的intermediate.dat 依赖,而不是虚假目标。

 .PHONY : always-remake

 intermediate.dat : always-remake
IIRC,我最后一次解决了这个问题,.PHONY没有按预期工作,我使用了:

 always-remake :
     @true

代替。但是,我不记得为什么,所以先试试.PHONY。

intermediate.dat本身虚假的问题是make 永远不会检查虚假文件的存在/日期,这是您想要的行为。您只需触发重建规则,该规则由过时的先决条件完成;虚假的先决条件总是过时的,所以它完成了这项工作。

答案 1 :(得分:0)

另一个技巧是使用order-only prerequisite,以及对make的递归调用。当您想要在需要创建intermediate.dat文件时实现一些额外的逻辑,或者当您想要将目标与exists && newer than make检查的常规.PHONY检查分离时,这非常有用

例如:

我们假设该文件包含后续任务所依赖的日期敏感材料,并且该文件在 12小时之后过期。我们只想在其中任何一个为真时重新创建文件:

  • 该文件超过12小时
  • 该文件不存在

实施制作目标&食谱,我们将创建一个check-intermediate.dat make目标,该目标会运行时间检查,如果文件已过期,则会有条件地删除该文件,然后重新运行check-intermediate.dat那个文件。

请注意,intermediate.dat: | check-intermediate.dat目标将通过order-only prerequisite syntax定义(例如intermediate.dat),这会导致它始终在目标之前运行(例如make)。时间检查费用低廉,我们一直希望它能够为我们运行和管理文件,但如果intermediate.dat上的原始.PHONY检查已经像normal prerequisite {{ 1}}目标会。

 .PHONY: check-intermediate.dat
 check-intermediate.dat:
    if [ -e intermediate.dat ]; then  find intermediate.dat -mmin +720 -exec bash -c 'rm -f "{}"; $(MAKE) intermediate.dat' \; ; fi

 intermediate.dat: | check-intermediate.dat
    echo run-expensive-tasks-here-to-create-intermediate.dat
 step1.dat: intermediate.dat
    sleep 10

 step2.dat: step1.dat
    sleep 15

 step3.dat: step2.dat
    sleep 10

 all: step3.dat
    sleep 5

现在,任何依赖于intermediate.dat目标的内容都将首先运行检查,如果文件已过期则删除该文件,并在运行其余的相关目标之前重新运行make intermediate.dat 。如果intermediate.dat文件已经存在,它将运行检查,如果检查通过,它将继续运行,而不会花费时间昂贵的娱乐任务。

依赖于.PHONY目标的问题在于,总是运行依赖于它的任务,因为GNU Make handles .PHONY targets的方式。这可能导致make运行总是执行昂贵的时间操作,即使它不需要:

  

伪目标不应该是真实目标文件的先决条件;如果是,每次make更新该文件时都会运行其配方。只要虚假目标永远不是真实目标的先决条件,只有当虚假目标是指定目标时才会执行虚假目标配方(参见指定目标的参数)。