如何在 CLion for Mac 上支持 C++20 模块

问题描述 投票:0回答:1

我无法使用 Clion 2023.3 成功编译 cpp20 模块代码。 这是代码:

//Hello.cppm
#include <iostream>
export module Hello;
export void hello() {
    std::cout << "Hello World!\n";
}
//main.cpp
import Hello;
int main() {
    hello();
    return 0;
}

当我构建这些代码时,出现了一些错误:

error: module interface compilation requires '-std=c++20' or '-fmodules-ts'
error: unknown type name 'import'
error: use of undeclared identifier 'hello'

我在一些网站上搜索并决定在 Clion 的终端中构建它 首先构建模块:

clang++ -std=c++20 -fmodules-ts Hello.cppm --precompile -o Hello.pcm  

Hello.pcm 已生成,没有错误, 然后构建main.cpp:

clang++ -std=c++20 main.cpp -fmodule-file=Hello=Hello.pcm Hello.pcm -o Hello.out

错误又来了:

error: unknown type name 'import'
error: use of undeclared identifier 'hello'

我的操作系统版本是 macOS Sonoma 14.2.1,clang 版本 15 使用的 clion 工具链捆绑(cmake 3.27.8)

有人可以帮忙吗? 谢谢!

c++ macos clang c++20 clion
1个回答
0
投票

就编译器开关而言,请使用

-std=c++20
-fmodules-ts
,但不要同时使用两者。模块 TS 已被 C++20 取代,所以我推荐前者。

我在程序本身中看到的唯一错误是省略了全局模块片段。它在模块单元中首先出现,并以

module;
声明开始。

老式的 include 指令属于全局模块片段。

// hello.cppm
// Clang uses the file extension `.cppm` for "module interface units."

module;               // "global module fragment" begins here
// Include directives belong in the global module fragment.
#include <iostream>

// The global module fragment ends when a module declaration is encountered.
export module Hello;  

export void hello() {
    std::cout << "Hello World!\n";
}
// end file: hello.cppm

根据模块的Clang文档

可导入模块单元的文件名应以.cppm(或.ccm、.cxxm、.c++m)结尾。模块实现单元的文件名应以.cpp(或.cc、.cxx、.c++)结尾。

如果文件名使用不同的扩展名,Clang 可能无法构建模块。

因此,请确保您的模块接口单元文件名以

.cppm
结尾。

非模块文件,例如

main.cpp
是常规的 C++ 翻译单元。因此,他们应该使用文件扩展名
.cpp

您的文件

main.cpp
看起来不错。

// main.cpp
import Hello;
int main() {
    hello();
    return 0;
}
// end file: main.cpp

我不是 Clang 用户,所以我在 MSVC 下运行你的程序。就 Clang 而言可能无关紧要,但上面的程序在 Visual Studio 中运行正确(尽管我确实使用了 Microsoft 的

ixx
文件扩展名作为模块接口单元)。

© www.soinside.com 2019 - 2024. All rights reserved.