23

我在我的项目中使用(GNU)Make。我目前正在为每个目录放置一个 makefile,并使用 SUBDIRS 指定子目录。有人向我建议,这不是使用 make 的理想方式,而是使用一个顶级 make 文件(或多个,使用 include 拆分)。我过去曾尝试过迁移/使用此布局,但在我看来,它没有必要复杂。

使用递归 makefile 有哪些优点/缺点?

4

8 回答 8

24

您应该记住的第一件事(只是为了消除任何误解)是我们不是在谈论单个与多个 makefile。在任何情况下,将您的 makefile 拆分为每个子目录可能是一个好主意。

递归生成文件不好主要是因为您将依赖关系树划分为几棵树。这会阻止正确表达 make 实例之间的依赖关系。这也导致(部分)依赖树被重新计算多次,这最终是一个性能问题(尽管通常不是一个大问题。)

为了正确使用单一制作方法,您需要使用一些技巧,尤其是当您拥有大型代码库时:

首先,使用 GNU make(你已经这样做了,我明白了)。GNU make 有许多简化事情的特性,您不必担心兼容性问题。

其次,使用特定于目标的变量值。例如,这将允许您为不同的目标拥有不同的 CFLAGS 值,而不是强制您在整个 make 中使用单个 CFLAGS:

 main: CFLAGS=-O2
 lib: CFLAGS=-O2 -g

第三,确保在 GNU make 支持的范围内使用 VPATH/vpath。

您还需要确保没有多个同名的源文件。VPATH 的一个限制是它不允许您拥有特定于目标的 VPATH 定义,因此源文件的名称必须共存于单个“VPATH 命名空间”中。

于 2008-11-26T12:26:03.930 回答
18

一篇题为“Recursive Make Considered Harmful”的文章可以在这里找到: http://miller.emu.id.au/pmiller/books/rmch/?ref= DDiyet.Com。(或者在SourceForge的Aegis项目中。)

它探讨了递归 makefile 的问题,并推荐了一种单一的 makefile 方法。

于 2008-11-26T06:06:43.977 回答
7

我广泛使用递归。每个叶节点都有自己的makefile,考虑:

$LIBS = libfoo libbar
$(LIBS):
    cd $@ && $(MAKE)

在大型系统上,没有这种结构将是一个相当大的挑战。人们所说的“递归使认为有害”是一种准确的评估。我认为每种情况都有些不同,我们会做出一些妥协。

于 2011-05-05T06:12:48.263 回答
4

跑到cmake.org,不要走路,并获得 Cmake,这是可用的最佳构建工具之一。

您仍将使用 GNU make,但在这种情况下,CMake 将为您生成 makefile。

我不能保证 100%,但我还没有遇到过它没有正确处理子目录之间的依赖关系的情况(即困扰递归 make 的问题)。至少,维护 Cmakefile 比维护 makefile 容易得多。强烈推荐。

不要使用 GNU 自动工具——那是疯狂的所在!

于 2008-11-26T12:46:43.373 回答
0

我过去从中获得的好处是在单个子目录中构建文件更容易。您可以使用依赖项来执行此操作,但要保持所有目标正确,需要做更多的工作。基本上,这使得更改和测试一个库变得更容易,而无需处理更大项目的全部复杂性。

于 2008-11-26T05:46:10.760 回答
0

要加入第三个选项,您可以使用 GNU Autotools。主要用于其他原因,但也可能有助于组织多目录构建。

http://www.lrde.epita.fr/~adl/autotools.html

但是,必须注意,结果是递归版本。

于 2008-11-26T06:13:24.353 回答
0

Makepp 是你的朋友。

http://makepp.sourceforge.net/

  • 向后兼容 make
  • 自动扫描标头依赖项
  • 优雅地处理目录树
于 2011-04-14T17:09:13.533 回答
-1

递归 make 的问题是评估所有不同的 make 文件与评估一个大型 make 文件的时间开销。其中一部分只是产生过程,而且(IIRC)你往往被迫假设其他make文件做了一些事情并在你真的不需要时重建。

我的看法是每个“单元”有一个制作文件,这或多或少相当于为您期望可以单独使用的每个代码块拥有一个制作文件(例如,作为一个独立的库)

OTOH,我当前的项目在构建过程中生成 make 文件时,整个地方都打破了这一点。:b

于 2008-11-26T05:53:55.330 回答