2016-06-12 21 views
1

我有一個Makefile,它有很多目標,每個目標的配方都很相似。如何避免使用類似食譜的Makefile目標中的重複?

foo: 
    gcc foo.c -o foo 
    mv foo ~/bin 

bar: 
    gcc bar.c -o bar 
    mv bar ~/bin 

baz: 
    gcc baz.c -o baz 
    mv baz ~/bin 

我想避免所有這些重複。我想要下面的東西(這不是有效的語法;這隻表達我的意圖)。

TARGET_NAME: 
    gcc $(TARGET_NAME).c -o $(TARGET_NAME) 
    mv $(TARGET_NAME) ~/bin 

是否可以這樣做?如果不是,我可以寫的最好的Makefile是什麼,可以最大限度地減少食譜中的重複?

+0

像@beta已經在其他地方指出的那樣,你的'Makefile'壞了,因爲你移動了你創建的文件,所以每次都會重新映射它們,無論它是否必要。此外,'go'的'-o'選項可以顯着地佔據一個子目錄。 'bin /%:%.c; gcc $ <-o $ @' – tripleee

回答

4

你的Makefile是錯誤的,因爲你的目標(foobar等)不依賴於它們的源文件(foo不依賴於foo.c等)所以,改變源代碼將不會導致目標被重建。

此外,你的makefile文件說你正在創建一個文件foo,但是你的配方實際上創建了一個文件~/bin/foo,這不是一回事。

無論如何,這正是pattern rules是:

EXES = foo bar baz 

all: $(addprefix $(HOME)/bin/,$(EXES)) 

$(HOME)/bin/%:: %.c 
     gcc $< -o [email protected] 

(感謝測試版指出在原來的我想到-O)

+2

你不是在違反[你自己的規則](http://make.mad-scientist.net/papers/rules-of-makefiles/)嗎? 6中的第2個,準確地說:目標模式應該與正在構建的事物的實際名稱相匹配('〜/ bin /%')。 – Beta

+0

您應該使用[靜態模式規則](https://www.gnu.org/software/make/manual/html_node/Static-Usage.html)以避免使用[隱式規則](https://www.gnu。組織/軟件/製作/手動/ html_node /靜態抗Implicit.html)。像這樣的東西:'foo bar baz:%:%.c' – jml

+0

你說得對。我認爲這是一個「cp」而不是「mv」。我會更新。關於「靜態模式規則」:我總是看到你「應該」使用它們的建議。我幾乎從不使用它們。實際上,我總是使用正常的模式規則,並且只有在使用靜態模式規則時,纔有了應該以不同方式構建的目標子集。我認爲這是一種風格/意見。我不會告訴人們他們「應該」在沒有任何正當理由的情況下使用他們。 – MadScientist

2

一個make規則實際上可以匹配多個目標:

foo bar baz: 
    gcc [email protected] -o [email protected] 
    mv [email protected] ~/bin 

然而,你應該作出明確的依賴關係的規則:

foo: foo.c 
bar: bar.c 
baz: baz.c 

foo bar baz: 
    gcc $< -o [email protected] 
    mv [email protected] ~/bin 

前三行只是指定依賴項,而沒有任何操作來實際構建它們。您可以在gcc的幫助下生成這些文件:gcc -MM foo.c將打印foo.c的規則。