我解决了你的任务。以下是执行此操作的说明。我在我的 Win 10 64 位上使用 LLVM 12.0 的当前版本(取自此处)中的 CLang 执行此操作,我还安装了 MSVC 2019 v16.9.4 社区(取自此处)。
首先创建以下文件:
module.modulemap:
module std_mod {
requires cplusplus17
header "std_mod.hpp"
export *
}
std_mod.hpp:
#include <iostream>
#include <map>
#include <set>
#include <vector>
使用.cpp:
import std_mod;
int main() {
std::cout << "Hello, World!" << std::endl;
}
在上面的文件std_mod.hpp
中,您可以放置您需要的任何标准头文件。您应该将所有可能的 STD 头文件放在所有项目中,以便能够在任何地方共享相同的预编译 STD 模块。
然后执行命令:
clang++ -### use.cpp -c -std=c++20 -m64 -g -O3 >use.txt 2>&1
在这里,-std=c++20 -m64 -g -O3
您可以使用项目所需的任何选项来代替。每个预编译模块都应具有与其他 .cpp 文件相同的编译选项,以便能够链接到最终二进制文件中。
上面的命令将产生use.txt
您需要复制的选项。在此选项中,您应该删除-emit-obj
选项、 -o
选项(及其后的路径),也删除use.cpp
. 然后添加到这个命令选项字符串module.modulemap -o std_mod.pcm -emit-module -fmodules -fmodule-name=std_mod
。在我的系统上,我得到了以下结果命令:
"D:\\bin\\llvm\\bin\\clang++.exe" "-cc1" module.modulemap -o std_mod.pcm -emit-module -fmodules -fmodule-name=std_mod "-triple" "x86_64-pc-windows-msvc19.28.29914" "-mincremental-linker-compatible" "--mrelax-relocations" "-disable-free" "-disable-llvm-verifier" "-discard-value-names" "-main-file-name" "use.cpp" "-mrelocation-model" "pic" "-pic-level" "2" "-mframe-pointer=none" "-fmath-errno" "-fno-rounding-math" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-gno-column-info" "-gcodeview" "-debug-info-kind=limited" "-resource-dir" "D:\\bin\\llvm\\lib\\clang\\12.0.0" "-internal-isystem" "D:\\bin\\llvm\\lib\\clang\\12.0.0\\include" "-internal-isystem" "d:\\bin2\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29910\\include" "-internal-isystem" "d:\\bin2\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29910\\atlmfc\\include" "-internal-isystem" "D:\\Windows Kits\\10\\Include\\10.0.19041.0\\ucrt" "-internal-isystem" "D:\\Windows Kits\\10\\include\\10.0.19041.0\\shared" "-internal-isystem" "D:\\Windows Kits\\10\\include\\10.0.19041.0\\um" "-internal-isystem" "D:\\Windows Kits\\10\\include\\10.0.19041.0\\winrt" "-O3" "-std=c++20" "-fdeprecated-macro" "-fdebug-compilation-dir" "D:\\t\\t4" "-ferror-limit" "19" "-fno-use-cxa-atexit" "-fms-extensions" "-fms-compatibility" "-fms-compatibility-version=19.28.29914" "-fdelayed-template-parsing" "-fno-implicit-modules" "-fcxx-exceptions" "-fexceptions" "-vectorize-loops" "-vectorize-slp" "-faddrsig" "-x" "c++"
如您所见,此命令包含包含的完整路径,它们是必需的。执行上面的命令,它将产生std_mod.pcm
您可以在任何地方使用相同编译选项的项目。
为什么需要上面的长命令?因为.modulemap
只有通过-cc1
命令才能使用文件,它执行低级 CLang 前端而不是简化的 CLang 驱动程序(驱动程序没有-cc1
选项)。这个低级前端可以完成许多驱动程序无法完成的技巧。
现在您可以编译通过下一个命令执行的最终use.cpp
程序:import std_mod;
clang++ use.cpp -o use.exe -std=c++20 -m64 -g -O3 -fmodule-file=std_mod.pcm
看到我添加了-fmodule-file=std_mod.pcm
- 每个导入的模块都需要这样的选项。作为替代方案,您可以使用-fprebuilt-module-path=<directory>
指定搜索所有预构建模块的位置。
不久前,我还在这里创建了关于如何在 CLang 中使用标头制作模块的问题和答案。
有关模块的更多说明,请参阅 CLang 的Modules Doc和CommandLine Doc。
附言。为什么我在上面实施了相当长的解决方案?因为至少在 Windows 的 CLang 下一个简单的程序
import <iostream>;
int main() {}
不编译,它说use.cpp:1:8: error: header file <iostream> (aka 'd:\bin2\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\iostream') cannot be imported because it is not known to be a header unit
。所以至少在 Win one 需要一个特殊的解决方案,解决方案import <header-name>;
在这里不起作用。
import <header>;
通过或语法导入的所有标头import "header";
都应具有特殊的已编译标头单元模块,并将其放置在特殊文件夹中以便能够使用。并且在 Win STD 标头上没有相应的已编译标头单元模块。同样在花了很多时间之后,我没有在 CLang 中找到如何在 Win 上创建这些所谓的标头单元的方法。只有上面的解决方案解决了我将标头作为模块导入的任务。