繁体   English   中英

如何使用 Clang++ 生成和使用预编译头文件?

[英]How do I generate and use precompiled headers with Clang++?

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

$ clang -cc1 test.h -emit-pch -o test.h.pch

并使用它们:

$ clang -cc1 -include-pch test.h.pch test.c -o test.s

问题是-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.

有没有办法使用高级界面中的预编译头文件,以便开发人员可以在日常工作中方便地利用此功能?

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

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

如果您有要预编译的 C++ 头文件,只需将其编译为任何其他 .cpp 文件即可。 请注意,我使用.hpp作为文件扩展名,因此编译器将其作为 C++ 头文件拾取。

clang -c precomp.hpp

这将产生precomp.hpp.gch

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

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

void func1() {...}
void main() {...}

编译器将自动使用相应的 .gch 文件,如果它存在于原始 .hpp 文件的位置。

我不知道为什么clang文档没有解释这一点,但确实正如@selbie 推测的那样,可以在不使用-cc1的情况下使用 Clang 预编译头文件(PCH)。

要生成 PCH 文件:

$ clang -c -o big-header.hh.pch big-header.hh <other options>

这是正常的编译命令,除了输入文件具有.hh (C++ 标头)扩展名。 clang将认识到这意味着生成 PCH。 或者,如果您不想使用该扩展名(或另一个,如.H.hpp ,这无疑是 C++),则在头文件名之前传递-xc++-header

您可以说big-header.hh.pch不是目标代码(尽管-c在命令行上),因为file会说它是“数据”(至少我的版本是这样)而不是目标代码。 为了更加确定,运行strings big-header.hh.pch | head strings big-header.hh.pch | head 第一行应该是“CPCH”(意思是“Clang PCH”)。

要使用 PCH 文件:

$ clang -c -include-pch big-header.hh.pch <other compile options>

添加-include-pch big-header.hh.pch是与gcc不同的关键步骤。 Clang不会仅仅因为它们的名称而自动拾取 PCH 文件。

以上是在 Linux 上使用 Clang+LLVM-14.0.0 测试的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM