如何通过 Clang++ 生成和使用预编译头?

Dun*_*eal 5 c++ build clang precompile

官方文档说明了如何通过接口使用预编译头-cc1,如下生成它们:

$ clang -cc1 test.h -emit-pch -o test.h.pch
Run Code Online (Sandbox Code Playgroud)

并使用它们:

$ clang -cc1 -include-pch test.h.pch test.c -o test.s
Run Code Online (Sandbox Code Playgroud)

问题是该-cc1接口的级别太低,开发人员无法通过 CLI 使用。-cc1事实上,常规高级接口最终会通过为其正确操作提供大量参数来调用低级接口,例如适合编译时系统的包含路径。如果没有这些参数,该-cc1界面就无法正常工作:

$ clang++ -cc1 /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h -emit-pch -o std.pch
/usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:33:10: fatal error: 'cassert' file not found
#include <cassert>
         ^~~~~~~~~
         1 error generated.
Run Code Online (Sandbox Code Playgroud)

有没有办法从高层接口使用预编译头,以便开发人员在日常工作中可以方便地利用此功能?

sel*_*bie 0

我认为你的问题的根源是你的文件名是test.h并且 clang 认为你正在编译 C 代码,而不是 C++ 代码。因此,当您 include 时<cassert>,clang 不知道它应该查看 C++ 包含路径。尝试命名您的文件test.hpp。您只需将所需的文件命名为带有.hpp. 您可以保留所有带有扩展名的头文件.h

无论如何,我可能会将此与 gcc/g++ 混淆,但每当我在 Mac 上编译代码时,Clang 都会遵循相同的行为。这就是我使用预编译头的方式。继续阅读...

如果您有想要预编译的 C++ 头文件,只需将其作为任何其他 .cpp 文件进行编译即可。请注意,我使用.hpp作为文件扩展名,以便编译器将其选择为 C++ 头文件。

clang -c precomp.hpp
Run Code Online (Sandbox Code Playgroud)

这将产生precomp.hpp.gch

现在要通过任何其他普通 C++ 文件使用预编译,只需包含普通.hpp文件:

// main.cpp
#include "precomp.hpp"

void func1() {...}
void main() {...}
Run Code Online (Sandbox Code Playgroud)

如果存在相应的 .gch 文件来代替原始 .hpp 文件,编译器将自动使用该文件。