2015-11-10 38 views
5

我一直在使用像這樣的奇怪規則很長一段時間,但突然間他們打破了新的環境。%*和依賴關係線上的*

有沒有一個強大的方法來做到這一點?

all: test.1.out 

test.%.out: %/test*.out 
    /bin/cp -f $< [email protected] 

在我的箱子(Ubuntu的):

alishan:~/Dropbox/make_insanity> make --version 
GNU Make 3.81 
Copyright (C) 2006 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. 
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. 

This program built for x86_64-pc-linux-gnu 
alishan:~/Dropbox/make_insanity> make 
/bin/cp -f 1/test.out test.1.out 

與這種對別人的Mac電腦代碼,Ubuntu機器,Ubuntu的虛擬機沒有問題。不知道他們的所有版本,但它似乎是OK代碼。

清除後,在我的mageia服務器在同一目錄。

[[email protected] make_insanity]$ make --version 
GNU Make 3.82 
Built for x86_64-mageia-linux-gnu 
Copyright (C) 2010 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. 
[[email protected] make_insanity]$ make 
make: *** No rule to make target `test.1.out', needed by `all'. Stop. 
[[email protected] make_insanity]$ 

更改%*到適當的文本「修復」的問題,但當然不會產生所期望的一般性。

+0

有人向我暗示,從3.81改爲3.82是可能的罪魁禍首。我查看了發行說明,但沒有發現任何似乎適用的內容。 https://lists.gnu.org/archive/html/make-alpha/2010-07/msg00025.html –

回答

1

我沒有絕對的把握,但我想你想

test.<name>.out 

<name>/test.out 

進行(如果存在的話)。如果這是正確的,你可以通過逆向工程 從目標名稱中獲取每個目標的先決條件名稱來強有力地實現。

targs := test.1.out test.a.out 

define src_of = 
$(patsubst .%,%,$(suffix $(basename $(1))))/$(basename $(basename $(1)))$(suffix $(1)) 
endef 

all: $(targs) 

test.%.out: $(call src_of,test.%.out) 
    cp -f $< [email protected] 

clean: 
    rm -f *.*.out 

無可否認,這有點兒一口。

因此,如果我們預先安排演示,其中的先決條件存在:

$ ls -LR 
.: 
1 a Makefile 

./1: 
test.out 

./a: 
test.out 
$ make 
cp -f 1/test.out test.1.out 
cp -f a/test.out test.a.out 
+0

謝謝。這在學習關於make的很酷的東西方面很有用,但是我可以使用沒有*的原始規則來完成。此外,在這個特定的應用程序中,規則的可讀性也很重要。 這個簡單的規則在各種平臺上工作了一段時間。如果我可以用簡單的方法保存它將會很好。 –

0

你可以做到這一點使用secondary expansion和通配符功能。注意,如果沒有這個,它永遠不會有效,所以無論你看到這個代碼是什麼都應該被認爲是破壞的

.SECONDEXPANSION: 

all: test.1.out 

test.%.out: $$(wildcard $$*/test*.out) 
    @echo Prerequisites found: $^ 

注意使用$*而非%的模式匹配(見automatic variables)是由一個額外的$逃跑了,整個事情被設置爲擴大兩次,兩組值得到擴展。

這就是說這整個佈局看起來不對。您正在使用$<,它只匹配先決條件的第一個單詞,即使使用通配符,您可能會有很多這樣的單詞。 Mike's answer可能是一個更好的選擇,因爲重新組織Makefile實際上很健壯。

+0

謝謝。這就是我想要的。 我明白你們倆在說什麼結構。 這個特殊的用例涉及到實時提供名稱稍微不一致的文件的人,所以我被困在了糟糕的結構中(當然,我可能試圖修復make的上游文件,但我通常認爲首先爲所有內容製作)。首先我應該這樣說。 –