2014-10-30 45 views
0

我有一個makefile,它從命令行接受一個變量並將其傳遞給編譯器(對於C++ preprocesor)。Makefile並不總是重建

下面是代碼:

bar=0 
file.o: foo.cpp  
ifeq($(bar), 0) 
    g++ file.cpp -D foo=1 -o file.o 
else 
    g++ file.cpp -D foo=0 -o file.o 
endif 

的問題是,運行

make bar=0 

然後

make bar=1 

後,它說,foo.o的是最新的(其它是,但我希望它重建,因爲代碼內部的變量更改)。

+0

它是'foo.o'和'foo.cpp',還是'file.o'和'file.cpp'?如果你想要一個目標文件,你應該在編譯時加上'-c'標誌。 – 2014-10-30 11:52:18

+0

你需要一個乾淨的目標。然後'乾淨'。 – 2014-10-30 13:16:25

+1

不,他沒有。 「乾淨」毫無意義。如果你需要清潔,爲什麼要使用Make。只需編寫一個shell腳本。 Make的全部觀點是人們不應該清理任何東西。 – 2014-10-30 13:19:23

回答

2

有使用Make在所有如果一個景區被迫重建或清洗不點。這裏的正確方法是實現一個「可靠變量」,其行爲就像一個文件。如果bar是這樣一個變量,你可以只說

file.o: foo.cpp bar 
    (your recipe here) 

這將意味着,如果「內容」 bar變化(值),則重建。

要詳細瞭解如何實現可靠的變量,看我的帖子

How do I add a debug option to Makefile

1

您可以使用Phony目標強制編譯器重建它。 好主意是定義清潔功能。然後使用重新編譯項目:

make clean 
make all 
+0

但是如果我運行 使bar = 1 兩次它會重建它沒有必要,有沒有辦法解決這個問題? – 2014-10-30 11:56:52

+0

您可以將條值存儲在臨時文件中,並在每次編譯之前進行比較。 – incogn1to 2014-10-30 12:08:37

1

如果你想保持它的簡單,而且不介意有一個額外的文件作爲一個標記,你可以做

bar = 0 
MARKER = compiled_with_foo_ 
file.o: $(MARKER)_$(bar)  
ifeq($(bar), 0) 
    rm -f $(MARKER)_1 
else 
    rm -f $(MARKER)_0 
endif 
    g++ -c file.cpp -D foo=$(bar) -o file.o 

$(MARKER)_$(bar): file.cpp 
    touch [email protected] 

並讓您的clean刪除兩個標記。