我在一个Web应用程序上工作,其Makefile包含以下内容:
dist/index.html: src/templates/index.html
@bin/insert-scripts $< --output $@
bin / insert-scripts 使用以下方法之一替换所提供文件中的<--scripts-->
:
问题是如果一个人在一个模式下构建dist / index.html(比如说“开发”),然后在另一个模式中再次构建它而不触及依赖,make会说没有什么可做的。我希望能够做的是使$ ENV成为dist / index.html的依赖:
dist/index.html: src/templates/index.html $ENV
@bin/insert-scripts $< --output $@
当然,这不起作用,所以我考虑使用名为ENV的文件,其中包含“开发”或“生产”。该文件将成为依赖项:
dist/index.html: src/templates/index.html ENV
@bin/insert-scripts $< --output $@
不是设置环境变量,而是设置ENV文件的内容。这似乎有点笨拙,但至少准确地表示了依赖树。
处理这种情况的最佳方法是什么?
答案 0 :(得分:6)
如果您必须为更改的环境强制执行重建,则始终可以为构建环境使用标记文件:
.PHONY: always-rebuild
environment : always-rebuild
echo $ENV > $@.tmp
diff --quiet $@ $@.tmp || cp $@.tmp $@
rm -f $@.tmp
dist/index.html : src/templates/index.html environment
diff
确保始终重建environment
(&lt; =检查),但仅在相关环境变量发生变化时触及。
答案 1 :(得分:4)
因此,您希望make
在以下两种情况下运行脚本:
src/templates/index.html
已更改dist/index.html
以来,此要求的问题是环境变量没有时间戳。因此,make无法知道目标是否是最新的。
通常类似情况下的解决方案是简单地具有单独的目标,例如dist-development/index.html
和dist-production/index.html
。您甚至可以找到一种方法来使用符号链接或其他内容来有效地将Web应用指向正确的 index.html 版本。但是使用 ENV 文件的替代方案也是可能的。我建议对你的程序进行一些改进:
.PHONY: ENV
ifneq "$(ENV)" "$(shell cat ENV)"
dist/index.html: ENV src/templates/index.html
@bin/insert-scripts $< --output $@
else
dist/index.html: src/templates/index.html
@bin/insert-scripts $< --output $@
endif
ENV:
echo $(ENV) >$@
这样,你的make将接受 $ ENV 的当前设置,并将其保存在具有正确时间戳的文件中。
答案 2 :(得分:1)
当所有相关信息都以文件名编码时,Make始终效果最佳:
all : dist-${ENV}/index.html
dist-development/index.html : src/templates/index.html
ENV=development bin/insert-scripts $< --output $@
dist-production/index.html : src/templates/index.html
ENV=production bin/insert-scripts $< --output $@