使用clang的C ++模块

时间:2016-12-29 11:20:56

标签: 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表示“模块的二进制表示由编译器根据需要自动生成。

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

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

知道如何解决它?

1 个答案:

答案 0 :(得分:2)

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

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

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

当没有启用Objective-C扩展时,没有import关键字,但是您还有另外一个窍门:它拦截#include预处理程序指令,以便它们改为“包括”所有文件列在相应的module.modulemap文件中(实际上,这实际上意味着生成和/或加载相应的PCH文件)。

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

使用-fmodules编译器标志启用了此模块化PCH hack。

这很有价值,因为它有助于加快大型代码库的构建过程,并且还允许懒惰地准备将旧代码库过渡到未来的模块化结构,而无需立即重写整个世界。

我怀疑它是否已经在生产中得到广泛使用,除了像google这样的一些参与程度很高的公司之外,该公司拥有知名的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文件视为Catch-$HASHSUM.pcm来验证模块系统是否已有效启用。对于同一模块,您可能最终会遇到几个问题,因为PCH依赖于(其他方面)依赖于所使用的编译器选项(例如,上例中的Objective-C支持)。 Clang自己管理这个缓存目录。它甚至会删除未使用的旧文件(无论如何,/tmp/在启动过程中也会被清除)。

正如您所发现的那样,新的-fmodules-ts编译器标志有效地要求我们都在寻找将来的模块TS支持。请注意,目前几乎无法使用。

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