2016-11-30 30 views
0

我有一個像patsubst與多個通配符

packages/ 
    foo/ 
    lib/ 
     a.js 
     b.js 
    bar/ 
    lib/ 
     c.js 
     d.js 

的目錄結構,我想寫一個簡單的Makefile通過編譯器和輸出編譯packages/foo/lib/a.jspackages/foo/build/a.js的結果運行的源文件。在過去,我做過類似

JS = $(shell find packages/foo/lib -name "*.js") 
BUILD = $(patsubst packages/foo/lib/%.js, packages/foo/build/%.js, $(JS)) 

.PHONY: all 
all: $(BUILD) 

packages/foo/lib/%.js: packages/foo/build/%.js 
    # Compile $^ and output to [email protected] 

這很好用。不過,我現在在做

JS = $(shell find packages/*/lib -name "*.js") 
BUILD = $(patsubst ...) 

這裏的問題是,patsubst似乎並不喜歡多%通配符(即packages/%/lib/%.js)。但是,如果我使用packages/%.js,那麼我無法知道在替換中使用哪個目錄。我相信有一個非常簡單的方法可以做到這一點,這是我在make文檔中找不到的。只要你不擔心額外的「LIB」和源「構建」路徑組件

BUILD = $(subst /lib/,/build/,$(JS)) 

回答

1

要定義BUILD,您可以用愚蠢的,但簡單的解決方案。

然而,這留給你如何定義實際的Makefile規則,除非你想手動指定每個目錄foobar規則問題等

相反,也許嘗試這樣的事情(記得要再次更換標籤的空間在適當情況下,如果你剪切和粘貼):

PACKAGES = $(wildcard packages/*) 

ALL := 

define add_package 
JS := $$(shell find $(1)/lib -name "*.js") 
BUILD := $$(patsubst $(1)/lib/%.js, $(1)/build/%.js, $$(JS)) 
$(1)/build/%.js:: $(1)/lib/%.js 
     echo COMPILE $$^ '->' [email protected] 
     cp $$^ [email protected] # super fast compiler! 
ALL += $$(BUILD) 
endef 

$(foreach p, $(PACKAGES), \ 
    $(eval $(call add_package,$(p)))) 

all: $(ALL) 

此評估每個包目錄的模板,所以你可以把任何東西在裏面,只要你得到的繁瑣加倍美元符號正確。

+0

太好了!非常感謝。和我的天賦相比,'cp'編譯器看起來真的很快,比如我看上去像'babel'和'traceur';的其他人;) –