使用 clang 的 C++ 模块

标签 c++ module clang c++-modules

As it looks like Clang 正在为 TS 模块提供支持。我tried this out使用 Clang,从 SVN(主干)编译,并且按预期工作。

我想将其带到下一步包装 catch库到模块中。

我试图以这种方式声明一个module.modulemap:

module Catch {
  header "catch/catch.hpp"
  export *
}

main.cpp包含:

import Catch;

int main(int argc, char* const argv[])
{
  int result = Catch::Session().run(argc, argv);
  return result;
}

compilation model指出“模块的二进制表示形式由编译器根据需要自动生成。

使用clang-4.0 -std=c++1z -fmodules-ts main.cpp编译main.cpp我得到:

main.cpp:1:8: fatal error: module 'Catch' not found
import Catch;
~~~~~~~^~~~~
1 error generated.

知道如何解决吗?

最佳答案

您引用的文档页面( http://clang.llvm.org/docs/Modules.html )中描述的内容实际上不是模块 TS。

这是 clang 的非标准 hack,利用预编译头基础设施使它们能够模块化地重用。技巧只是允许以任何顺序加载预编译头,甚至在已经解析了一些代码之后加载。这是基于这样的假设:先前解析/加载的代码不应该对进一步预编译的代码产生任何副作用。其他更传统的 PCH 处理在这方面可能被认为过于迂腐,并且最终灵活性低得多(即模块化程度低得多),因为它们需要一个需要首先加载的整体 PCH(例如 MSVC),或者一个具有固定顺序 (GCC) 的 PCH 链。

objective-C 语言通过 @import 关键字进行了增强,该关键字有效地“包含”相应 module.modulemap 文件中列出的所有文件(这实际上意味着生成和/或加载相应的 PCH 文件)。

当 Objective-C 扩展未启用时,就没有 import 关键字,但您仍然有另一个技巧:它拦截 #include 预处理器指令,以便它们相反,“包含”相应 module.modulemap 文件中列出的所有文件(这实际上意味着生成和/或加载相应的 PCH 文件)。

没有 moduleexport 关键字(这些仅出现在 module.modulemap 文件中);一切都已导出。

这种模块化 PCH 黑客是通过 -fmodules 编译器标志启用的。

它的值(value)在于它有助于加快大型代码库的构建过程,并且还允许延迟地准备旧代码库向 future 模块化结构的过渡,而不需要立即重写整个世界。

我怀疑它是否在生产中得到广泛使用,除了谷歌等一些非常投入的公司之外,谷歌拥有知识渊博的 clang 开发人员,他们可以在需要时修复错误。

要真正使您的代码与该系统兼容,您需要:

  • 编辑 main.cpp 以使用 @import Catch; 并使用以下命令编译 clang++ -fmodules -I 。 -xobjective-c++ main.cpp

  • 编辑main.cpp以使用#include "catch/catch.hpp"并使用以下命令编译clang++ -fmodules main .cpp

第一次使用时,请注意使用 -I 正确设置预处理器包含路径的重要性,因为系统将在后台查找您的 module.modulemap 文件预处理器路径,即使您没有在代码中编写任何 #include 指令。

从技术上讲,您可以通过查看 /tmp/org.llvm.clang.$USER/ModuleCache/ 目录下生成的 PCH 文件来验证模块系统是否已有效启用,如 捕获-$HASHSUM.pcm。由于 PCH 依赖于(除其他外)所使用的编译器选项(例如上例中的 Objective-C 支持),因此您最终可能会为同一模块提供多个选项。 Clang 自己管理这个缓存目录;它甚至会删除旧的未使用的文件(无论如何 /tmp/ 在启动过程中也会被清除)。

正如您所发现的,新的 -fmodules-ts 编译器标志实际上要求我们正在寻找的 future 模块 TS 支持。请注意,它目前几乎无法使用。

已经提出并回答了有关如何使用它的问题:Clangs C++ Module TS support: How to tell clang++ where to find the module file?

关于使用 clang 的 C++ 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41378685/

相关文章:

ios - 如何在运行时访问类的源代码级定义?

clang - clang 命令选项 -lm 是什么意思?

c++ - 从一系列图像创建 CvCapture

c++ - 如何使用 C++ 迭代器?

c++ - 枚举的复合赋值运算符真的应该根据它们相关的算术运算符来定义吗?

PythonAnywhere:导入 Mechanize 给出 ImportError,但 pip 给出 "Already satisfied"

Python导入两个具有相同类名的模块

c++ - STL C++ 中的内存分配

Linux/内核模块 : Can a driver be used by two user programs?

c++ - 返回 ARM NEON 下的 Z 标志