2012-02-16 79 views
11

我正在使用makefile編譯一個由多個.c文件組成的程序,並且任何時候調用make它只會編譯上次運行後修改的那些文件(此處沒有特別之處)。控制make的詳細程度

爲了避免弄亂我的屏幕,我在每個$(CC)通話開始時預先考慮@,和之前我打印定製echo消息。例如:

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

我的問題是:我怎麼能控制make更「動態的方式」的詳細程度,以便能夠:

  1. 正常行爲:只有一個爲每個執行的生成文件規則打印自定義消息。
  2. 詳細行爲:打印每個生成​​文件規則實際執行的命令(就好像根本沒有使用@)。

回答

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)[email protected]$(MATHOPTS) 

如果您需要在規則中執行其他命令,我喜歡以下代碼片段。寫$(AT)而不是@,它將在V=0時保持沉默,但在V=1時打印。

AT_0 := @ 
AT_1 := 
AT = $(AT_$(V)) 
+2

在你的第一部分中,我想還​​需要重寫'CC = $(CC _ $(V))'。 – 2012-02-16 22:20:19

+1

是的。缺席是我現在要解決的一個大腦放屁。我還應該指出,遞歸變量擴展已經得到了廣泛的實施,但目前在POSIX中還沒有實現(但在未來的版本中將會改變)。 – 2012-02-17 07:34:51

+1

偉大的解決方案@JackKelly。創建'AT'變量的那個簡單而有效! – 2012-02-22 18:47:46

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)[email protected]$(MATHOPTS), \ 
     Compiling $<) 

然後平原make調用的結果會是這樣的:

Compiling foo.c 

make V=1會給:

gcc -Wall -c foo.c -o foo.o ... 
+0

感謝@Eldar!你的建議非常好,但重新定義Jack提出的「@」更簡單。順便說一句,我完全不知道你可以這樣定義一個函數。 – 2012-02-22 18:49:29

+0

@尼古拉斯,不客氣! – 2012-02-22 22:43:29

7

另一種解決方案(其中一個我喜歡,因爲它的靈活)

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

%.o: %.c 
    $(vecho) "-> Compiling [email protected]" 
    $(Q)$(CC) $(CFLAGS) -c $< -o [email protected] 

可以跳過vecho的東西,但它有時派上用場。

+0

輝煌的解決方案。 – Benoit 2016-07-26 12:12:35

3

既然不能在AT = $(AT_$(V))建議發表評論,請注意Automake的確實提供了一個標準的宏做同樣的事情爲AT,這就是所謂AM_V_at

你還會發現,它還有另一個非常有用的AM_V_GEN變量,解析要麼沒有或@echo " GEN " [email protected];,取決於冗長。

這可以讓你的代碼是這樣的:

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 

非常方便,這就不需要定義自己的宏。

+0

這是要走的路! – rockdaboot 2017-06-22 09:29:45

4

代替使用「@gcc」進行編譯,您可以省略該「@」並將「-s」選項傳遞給make命令。 (保留「@echo」原樣)。然後,「make -s」將是您的簡短命令,「make」將是冗長的。

的「-s」或者「--silent」標誌,使防止所有呼應,彷彿所有的食譜開始與「@」。

From the GNU Make manual pages

(其他的答案更好地回答你的問題,但這種做法值得一提。)