2011-05-18 134 views
7

我在root in a directory layout中有幾個小部件,用​​3210表示。查找makefile依賴關係

我在這裏的GNUmakefile能夠構建它們。儘管如果我更新文件夾,依賴關係不會被跟蹤。我不想明顯依賴乾淨的目標,那麼如何跟蹤每個文件夾的內容?

WGTS := $(shell find -name 'config.xml' | while read wgtdir; do echo `dirname $$wgtdir`.wgt; done) 
all: $(WGTS) 
%.wgt: 
    @cd $* && zip -q -r ../$(shell basename $*).wgt . 
    @echo Created [email protected] 
clean: 
    rm -f $(WGTS) 

我希望是這樣的:

%.wgt: $(shell find $* -type f) 

會的工作,但事實並非如此。 Help

+0

所以......你想'foo.wgt'依賴'foo /'中的所有東西嗎? – Beta 2011-05-18 14:33:12

+0

沒錯...... – hendry 2011-05-18 14:42:58

回答

4

結合Beta's idea與我:

 
WGTS := $(shell find -name config.xml) 
WGTS := $(WGTS:/config.xml=.wgt) 
WGTS_d := $(WGTS:.wgt=.wgt.d) 

all: $(WGTS) 
clean: 
    rm -f $(WGTS) $(WGTS_d) 

-include $(WGTS_d) 

define WGT_RULE 
$(1): $(shell find $(1:.wgt=)) 
$(1:.wgt=)/%: 
    @ 
endef 
$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ)))) 
%.wgt: 
    @echo Creating [email protected] 
    @(echo -n "[email protected]: "; find $* -type f | tr '\n' ' ') > [email protected] 
    @cd $* && zip -q -r ../$(shell basename $*).wgt . 

例子:

 
$ mkdir -p foo bar/nested 
$ touch {foo,bar/nested}/config.xml 
$ make 
Creating bar/nested.wgt 
Creating foo.wgt 
$ make 
make: Nothing to be done for `all'. 
$ touch foo/a 
$ make 
Creating foo.wgt 
$ rm foo/a 
$ make 
Creating foo.wgt 
$ make 
make: Nothing to be done for `all'. 

這裏唯一的潛在問題是假的規則,可以讓使忽略目標,它不知道如何建立它們嵌套在目錄中。 (在我的示例中爲foo/a)。如果這些是需要知道如何構建的真正目標,則重複的配方定義可能是一個問題。

+0

我需要它來解釋添加的新文件。不太明白需要寫出那個.wgt.d的東西,它看起來像對我來說很重要。在config.xml中不會有config.xml的情況。 :) – hendry 2011-05-22 13:22:37

+0

@hendry:寫出依賴文件可以簡單地將它們包含在後續運行中,而無需重新生成所有信息。它在大多數情況下都能很好地工作(並且通常用於在頭文件中生成C源依賴項)。但它不能處理添加僅依賴於文件系統狀態的目標文件。 – 2011-05-22 14:41:46

+0

@thomas這個Makefile可以考慮添加以及刪除文件,但是我無法適應它來說明我的小部件在任意目錄結構中的位置http://tests.wacapps.net/?p=wac2tests;a=斑點; F =樣本/生成文件;我想,如果我們理解了http://www.gnu.org/s/hello/manual/make/Secondary-Expansion.html,我們會找到答案 – hendry 2011-05-22 15:24:21

1

可能做到這一點的最好辦法是明確創建的前提名單,事先:

define WGT_RULE 
$(1).wgt: $(wildcard $(1)/*) 
endef 

$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ)))) 

還有另外一個這是非常聰明的(一個短語,做一個優秀的程序員警惕)的方式。多年前,我想出了一個將左右目錄作爲先決條件的左撇子。如果上述不夠好,我會看看我能不能挖掘我的舊筆記本。

編輯:
對不起,我沒有考慮子目錄。這裏有一個完整的makefile(我忽略了clean規則),它應該做到這一點。

WGTS := $(shell find -name 'config.xml' | while read wgtdir; do echo `dirname $\ 
$wgtdir`.wgt; done) 
all: $(WGTS) 

# This constructs a rule without commands ("foo.wgt: foo/bar.txt foo/baz.dat..."). 
define WGT_RULE 
$(1).wgt: $(shell find $(1)) 
endef 

# This invokes the above to create a rule for each widget. 
$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ)))) 

%.wgt: 
    @cd $* && zip -q -r ../$(shell basename $*).wgt . 
    @echo Created [email protected] 
+0

我只是試着在一個子目錄中創建一個新文件,而makefile沒有選擇它。 :(有沒有辦法避免這個WGT_RUL?對我來說這似乎有點不必要,我更喜歡它的'%.wgt':對不起,很難... – hendry 2011-05-18 17:01:49

+0

這是行不通的:'hendry @ x201 foo $ MKDIR酒吧 亨德利@ X201 FOO $觸杆/ config.xml中 亨德利@ X201富$使 發現:'./bar.wgt':沒有這樣的文件或目錄 創建bar.wgt 亨德利@ X201 FOO $使對於'所有要做什麼都不做: 使 ' 亨德利@ X201富$ VIM的Makefile 亨德利@ X201 FOO $觸杆/ foo的 亨德利@ X201富$使 化妝:爲'所有做沒有什麼'。 hendry @ x201 foo $ ' – hendry 2011-05-20 07:45:13