简体   繁体   English

如何编译/使用 CLang C++ 下的 header 单元模块?

[英]How to compile/use header unit modules under CLang C++?

It is said in docs that modules support in CLang is partial.在文档中说 CLang 中的模块支持是部分的。 I'm using CLang under Windows 64-bit from recent release of LLVM 12.0.我在最近发布的 LLVM 12.0 的 Windows 64 位下使用 CLang。

I successfully managed to use regular modules, (that you import through import modulename; ).我成功地使用了常规模块(通过import modulename; )。

But I haven't managed to create and use header unit modules, those that you import through import "header.hpp";但是我还没有设法创建和使用 header 单元模块,那些通过import "header.hpp"; . . Can you suggest how to do that with examples?你能建议如何用例子来做到这一点吗?

For trying header units I created next toy files:为了尝试 header 单元,我创建了下一个玩具文件:

hello.hpp :你好.hpp

#include <vector>

use.cpp :使用.cpp

import "hello.hpp";

int main() {
    std::vector<int> v(123);
}

Then I successfully (I hope) compiled header unit hello.hpp into PCM file:然后我成功(我希望)将 header 单元hello.hpp编译成 PCM 文件:

clang++ -std=c++20 -Xclang -emit-header-module -I. hello.hpp -o hello.pcm

Command ran without errors and produced hello.pcm .命令运行没有错误并产生hello.pcm If you run command above without -o flag then file hello.hpp.gch is created.如果您在没有-o标志的情况下运行上面的命令,则会创建文件hello.hpp.gch

Then I tried to compile use.cpp , but without success, somehow it can't recognize my header unit and/or can't find corresponding hello.pcm .然后我尝试编译use.cpp ,但没有成功,不知何故它无法识别我的 header 单元和/或找不到相应hello.pcm I think I'm missing some special flags that show compiler that it is header unit.我想我错过了一些特殊标志,这些标志显示编译器它是 header 单元。 Next command was used:使用了下一个命令:

clang++ -std=c++20 -fprebuilt-module-path=. -fmodule-file=hello.hpp=hello.pcm -I. use.cpp

Which gave compile error:这给出了编译错误:

use.cpp:1:8: error: header file "hello.hpp" (aka './hello.hpp') cannot be imported because it is not known to be a header unit
import "hello.hpp";
       ^

Under MSVC I successfully managed to use regular modules and header unit modules.在 MSVC 下,我成功地使用了常规模块和 header 单元模块。 But not in CLang.但不在 CLang 中。 Can you help me with that?你能帮我解决这个问题吗? Or tell me maybe CLang header units are not yet supported.或者告诉我也许 CLang header 单元尚不受支持。

Finally I managed to solve almost task above.最后我设法解决了上面的几乎任务。

Instructions below are for Windows 64-bit, most recent CLang from LLVM 12.0 release (which you can get here ) and most recent MSVC Community Build Tools 2019 v16.9.4 (which you can get from here ).以下说明适用于 Windows 64 位、来自 LLVM 12.0 版本的最新 CLang(您可以在此处获得)和最新的 MSVC 社区构建工具 2019 v16.9.4(您可以从此处获得)。

I solved task not exactly for header units but for header modules, which behave almost same, there is no difference in their usage.我解决的任务不完全是 header 单元,而是 header 模块,它们的行为几乎相同,它们的用法没有区别。

Toy example files below:玩具示例文件如下:

module.modulemap : module.modulemap

module mod {
    requires cplusplus17
    header "mod.hpp"
    export *
}

mod.hpp :模组.hpp

#include <iostream>

use.cpp :使用.cpp

import mod;

int main() {
    std::cout << "Hello, world!" << std::endl;
}

I used next 3 commands:我使用了接下来的 3 个命令:

clang++.exe -cc1 module.modulemap -o prebuilt/mod.pcm -emit-module -fmodules -fmodule-name=mod -std=c++20 ^
    -internal-isystem "d:\\bin2\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29910\\include" ^
    -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.19041.0\\ucrt" ^
    -debug-info-kind=limited -fms-extensions -fms-compatibility -fms-compatibility-version=19.28 -xc++ ^
    -fmath-errno -fexceptions -fcxx-exceptions -triple x86_64-pc-windows-msvc || exit /b
    
clang++.exe -cc1 -emit-obj use.cpp -fmodule-file=prebuilt/mod.pcm -std=c++20 ^
    -internal-isystem "d:\\bin2\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29910\\include" ^
    -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.19041.0\\ucrt" ^
    -debug-info-kind=limited -fms-extensions -fms-compatibility -fms-compatibility-version=19.28 -xc++ ^
    -fmath-errno -fexceptions -fcxx-exceptions -triple x86_64-pc-windows-msvc || exit /b
    
clang++.exe use.o -o use.exe || exit /b

which all worked without errors.这一切都没有错误。 You can see that there are full paths to include directories of standard library, these paths are specific to my system.您可以看到包含标准库目录的完整路径,这些路径特定于我的系统。 This is needed because in commands I used -cc1 option which enabled to use low level CLang front end instead of simplified driver, this front end needs a lot of low-level options to work.这是必需的,因为在命令中我使用-cc1选项,它启用了使用低级 CLang 前端而不是简化的驱动程序,这个前端需要很多低级选项才能工作。

You can get all options just by doing clang++ -### use.cpp , this will dump to console all options that are needed for your system.您只需执行clang++ -### use.cpp即可获得所有选项,这将转储以控制系统所需的所有选项。

Commands above can be used with -cc1 front end only, driver doesn't support module map file.上述命令只能与-cc1前端一起使用,驱动程序不支持模块 map 文件。

Actually among those 3 commands above second command can be simplified, compiling object file doesn't need low-level front-end.实际上上面第二条命令的这3条命令可以简化,编译object文件不需要低级前端。 But it can be simplified only in the case if 1st command has default params obtained by clang -### command, then 2nd command can be short-written as clang++ use.cpp -o use.o -c -std=c++20 -fmodule-file=prebuilt/mod.pcm .但是只有在第一个命令具有通过clang -###命令获得的默认参数的情况下才能简化,那么第二个命令可以简写为clang++ use.cpp -o use.o -c -std=c++20 -fmodule-file=prebuilt/mod.pcm

Result of these commands is that use.o is compiled within a fraction of a second.这些命令的结果是use.o在几分之一秒内被编译。 It is known that iostream takes a lot of time to compile.众所周知, iostream需要大量时间来编译。 Very fast compilation of use.o means that we used modules correctly and boosted our speed. use.o的快速编译意味着我们正确使用了模块并提高了速度。

Why I wanted header units in the first place?为什么我首先想要 header 单元? To be able to upgrade my old code, just by automated replacing regular old-style includes with imports, to greatly improve compilation time.为了能够升级我的旧代码,只需使用导入自动替换常规的旧式包含,从而大大缩短编译时间。 This replacement is only possible with header units or header modules.这种更换仅适用于 header 单元或 header 模块。 Regular modules can't export other full header as I know.据我所知,常规模块无法导出其他完整的 header。

For further instructions regarding modules see CLang's Modules Doc and CommandLine Doc .有关模块的更多说明,请参阅 CLang 的Modules DocCommandLine Doc

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

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