makefile - 一个共享的 Makefile 依赖只运行一次

标签 makefile gnu-make

TL;博士

多个目标共享的依赖只被调用一次。

为什么?

总结

在这个微型 Makefile 示例中,我希望 deploy-everywherestaging-repo 代码部署到 stagingprod-repo 代码到 prod

相反,stagingprod 都获得 staging-repo 代码,诚然,这是次优的。

这似乎是因为 clone-repo 在第二次检查时被跳过/修剪,作为 deploy-to-prod 的一部分(参见 -d 日志输出如下)。

为什么会发生这种情况,我可以改变这种行为吗?

$ cat Makefile

.PHONY: deploy-everywhere deploy-to-prod deploy-to-staging clone-repo

deploy-everywhere: deploy-to-staging deploy-to-prod
    @echo "deployed everywhere"

deploy-to-prod: repo="prod-repo"
deploy-to-prod: clone-repo
    @echo "deployed to prod (from $(repo))"

deploy-to-staging: repo="staging-repo"
deploy-to-staging: clone-repo
    @echo "deployed to staging (from $(repo))"

clone-repo:
    @echo "clone-repo $(repo)"

更多详细信息(日志、版本)

这是运行 make 的输出:

$ make deploy-everywhere
clone-repo staging-repo
deployed to staging (from staging-repo)
deployed to prod (from prod-repo) <<<<< THIS IS A LIE, WE NEVER CLONED THE PROD REPO!!
deployed everywhere <<<< RIIIIGHT.

额外的日志记录:

$ make -d deploy-everywhere
...
  Successfully remade target file `deploy-to-staging'.
  Considering target file `deploy-to-prod'.
   File `deploy-to-prod' does not exist.
    Pruning file `clone-repo'.          <<<< WHY? WHY?!?!?!?! WHY.
   Finished prerequisites of target file `deploy-to-prod'.
  Must remake target `deploy-to-prod'.
...

我正在运行 GNU Make 3.81:

$ make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin11.3.0

最佳答案

这是设计使然。 makefile 中的目标更像是名词而不是动词。

您可以通过多种方式实现您的目标。这是一个:

deploy-to-prod: clone-prod-repo
    @echo "deployed to prod (from prod-repo)"

deploy-to-staging: clone-staging-repo
    @echo "deployed to staging (from staging-repo)"

clone-%-repo:
    @echo "clone $*-repo"

编辑:好吧,clone 操作需要多个参数。这是一种方法:

deploy-to-prod: PARAM1=ProdOne
deploy-to-prod: PARAM2=ProdTwo
deploy-to-prod: clone-prod-repo
    @echo "deployed to prod (from prod-repo)"

deploy-to-staging: PARAM1=StagingFirst
deploy-to-staging: PARAM2=StagingSecond
deploy-to-staging: clone-staging-repo
    @echo "deployed to staging (from staging-repo)"

clone-%-repo:
    @echo clone $*-repo with $(PARAM1) and $(PARAM2)

还有一个:

define clone-repo
@echo clone using $(1)
@echo and $(2) in some way
endef

deploy-to-prod:
    @echo $@
    $(call clone-repo, ProdOne, ProdTwo)

deploy-to-staging:
    @echo $@
    $(call clone-repo, StagingFirst, StagingSecond)

关于makefile - 一个共享的 Makefile 依赖只运行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60518776/

相关文章:

python - 使用Makefile bash保存python文件的内容

makefile - 为什么 make 不检测 header 依赖项的变化

ubuntu - Makefile:缺少分隔符

c - 如何在makefile中扩展嵌套变量

makefile - CodeBlocks:如何在从自定义 Makefile 构建后运行

python - 为什么 Python 项目中没有用于自动化的 Makefile?

unix - Makefile 中的规则参数

c++ - Vc++/c++ Force Include Header 异常

makefile - IBM AIX 附带的 make 实用程序与 gnu make 兼容吗

macos - 如何运行 "gmake install"?