2017-05-09 93 views
0

我有一個小型項目用於測試,我想鏈接測試解決方案的不同實現。makefile中的變量相關目標

所以,我創建生成文件,看起來像這樣

CC=g++ 
FLAGS=-Wall -O2 
CFLAGS=-c $(FLAGS) 
I_PATH=implementation1.cpp 

all: instance 

instance: instance.cpp .implementation.o 
    $(CC) $(FLAGS) instance.cpp .implementation.o -o [email protected] 

.implementation.o: $(I_PATH) 
    $(CC) $(CFLAGS) $(I_PATH) -o [email protected] 

clean: 
    -rm .implementation* 
    -rm instance 

這裏,I_PATH是解決方案的實施路徑。我想測試通過命令行參數傳遞不同實現的不同解決方案:make I_PATH=implementation2.cpp

但是,由於我的所有實現編譯爲相同的目標文件.implementation.o,因此make不能理解某些內容會發生變化並且不會重建項目。

當然,在運行make之前,我可以撥打make clean進行具體實施。但是這會增加構建時間(我可以多次對一個實現運行測試)並且不太舒服。

我可以解決這個Makefile來是這樣的:

CC=g++ 
FLAGS=-Wall -O2 
CFLAGS=-c $(FLAGS) 
I_PATH=implementation1.cpp 
C_PATH := $(shell echo -n $(I_PATH) | md5sum | awk '{print ".implementation_" substr($$1, 0, 10) ".o";}') 

all: force instance 

force_relink: 
    touch -c $(C_PATH) 

instance: instance.cpp $(C_PATH) 
    $(CC) $(FLAGS) instance.cpp $(C_PATH) -o [email protected] 

$(C_PATH): $(I_PATH) 
    $(CC) $(CFLAGS) $< -o [email protected] 

clean: 
    -rm .implementation* 
    -rm instance 

在這裏,我創建I_PATH依賴對象文件(帶路徑實現的哈希值),此外力重新鏈接instance.cpp每一次目標文件make運行。

但也許有一些機制在make來解決這種行爲?或者我可以用不同的方法實現相同的目標?

回答

1

爲每個已編譯的.o文件指定一個不同的名稱並且只需鏈接到編譯的.o文件是否更有意義?

instance: instance.cpp $(IMPL_O) 
    $(CC) $(FLAGS) $^ -o [email protected] # propably no need to override default rule 

使用make IMPL_O=implementation2.o產生在你的問題的例子。

這樣,每個文件的名稱才能真正揭示其身份,而且您不必明確地跟蹤任何內容。

(當然,你可以重構.o擴展到Makefile文件本身,所以你只能說IMPL=implementation2或什麼的。)

+0

是的,這是有道理的 - 簡單,很好的解決方案。 你能否提出另一種重新鏈接方式或我的方法可以接受? 下一步需要的重新鏈接:make make IMPL_O = i1.o','make IMPL_O = i2.o','make IMPL_O = i1.o' - 在第三個調用中,make不跟蹤更改並且不會重建任何內容。 –

+0

如果簡單地刪除文件並重新制作文件是不可接受的,那麼如果參數更改,就可以使用之前用'md5sum'做的事情來強制重製。 – tripleee

+0

...或者,您也可以給每個已編譯的製品一個唯一的名稱,以反映它嵌入的實現。 – tripleee