有没有办法在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 $@))
@mkdir -p $(dir)/build
@$(duo) $(dir)/index.js > $(dir)/build/build.js
有关如何制作此DRY的任何想法吗?
答案 0 :(得分:3)
良好的第一个开始是停止重复目标/等。在规则体中,并使用自动变量代替它们。所以'$@'
表示目标文件名,'$(@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 > '$@'
lib/page/build/build.js: lib/page/index.js node_modules component.json
@mkdir -p '$(@D)'
@$(duo) lib/page/index.js > '$@'
lib/popup/build/build.js: lib/popup/index.js node_modules component.json
@mkdir -p '$(@D)'
@$(duo) lib/popup/index.js > '$@'
lib/background/build/build.css: lib/background/index.css node_modules component.json
@mkdir -p '$(@D)'
@$(duo) lib/background/index.css | $(myth) > '$@'
lib/page/build/build.css: lib/page/index.css node_modules component.json
@mkdir -p '$(@D)'
@$(duo) lib/page/index.css | $(myth) > '$@'
lib/popup/build/build.css: lib/popup/index.css node_modules component.json
@mkdir -p '$(@D)'
@$(duo) lib/popup/index.css | $(myth) > '$@'
然后,当您拥有共享文件名模式和类似规则体的目标和先决条件时,您会发现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 > '$@'
%/build/build.js: %/index.js node_modules component.json
@mkdir -p '$(@D)'
@$(duo) '$*'/index.js > '$@'
%/build/build.js: %/index.js node_modules component.json
@mkdir -p '$(@D)'
@$(duo) '$*'/index.js > '$@'
%/build/build.css: %/index.css node_modules component.json
@mkdir -p '$(@D)'
@$(duo) '$*'/index.css | $(myth) > '$@'
%/build/build.css: %/index.css node_modules component.json
@mkdir -p '$(@D)'
@$(duo) '$*'/index.css | $(myth) > '$@'
%/build/build.css: %/index.css node_modules component.json
@mkdir -p '$(@D)'
@$(duo) '$*'/index.css | $(myth) > '$@'
他们看到你真的只有两个重复的规则,所以你把它们组合起来。
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 > '$@'
%/build/build.css: %/index.css node_modules component.json
@mkdir -p '$(@D)'
@$(duo) '$*'/index.css | $(myth) > '$@'
然后,由于make不会处理目录目标/先决条件,您可以放弃lib/background/build
,lib/page/build
和lib/popup/build
个中间目标,只列出实际文件作为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 > '$@'
%/build/build.css: %/index.css node_modules component.json
@mkdir -p '$(@D)'
@$(duo) '$*'/index.css | $(myth) > '$@'
我应该提一下,我没有测试过这个(因为没有想要模拟目录布局/等等),但转换是直截了当的,概念很简单所以应该可以正常工作。但一切皆有可能。
要清理build
先决条件,您可以使用以下内容:
build: $(foreach d,background page popup,$(addprefix lib/$d/build/,build.js build.css))