制作取决于环境变量的目标

时间:2013-02-12 19:43:54

标签: build makefile

我在一个Web应用程序上工作,其Makefile包含以下内容:

dist/index.html: src/templates/index.html
    @bin/insert-scripts $< --output $@

bin / insert-scripts 使用以下方法之一替换所提供文件中的<--scripts-->

    当$ ENV是“开发”时,
  • 许多脚本标签(用于jQuery,Underscore等),或
  • 当$ ENV为“production”时,单个脚本标记(指向连接的缩小文件)。

问题是如果一个人在一个模式下构建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文件的内容。这似乎有点笨拙,但至少准确地表示了依赖树。

处理这种情况的最佳方法是什么?

3 个答案:

答案 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 以来,
  • ENV 环境变量发生了变化

此要求的问题是环境变量没有时间戳。因此,make无法知道目标是否是最新的。

通常类似情况下的解决方案是简单地具有单独的目标,例如dist-development/index.htmldist-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 $@