2014-08-27 167 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