2016-04-15 70 views
1

我有一個makefile,基本上是這樣的:在缺乏規則的遞歸擴展的先決條件

DIRS = a 
all : $(DIRS) 
DIRS += b 
a b: 
    @ echo [email protected] 

我很驚訝地發現,只有a被打印出來。爲什麼?我認爲遞歸擴展的全部優點是我可以爲了方便而以任意順序擴展我的變量。有沒有辦法獲得我想要的all先決條件的行爲?

回答

1

問題是,製作已已經擴展$(DIRS)您附加到它。

3.7 How make Reads a Makefile

GNU化妝確實在兩個不同階段的工作。在第一階段,它讀取所有makefile,包括makefile等,並內化所有變量及其值,隱式和顯式規則,並構造所有目標及其先決條件的依賴關係圖。在第二階段,使用這些內部結構來確定需要重建的目標以及調用必要的規則。

理解這種兩階段方法很重要,因爲它直接影響變量和函數擴展的發生;編寫makefile時,這通常會造成一些混淆。這裏我們將介紹Makefile中不同構造擴展發生的階段的總結。我們說如果在第一階段發生擴展,立即展開:在這種情況下,make會在解析生成文件時展開構造的該部分中的所有變量或函數。我們認爲如果不立即進行擴展,擴展會被延遲。延遲構建的擴展不會執行,直到構造出現在後面的直接上下文中,或者直到第二個階段。

...

規則定義

規則始終是擴大以同樣的方式,無論形式:

immediate : immediate ; deferred 
    deferred 

也就是說,目標和前提章節展開立即,用於構建目標的配方總是推遲。這個通用規則對於顯式規則,模式規則,後綴規則,靜態模式規則和簡單的先決條件定義都是正確的。

您可以隨時先決條件添加到目標。

因此,如果您知道b是將其添加到all的先決條件列表中,那麼您可以添加all: b

您還可以將all:置於頂部(用於默認目標選擇),然後將all: $(DIRS)置於底部以使用完整的DIRS值作爲先決條件。

最後,您可以使用Secondary Expansion來強制執行額外的擴展階段,該階段應按照您的要求進行。

.SECONDEXPANSION: 
all: $$(DIRS)