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

dav*_*ers 7 makefile build

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

dist/index.html: src/templates/index.html
    @bin/insert-scripts $< --output $@
Run Code Online (Sandbox Code Playgroud)

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

  • 当$ ENV是"开发"时,或许多脚本标签(用于jQuery,Underscore等)
  • $ ENV是"生产"时,单个脚本标记(指向连接的,缩小的文件).

问题是如果一个人在一个模式下构建dist/index.html(比如说"开发"),然后在另一个模式再次构建它而不触及依赖关系,make会说没有什么可做的.我希望能够使$ ENV成为dist/index.html的依赖:

dist/index.html: src/templates/index.html $ENV
    @bin/insert-scripts $< --output $@
Run Code Online (Sandbox Code Playgroud)

当然,这不起作用,所以我考虑使用一个名为ENV的文件,其中包含"开发"或"生产".该文件将成为依赖项:

dist/index.html: src/templates/index.html ENV
    @bin/insert-scripts $< --output $@
Run Code Online (Sandbox Code Playgroud)

可以设置ENV文件的内容,而不是设置环境变量.这似乎有点笨重,但至少准确地表示依赖树.

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

thi*_*ton 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
Run Code Online (Sandbox Code Playgroud)

diffING确保environment始终重新修建(<=选中),但是当相关的环境变量只改变感动.


Ale*_*ohn 5

因此,您希望make在以下两种情况下运行脚本:

  • src/templates/index.html 改变了
  • ENV环境变量自上次生成以来已更改dist/index.html

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

通常在类似情况下的解决方案是简单地使用单独的目标,例如dist-development/index.htmldist-production/index.html。你甚至可以找到一种使用符号链接或其他东西的方法来有效地将网络应用程序指向正确的最新版本的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) >$@
Run Code Online (Sandbox Code Playgroud)

这样,您的 make 将接受$ENV的当前设置并将其保存在具有正确时间戳的文件中。