为啥 Makefile 目标依赖于两个目标,但只运行一次?
Posted
技术标签:
【中文标题】为啥 Makefile 目标依赖于两个目标,但只运行一次?【英文标题】:Why the Makefile target is dependent on two targets, but only run once?为什么 Makefile 目标依赖于两个目标,但只运行一次? 【发布时间】:2021-10-09 07:33:45 【问题描述】:write:
@echo `date`
file_1: write file_2
@echo "file_1 begin"
$(shell sleep 3)
@echo "file_1 end"
file_3: write file_4
@echo "file_3 begin"
$(shell sleep 3)
@echo "file_3 end"
all: file_1 file_3
.PHONY: write
当我运行 make 时,它会输出:
Sat Oct 9 15:22:45 CST 2021
file_1 begin
file_3 begin
file_1 end
file_3 end
target write
只运行一次。
我的最终目标是通过写目标write
的开始时间来计算file_1
和file_3
的执行时间。在测试是否会覆盖的过程中,发现了以上问题。如果有更好的计算时间的方法,请告诉我。
【问题讨论】:
它按预期工作。我不认为一个目标可以多次执行。要测量时间,请考虑使用time
命令。
Makefile 目标不类似于函数,表达对目标的依赖也不类似于调用函数。 make
确定需要构建哪些目标,以什么顺序,以便请求的目标目标在其依赖关系方面是最新的。在给定的运行中,没有任何目标被构建超过一次。
另外,依赖任何目标的依赖列表的顺序是不明智的。您发现与此类排序相关的任何行为模式都来自make
实现细节,而不是make
实用程序的规范。
【参考方案1】:
首先,在配方中使用$(shell ...)
函数几乎总是错误的。配方已经在 shell 中运行,因此不需要它,并且它具有意外行为。为什么不在这里直接使用@sleep 3
?
没有办法在一次 make 调用中多次构建单个目标。那将是非常糟糕的:考虑如果您有多个程序都依赖于一个.o
文件,例如:您想多次重新编译该.o
文件吗?
无论如何,这不会真正做到你想要的:
file_1: write file_2
这并没有测量file_1
的执行时间,因为写入了开始日期,然后构建了file_2
,然后构建了file_1
。所以你也包括了file_2
的执行时间。
当然,如果您启用了并行构建,那么所有的赌注都没有了。
如果您想测量某些东西,请将启动/停止操作放在配方中,而不是使用先决条件。您可以将其隐藏在变量中以减少输入的繁琐。
【讨论】:
感谢您的回答。关于 $(shell...) 的使用,已更正。因为以前不知道`
不能在'
中使用。 Put the start/stop operation in the recipe without using prerequisites.
配方中的执行时间是否忽略了先决条件?
我不太明白需要shell
的问题,但无论如何,这并不重要。在完成所有先决条件后,将作为一个单元调用配方。因此,如果您将开始时间作为配方中的第一个命令,它将显示该配方开始的时间,而不包括其任何先决条件。您可以轻松地对此进行试验。以上是关于为啥 Makefile 目标依赖于两个目标,但只运行一次?的主要内容,如果未能解决你的问题,请参考以下文章