gnu-make - --always-make 可以不影响子 make 吗?

标签 gnu-make

使用 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/

相关文章:

makefile - 自动依赖检测在 GFortran 中不起作用

linux - 每次我对 linux 内核做一点改动时,我是否应该安装 modules_install

c - 尽管已安装并正常运行,但如何修复 make 文件中的 gcc 未找到错误?

c - 使用 GNU Make 迭代文件目录

linux - 从 makefile 执行复杂的 shell 命令

c++ - Makefile C++ Linux 的问题

linux - 如何处理 make 中的特殊情况?

grep - GNU makefile 中的 $(shell) 函数导致 'unterminated call to function shell: missing )'

c++ - 目标文件是为比链接更新的 OSX 版本构建的

qt - 在 qmake 的 Makefile 中添加额外的变量