我正在使用makefile来编译由许多.c
文件组成的程序,并且在任何时候make
被调用它只会编译在最后一次运行之后修改的文件(在此之前没有什么特别的)。
为避免我的屏幕混乱,我在每个@
电话的开头添加$(CC)
,在此之前我会打印自定义的echo
消息。例如:
%.o: %.c $(h1) $(h3) %.h
@echo -e "\tCompiling <" $<
@$(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS)
我的问题是:如何以更“动态的方式”控制make
的详细程度,以便能够:
@
一样)。答案 0 :(得分: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))
答案 1 :(得分:8)
另一种解决方案(我喜欢它的一种解决方案,因为它很灵活)
ifeq ("$(BUILD_VERBOSE)","1")
Q :=
vecho = @echo
else
Q := @
vecho = @true
endif
%.o: %.c
$(vecho) "-> Compiling $@"
$(Q)$(CC) $(CFLAGS) -c $< -o $@
你可以跳过vecho的东西,但它确实派上用场了。
答案 2 :(得分: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 ...
答案 3 :(得分:4)
而不是使用&#34; @ gcc&#34;编译,你可以省略&#34; @&#34;并传递&#34; -s&#34;改为make命令的选项。 (离开&#34; @ echo&#34;原样。)然后&#34; make -s&#34;将是你简短的make命令,&#34; make&#34;会很冗长。
要生成的'-s'或'--silent'标志会阻止所有回显,就好像所有食谱都以'@'开头一样。
From the GNU Make manual pages
(其他答案更好地回答了你的问题,但这种方法值得一提。)
答案 4 :(得分:3)
由于我无法对AT = $(AT_$(V))
建议发表评论,请注意Automake确实提供了与AT
完全相同的标准宏,称为AM_V_at
。
您还会发现它还有另一个非常有用的AM_V_GEN
变量,可以解析为空或@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
非常方便,这样就无需定义自己的宏。