我可以使用单独的翻译单元来减少仅标头库的编译时间吗?

Can I reduce the compile-time of my header-only library with a separate translation unit?

提问人:Fabian 提问时间:5/12/2022 最后编辑:Fabian 更新时间:5/12/2022 访问量:389

问:

我正在寻找一种方法来减少仅标头库的编译时间。如果只有标头,则每个翻译单元必须编译所需的所有函数,因此在编译步骤中会完成大量重复工作。我的想法是将编译移动到单个翻译单元,这将创建一个其他翻译单元可以链接到的单个对象文件。这允许仅标头库有效地像静态库一样运行,该库与实际的生产代码一起编译。

库的典型标头如下所示。它包括所有声明(当然都是),而定义隐藏在宏后面。inlineMYUTILS_INLINE

// MyUtils1.hpp, example utility header
#ifndef MyUtils1_h__
#define MyUtils1_h__

class MyClass1{...};
inline int myfunction1(void);

#ifdef MYUTILS_INLINE
#include MyUtils1.cpp
#endif // MYUTILS_INLINE
#endif // MyUtils1_h__

MyUtils1.cpp可以包含实现所需的其他标头,并包含定义。

// MyUtils1.cpp, example implementation file
#include MyUtils1.hpp
#include "additionalheader.hpp"

MyClass1::MyClass1(void) {...}
inline int myfunction1(void){...}

在我的代码中,可以正常包含库的标头。还有一个附加文件或 ,它是唯一设置并查看定义并编译它们的文件:MyUtils.cppMyUtils.inlMYUTILS_INLINE

// MyUtils.cpp, separate translation unit in my project
// set macro to get the definitions and compile them.
#define MYUTILS_INLINE
// include all headers which are used throughout the project
#include "MyUtils1.hpp"
#include "MyUtils2.hpp"
#include "MyUtils3.hpp"

优势:

  • 由于没有重复工作,减少了编译时间
  • 更少的标头依赖项,定义所需的标头可以隐藏在MyUtils1.cpp
  • 选择加入行为:如果用户全局定义,则他不需要,并且一切都像以前一样工作MYUTILS_INLINEMyUtils.cpp

弊:

  • 优化潜力较小,因为函数不再是内联的
  • 提供两倍数量的文件(每个标头一个实现文件)

现在,在我重组整个图书馆之前,我想问一下关于这个问题的想法:

  • 我刚刚重新发明了什么吗?
  • 我是否遗漏了一些要点?优点还是缺点?
  • 有没有类似或更好的方法?

我注意到 Catch 实际上对 .CATCH_CONFIG_MAIN

编辑

我读过一些关于预编译头文件的文章,并在我的一个项目中尝试过它们。当他们尝试解决相同的问题时,他们还有其他问题,尤其是关于头文件之间的干净依赖关系。我建议的方法有很大不同,因为每个文件仍然管理自己的依赖项,但可以选择将工作传递给翻译单元。MyUtils.cpp

C++ 编译时 标头

评论

0赞 KamilCuk 5/12/2022
en.wikipedia.org/wiki/Precompiled_header
2赞 n. m. could be an AI 5/12/2022
您正在制作的不仅仅是一个标题库。它是一个作为源代码分发的常规库(除非用户定义MYUTILS_INLINE,在这种情况下,它再次成为仅标头库)。
0赞 BoP 5/12/2022
作为折衷方案,您可以将小函数(应该内联)保留在标头中,并将较大的函数移动到 .cpp 文件中。软件开发几乎从来都不是“单一规则”。
0赞 Fabian 5/12/2022
预编译标头存在几个问题 (qualitycoding.org/precompiled-header)。一个很大的缺点是,它们创建了一大堆在所有项目文件中共享的标头依赖项。依赖关系很容易失控。
0赞 MSalters 5/12/2022
你知道模块吗?C++20,相当新。

答: 暂无答案