递归结交——朋友还是敌人?
我在我的项目中使用 (GNU) Make。 我目前为每个目录放置一个 makefile,并使用 SUBDIRS 指定子目录。 有人向我建议,这不是使用 make 的理想方式,即使用一个顶级 make 文件(或多个,使用 include 分割)。 我过去曾尝试过迁移/使用此布局,但在我看来,这没有必要复杂。
使用递归 makefile 有哪些优点/缺点?
I'm using (GNU) Make in my project. I'm currently putting one makefile per directory and specify the subdirectories using SUBDIRS.
It's been suggested to me that this is not the ideal way of using make, that using a one toplevel make file (or several, split up using include). I've tried migrating/using this layout in the past, but it appears to me that it's unnecessary complicated.
Which are the benefits/drawbacks of using recursive makefiles?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我广泛使用递归。 每个叶节点都有自己的 makefile,请考虑:
在大型系统上,没有这种结构将是一个相当大的挑战。 人们所说的“递归使人认为有害”是一个准确的评估。 我认为每种情况都有点不同,我们会做出一些妥协。
I use recursion extensively. each leaf node will have its own makefile, consider:
On large systems it would be quite a challenge to not have this structure. What folks talk about "recursive make considered harmful" is an accurate assessment. I think each situation is a little different and we make some compromises.
跑,而不是走路,到 cmake.org 并获取 Cmake,它是最好的构建工具之一。
您仍将使用 GNU make,但在这种情况下,CMake 将为您生成 makefile。
我不能保证100%,但我还没有遇到过它没有正确处理子目录之间依赖关系的情况(即困扰递归make的问题)。 至少,维护 Cmakefile 比 makefile 容易得多。 强烈推荐。
不要使用 GNU 自动工具——那样才是疯狂的所在!
Run, don't walk, to cmake.org and get Cmake, one of the best build tools available.
You will still be using GNU make, but in this case CMake will generate the makefiles for you.
I can't guarantee 100%, but I have yet to come across a case where it has not correctly handled dependencies between subdirectories correctly (ie the problem that plagues the recursive make). At the very least it is a lot easier to maintain Cmakefiles than makefiles. Highly recommended.
Do not use GNU autotools - that way madness lies!
我过去从中获得的好处是可以更轻松地在单个子目录中构建文件。 您可以通过依赖项来做到这一点,但要保持所有目标的一致性需要做更多的工作。 基本上,这使得更改和测试一个库变得更加容易,而无需处理较大项目的全部复杂性。
The benefit that I've gotten from this in the past is that it's easier to build files in a single subdirectory. You can do this with dependencies, but it's a bit more work to keep all of the targets straight. Basically, this makes it easier to make changes and test one library without having to deal with the full complexity of the larger project.
要添加第三个选项,您可以使用 GNU Autotools。
主要用于其他原因,但也可能有助于组织多目录构建。
http://www.lrde.epita.fr/~adl/autotools.html< /a>
但必须注意,结果是一个递归版本。
To throw in a third option, you could use GNU Autotools.
Mostly used for other reasons, but may also helpful at organizing a multi-directory build.
http://www.lrde.epita.fr/~adl/autotools.html
It has to be noted, though, that the result is a recursive version.
马可普是你的朋友。
http://makepp.sourceforge.net/
Makepp is your friend.
http://makepp.sourceforge.net/
递归 make 的问题是评估所有不同的 make 文件与评估一个大型 make 文件的时间开销。 其中一部分只是生成过程,但(IIRC)您往往被迫假设其他 make 文件做了一些事情,并在您实际上不需要时进行重建。
我的看法是每个“单元”都有一个 make 文件,这或多或少相当于为您期望可以单独使用的每个代码块创建一个 make 文件(例如作为独立库)
OTOH 我当前的当我在构建过程中生成 make 文件时,项目到处都打破了这一点。 :b
The issue with recursive make is the time overhead of evaluating all the different make files vs. evaluating one large make file. Part of this is just spawning processes but also (IIRC) you tend to be forced into assuming that other makes files did something and rebuilding when you don't really need to.
My take on it is to have a single make file per "Unit", that more or less amounts to having a make file for each chunk of code that you expect could be used on it's own (e.g. as an independent library)
OTOH my current project breaks this all over the place as I'm generating make files during the build. :b
您应该记住的第一件事(只是为了消除任何误解)是我们不是在谈论单个 makefile 与多个 makefile。 无论如何,将 makefile 拆分为每个子目录可能是一个好主意。
递归 makefile 不好主要是因为您将依赖关系树划分为多个树。 这会阻止正确表达 make 实例之间的依赖关系。 这也会导致(部分)依赖关系树被重新计算多次,这最终是一个性能问题(尽管通常不是一个大问题)。
为了正确使用单个依赖关系树,您需要使用一些技巧-make 方法,尤其是当您拥有大型代码库时:
首先,使用 GNU make(我明白,您已经这样做了)。 GNU make 有许多功能可以简化事情,您不必担心兼容性。
其次,使用特定于目标的变量值。 例如,这将允许您为不同的目标拥有不同的 CFLAGS 值,而不是强迫您在整个 make 中使用单个 CFLAGS:
第三,确保您在 GNU make 支持的全部范围内使用 VPATH/vpath。
您还需要确保没有多个同名的源文件。 VPATH 的一个限制是它不允许您拥有特定于目标的 VPATH 定义,因此源文件的名称必须共存于单个“VPATH 命名空间”中。
The first thing you should keep in mind (just to eliminate any misunderstanding) is that we're not talking about a single vs. multiple makefiles. Splitting your makefile in one per subdirectory is probably a good idea in any case.
Recursive makefiles are bad primarily because you partition your dependency tree into several trees. This prevents dependencies between make instances from being expressed correctly. This also causes (parts of) the dependency tree to be recalculated multiple times, which is a performance issue in the end (although usually not a big one.)
There are a couple of tricks you need to use in order to properly use the single-make approach, especially when you have a large code base:
First, use GNU make (you already do, I see). GNU make has a number of features which simplifies things, and you won't have to worry about compatibilities.
Second, use target-specific variable values. This will allow you to have, for example, different values of CFLAGS for different targets, instead of forcing you to have a single CFLAGS in your entire make:
Third, make sure you use VPATH/vpath to the full extent supported by GNU make.
You also want to make sure that you do not have multiple source files with the same name. One limitation of VPATH is that it does not allow you to have target-specific VPATH definitions, so the names of your source files will have to co-exist in a single "VPATH namespace".
题为“递归使人认为有害”的文章可以在这里找到: http://miller.emu.id.au/pmiller/books/rmch/?ref=DDiyet.Com。 (或者在 SourceForge 的 Aegis 项目中。)
它探讨了递归 makefile 的问题,并推荐了一个单一 makefile 方法。
An article entitled "Recursive Make Considered Harmful" can be found here: http://miller.emu.id.au/pmiller/books/rmch/?ref=DDiyet.Com. (Or at the Aegis project at SourceForge.)
It explores the problems with recursive makefiles, and recommends a single-makefile approach.