如何在Clang中使用C ++模块?

时间:2015-10-23 16:52:22

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

模块是#includes的替代品。 Clang has a complete implementation for C++。如果我现在想使用Clang使用模块,我该怎么办?

使用

import std.io;
C ++源文件中的

还没有工作(编译),因为模块的规范(包括语法)不是最终的。

Clang documentation表示,当传递-fmodules标志时,#include会被重写为其相应的导入。但是,检查预处理器会另外建议(test.cpp只包含#include <stdio.h>和一个空的main):

$ clang++-3.5 -fmodules -E test.cpp -o test
$ grep " printf " test
extern int printf (const char *__restrict __format, ...);

此外,使用-fmodules与无标志编译此测试文件会产生相同的目标文件。

我做错了什么?

2 个答案:

答案 0 :(得分:23)

截至this commit,Clang对Modules TS有实验支持。

让我们采用与VS blog post关于实验模块支持相同的示例文件(稍作更改)。

首先,定义模块接口文件。默认情况下,Clang将cppm扩展名(和其他一些)的文件识别为C ++模块接口文件。

// file: foo.cppm
export module M;

export int f(int x)
{
    return 2 + x;
}
export double g(double y, int z)
{
    return y * z;
} 

请注意,模块接口声明需要export module M;而不仅仅是module M;,就像在VS博客文章中一样。

然后按如下方式使用模块:

// file: bar.cpp
import M;

int main()
{
    f(5);
    g(0.0, 1);
    return 0;
}

现在,使用

预编译模块foo.cppm
clang++ -fmodules-ts --precompile foo.cppm -o M.pcm

或者,如果模块接口扩展名不是cppm(比如说​​ixx,就像VS一样),你可以使用:

clang++ -fmodules-ts --precompile -x c++-module foo.ixx -o M.pcm

然后使用

构建程序
clang++ -fmodules-ts -c M.pcm -o M.o
clang++ -fmodules-ts -fprebuilt-module-path=. M.o bar.cpp

或者,如果pcm文件名与模块名称不同,则必须使用:

clang++ -fmodules-ts -fmodule-file=M.pcm bar.cpp

我使用r303050 build(2017年5月15日)在Windows上测试了这些命令。

注意:使用-fprebuilt-module-path=.选项时,我会收到警告:

  

clang ++。exe:warning:编译期间未使用的参数:' - fprebuilt-module-path =。' [-Wunused的命令行参数的]

似乎不正确,因为没有该选项,找不到模块M

答案 1 :(得分:13)

就像你提到的那样,clang还没有导入的C ++语法, 所以我怀疑#include指令在预处理文件时会被字面重写为导入,因此这可能不是测试模块是否按预期工作的最佳方式。

但是,如果您明确设置-fmodules-cache-path=<path>,则可以在构建期间观察使用预编译模块文件(* .pcm)填充它的clang - 如果涉及任何模块。

如果你想立即使用模块启用的标准库,你需要使用libc ++(从版本3.7.0开始,它似乎附带了module.modulemap) - 尽管根据我的经验,这并不完全有效还没。 (Visual Studio 2015的C ++编译器也应该在11月份通过Update 1获得某种形式的模块支持)

独立于stdlib,您仍然可以在自己的代码中使用模块。 clang文档包含Module Map Language的详细说明,但是 我还设置了一个小示例项目here(使用cmake),它应该在构建时生成一个带有一些模块的cache目录。