几年前,我读过Recursive Make Considered Harmful论文并在我自己的构建过程中实现了这个想法。最近,我读了另一篇关于如何implement non-recursive make
的文章。 。所以我有一些非递归的数据点 make
至少适用于一些项目。
但我很好奇其他人的经历。您是否尝试过非递归 make
?它使事情变得更好还是更糟?值得花时间吗?
最佳答案
我工作的公司使用非递归 GNU Make 系统。它基于米勒的论文,特别是您提供的“实现非递归制作”链接。我们已经成功地将 Bergen 的代码改进为一个子目录 makefile 中根本没有样板的系统。总的来说,它运行良好,并且比我们以前的系统(使用 GNU Automake 完成的递归操作)要好得多。
我们支持所有“主要”操作系统(商业):AIX、HP-UX、Linux、OS X、Solaris、Windows,甚至 AS/400 大型机。我们为所有这些系统编译相同的代码,并将平台相关部分隔离到库中。
我们的树中有超过 200 万行 C 代码,分布在大约 2000 个子目录和 20000 个文件中。我们认真考虑过使用 SCons,但就是无法让它运行得足够快。在较慢的系统上,Python 会花费几十秒来解析 SCons 文件,而 GNU Make 在大约一秒内完成同样的事情。这是大约三年前的事,所以从那以后情况可能发生了变化。请注意,我们通常将源代码保存在 NFS/CIFS 共享上,并在多个平台上构建相同代码。这意味着构建工具扫描源代码树以查找更改的速度甚至更慢。
我们的非递归 GNU Make 系统并非没有问题。以下是您可能会遇到的一些最大障碍:
- 使其可移植(尤其是 Windows)需要大量工作。
- 虽然 GNU Make 几乎是一种可用的函数式编程语言,但它不适合大规模编程。特别是,没有命名空间、模块或类似的东西可以帮助您将各个部分相互隔离。这可能会导致问题,尽管没有您想象的那么严重。
相对于我们旧的递归 makefile 系统的主要优点是:
- 快。检查整个树(2k 目录、20k 文件)大约需要两秒钟,然后确定它是最新的或开始编译。旧的递归方法需要一分多钟才能完成任何操作。
- 它正确处理依赖关系。我们的旧系统依赖于子目录的构建顺序等。就像您从阅读 Miller 的论文中所期望的那样,将整个树视为单个实体确实是解决此问题的正确方法。
- 经过我们付出的努力,它可以移植到我们所有支持的系统上。太酷了。
- 抽象系统允许我们编写非常简洁的makefile。仅定义库的典型子目录只有两行。其中一行给出了库的名称,另一行列出了该库所依赖的库。
关于上面列表中的最后一项。我们最终在构建系统中实现了一种宏扩展工具。子目录 makefile 列出了程序、子目录、库以及 PROGRAMS、SUBDIRS、LIBS 等变量中的其他常见内容。然后,每一个都被扩展为“真正的”GNU Make 规则。这使我们能够避免很多命名空间问题。例如,在我们的系统中,可以有多个同名的源文件,没有问题。
无论如何,这最终都是一项艰巨的工作。如果您可以让 SCons 或类似的代码适用于您的代码,我建议您首先查看一下。
关于build-process - 您对非递归 make 有什么经验?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/559216/