理解GNU make的执行流程

理解GNU make的执行流程

我有以下内容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.'
$

当我执行时maketouch file.txt即使它已经存在,then 也总是被执行。为什么会这样?bar如果满足依赖性(即存在),我预计目标不会运行file.txt。另外,我是否正确地默认选择我的示例中指定的make第一个目标?Makefileall

答案1

首先,make 并不关心命令正在做什么;它只关心命令正在做什么。它只是将它们传递给 shell。

其次,由于您从未创建任何bar文件,file.txt因此总是比 更新barbar: 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

相关内容