C++ 创意C++;自动统一构建系统,它会工作吗?

C++ 创意C++;自动统一构建系统,它会工作吗?,c++,build,compilation,compiler-construction,C++,Build,Compilation,Compiler Construction,这听起来有点疯狂,但我有以下想法 在C++中,当你把所有的代码放在一个文件中时,调用它们,使用简单的复制和粘贴。这允许闪电般的快速编译 现在为了简单起见,让我们假设我们有一个只有头的库,并且我们限制自己只使用类(这样我们就有了一个garaunited名称空间)。 现在我想知道,如果把它变成自动的,效果会如何。将制作一个脚本/工具来预处理.h文件;挑选包含项和依赖项。该工具将递归遍历每个.h文件,并构造包含的依赖项的映射。然后使用#includes和compile将这些依赖项放在一个文件(main

这听起来有点疯狂,但我有以下想法

在C++中,当你把所有的代码放在一个文件中时,调用它们,使用简单的复制和粘贴。这允许闪电般的快速编译

现在为了简单起见,让我们假设我们有一个只有头的库,并且我们限制自己只使用类(这样我们就有了一个garaunited名称空间)。 现在我想知道,如果把它变成自动的,效果会如何。将制作一个脚本/工具来预处理.h文件;挑选包含项和依赖项。该工具将递归遍历每个.h文件,并构造包含的依赖项的映射。然后使用#includes和compile将这些依赖项放在一个文件(main.cpp)中


现在我想听听你们对自动统一构建创建者的看法。这样做明智吗?它会像我期望的那样工作吗?

你完成了什么

您讨厌“仅标题”,因为“每次都需要重新编译世界”。在您的“勇敢的新世界”中,只有一个文件,因此无论发生什么情况,每次都会编译它

人们花费了大量的时间和精力,使得C++可以使用库等来帮助加快编译速度。哦,顺便说一下,我今天看到的系统有1700多万行代码。你想把它放在一个文件里吗

OP在评论中提供的链接是一个很好的解释。我看到的最大问题是可伸缩性。它确实让我想起了我的(继承的)代码库中的一个区域,在这个区域中,守卫在include之外,以避免打开文件。e、 g

#ifndef BLAH_H
#include <blah.h>
#endif
#如果没有
#包括
#恩迪夫

Unity的版本真的太贵了

这允许闪电般的快速编译

这几天不完全是真的。假设您有专门的机器进行编译,并且有足够的RAM,则编译不受I/O限制。每个现代操作系统都会在首次读取文件后缓存文件,然后再从内存中获取它们。您可以通过管道或将它们存储在RAM驱动器中来避免中间文件。所以预处理器的工作大部分时间只是连接文件。这很快。实时时间用于编译和链接

因此,任何具有数千个文件的严肃应用程序都将是巨大的。现实世界的例子-我们使用的应用程序源代码占用超过100MB的数据(不包括系统和第三方)。因此,您的系统必须在大约150MB的文件上运行。如果一些编译器拒绝编译它,我不会感到惊讶。更不用说编译的时间了。最好将文件拆分成更小的文件并并行编译。又是一个真实的例子-单线程编译需要40分钟才能完成,在一台服务器上运行16个线程,大约2.5-3分钟,在16台服务器上编译,每台服务器16个核心,distcc 30秒,再加上一些链接时间

当LTO和静态构建完成时,unity构建的另一个好处——更好的优化——消失了


回答你的问题-是的,你能做到。这有意义吗?怀疑

是的。。为什么不呢,如果它可以放入ram中并且gcc接受它。。它的编译速度会比你现在做的更快吗?不,它会比堆慢。现在,我重新编译文件中的1000行代码,这些代码并没有改变整个系统中的1700万行,但是当您不得不发布时会发生什么呢。你需要花一周的时间重新编译,或者在新硬件上投入巨资?一周的时间编译?你从哪里弄来的?我的1700多万个系统(我正在照看的2个系统中较小的一个)的完整干净构建需要几个小时——可能会更少,但makefile是一个旧的、不可靠的文件。你似乎忽视了你整个想法中的一个基本缺陷,那就是每次构建时总是重新编译所有内容。如何能一直重新编译所有的东西比重新编译已经改变的东西更好?你认为你的发布版本怎么可能比我的快?也许这些链接会比我解释得更好:整个前提是编译器在unity构建过程中所做的工作要少得多。它不需要链接,不需要打开那么多的文件,不需要解析那么多的文件,等等。一个150 MB的统一构建需要多长时间。我听过一些故事,因为代码库的原因,构建花费了一整天的时间。当将所有内容合并到一个文件中时,需要几分钟的时间。我不能为其他版本说话——我可以为我知道的事情说话。另外-需要多少内存?例如,仅使用LTO就占用了大约35GB的RAM—在gcc 5.1或5.4中对其进行改进之后—然后才崩溃。