2009-08-27 60 views
13

我正在嘗試編寫一個GNU Make Makefile,它具有類似目標的加載,其中構建命令在它們之間略有不同。 我試圖用target-specific variables來表示這些變化。其中一些變量值指的是我想用作先決條件的文件。例如:特定於目標的變量作爲Makefile中的先決條件

target_1:special_filename=target1_prereq 
target_2:special_filename=target2_prereq 

target_1 target_2: common_filename $(special_filename) 
    do_something common_filename --a-weird-option=$(special_filename) 

當我喊「讓target_1」,我想它做target1_prereq如果它不存在。目前,即使使用正確的參數調用build命令(do_something),它似乎也不會使用target1_prereq作爲先決條件。

我使用的是GNU Make 3.80。


編輯:從實際系統 一些更多的併發症。一些變量本身是基於其他變量的值。手動指定先決條件不會縮放。 稍微複雜一點的例子:

target_1:special_filename_base=target1_prereq 
target_2:special_filename_base=target2_prereq 

some_filename_a = $(special_filename_base).exta 
some_filename_b = $(special_filename_base).extb 

target_1 target_2: common_filename $(special_filename_b) $(special_filename_a) 
    do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b) 

回答

3

目標專用變量僅在目標的命令(或其他特定於目標的賦值)中定義;它不能用作目標的先決條件之一。我不認爲有一個乾淨的方式做你的製作想要的東西,但有幾個kludgey方法,如以下內容:

 
EXTENSIONS = .exta .extb 
target_1: $(addprefix target1_prereq,$(EXTENSIONS)) 
target_2: $(addprefix target2_prereq,$(EXTENSIONS)) 

target_1 target_2: common_filename 
    do_something common_filename --a-weird-option=$(filter %.exta,$^) --second=$(filter %.extb,$^) 
+4

爲了其他任何人的利益而復活此主題。 [更優雅的解決方案](http://stackoverflow.com/questions/9311743/make-using-target-specific-variables-in-prerequisites)使用二次擴展。 – Seth 2012-10-30 00:30:56

+0

@Seth,我同意:'target_1 target_2:common_filename $$(special_filename_base).exta $$(special_filename_base).extb ...' – Beta 2012-10-30 05:02:20

2

舉一個簡單的解決方法:

 
target_1:special_filename=target1_prereq 
target_1:target1_prereq 
target_2:special_filename=target2_prereq 
target_2:target2_prereq 

target_1 target_2: common_filename $(special_filename) 
    do_something common_filename --a-weird-option=$(special_filename) 

有一定的冗餘度,但它是局部的,所以它不是太糟糕了。

+0

我想這解決了我發佈的具體情況,但我希望得到更通用的解決方案。 我會用更復雜的例子編輯。 – 2009-08-27 10:29:26

2

,我發現了一個相當乾淨的方式邊踩着這個限制。它會去是這樣的:

target_1:export special_filename_base=target1_prereq 
target_2:export special_filename_base=target2_prereq 

some_filename_a = $(special_filename_base).exta 
some_filename_b = $(special_filename_base).extb 

target_1 target_2: 
    $(MAKE) -f $(firstword $(MAKEFILE_LIST)) target-proxy 

target-proxy: common_filename $(special_filename_b) $(special_filename_a) 
    do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b) 

兩個要點:

  1. export目標變量,因此,他們將訪問,當我們重新運行Makefile文件。
  2. 創建一個具有target_1 target_2所有原始先決條件的代理目標,並在target_1 target_2中使用此代理目標再次調用Makefile。由於目標特定變量屆時將有值(我們由當時的配方)他們export版,他們將在target-proxy可 - 瞧:)

的缺點這種方法是我們正在創建另一個make進程 - 如果它只是另一個,那麼它可能是好的,但YMMV所以要格外小心。

相關問題