本文稍微讨论如何在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对于这一点还没有很好的支持:

剖析编译性能

参考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选项。更多可参考:

小结

目前感觉不管是clang还是gcc的预编译还不是很好使用,在一个小项目上实验了一下,并没有明显性能上的提升。还不如自己把头文件依赖关系整理清楚来的好。

不过随着C++的继续发展,以后C++会逐渐模块化。一部分C++的代码可以编译成模块这种中间产品,供其他模块导入使用。就变得跟Java和Python之类的语言很相似了。

其他参考

(完)