makefile - Make:一次调用两个虚假目标时“对目标无事可做”
问题描述
简单的生成文件:
.PHONY:\
gitbranch-foo
gitbranch-foo: dir=./foo
gitbranch-foo: git-spawn-branch
.PHONY:\
gitbranch-bar
gitbranch-bar: dir=./bar
gitbranch-bar: git-spawn-branch
.PHONY:\
git-spawn-branch
git-spawn-branch:
@$(call git_branch,$(dir),$(branch))
@echo > /dev/null
define git_branch
cd $(1); \
git checkout -b $(2) || true; \
git push -u origin $(2) || true;
endef
一次调用两个规则:
make gitbranch-foo gitbranch-bar branch=something/blah/blah -rRd
如您所见,'foo' repo 切换成功,但 make 甚至没有处理 'bar' repo。为什么?
Switched to a new branch 'something/blah/blah' <-- 'foo' switches successfully
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create pull request for something/blah/blah:
remote: ....
remote:
To xyz.net:foo
* [new branch] master -> something/blah/blah
Branch 'something/blah/blah' set up to track remote branch 'something/blah/blah' from 'origin'.
make: Nothing to be done for 'gitbranch-bar'. <-------- 'bar' is not even processed why?
'make' 的调试输出如下所示:
Branch 'something/blah/blah' set up to track remote branch 'something/blah/blah' from 'origin'.
Everything up-to-date
Reaping winning child 0x563e010f42d0 PID 2092
Live child 0x563e010f42d0 (git-spawn-branch) PID 2096
Reaping winning child 0x563e010f42d0 PID 2096
Removing child 0x563e010f42d0 PID 2096 from chain.
Successfully remade target file 'git-spawn-branch'.
Finished prerequisites of target file 'gitbranch-foo'.
Must remake target 'gitbranch-foo'.
Successfully remade target file 'gitbranch-foo'.
Considering target file 'gitbranch-bar'.
File 'gitbranch-bar' does not exist.
Pruning file 'git-spawn-branch'.
Finished prerequisites of target file 'gitbranch-bar'.
Must remake target 'gitbranch-bar'.
Successfully remade target file 'gitbranch-bar'.
make: Nothing to be done for 'gitbranch-bar'.
但不能从中做出正面或反面。任何关于“make”为何以这种方式表现的见解都值得赞赏。
注意:我知道我可以像下面这样重构 makefile 来让它完成我的竞标 - 我只是想了解为什么原始方法没有按预期工作
.PHONY:\
gitbranch-foo
gitbranch-foo:
@$(call git_branch,./foo,$(branch))
@echo > /dev/null
.PHONY:\
gitbranch-bar
gitbranch-bar:
@$(call git_branch,./bar,$(branch))
@echo > /dev/null
define git_branch
cd $(1); \
git checkout -b $(2) || true; \
git push -u origin $(2) || true;
endef
解决方案
答案完全是由于make
的规则,与此处的任何其他标签无关(我将删除所有其他标签)。不起作用的makefile说:
- 建设
gitbranch-foo
,我们必须建设git-spawn-branch
- 建设
gitbranch-bar
,我们必须建设git-spawn-branch
(当然还有构建git-spawn-branch
自身的代码和其他相关的东西,但让我们停在这里)。
然后运行make,告诉它同时构建gitbranch-foo
和gitbranch-bar
.
Make 选择其中一个来构建——<code>gitbranch-foo,在本例中——并开始构建。 哦,嘿,make 对自己说,这需要git-spawn-branch
构建,我们还没有这样做。git-spawn-branch
Off go make,根据规则构建。现在它已经建成了!使可以回到建筑物gitbranch-foo
。这将执行剩余的配方,它是空的。
如果允许并行构建,make
现在也可以在构建gitbranch-bar
时开始gitbranch-foo
构建。如果没有,我们等待gitbranch-foo
此时完全建成。无论哪种方式,我们都很快开始构建gitbranch-bar
。 嗯, make 对自己说,这需要git-spawn-branch
构建......但幸运的是,我已经做到了!向前!让我们做剩下的gitbranch-bar
吧! 这需要执行空的配方,这非常快。
制作完成。它已经构建了所需的一切。
(有效的 makefile$call
直接从每个规则中明智地使用,因此$call
需要为每个目标运行扩展为的命令,而不是隐藏在可以只构建一次并且永远不需要运行的第三个目标中更远。)
(请注意,gmake 文档提到.PHONY
每次都运行一个规则。这意味着每次调用make
一次,而不是每次调用该规则一次。)
推荐阅读
- sql - oracle 从列中获取所有匹配的匹配项
- reactjs - Heroku - 错误 R10(引导超时) -> Web 进程未能在使用 Webpack 启动后 60 秒内绑定到 $PORT
- ios - 如何从 JSON 创建对象集合
- javascript - getElementById 返回 null 即使它在 HTML
- java - WSGEN错误:编译失败,应该报错
- python - 如何在 Python 中的数据框上迭代 if else 语句?
- node.js - 分离 REST API 和 App Server
- hibernate - 当通过 join fetch 获取具有 @OneToOne 的实体时,会急切地获取 @OneToOne
- python - 使用 python 抓取具有多个部分的页面
- json - how to print this i m not getting any output train api