2012-01-23 94 views
6

我有一個C++項目,它爲源文件(.cpp,.c,.cc)和各種擴展名的頭文件(.hpp,.h,.hh )。源文件位於一個名爲src目錄,頭文件是可以預見在一個叫INC目錄。在一個生成文件中使用多個源文件擴展名

我想用一個規則來編譯源像

vpath %.c $(SRC) 

%.o: %.c 
    $(COMPILER) $(FLAGS) $< $(INCFLAG)$(INC) 

當然,這工作,如果我知道源文件的格式爲%.c,但在多個可能的文件擴展名的情況下,我需要爲%.cpp和%.cc建立一個類似的規則。當然,三條規則並不是一個大問題,但是如果能夠使用這個makefile作爲任何項目的拖放操作,即使是使用不同的語言,也不需要重新編寫規則,那將會很不錯。

所以,我怎麼能寫一個規則(或完成同樣的目標其它一些結構),其工作原理是:

SRC_EXT = cpp c cc 
vpath %.$(SRC_EXT) $(SRC) 

%.o: %.$(SRC_EXT) 
    $(COMPILER) $(FLAGS) $< $(INCFLAG)$(INC) 

感謝您的幫助。

回答

3

你不能在標準的POSIX make。但是,既然你提到vpath,我會假設你正在使用GNU make。如果你有一個足夠新版本(3.81或更新版本),你可以做到這一點很容易足以與呼叫和eval:

SRC_EXT = cpp c cc 

define compile_rule 
%.o : %.$1 
     $$(COMPILER) $$(FLAGS) $$< $$(INCFLAG)$$(INC) 
endef  
$(foreach EXT,$(SRC_EXT),$(eval $(call compile_rule,$(EXT)))) 

如果你不具有足夠的新的GNU製作,或寧願一個替代的解決方案,你可以用生成的makefile做同樣的事情。

+0

aha!大!我想知道如何調用編譯規則,但foreach是如何被調用的?它只是坐在文件中,因爲在設置SRC_EXT變量之後它會立即被調用?即使.o是最新的,這是否會強制重新編譯所有源文件? – user487100

+1

Makefile解析是關於擴展事物的。無論何時在「立即上下文」中遇到變量或函數(請參閱GNU make手冊中的「如何讀取Makefile」),它將擴展它。當然,這可能涉及許多步驟。一旦擴展完成,剩下的東西就會被解析爲一個makefile文件。 eval函數是非常特殊的。基本上這個foreach循環是通過在讀入makefile時進行擴展和分析的,並且它以與編寫它們一樣的方式定義規則。所以它的行爲就像任何其他make規則(不會強制重新編譯)。 – MadScientist

+0

很酷。謝謝! – user487100

相關問題