2017-07-18 91 views
1

我有這樣的事的作品:

target1.PREREQUISITES = file11 file12 file13 
target2.PREREQUISITES = file21 file22 file23 

$(myDir)target1.sfx : $(target1.PREREQUISITES) 
    <same recipe here> 

$(myDir)target2.sfx : $(target2.PREREQUISITES) 
    <same recipe here> 

,這就是我想做的事情,但它不工作:

target1.PREREQUISITES = file11 file12 file13 
target2.PREREQUISITES = file21 file22 file23 

$(myDir)%.sfx : $(%.PREREQUISITES) 
    <commun recipe here> 

它總是說因爲目標是最新的,所以沒有什麼可做的。

我有這樣的感覺,問題可能是每個製作階段都做了什麼,我的意思是,先做的是%或$。它應該工作得很好嗎?

回答

0

感謝user657267的回答,它的工作和它給了我一個很好的領導。對於那些不太熟悉的人,請注意雙美元符號。不過,我在這裏列出了我的答案,因爲它仍然使用%標誌,這是我原始問題的一部分,與您的標準一樣好。我正在使用以下解決方案。

.SECONDEXPANSION: 

$(mydir)%.sfx: $$(%.PREREQUISITES) 
    echo $^ 

我只是注意到了,意識到這一點,在使用二次擴張時做出不告訴你,一缺少的必備條件沒有規則,而是顯示一個誤導性的消息說,沒有規則使目標

1

你需要像secondary expansion這個工作,否則該變量的前提條件中發生之前圖案取代擴大,而你還沒有定義了一個名爲%.PREREQUISITES變量。

.SECONDEXPANSION: 

$(mydir)%.sfx: $$($$*.PREREQUISITES) 
    echo $^ 
+0

謝謝。它可以工作,但是我得到了第二個不希望的效果:如果其中一個必備文件丟失,例如file12,請抱怨沒有制定目標的規則,而不是抱怨缺少制定file12的規則。 –

+0

不幸的是,make手冊沒有在帶''''符號的先決條件中使用的變量示例。在前提條件中,我確實只看到一個帶有'%'的例子,但它不是一個變量,而是一個函數,但是我不清楚爲什麼這個例子可以工作,而不是我的。這是手冊中的內容:'%.o:$$(addsuffix /%.c,foo bar)foo.h' –

+0

其實我只是用這種方法試了一個測試文件,並且和你的建議一樣好,理解爲什麼:**'$(myDir)%。sfx:$$(%。PREREQUISITES)'**並且它與您的副作用相同:它不會告訴您缺少必備文件。 –

2

用戶657267提出的第二種擴展工作良好。 GNU使還支持一種,你可以用它來實例化幾個規則非常相似的形式循環機制:

target1.PREREQUISITES = file11 file12 file13 
target2.PREREQUISITES = file21 file22 file23 
TARGETS = target1 target2 

# $(1) is a parameter to substitute. The $$ will expand as $. 
define MY_rule 
$$(myDir)$(1).sfx : $$($(1).PREREQUISITES) 
    <same recipe here> 
endef 
$(foreach target,$(TARGETS),$(eval $(call MY_rule,$(target)))) 
  • foreach環比在$(TARGETS)所有文字和當前的單詞分配給$(target)
  • call執行的MY_rule的膨脹,其中它可以代替$(1)$(target)$$$的當前值。
  • eval實例化call擴展的結果作爲常規規則。

foreach第一次迭代中,對實例的結果,將是:

$(eval $(call MY_rule,target1)) 

call將作爲評估:

$(myDir)target1.sfx : $(target1.PREREQUISITES) 
    <same recipe here> 

eval將實例它作爲一項規則。 重要:不要忘記,call執行第一次擴展。因此,如果您的<same recipe here>包含$符號,請不要忘記將它們加倍,除非它們的擴展是call是好的。如果你的配方使用shell變量,甚至有可能你最終得到的結果是$$$$var

這個機制稍微強大一些,通用的第二個擴展。它甚至有一個以上的參數可與嵌套循環替換和:

target1.PREREQUISITES = file11 file12 file13 
target2.PREREQUISITES = file21 file22 file23 
TARGETS = target1 target2 
DIRS = myDir 

# $(1): target 
# $(2): directory 
define MY_rule 
$(2)$(1).sfx : $$($(1).PREREQUISITES) 
    <same recipe here> 
endef 
$(foreach target,$(TARGETS),$(foreach dir,$(DIRS),$(eval $(call MY_rule,$(target),$(dir))))) 

你甚至可以嵌入foreach-eval-calldefine-endef

target1.PREREQUISITES = file11 file12 file13 
target2.PREREQUISITES = file21 file22 file23 
TARGETS = target1 target2 
DIRS = myDir 

# $(1): target 
# $(2): directory 
define MY_rule_1 
$(2)$(1).sfx : $$($(1).PREREQUISITES) 
    <same recipe here> 
endef 

# $(1): directory 
define MY_rule_2 
$$(foreach target,$$(TARGETS),$$(eval $$(call MY_rule_1,$$(target),$(1)))) 
endef 
$(foreach dir,$(DIRS),$(eval $(call MY_rule_2,$(dir))))