2015-04-03 37 views
0

我覺得有一種基本的我缺少關於GNU make(我使用3.81,如果它很重要)靜態模式規則匹配(顯然有人做了我在哪裏工作,因爲這被發現是因爲我試圖修復已被評論過的規則)。我試圖簡化我的例子,直到它的癥結所在(希望我沒有錯過任何真正的例子中的重要東西)。Makefile靜態模式規則匹配問題

所以這似乎工作,我會期望

JUNK:=foo bar 
BINS:=$(patsubst %,bin/%,$(JUNK)) 

all : $(BINS) 
.PHONY : all 

# This works 
$(BINS) : bin/% : % 
     mkdir -p bin && cp $< [email protected] 

但這(這是接近我的真正的Makefile中)不會根據我的理解

JUNK:=foo bar 
BINS:=$(patsubst %,bin/%,$(JUNK)) 

all : $(BINS) 
.PHONY : all 

# This doesn't work 
$(JUNK) : bin/% : % 
     mkdir -p bin && cp $< [email protected] 

# This doesn't work either 
#bin/$(JUNK) : bin/% : % 
#  mkdir -p bin && cp $< [email protected] 

在這兩種情況下我應該會發生什麼事情,我預料到兩種Makefiles都會表現得完全一樣;但是,只有第一個行爲如我所料(即正確將文件複製到垃圾桶)和第二給出了下面的輸出

Makefile:12: target `foo' doesn't match the target pattern 
Makefile:12: target `bar' doesn't match the target pattern 
make: *** No rule to make target `bin/foo', needed by `all'. Stop. 

什麼是更令人困惑的是,有幾乎相同的其他靜態模式規則在make我正在檢查那個工作。

所以我顯然知道如何解決這個問題,但是我想知道爲什麼第二個代碼塊(以及第二個代碼塊中的註釋掉的部分)沒有按照我期望的那樣做至。

在此先感謝您的幫助/見解。

回答

2

第一個不起作用,因爲,擴大JUNK變量後,讓看到這個:

foo bar : bin/% : % 

靜態模式規則的工作方式是,第一圖案(目標圖案)必須比賽目標列表中的每個單詞。這表明目標名稱的哪一部分是詞幹(與%匹配的部分)。如果目標模式不匹配,make就不知道該詞幹是什麼。模式bin/%與文本foo(文本foo中沒有bin/)不匹配,因此您會看到您看到的錯誤。

第二個不起作用,因爲在這個例子中的exanding JUNK變量的結果(bin/$(JUNK) : bin/% : %)看起來像這樣:

bin/foo bar : bin/% : % 

這裏,bin/foo模式匹配,但bar不匹配和所以你會得到和上一次一樣的錯誤。

爲了使它工作,你必須有bin/前置到目標,不只是第一目標,因此,使用的patsubst(或addprefix會工作爲好)。