如何在Clang中使用c++模块

How do I use C++ modules in Clang?

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

模块是#includes的替代品。Clang有一个完整的c++实现。如果我现在想使用Clang使用模块,我该怎么做呢?


使用

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

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


Clang文档指出,当传递-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编译这个测试文件与不使用任何标记生成相同的目标文件。

我做错了什么?

从这次提交开始,Clang已经对Modules TS提供了实验性的支持。

让我们采用与VS博客中关于实验性模块支持的文章相同的示例文件(只做了一点改动)。

首先,定义模块接口文件。默认情况下,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

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

注意:当使用-fprebuilt-module-path=.选项,我得到一个警告:

clang++.exe: warning:编译过程中未使用的参数:'-fprebuilt-module-path=. '"[-Wunused-command-line-argument]

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

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

然而,如果您显式地设置-fmodules-cache-path=<path>,您可以观察到clang在构建期间使用预编译的模块文件(*.pcm)填充它-如果涉及任何模块的话。

您需要使用libc++(它似乎带有一个模块)。如果你现在想使用一个支持模块的标准库(Modulemap(3.7.0版本))——尽管根据我的经验,这还不能完全工作。(Visual Studio 2015的c++编译器也应该在11月的更新1中获得某种形式的模块支持)

独立于stdlib,您仍然可以在自己的代码中使用模块。clang文档包含了模块映射语言的详细描述。