2017-05-04 205 views
1

我的項目包含.c和.s(asm)文件。我用'gcc'編譯這兩種類型,並將輸出.o文件放在單獨的目錄'./bin'中。要做到這一點我使用單生成文件的規則是這樣使用通配符搜索先決條件時,Makefile的'vpath'不起作用

bin/%.o: %.[cs] 
     $(CC) $(CFLAGS) -o [email protected] -c $< 

(據我瞭解,在這樣的環境中使用方括號通配符是有點不合常規,但它的工作,它看起來整潔,所以.. 。)

有一天,我決定把我的一些.c文件移動到專用目錄「./common」,所以我在生成文件的開頭添加

vpath %.c common 

。現在,每當我嘗試「製作」時,它就會停止並在我移動的文件上拋出錯誤。例如,對於'common/foo.c'我得到

"*** No rule to make target bin/foo.o, needed by..." 

好像我還沒有指定'vpath'。但是,當我修改的規則只編譯.c文件

bin/%.o: %.c 
     ... ... 

神奇它再次開始正常運行,並檢查「./common」的來源。

看起來像'vpath'機制和通配符不能一起工作,但我仍然是'make'的新手,並且渴望知道這種行爲的確切原因。任何想法的人?提前致謝。

(測試用make-3.81,使-4.1)。


UPD:把所有的文件和 'bin' 目錄駐留在同一水平上,像這樣

|-bin/ 
|-foo.c 
|-bar.s 
|-baz.c 
|-Makefile 

這裏的MWE

ROOTS = foo.o bar.o 
OBJS = baz.o 
SS  = $(addprefix bin/,$(ROOTS) $(OBJS)) 

all: ff.out 

ff.out: $(SS) 
    ld -o [email protected] $^ 

bin/%.o: %.[cs] 
    gcc -o [email protected] -c $< 

現在,如果我動,說「foo.c的」以獨立的目錄,並指定「VPATH」,停止建設「無規則,使目標bin/foo.o,由ff.out需要「。

+0

發佈原始生成文件的[mcve],爲方括號指定沒有特殊含義,因此它必須使用其內置規則,但是某些內容並不會增加您對行爲的描述。 – user657267

+0

@ user657267那麼,'make'spec/4.3會告訴別人:方括號會以類似bash的方式作爲通配符處理。我已經將MWE添加到了我的問題中。 –

+0

對不起,你是對的,我不敢相信我不知道。 – user657267

回答

0

我建議仔細閱讀How Not to Use VPATH,因爲您似乎在第三步通過在一些地方使用OBJDIR而不是其他地方。

要顯示,使用靜態模式規則不會讓您不必每個源目錄至少需要一個規則,或者每個源目錄至少需要一個調用。所以,簡單的答案是添加新規則新common/目錄是一樣的另一種:

bin/%.o: common/%.[cs] 
    gcc -o [email protected] -c $< 

有很多更全面的,而是複雜的,答案,看到他們中的一些連打文章。

對於簡單的項目,沒有理由不通過添加額外的規則來跟蹤主Makefile中的目錄。此外,還有一個合理的情況是沒有該bin/目錄並將其分割爲.o.out位置。經銷商和其他人希望能夠控制從哪裏創建文件的目錄。

我拋出了一個git repo with branches根據你的減少的例子,可能會澄清的事情。

+0

感謝您的回答!事實上,我讀過你之前建議的文章,但它對我沒有多大幫助,而你的第二個選擇對我來說並不合適。現在我開始認爲我必須拒絕使用'vpath'並直接指定所有源路徑的想法。 但是真正讓我感到困惑的是,我找不到任何Makefiles的例子,其中通配符如'?'或'[...]'被使用。奇怪。 –

+0

您應該直接指定srcdirs,我已經更新了我的答案以使其更清晰。您可能看不到通配符,因爲明確列出文件是首選,或者是其他類型的製作工具。 –