功能级别的C ++智能makefile

时间:2011-10-09 18:01:40

标签: c++ compiler-construction

复制/粘贴:

http://forums.cgsociety.org/showthread.php?f=89&t=1010489

当你处理一个使用大量模板函数的大型.cpp时,你是不是觉得很烦人,当你在一个函数中改变一个字符时,你需要等待一整分钟来编译整个文件?好吧,有些人可能已将大型.cpp的某些部分移动到新文件中,但我正在考虑更自动化的过程。

所以我想知道是否有一个makefile和一个支持在函数级别构建.cpp的编译器。这意味着如果您要更改一个函数,则只会重新编译该函数,而不是整个文件。如果没有这样的东西,这里有一个python脚本的基本思路:

预赛:

每个文件* .cpp会有一个目录,它包含最后一次构建的.cpp的最后一个副本(我们称之为旧副本),以及文件中每个函数的func * .cpp文件的.cpp。

现在进行构建过程:

  1. 如果file.cpp比旧版本更新(按文件日期比较),则需要重建。
  2. 旧文件和新文件之间的差异,并最终找到已更改的函数。如果除了函数之外发生了某些变化,请重新创建整个file.cpp目录。
  3. 对于每个更改的函数,创建一个新的func.cpp,它将包含所有标题,以及file.cpp中所有函数的原型。
  4. 运行所有func * .cpp文件的常规构建过程。
  5. 一些细节:

    1. 这也是一个包含所有全局变量的文件,每个func * .cpp除了以前的函数原型外,还有以前全局变量的extern声明。
    2. 请注意,调试将自然地在func * .cpp文件上进行。
    3. 函数符号与其.cpp之间的连接可以通过符号db文件进行。
    4. 评论:

      1. 这将是一个智能的编译步骤,使用任何当前的编译器工具,可以顺利地适应构建管道。
      2. 想想其含义。这就像每个函数都有一个单独的.cpp文件。你能想象平均编译时间的提升吗?
      3. 对于那些将编译过程委托给链接时(Visual Studio优化部分/ gl / ltcg)的人,请务必注意等待更长时间,并且它没有太大作用,至少对于每天使用代码。所以我个人禁用了这些。
      4. 似乎有人已经给了这个想法一个名字: http://en.wikipedia.org/wiki/Incremental_compiler 有没有人尝试过用于Windows的IBM VisualAge C ++编译器?

3 个答案:

答案 0 :(得分:1)

仅编译.cpp文件的摘录的想法存在一些问题。

  1. 编译单元不仅仅具有功能。您还有文件范围的变量。您的摘录构建器必须检测这些变量并将它们声明为extern。而且你必须为变量创建一个单独的摘录。如果在文件范围内有静态变量,则必须保持静态,并且不能为某些摘录声明为extern。

  2. 即使它被视为邪恶,C ++预处理器也支持#define会影响整个编译单元的内容。您的摘录构建器必须检测所有未被#if子句抑制的#defines。

  3. 编译所有摘录时,与编译完整的.cpp文件相反,您会得到不同的输出文件。这会影响链接过程。

  4. 这一切都会使编译过程变得更加复杂。将编译单元分解出来更有意义。

答案 1 :(得分:0)

虽然这个想法确实可以帮助减少编译时间,但是有许多问题会使它变得不切实际。除了哈珀指出的问题,我还能想到这些:

  • 编译器没有内存,他们不会跟踪您对源文件所做的更改。

  • 优化编译器不能独立地处理函数,它们将代码作为一个整体来决定编写高效代码的内容和方法。为了能够使用智能重建技术,您需要禁用优化。

  • 内联函数显然无法解决此问题。

  • 模板类的方法很难支持,因为一个函数的更改需要在模板的所有实例化中进行更改。

我的观点是,缩短编译时间的标准解决方案将足以改善您的情况,因此不需要这样的事情。我推荐以下内容:

  • 尽可能在其他头文件中#include头文件。改为使用前向声明。

  • 除了内联之外,不要在头文件中编写函数/方法实现。

  • 保持源文件的大小。我总是为每个文件写一个类。

  • 不要在头文件中公开类实现细节。诸如Pimpl Idiom之类的技术对此非常有用。

通过上述建议,您可以非常接近于仅重新编译已更改的文件,仅此而已。

答案 2 :(得分:0)

  

当你在一个大型的.cpp工作时,你不觉得这很烦人吗?   使用重模板功能,当你改变一个   在一个函数中,你必须等待一个整体   编译整个文件的分钟?

整分钟?不,我实际上没有。你已经担心这个问题已经超过一分钟了。您最好等待,或者不要对源文件进行如此微小的更改。