配方命令的彩色打印

Colorise printing of recipe commands

我想要 运行 Makefile with/without 详细模式的选项,并对配方中命令的打印进行着色。

经过一些研究,我发现实现 "verbose mode" 的典型方法是引入一个变量 VERBOSE,可以在命令行上设置,如下例所示。

SHELL=/bin/bash

.PHONY: all hack

red = 3[31;1m
green = 3[32;1m
reset = 3[0m

VERBOSE ?= 0
export VERBOSE
AT_0 := @
AT_1 :=
AT    = $(AT_$(VERBOSE))

all:
    $(AT) printf '$(green)%s\n$(reset)' "GNU Is Not UNIX"

hack:
    @\
    if [[ $${VERBOSE} -eq 1 ]]; then \
      printf '$(red)%s\n$(reset)' "printf '$(green)%s\n$(reset)' \"GNU Is Not UNIX\""; \
    fi; \
    printf '$(green)%s\n$(reset)' "GNU Is Not UNIX"

如您所见,现在可以选择在食谱中显示关键命令:

usr@cmptr $ make
GNU Is Not UNIX
usr@cmptr $ make VERBOSE=1
printf '3[32;1m%s\n3[0m' "GNU Is Not UNIX"
GNU Is Not UNIX

现在回到开头。有没有人建议我如何修改这种方法,这样它也可以为配方的命令着色 而无需 修改命令本身的输出颜色?

所需结果显示在 hack 目标中

usr@cmptr $ make VERBOSE=1 hack
printf '3[32;1m%s\n3[0m' "GNU Is Not UNIX"
GNU Is Not UNIX

这不是处理冗长模式的最佳方式。看看 http://make.mad-scientist.net/managing-recipe-echoing/

通过在开头添加 @ 来抑制的输出是由 make 打印的,而不是由 shell 打印的。没有办法让 make 为其输出着色(除了编辑 make 的源代码)。

如果你想看到彩色的命令,你必须自己打印出来。如果这样做,您将希望一直按字面意义使用 @,并且不允许通过 VERBOSE 或其他方式覆盖它。您的规则都必须采用以下格式:

foo:
        @ printf '$(green)%s$(reset)\n' 'my command'; my command

如果你也想要详细模式,除非你启用它,否则它不会打印命令,你必须将这些结合起来。一种选择是使用您可以调用的宏,如下所示:

ifeq ($(VERBOSE),)
    run = @ 
else
    run = @ printf '$(green)%s$(reset)\n' '$(subst ','\'',)'; 
endif

foo:
        $(call run,my command)

请注意,如果 my command 可以包含逗号,则您必须在 make 中隐藏它们。