使用 GNU Make 4.1
摘要
我正在从 makefile a.mk
调用子 make b.mk
。
调用b.mk
以确保子系统已构建。
有时我想强制重新制作a.mk
的目标:
make -f a.mk <target> --always-make
当我这样做时,b.mk
也会认为所有目标都已过时,但我不希望它如此。
补救失败
我已经尝试使用make -f b.mk MAKEFLAGS=
,如手册中建议的那样
5.7.3 Communicating Options to a Sub-make ,但运气不好。
这是a.mk
的要点:
.PHONY: all
$(info ===> a.mk MAKEFLAGS: $(MAKEFLAGS))
all:
$(MAKE) -f b.mk y MAKEFLAGS=
和b.mk
:
$(info ===> b.mk MAKEFLAGS: $(MAKEFLAGS))
y: x
cp $< $@
现在,即使 b.mk
通常认为 y
是最新的:
$ make -f b.mk y
===> b.mk MAKEFLAGS:
make: 'y' is up to date.
...当使用 --always-make (-B)
调用 a.mk
时,会重新生成 y
:
$ make -f a.mk --always-make
===> a.mk MAKEFLAGS: B
make -f b.mk y MAKEFLAGS=
make[1]: Entering directory '/home/matt/junk/make-b'
===> b.mk MAKEFLAGS:
cp x y
make[1]: Leaving directory '/home/matt/junk/make-b'
如您所见,B
标志出现在 a.mk
的 MAKEFLAGS 中,但不在 b.mk
的 MAKEFLAGS 中。
但是,y
是由 b.mk
重新制作的。
问题
- 为什么?
- 有办法解决这个问题吗?
- 对于 GNU make,我希望这种行为有一个很好的理由。原因是什么?
更新:2020-08-05
我到底为什么要这样做?
在答案中https://stackoverflow.com/a/63231100/685715 ,有人请求查看一个示例,希望强制重新制作特定目标,但又不想强制子制作。
这里不是发明一些东西,而是实际 makefile 的摘录,它引发了我的问题:
WWW_SVG := score.svg
%Score.app/$(WWW_SVG): %Score.svg | %Score.app/
cd $(MUSIC_SCORE_PLAYER) && $(MAKE) -f $(MUSIC_SCORE_PLAYER_MAKEFILE) $(MUSIC_SCORE_PLAYER_TGT) MAKEFLAGS=
cp $< $(MUSIC_SCORE_PLAYER_DIR)$(WWW_SVG)
node $(MUSIC_SCORE_PLAYER_SVG_CONVERTER) > $@
该规则的目的是从另一个 SVG 创建一个 SVG。 在 Web 应用程序加载并修改原始 SVG 后,新的 SVG 会镜像 DOM 的 SVG 部分的状态。
- 配方的第一行使用子版本来确保网络应用程序是最新的,但它可能不是我目前正在开发的。该 Web 应用程序是一个独立的项目,与包含从中提取上述代码片段的 makefile 的项目不同。
- 第二行将原始 SVG 复制到 Web 应用程序的部署目录中,以便 Web 应用程序可以加载它
- 第三行调用节点脚本来启动 Web 应用程序,从其 DOM 中提取 SVG,并将其写入 stdout。然后将其重定向以更新 SVG 目标。
在测试时,我希望能够强制重新制作具有与 %FooScore/score.svg
匹配的先决条件的目标,但无需重建 Web 应用程序,除非它已经过时了。
当然,我可以移动调用子 make 的行,以便仅调用一次,而不是为每个匹配规则的目标调用一次。但这是一种优化,而不是解决方案。
最佳答案
“始终构建”的要点是调用构建的所有部分。如果这个不被传递给子品牌是没有意义的。事实上,许多 makefile 在顶层 makefile 中几乎没有发生任何事情:它们只是调用一组子 make。如果“永远构建”不被传承下去,它就没有什么用处。
不幸的是,您的示例都是以这种方式工作的,但事实并非如此。为了提出解决方案,我们需要看一个更现实的例子。特别是,您说您想强制重新制定特定目标,但在上面的示例中您没有表明这一点。 reshape 的目标是什么?它如何与 b.mk
的子 make 调用交互?
作为一个注释,我应该说,你不应该永远使用make
来调用子make。您应该始终使用$(MAKE)
(或者等效的${MAKE}
)。
关于gnu-make - --always-make 可以不影响子 make 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63224700/