【问题标题】:C++ modules using clang使用 clang 的 C++ 模块
【发布时间】:2016-12-29 11:20:55
【问题描述】:

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.

知道如何解决吗?

【问题讨论】:

  • 尝试使用-fmodule-file=<path> 指定模块文件(clang 应该自动执行此操作,但我们正在调试)。
  • @ShmuelH。使用该选项 Clang 报告:致命错误:file 'module.modulemap' is not a valid precompiled module file.
  • 我错了,是-fmodule-map-file
  • Clang 仍然在向fatal error: module 'Catch' is needed but has not been provided, and implicit use of module files is disabled 抱怨我试图玩一些标志,但它不起作用
  • @ShmuelH。我还需要提供 -fmodules-ts 来启用模块,这与 clang 文档提供的 -fmodules 形成对比。 ://

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


【解决方案1】:

您参考的文档页面(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 hack 使用 -fmodules 编译器标志启用。

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

我怀疑它是否在生产中得到了广泛使用,除了像谷歌这样的一些非常参与的公司,谷歌有知名的 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 文件,即使您不写任何@ 987654340@ 代码中的指令。

从技术上讲,您可以通过查看/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?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-23
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-05
    • 2022-01-07
    • 2021-05-30
    • 1970-01-01
    相关资源
    最近更新 更多