2012-09-06 14 views
21

在下面的Makefile定義:

  1. 是什麼在倒數第二行[email protected]代表什麼?
  2. 中間的|符號怎麼樣?
define KERNEL_RULE 
$(DESTDIR)/$(1) : kernel_modules 
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR) 
    cp $(DESTDIR)/$(1) [email protected] 
endef 

回答

52

(你有變量名的可悲的選擇,讓我們單獨改變DESTDIRSOURCE_DIR離開DEST_DIR。)

假設你正在寫一個普通的規則:

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo 
    cp $(SOURCE_DIR)/foo $(DEST_DIR)/foo 

這有效,但冗餘很麻煩。遲早你會在preq中更改$(DEST_DIR)/foo,但忘記在規則中更改它。規則很難閱讀。所以我們把在automatic variable

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo 
    cp $(SOURCE_DIR)/foo [email protected] 

當這個規則的執行,[email protected]將擴大到目標,$(DEST_DIR)/foo的名稱。

現在,我們要確保$(DEST_DIR)這個規則的執行之前就存在(我們可以做的比這還要好,但讓我們停在那裏。),但我們不希望這是一個先決條件就是這樣,因爲在缺少該目錄不應該足以導致此規則運行。所以我們使它成爲order-only prerequisite

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo | $(DEST_DIR) 
    cp $(SOURCE_DIR)/foo [email protected] 

現在,我們希望這樣的許多規則,針對不同的目標,而不是做the smart way,我們將使用"canned recipe",排序的模板上飛創建規則。

# This won't work 
define KERNEL_RULE 
$(SOURCE_DIR)/$(1) : kernel_modules 
$(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR) 
    cp $(SOURCE_DIR)/$(1) [email protected] 
endef 

的問題是,當我們評估這個定義,[email protected]將擴大,而且因爲它不是一個規則是,它會擴大到什麼。因此,我們將其更改爲[email protected]

# This will work 
define KERNEL_RULE 
$(SOURCE_DIR)/$(1) : kernel_modules 
$(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR) 
    cp $(SOURCE_DIR)/$(1) [email protected] 
endef 

當撥打電話這一定義,[email protected]擴展到[email protected],然後如果/當它運行的規律,[email protected]將擴大到目標的名稱。

+12

我們再次見面,我必須承認不情願的滿意。訂單唯一的先決條件的東西特別好。 –

+19

@JackKelly,你的痛苦和勉強的讓步對我來說比從不露面的人羣中得到的百分點更寶貴。 – Beta