xjc*_*jcl 33 c++ clang c++20 c++-modules
模块是#includes的替代品.Clang有一个完整的C++实现.如果我现在想使用Clang使用模块,我该怎么办?
运用
import std.io;
Run Code Online (Sandbox Code Playgroud)
在C++源文件中还没有工作(编译),因为模块的规范(包括语法)不是最终的.
该锵文件指出,经过时-fmodules标志,#包括将被改写到相应的进口.但是,检查预处理器会另外建议(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, ...);
Run Code Online (Sandbox Code Playgroud)
此外,使用-fmodulesvs no flags 编译此测试文件会产生相同的目标文件.
我究竟做错了什么?
Smi*_*Smi 28
让我们看一下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;
}
Run Code Online (Sandbox Code Playgroud)
请注意,模块接口声明需要export module M;而不仅仅是module M;在VS博客文章中.
然后使用模块如下:
// file: bar.cpp
import M;
int main()
{
f(5);
g(0.0, 1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,预编译模块foo.cppm与
clang++ -fmodules-ts --precompile foo.cppm -o M.pcm
Run Code Online (Sandbox Code Playgroud)
或者,如果模块接口扩展名不是cppm(比如说ixx,与VS一样),您可以使用:
clang++ -fmodules-ts --precompile -x c++-module foo.ixx -o M.pcm
Run Code Online (Sandbox Code Playgroud)
然后用它构建程序
clang++ -fmodules-ts -c M.pcm -o M.o
clang++ -fmodules-ts -fprebuilt-module-path=. M.o bar.cpp
Run Code Online (Sandbox Code Playgroud)
或者,如果pcm文件名与模块名称不同,则必须使用:
clang++ -fmodules-ts -fmodule-file=M.pcm bar.cpp
Run Code Online (Sandbox Code Playgroud)
我已经使用r303050版本(2017年5月15日)在Windows上测试了这些命令.
注意:使用该-fprebuilt-module-path=.选项时,我收到警告:
clang ++.exe:warning:编译期间未使用的参数:' - fprebuilt-module-path =.' [-Wunused的命令行参数的]
这似乎是不正确的,因为没有该选项,M找不到该模块.
mel*_*k47 13
就像你提到的,铛还没有对进口C++的语法,所以我怀疑,#include指示将要字面上预处理的文件时改写为进口,所以这可能不是以测试是否如预期模块工作的最佳途径.
但是,如果您-fmodules-cache-path=<path>明确设置,则可以在构建期间观察使用预编译模块文件(*.pcm)填充它的clang - 如果涉及任何模块.
如果你现在想要使用模块启用的标准库,你需要使用libc ++(从版本3.7.0开始,它似乎附带了module.modulemap) - 尽管根据我的经验,这还没有完全正常工作.(Visual Studio 2015的C++编译器也应该在11月的Update 1中获得某种形式的模块支持)
独立于stdlib,您仍然可以在自己的代码中使用模块.铛文档包含的详细说明模块地图语言,但我还设置了一个小例子项目在这里(使用cmake)应该产生一个cache建立在与一些模块的目录.