2014-08-27 171 views
3

有沒有辦法在Makefile中簡化這種重複?如何刪除Makefile中的重複?

duo = ./node_modules/.bin/duo 

build: lib/background/build lib/page/build lib/popup/build 

lib/background/build: lib/background/build/build.js lib/background/build/build.css 
lib/page/build: lib/page/build/build.js lib/page/build/build.css 
lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css 

lib/background/build/build.js: lib/background/index.js node_modules component.json 
    @mkdir -p lib/background/build 
    @$(duo) lib/background/index.js > lib/background/build/build.js 

lib/page/build/build.js: lib/page/index.js node_modules component.json 
    @mkdir -p lib/page/build 
    @$(duo) lib/page/index.js > lib/page/build/build.js 

lib/popup/build/build.js: lib/popup/index.js node_modules component.json 
    @mkdir -p lib/popup/build 
    @$(duo) lib/popup/index.js > lib/popup/build/build.js 

lib/background/build/build.css: lib/background/index.css node_modules component.json 
    @mkdir -p lib/background/build 
    @$(duo) lib/background/index.css | $(myth) > lib/background/build/build.css 

lib/page/build/build.css: lib/page/index.css node_modules component.json 
    @mkdir -p lib/page/build 
    @$(duo) lib/page/index.css | $(myth) > lib/page/build/build.css 

lib/popup/build/build.css: lib/popup/index.css node_modules component.json 
    @mkdir -p lib/popup/build 
    @$(duo) lib/popup/index.css | $(myth) > lib/popup/build/build.css 

基本上,我想從頂層運行一個簡單的命令make build,並在必要時僅重建這些子項目。我想不必爲每個子項目使用Makefile,因爲這也是重複的。我試過的與通配符路徑有關的所有東西都沒有解決,所以想知道是否有辦法做到這一點。例如,我試着做類似這樣的事情(類似於js和css),但沒有運氣:

js = $(shell find lib test -type f -name '*.js' ! -path "*build.js") 

$(js)/build/build.js: node_modules component.json 
    # somehow get the directory such as lib/background based on the make command? 
    local dir=$(shell dirname $(shell dirname [email protected])) 
    @mkdir -p $(dir)/build 
    @$(duo) $(dir)/index.js > $(dir)/build/build.js 

任何想法如何使這個幹?

+0

企圖是不會因爲'$(JS)工作'是文件名列表,因此將目標擴展插槽添加到列表中最後的文件名後附加'/ build/build.js'的文件名列表。 – 2014-08-27 20:56:16

回答

3

一個好的第一開始就是停止重複目標/等。在規則體中,並使用它們的自動變量。所以'[email protected]'目標文件名的目標文件,'$(@D)'中的目錄路徑(如dirname)等

它可以幫助您:

duo = ./node_modules/.bin/duo 

build: lib/background/build lib/page/build lib/popup/build 

lib/background/build: lib/background/build/build.js lib/background/build/build.css 
lib/page/build: lib/page/build/build.js lib/page/build/build.css 
lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css 

lib/background/build/build.js: lib/background/index.js node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) lib/background/index.js > '[email protected]' 

lib/page/build/build.js: lib/page/index.js node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) lib/page/index.js > '[email protected]' 

lib/popup/build/build.js: lib/popup/index.js node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) lib/popup/index.js > '[email protected]' 

lib/background/build/build.css: lib/background/index.css node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) lib/background/index.css | $(myth) > '[email protected]' 

lib/page/build/build.css: lib/page/index.css node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) lib/page/index.css | $(myth) > '[email protected]' 

lib/popup/build/build.css: lib/popup/index.css node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) lib/popup/index.css | $(myth) > '[email protected]' 

然後意識到pattern rules是有幫助的,當你有目標和先決條件共享文件名模式和類似的規則主體,你也可以開始使用它們。他們也給你額外的automatic variable

你得到這個(中間)階段:

duo = ./node_modules/.bin/duo 

build: lib/background/build lib/page/build lib/popup/build 

lib/background/build: lib/background/build/build.js lib/background/build/build.css 
lib/page/build: lib/page/build/build.js lib/page/build/build.css 
lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css 

%/build/build.js: %/index.js node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.js > '[email protected]' 

%/build/build.js: %/index.js node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.js > '[email protected]' 

%/build/build.js: %/index.js node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.js > '[email protected]' 

%/build/build.css: %/index.css node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.css | $(myth) > '[email protected]' 

%/build/build.css: %/index.css node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.css | $(myth) > '[email protected]' 

%/build/build.css: %/index.css node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.css | $(myth) > '[email protected]' 

而且他們你看,你真的只得到了兩個重複的規則,這樣你將它們結合起來。

duo = ./node_modules/.bin/duo 

build: lib/background/build lib/page/build lib/popup/build 

lib/background/build: lib/background/build/build.js lib/background/build/build.css 
lib/page/build: lib/page/build/build.js lib/page/build/build.css 
lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css 

%/build/build.js: %/index.js node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.js > '[email protected]' 

%/build/build.css: %/index.css node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.css | $(myth) > '[email protected]' 

然後,因爲make不處理目錄的目標/先決條件,以及一個可能會喜歡,你可以刪除lib/background/buildlib/page/buildlib/popup/build中間目標,只是列出了實際的文件作爲prereqs的build

duo = ./node_modules/.bin/duo 

build: lib/background/build/build.js lib/background/build/build.css \ 
     lib/page/build/build.js lib/page/build/build.css \ 
     lib/popup/build/build.js lib/popup/build/build.css 

%/build/build.js: %/index.js node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.js > '[email protected]' 

%/build/build.css: %/index.css node_modules component.json 
     @mkdir -p '$(@D)' 
     @$(duo) '$*'/index.css | $(myth) > '[email protected]' 

我也許應該指出,我沒有測試這個(爲缺乏慾望小樣的目錄佈局/等的),但轉換爲直線前進和概念相當簡單,所以它應該工作正好。但任何事情都有可能。

要清理build先決條件,你可以使用類似:

build: $(foreach d,background page popup,$(addprefix lib/$d/build/,build.js build.css)) 
+0

老兄,沒辦法。你是主人!這太酷了,清理得太多了。 – 2014-08-27 21:12:33

+0

有沒有什麼辦法來清理'build:'依賴關係,所以它們也被模式化了?像'build:%/ build/build.js%/ build/build.css'?這似乎並不適用於我。 'make:***沒有規則來製作'build'所需的目標'%/ build/build.js'。 Stop.' – 2014-08-27 21:13:50

+1

是的,那不會那樣工作。如果你願意,你可以用一些make函數清理它。等一下。 – 2014-08-27 21:14:30