本文稍微讨论如何在clang中进行预编译。
clang编译器支持预编译头文件,参考Precompiled Headers。
实际使用起来所需要的步骤比较简单,首先第一步是编译头文件
clang -x c++-header pch_std.h -o pch_std.h.pch
- 这里的pch_std.h是被预编译的头文件,名字可以任意取
- 由于clang默认头文件是c语言头文件,所以这里需要加上
-x c++-header
指明这是c++头文件。或者你也可以直接使用clang++
来表明编译对象是c++头文件。 -o pch_std.h.pch
指明输出的文件名,如果不指明,会默认生成.gch
结尾的头文件,这是为了和gcc的行为一致吧。
有一点clang和gcc不一致,gcc在编译的时候如果看到了#include "pch_std.h"
这个语句,就会去找有没有对应的预编译好的头文件存在,而clang则不会。对于clang,需要在命令行指定好预编译的头文件:
clang -include pch_std.h test.cc -o test
或者
clang -include-pch pch_std.h.pch test.cc -o test
由于这个问题,你需要修改编译配置,才能用上clang的预编译好的头文件。
目前看来,cmake对于这一点还没有很好的支持:
- Using pre-compiled headers with CMake
- Speeding up the Build of C and C++ Projects
- Support for precompiled headers
- https://github.com/microblink/build/blob/master/pch.cmake
- https://github.com/iboB/cmake-pch/blob/master/precompiled_header.cmake
- https://github.com/nanoant/CMakePCHCompiler
- larsch/PrecompiledHeader.cmake
剖析编译性能
参考Profiling the C++ compilation process,gcc支持下面两个选项来输出编译时候的一些分析内容:
-Q
Makes the compiler print out each function name as it is compiled, and print some statistics about each pass when it finishes.-ftime-report
Makes the compiler print some statistics about the time consumed by each pass when it finishes.
目前clang貌似只支持-ftime-report
选项。更多可参考:
- time-trace: timeline / flame chart profiler for Clang
- Investigating compile times, and Clang -ftime-report
小结
目前感觉不管是clang还是gcc的预编译还不是很好使用,在一个小项目上实验了一下,并没有明显性能上的提升。还不如自己把头文件依赖关系整理清楚来的好。
不过随着C++的继续发展,以后C++会逐渐模块化。一部分C++的代码可以编译成模块这种中间产品,供其他模块导入使用。就变得跟Java和Python之类的语言很相似了。
其他参考
- Precompiled Header and Modules Internals¶
- Decrease clang compile time with precompiled headers
- https://en.wikipedia.org/wiki/Precompiled_header
- GCC Precompiled Headers
- Precompiled Headers with GCC
- Clang Users Manual: Precompiled Headers
- sakra/cotire可以自动使用cmake帮你自动处理预编译。
(完)