简体   繁体   English

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

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

The official docs state how precompiled headers are to be used through the -cc1 interface, like so to generate them:官方文档说明了如何通过-cc1接口使用预编译的头文件,例如生成它们:

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

And to use them:并使用它们:

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

The problem is that the -cc1 interface is way too low-level to be used by developers from the CLI.问题是-cc1接口太低级,无法由 CLI 的开发人员使用。 In fact, the regular high-level interface ultimately calls into the low-level -cc1 interface by supplying it with a very large set of arguments that are necessary for its correct operation, for example the include paths appropriate for the compile time system.事实上,常规高级接口最终调用低级-cc1接口,方法是为其提供正确操作所需的大量参数,例如适合编译时系统的包含路径。 Without these arguments, the -cc1 interface has no prayer of working:没有这些参数, -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.

Is there a way to use precompiled headers from the high-level interface, such that a developer may conveniently tap into this feature during their daily work?有没有办法使用高级界面中的预编译头文件,以便开发人员可以在日常工作中方便地利用此功能?

I think the root of your problem is that your filename is test.h and clang thinks you are compiling C code, not C++ code.我认为您的问题的根源是您的文件名是test.h并且 clang 认为您正在编译 C 代码,而不是 C++ 代码。 Hence, when you include <cassert> , clang doesn't know it should be looking at the C++ include path.因此,当您包含<cassert>时,clang 不知道它应该查看 C++ 包含路径。 Try naming your file test.hpp .尝试命名您的文件test.hpp You only have to name the file you want as the precomp header with .hpp .您只需使用 .hpp 将您想要的文件命名为.hpp头文件。 You can keep all your header files with .h extensions.您可以使用.h扩展名保留所有头文件。

In any case, I might be getting this confused with gcc/g++, but Clang follows the same behavior whenever I compile my code on Mac.无论如何,我可能会将此与 gcc/g++ 混淆,但每当我在 Mac 上编译我的代码时,Clang 都会遵循相同的行为。 This is how I make use of precompiled headers.这就是我使用预编译头文件的方式。 Read on...继续阅读...

If you've got a C++ header file you want to precompile, just compile it as any other .cpp file.如果您有要预编译的 C++ 头文件,只需将其编译为任何其他 .cpp 文件即可。 Notice that I'm using .hpp as the file extension so the compiler picks it up as a C++ header file.请注意,我使用.hpp作为文件扩展名,因此编译器将其作为 C++ 头文件拾取。

clang -c precomp.hpp

This will produce precomp.hpp.gch这将产生precomp.hpp.gch

Now to use the precomp by any other ordinary C++ file, just include the ordinary .hpp file:现在要使用任何其他普通 C++ 文件的预编译,只需包含普通的.hpp文件:

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

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

The compiler will automatically use the corresponding .gch file if its present in place of the original .hpp file.编译器将自动使用相应的 .gch 文件,如果它存在于原始 .hpp 文件的位置。

I don't know why the clang docs do not explain this, but indeed as @selbie surmises, it is possible to use Clang precompiled headers (PCH) without using -cc1 .我不知道为什么clang文档没有解释这一点,但确实正如@selbie 推测的那样,可以在不使用-cc1的情况下使用 Clang 预编译头文件(PCH)。

To generate a PCH file:要生成 PCH 文件:

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

This is the normal compile command, except the input file has the .hh (C++ header) extension.这是正常的编译命令,除了输入文件具有.hh (C++ 标头)扩展名。 clang will recognize that means to generate a PCH. clang将认识到这意味着生成 PCH。 Alternatively, pass -xc++-header before the header file name if you do not want to use that extension (or another, like .H or .hpp , that is unambiguously C++).或者,如果您不想使用该扩展名(或另一个,如.H.hpp ,这无疑是 C++),则在头文件名之前传递-xc++-header

You can tell that big-header.hh.pch is not object code (despite the -c on the command line) because file will say it is "data" (at least my version does) rather than object code.您可以说big-header.hh.pch不是目标代码(尽管-c在命令行上),因为file会说它是“数据”(至少我的版本是这样)而不是目标代码。 To be extra sure, run strings big-header.hh.pch | head为了更加确定,运行strings big-header.hh.pch | head strings big-header.hh.pch | head . strings big-header.hh.pch | head The first line should be "CPCH" (meaning "Clang PCH").第一行应该是“CPCH”(意思是“Clang PCH”)。

To use the PCH file:要使用 PCH 文件:

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

The addition of -include-pch big-header.hh.pch is the key step that is different compared to gcc .添加-include-pch big-header.hh.pch是与gcc不同的关键步骤。 Clang will not automatically pick up PCH files just due their name. Clang不会仅仅因为它们的名称而自动拾取 PCH 文件。

The above was tested with Clang+LLVM-14.0.0 on Linux.以上是在 Linux 上使用 Clang+LLVM-14.0.0 测试的。

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

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