2010-07-24 61 views
2

在編寫一個精心設計的Makefile時,如果文件已被更改,那麼只需最小程度的保留,似乎install:目標往往被忽略。更多的時候則不能安裝目標看起來像:僅當文件發生更改時才進行安裝

TRG := /trg 
BIN_TRG := $(TRG)/bin 
ETC_TRG := $(TRG)/etc 
BIN_FILES := b1 b2 b3 
ETC_FILES := e1 e2 e3 

install: 
    install $(BIN_FILES) $(BIN_TRG) 
    install $(ETC_FILES) $(ETC_TRG) 

.PHONY: install 

也就是說,沒有依賴假目標檢查都沒有。

如果不是簡單安裝,而是需要填充臨時區域來準備諸如RPM包等二進制包,或者下一階段構建依賴於該臨時區域,則此類問題會變得更加嚴重。在這種情況下,在安裝階段之後,依賴關係樹就會崩潰。

問題是:安裝規則跟蹤依賴關係的最佳方法是什麼?

回答

2

我不熟悉你的「安裝」功能,您的兩種解決方案使用不同的方法,但這個怎麼樣:

TRG := /trg 
BIN_TRG := $(TRG)/bin 
ETC_TRG := $(TRG)/etc 
BIN_FILES := b1 b2 b3 
ETC_FILES := e1 e2 e3 
INSTALLS := $(addprefix $(BIN_TRG)/,$(BIN_FILES)) \ 
     $(addprefix $(ETC_TRG)/,$(ETC_FILES)) 

install: $(INSTALLS) 

$(BIN_TRG)/% $(ETC_TRG)/%: % 
    install $< [email protected] 

.PHONY: install 

編輯:附:如果您想要install步驟填充暫存區域或其他任何地方,請使暫存區域成爲具有自己規則的單獨目標。

+0

謝謝,這是非常有幫助的。 – theosp 2011-03-11 09:45:22

0

我發現的一種方法是專門描述安裝規則的依賴關係。對於每一個文件,我們需要構建一個規則,如:

trg_dir/my_file: my_file 
    install $< [email protected] 

要做到這一點,但是需要一些使用gmake法寶:

TRG := /trg 
BIN_TRG := $(TRG)/bin 
ETC_TRG := $(TRG)/etc 
BIN_FILES := b1 b2 b3 
ETC_FILES := e1 e2 e3 
INSTALLS := $(addprefix $(BIN_TRG)/,$(BIN_FILES)) \ 
      $(addprefix $(ETC_TRG)/,$(ETC_FILES)) 

install: $(INSTALLS) 

define install_rule 
$(1)/$(2): $(2) 
    install $(2) $(1)/$(2) 
endef 

$(foreach file,$(BIN_FILES),$(eval $(call install_rule,$(BIN_DIR),$(file)))) 
$(foreach file,$(ETC_FILES),$(eval $(call install_rule,$(ETC_DIR),$(file)))) 

.PHONY: install 

我覺得這個代碼需要一些解釋,這也是我的主要抱着它 - 它是更復雜,然後這樣一個看似普通的任務應該是:

目標保持虛假,但它現在將只用於檢查單個安裝規則,是最新的。

通過評估調用單個規則的宏定義的結果來生成規則。我們使用​​函數遍歷每個文件,並在$(call ...)install_rule時給出正確的參數。


我把問題和答案在這裏,我雖然看似解決了它已經,因爲我不滿意這個解決方案。任何更優雅的將被熱切接受。

0

由於make不支持僞目標的先決條件,因此您必須在磁盤上創建實際的虛擬文件,並在安裝目標觸發器時觸摸該文件。

.PHONY: install 

install: dummy 

dummy: $(FILES_THAT_WERE_CHANGED) 
     install $(BIN_FILES) $(BIN_TRG) 
     install $(ETC_FILES) $(ETC_TRG) 
     touch dummy 
相關問題