12

我正在使用makefile来编译由许多.c文件组成的程序,并且任何时候make调用它都只会编译上次运行后修改的那些文件(直到这里没有什么特别的)。

为了避免弄乱我的屏幕,我@在每次$(CC)通话开始时预先准备好,并在它之前打印一条自定义echo消息。例如:

%.o: %.c $(h1) $(h3) %.h
    @echo -e "\tCompiling <" $< 
    @$(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS)

我的问题是:我怎样才能make以更“动态的方式”控制冗长,以便能够:

  1. 正常行为:只为每个执行的 makefile 规则打印一条自定义消息。
  2. 详细行为:打印每个 makefile 规则实际执行的命令(好像@根本没有使用)。
4

5 回答 5

16

我会像 automake 那样做:

V = 0
ACTUAL_CC := $(CC)
CC_0 = @echo "Compiling $<..."; $(ACTUAL_CC)
CC_1 = $(ACTUAL_CC)
CC = $(CC_$(V))

%.o: %.c $(h1) $(h3) %.h
        $(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS)

如果您需要在规则中执行其他命令,我喜欢下面的代码片段。写$(AT)而不是,@它会在什么时候保持沉默,V=0但在什么时候打印V=1

AT_0 := @
AT_1 := 
AT = $(AT_$(V))
于 2012-02-16T20:29:20.490 回答
9

另一种解决方案(我喜欢它,因为它很灵活)

ifeq ("$(BUILD_VERBOSE)","1")
Q :=
vecho = @echo
else
Q := @
vecho = @true
endif

%.o: %.c
    $(vecho) "-> Compiling $@"
    $(Q)$(CC) $(CFLAGS) -c $< -o $@

你可以跳过 vecho 的东西,但它有时会派上用场。

于 2012-03-07T22:02:16.580 回答
5

您可以省略“@”并将“-s”选项传递给您的 make 命令,而不是使用“@gcc”进行编译。(保持“@echo”不变。)然后“make -s”将是您的简短 make 命令,而“make”将是冗长的。

'-s' 或 '--silent' 标志可防止所有回显,就好像所有食谱都以'@'开头。

来自 GNU Make 手册页

(其他答案更好地回答了您的问题,但这种方法值得一提。)

于 2015-09-20T21:57:12.087 回答
4

我会创建一个函数,它需要一个命令来执行并决定是否回显它。

# 'cmd' takes two arguments:
#   1. The actual command to execute.
#   2. Optional message to print instead of echoing the command
#      if executing without 'V' flag.
ifdef V
cmd = $1
else
cmd = @$(if $(value 2),echo -e "$2";)$1
endif

%.o: %.c $(h1) $(h3) %.h
    $(call cmd, \
        $(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS), \
        Compiling $<)

那么普通make调用的结果将是这样的:

Compiling foo.c

鉴于make V=1将给出:

gcc -Wall -c foo.c -o foo.o ...
于 2012-02-16T16:19:37.020 回答
3

由于我无法对该AT = $(AT_$(V))建议发表评论,请注意 Automake 确实提供了一个标准宏,它与 执行相同的操作AT,称为AM_V_at.

您还会发现它还有另一个非常有用AM_V_GEN的变量,可以解析为 nothing 或@echo " GEN " $@;,具体取决于详细程度。

这允许您编写如下代码:

grldr.mbr: mbrstart
    $(AM_V_GEN)
    $(AM_V_at)-rm -f grldr.mbr
    $(AM_V_at)cat mbrstart > grldr.mbr

其输出将是(详细禁用):

  GEN    grldr.mbr

或(启用详细信息):

rm -f grldr.mbr
cat mbrstart > grldr.mbr

非常方便,这消除了定义自己的宏的需要。

于 2014-11-12T19:24:37.257 回答