首页 > 解决方案 > 在 Makefile 中打印所有正在进行的目标

问题描述

我编写了一个 makefile,它具有非常复杂的依赖关系,并并行执行多个作业(例如 make -j100)。我正在尝试找到一种方法来打印所有当前正在运行的目标名称。任何想法?提前致谢。

标签: makefilegnu-make

解决方案


如果您想要的是一种可以在 make 运行时不时运行的命令,并且显示所有当前正在执行的配方,您可以稍微修改您的配方,以便它们首先创建一个具有目标名称的临时文件,做他们应该做的任何事情并删除临时文件。随时列出这些临时文件将向您显示当前正在执行的配方。

例如,如果所有目标都位于调用 make 的目录下(或其子目录):

TAGSDIR := .tags
MKTAG   = mkdir -p "$(TAGSDIR)/$(@D)" && touch "$(TAGSDIR)/$@"
RMTAG   = rm -f "$(TAGSDIR)/$@"

<target>: <prerequisites>
  @$(MKTAG)
  <regular recipe>
  @$(RMTAG)

并列出所有文件.tags以获取所有当前正在运行的配方的名称。示例find

find .tags -type f -printf '%P\n'

您甚至可以将其封装在无限循环中并刷新列表,例如每秒:

while true; do clear; find -type f -printf '%P\n'; sleep 1; done

编辑

Andreas注意到,只有当目标都位于调用 make 的目录下时,这才有效。例如,如果目标是../foobar,则临时标记文件将是.tags/../foobar,这不是我们想要的。

Andreas建议..\.\./替换\/。我们也许可以在 GNU/Linux 和 macOS 下找到一种方法来做这样的事情(但不完全是,文件名中不能有斜杠),但在 Windows 下仍然可能存在其他问题(C:、反斜杠...)。

我们还可以将目标的名称存储在文本文件中,并使用mktemp或等价物生成具有唯一名称的文本文件。但是我们需要一种方法将这个唯一的名称从 传播MKTAGRMTAG。这可以通过 shell 变量和单行配方(或.ONESHELL特殊目标)实现,但不是很好。

当您使用 GNU make 时,我们也可以使用和创建名为但我不知道在 Windows 下使用驱动器号做什么的abspath临时文件,也不知道您是否可以在 Windows 下命名文件...$(TAGSDIR)/$(abspath $@)abspathsomething\c:\something

因此,如果您的目标并非全部位于调用 make 的目录下,则最好使用另一种解决方案。


推荐阅读