Makefile 规则在 -s(或 --silent)模式下表现不同

Makefile rules that behave differently with -s (or --silent) mode

在我正在处理的一个大型项目中,有如下所示的规则:

output: input
    echo Building $@; command_to_build output

我认为 Makefile 的作者通常使用 make -s 进行构建,在这种情况下这种情况是有道理的(尽管它确实会阻止您 cut/pasting 来自控制台的东西)。

有没有办法让 make 在静默模式下 运行 时回显 "Building $@" 的等价物,而在 运行 正常时只打印出实际的构建命令?

我想出的中途之家是

output: input
    @echo Building $@
    command_to_build output

比以前稍微好一点(和 -s 看起来一样),但如果你不使用 -s,仍然会向控制台发送垃圾邮件 "Building foo" 消息。

以防万一,此源代码树仅使用 GNU Make 进行编译。

方法是有的,就是有点迂回。诀窍是使用特殊变量 MAKEFLAGS (我相信它是特定于 GNU 的)。

MAKEFLAGS 包含以相当可解析的格式传递给 make 的标志;如果传递了任何单字符形式的选项,则在其第一个单词中分组,如果传递了 none,则 MAKEFLAGS 要么以 - 开头,要么为空。也就是说:

  • make -ks 产量 MAKEFLAGS = ks
  • make -j2 --silent 产量 MAKEFLAGS = s -j --jobserver-fds=3,4
  • make --warn-undefined-variables 产量 MAKEFLAGS = --warn-undefined-variables

等等。所以我们可以使用这个:

ifneq (,$(filter-out -%,$(word 1,$(MAKEFLAGS))))
  SILENT = $(findstring s,$(word 1,$(MAKEFLAGS)))
else
  SILENT =
endif
如果传递 -s--silent--quiet 中的任何一个(或可能在future 其单字符等价物为 -s) 否则为空。以后可以这样使用:

ifeq (s,$(SILENT))
  echo Building $@
endif