使用 clang 的 C++ 模块
C++ modules using clang
As it looks like Clang is providing support for the modules TS. I 使用 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 的 non-standard hack,它利用预编译的 headers 基础设施使它们模块化可重用。诀窍就是允许预编译的 headers 以任何顺序加载,甚至在已经解析了一些代码之后加载。这是基于这样的假设,即以前的 parsed/loaded 代码不应该对进一步的预编译代码产生任何副作用。其他更传统的 PCH 处理在这方面被认为过于迂腐,最终变得非常不灵活(即模块化程度低得多),因为它们需要一个需要首先加载的整体 PCH(例如 MSVC),或者一个具有固定顺序 (GCC) 的 PCH 链。
objective-C 语言增加了一个 @import
关键字,该关键字有效 "include" 相应 module.modulemap
文件中列出的所有文件(这实际上意味着生成 and/or加载相应的PCH文件)。
当 objective-C 扩展未启用时,没有 import
关键字,但您还有另一个技巧:它拦截 #include
预处理器指令,以便它们代替 "include" 相应 module.modulemap
文件中列出的所有文件(这实际上意味着生成 and/or 加载相应的 PCH 文件)。
没有 module
和 export
关键字(这些仅出现在 module.modulemap
文件中);全部导出。
此 modular-PCH hack 是通过 -fmodules
编译器标志启用的。
它的价值在于它有助于加快大型代码库的构建过程,并且它还允许延迟准备旧代码库向未来模块化结构的过渡,而无需立即重写整个世界。
我怀疑它是否在生产中得到广泛使用,除了像 google 这样的少数 very-involved 公司,这些公司拥有知名的 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 依赖于(amgonst 其他东西)所使用的编译器选项(例如,上面示例中的 objective-C 支持),因此您可能最终会为同一个模块得到多个。 Clang 自己管理这个缓存目录;它甚至会删除未使用的旧文件(无论如何 /tmp/
在启动期间也会被清除)。
正如您所发现的,新的 -fmodules-ts
编译器标志有效地请求我们都在寻找的未来模块 TS 支持。请注意,它目前几乎无法使用。
关于如何使用它的问题已经被提出并得到回答:Clangs C++ Module TS support: How to tell clang++ where to find the module file?
As it looks like Clang is providing support for the modules TS. I
我想将它带到下一步,将 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 的 non-standard hack,它利用预编译的 headers 基础设施使它们模块化可重用。诀窍就是允许预编译的 headers 以任何顺序加载,甚至在已经解析了一些代码之后加载。这是基于这样的假设,即以前的 parsed/loaded 代码不应该对进一步的预编译代码产生任何副作用。其他更传统的 PCH 处理在这方面被认为过于迂腐,最终变得非常不灵活(即模块化程度低得多),因为它们需要一个需要首先加载的整体 PCH(例如 MSVC),或者一个具有固定顺序 (GCC) 的 PCH 链。
objective-C 语言增加了一个 @import
关键字,该关键字有效 "include" 相应 module.modulemap
文件中列出的所有文件(这实际上意味着生成 and/or加载相应的PCH文件)。
当 objective-C 扩展未启用时,没有 import
关键字,但您还有另一个技巧:它拦截 #include
预处理器指令,以便它们代替 "include" 相应 module.modulemap
文件中列出的所有文件(这实际上意味着生成 and/or 加载相应的 PCH 文件)。
没有 module
和 export
关键字(这些仅出现在 module.modulemap
文件中);全部导出。
此 modular-PCH hack 是通过 -fmodules
编译器标志启用的。
它的价值在于它有助于加快大型代码库的构建过程,并且它还允许延迟准备旧代码库向未来模块化结构的过渡,而无需立即重写整个世界。
我怀疑它是否在生产中得到广泛使用,除了像 google 这样的少数 very-involved 公司,这些公司拥有知名的 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 依赖于(amgonst 其他东西)所使用的编译器选项(例如,上面示例中的 objective-C 支持),因此您可能最终会为同一个模块得到多个。 Clang 自己管理这个缓存目录;它甚至会删除未使用的旧文件(无论如何 /tmp/
在启动期间也会被清除)。
正如您所发现的,新的 -fmodules-ts
编译器标志有效地请求我们都在寻找的未来模块 TS 支持。请注意,它目前几乎无法使用。
关于如何使用它的问题已经被提出并得到回答:Clangs C++ Module TS support: How to tell clang++ where to find the module file?