模块是#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
与无标志编译此测试文件会产生相同的目标文件。
我做错了什么?
答案 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
目录。