C 模块使用clang

C++ modules using clang

本文关键字:clang 模块      更新时间:2023-10-16

看起来Clang正在为模块提供支持。我使用clang尝试了这一点,该clang从SVN(TRUNK)编辑,并且按照预期的方式工作。

我想将其带到下一步,将捕获库包裹到模块中。

我尝试以这种方式声明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;
}

编译模型指出," 模块的二进制表示是由编译器自动生成的。

使用 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的非标准黑客攻击,以利用预编译的标头基础架构使其可重复使用。诀窍仅仅是允许以任何顺序加载预编译的标头,甚至在已经解析了一些代码后加载。这是基于以下假设:先前解析/加载的代码不应具有进一步预编码的任何副作用。在这方面,其他更传统的PCH处理程序可能被认为是过多的pch,最终的灵活性要少得多(即模块化少得多),因为它们需要一个需要的单片PCH,它需要是第一件事(例如,MSVC),或带固定订购(GCC)的PCH链。

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

当不启用Objective-C扩展名时,没有import关键字,但是您仍然有另一个技巧:它拦截#include Preprocessor指令,以便它们"包括"相应的module.modulemap文件中列出的所有文件(哪个文件),同样,实际上是指生成和/或加载相应的PCH文件)。

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

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

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

我怀疑它在生产中是否已使用,除了像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/ DIR下的生成的PCH文件,如Catch-$HASHSUM.pcm,从而有效地启用了模块系统。您可能最终会为同一模块提供几个,因为PCH是使用的编译器选项(例如上述示例中的Objective-C支持)的依赖(其他内容)。Clang本身管理此缓存DIR;它甚至删除了旧未使用的文件(无论如何,/tmp/在引导过程中也被删除)。

您发现,新的-fmodules-ts编译器标志有效地询问了我们都在寻找的未来模块TS支持。请注意,目前几乎无法使用。

关于如何使用它的问题已经被询问和回答:clangs C 模块TS支持:如何告诉Clang 在哪里找到模块文件?