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.
知道如何解决它?
答案 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文件)。
没有module
和export
关键字(它们仅出现在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?