我可以使用单独的翻译单元减少仅标题库的编译时间吗?
我正在寻找一种减少仅标题库的编译时间的方法。如果只有标题,则每个翻译单元必须编译所需的所有功能,因此在编译步骤中完成了许多重复的工作。我的想法是将汇编移至单个翻译单元,该单元创建了其他翻译单元可以链接到的单个对象文件。这使得仅标头库的行为像静态库一样有效地行为,该库与实际的生产代码一起编译。
图书馆的典型标题看起来像这样。它包括所有声明(当然是所有inline
),而定义隐藏在宏myutils_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.cpp
或myutils.inl
,这是唯一设置myutils_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_inline
在全球范围内,他不需要myutils.cpp
,所有工作都像
缺点之前一样:
- 优化潜力较小,因为函数不再是
- 文件之前的两倍(每个标头的一个实现文件)的两倍(一个实现文件)
在我重组我的 整个图书馆,我想问一下:
- 我只是重新发明了什么吗?
- 我错过一些要点吗?优点还是缺点?
- 有类似或更好的方法吗?
我注意到 catch 。
编辑
我已经阅读了一些有关预编译标题的文章,并在我的一个项目中尝试了它们。当他们试图解决相同的问题时,他们还有其他问题,尤其是关于标头文件之间的干净依赖关系。我建议的方法有很大的不同,因为每个文件仍然管理自己的依赖关系,但可以选择将工作传递给翻译单元myutils.cpp
。
I am looking for a way to reduce compile-time for header-only libraries. If there are only headers, each translation unit must compile all functions it needs, hence there is a lot of duplicate work done in the compilation step. My idea is to move the compilation to a single translation unit, which creates a single object file the other translation units can link to. This allows the header-only library to effectively behave like a static library which is compiled along with the actual productive code.
A typical header of the library looks like this. It includes all the declarations (all inline
of course), while the definitions are hidden behind the macro MYUTILS_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
can include additional headers required for the implementation and contains the definitions.
// MyUtils1.cpp, example implementation file
#include MyUtils1.hpp
#include "additionalheader.hpp"
MyClass1::MyClass1(void) {...}
inline int myfunction1(void){...}
In my code, the headers of the library can be included normally. There is one additional file MyUtils.cpp
or MyUtils.inl
, which is the only file which sets MYUTILS_INLINE
and hence sees the definitions and compiles them:
// 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"
Advantages:
- reduced compile-time due to no duplicate work
- fewer header dependencies, headers needed for definitions can be hidden in
MyUtils1.cpp
- opt-in behavior: If user defines
MYUTILS_INLINE
globally, he does not needMyUtils.cpp
and all works as before
Disadvantages:
- less optimization potential because functions are no longer inline
- ship twice as many files (one implementation file for each header)
Now before I restructure my entire library, I want to ask for thoughts about this:
- Did I just reinvent something?
- Do I miss some important points? Advantages or disadvantages?
- Is there a similar or better way?
I noticed that Catch actually does something similar with CATCH_CONFIG_MAIN
.
EDIT
I have read some articles about precompiled headers and tried them in one of my projects. While they try to solve the same problem, they have other issues, especially regarding clean dependencies between header files. My suggested approach is considerably different, as each file still manages its own dependencies but has the option to pass work to the translation unit MyUtils.cpp
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论