我有以下内容Makefile
:
$ cat Makefile
all: foo
foo: bar
@true
bar: file.txt
touch file.txt
file.txt:
@echo 'Created file.txt'
run:
@echo 'Target without dependency.'
$
当我执行时make
,touch file.txt
即使它已经存在,then 也总是被执行。为什么会这样?bar
如果满足依赖性(即存在),我预计目标不会运行file.txt
。另外,我是否正确地默认选择我的示例中指定的make
第一个目标?Makefile
all
答案1
首先,make 并不关心命令正在做什么;它只关心命令正在做什么。它只是将它们传递给 shell。
其次,由于您从未创建任何bar
文件,file.txt
因此总是比 更新bar
,bar: file.txt
规则将匹配,并且touch file.txt
命令将运行。
显然,您应该在以目标为目标的file.txt
规则中触摸或创建。file.txt
另外,我是否正确地认为 make 默认选择 Makefile 的第一个目标(在我的示例中名为 all)?
是的。
答案2
您Makefile
没有使用任何非标准功能,因此您的问题不是特定于 GNU make 的。
makefile 中的第一个常规目标是全部,这使其成为所谓的默认目标。
因为我假设
"all"
文件系统中不存在名为 的文件,并且 makefile 不会创建文件,所以all
可以将其视为始终被视为过时的伪目标。all
取决于foo
它也不是由 makefile 创建的,因此也总是被认为是过时的。foo
取决于bar
并且何时foo
“创建”(从 makefile 的角度来看),true
执行虚拟命令...但不是名为foo
.所以foo
也总是被认为是过时的。bar
取决于file.txt
并且何时bar
“创建”(从 makefile 的角度来看),该命令touch file.txt
被执行。这使得file.txt
更近,如果文件bar
确实存在,这将主动使bar
相对于 过时file.txt
,因为bar
将不再比 更年轻file.txt
。使最近的命令
file.txt
只是一个echo
命令,对但没有任何影响file.txt
,但因为任何make
实现都假定一个特殊的日期比任何文件都年轻(不检查目标文件的实际存在或时间戳)运行目标命令后,这不会导致运行make
失败。
所以你的 makefile 不会file.txt
在规则中make 或 remake file.txt
。
另一方面,您的makefile
制作file.txt
相对于预计的处理bar
时间来说bar
已经过时了。请注意,这bar
取决于file.txt
.
我建议您从更简单的 makefile 开始,以了解其工作原理make
。