2012-06-06 130 views
1

說我有以下生成文件沒有指定命令:make執行在makefile

TARGETS = a b c 

all: $(TARGETS) 
    @echo Done. 

%.o: %.cpp 
    @echo Compiling [email protected] 
    touch [email protected] 

%: %.o 
    @echo Building [email protected] 
    touch [email protected] 

我預計,這應該沒有問題,運行:all規則將觸發%,規則,可能會觸發%.o規則,生成a.ob.oc.o文件,然後最終生成a,bc文件。

但是,在運行make導致以下的輸出:

[email protected]:~/Downloads$ make 
g++  a.cpp -o a 
/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/../../../crt1.o: In function `_start': 
(.text+0x20): undefined reference to `main' 
collect2: ld returned 1 exit status 
make: *** [a] Error 1 

爲什麼我試圖運行g++所有的突然?我對此沒有規定。另外,運行make a.o,然後make a工作正常,但運行make a會導致上述行爲。

我該怎麼做才能防止make「想出」它認爲適合目標的命令?

回答

0

最後一條規則似乎被忽略或誤解,因此請回落它對cpp文件的隱含規則(請參閱Catalogue of Implicit Rules)。
它可工作圍繞這個語法:

TARGETS := a b c 

all: $(TARGETS) 
     @echo Done. 

%.o: %.cpp 
     @echo Compiling [email protected] 
     touch [email protected] 

define make_target 
$(1): $(1).o 
     @echo Building [email protected] 
     touch [email protected] 
endef 
$(foreach tgt, $(TARGETS), $(eval $(call make_target, $(tgt)))) 

順便說一句,使用make all而不是make或只有第一個目標將建成。

+0

這很酷!但是,請您解釋一下您的解決方案中發生了什麼,以及它爲什麼可行,而不是我的解決方案? – gablin

+0

其實我沒有解釋爲什麼「%:%o」規則被忽略。但是,如果將其替換爲「%.exe:%o」(與每個目標名稱一起),它就可以工作!我的解決方案爲每個目標(使用define..endef)定義了一個通用規則,並且$(foreach ..,$(eval ..))宏將其擴展爲目標的每個元素(請參閱http:// www .gnu.org /軟件/製作/手動/ make.html#EVAL-功能)。 – Francois

+0

...並回答你最初的問題,因爲「%:%.o」規則被忽略,使得它回到它的C++隱式編譯規則上(參見http://www.gnu.org/software/make/manual /make.html#Catalogue-of-Rules),這就是令人驚訝的g ++調用的來源。 – Francois

0

有三個規則這裏涉及到兩個,你寫道:

%.o: %.cpp 
    @echo Compiling [email protected] 
    touch [email protected] 

%: %.o 
    @echo Building [email protected] 
    touch [email protected] 

,一個是「建」:

%: %.cpp 
    $(CXX) $< -o [email protected]  # There's a little more to it, but never mind. 

當您嘗試建立a,使經過它的規則清單並出現兩位候選人:

%: %.o # yours 
%: %.cpp # built in 

如果a.o已經存在,那麼您的規則優先(這就是爲什麼如果您首先make a.o您的鏈條工作)。如果不是,那麼Make選擇第二個,因爲a.cpp確實存在

如果你不想讓你的構建目標時要考慮這些內置的規則,使用make -r,也被稱爲make --no-builtin-rules.