如何在递归生成文件中获取目标的依赖关系?

Posted

技术标签:

【中文标题】如何在递归生成文件中获取目标的依赖关系?【英文标题】:How can I get the dependencies of a target in a recursive makefile? 【发布时间】:2019-03-23 10:30:48 【问题描述】:

当一个项目依赖于其他有自己的makefile的项目时,递归make的用法如下:

LIBDIR := path/to/lib
LIBNAME := library.a
LIBPATH := $(LIBDIR)/$(LIBNAME)

$(LIBPATH):
        $(MAKE) -C $(LIBDIR) $(LIBNAME)

然而,明显的问题是 make 无法确定 $(LIBPATH) 的依赖关系,因为它是在 $(LIBDIR) 的递归 makefile 中定义的。

我目前正在做的是使用 .PHONY 目标来强制检查子项目是否需要重建:

$(LIBPATH): always_build
        $(MAKE) -C $(LIBDIR) $(LIBNAME)

.PHONY: always_build

虽然这允许我在需要时触发重建,但它仍然需要遍历很多目录并多次调用 make,只是为了发现什么都不需要做。

有没有办法从子 makefile 中获取依赖项,以便我可以将它们添加为 $(LIBPATH) 的依赖项,以便仅在确实需要调用子 makefile 时才调用它?

【问题讨论】:

事实上,这是“为什么递归 make 被认为有害”的主要原因。将其重写为非递归或只是使用它。 这个github.com/igagis/prorab 应该可以帮助您开始使用非递归快速制作 【参考方案1】:

如果您的意思是,以自动化方式,那么不会。即使有也没有任何意义。

为了获得这些先决条件,您必须调用 make 来计算它们。一旦该子make计算了它们,它将通知父make,并且父make将检查先决条件,然后如果有任何过期,它将再次调用子make,这将重新计算实际构建目标的先决条件。

远非更高效,您实际上要做的工作量是原来的三倍!

在递归 make 场景中,您当前将过期计算委托给子 make 的方法是您能做的最好的方法。

您真正要问的是使用非递归 make 环境,其中单个 make 实例知道所有先决条件并确定什么是过时的。但是请注意,这并不能真正解决“不读取大量 makefile”的问题。

最终你无法知道你的项目完全是最新的,而不检查它是否完全是最新的......这意味着检查所有的依赖关系。

【讨论】:

以上是关于如何在递归生成文件中获取目标的依赖关系?的主要内容,如果未能解决你的问题,请参考以下文章

make--变量与函数的综合示例 自动生成依赖关系

makefile中依赖关系如何写?

通过递归调用构建依赖关系make?

如何在 CMake 中正确创建目标之间的依赖关系?

Makefile 7——自动生成依赖关系 三颗星

Makefile学习7————自动生成依赖关系 三颗星