前言

本文写于2024.5.19,我的系统为22.04.1-Ubuntu,默认带的是gcc11,它还不支持C++20。为了用上一些C++20的特性,便打算配置一下C++20的环境,期间走了不少弯路,故写一份笔记造福后人。

这里列出我的一些配置:

  • 22.04.1-Ubuntu
  • CLion 2024.1

配置过程

下载clang18

首先,需要下载支持C++20的编译器。从cppreference上可以找到支持C++20的编译器有哪些。这里选择下载clang18,因为当下的gcc13尚不支持C++20的模块功能。

如果用cmake,cmake需要3.28以上才支持C++20模块功能

参考一篇知乎文章,在命令行下输入以下内容安装LLVM18(其带有clang18):

1
2
3
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 18

下载完之后用下面的命令查看一下clang18是否成功安装。

1
clang-18 --v

输出应该如下:

1
2
3
4
5
6
7
8
9
Ubuntu clang version 18.1.6 (++20240517093811+3d0752b9492e-1~exp1~20240517213934.128)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/12
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/12
Candidate multilib: .;@m64
Selected multilib: .;@m64

下载gcc12

从刚才clang-18 --v可以看到,clang18需要gcc12,如果没有的话,需要安装一下。

具体而言,是需要gcc12带的C++标准库libstdc++。如果没有的话会报错。

1
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/12

用下面的命令安装gcc12和g++12:

  • gcc 是GCC套件中的C语言编译器,用于编译C语言源代码。
  • g++ 是GCC套件中的C++语言编译器,用于编译C++语言源代码。
1
sudo apt install gcc-12 g++12

安装libc++

gcc12带的C++标准库libstdc++是不含C++20的库的(gcc13带的C++标准库才含有C++20的库),所以还需要下载llvm带的另一个C++标准库libc++(是的,刚才安装llvm-18的时候并没有安装这个C++标准库)。

用以下命令来安装:

1
sudo apt install libc++-18-dev libc++abi-18-dev

配置工具链

打开CLion的设置,打开构建、执行、部署中的工具链一项。

image-20240519114554944

应该可以在/usr/bin中找到clang-18(点C Compiler旁边像文件夹的那个按钮)。

image-20240519114703299

同样,设置C++ compiler为clang++-18,到这里编译器就设置好了。

更改cmakelist

现在直接编译还成功不了,因为clang-18会去找gcc12的标准库libstdc++,而其还不支持C++20。所以需要设置标准库为我们安装的libc++-18。在cmakelist.txt中添加如下语句:

1
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")

在CMake中,CMAKE_CXX_FLAGS是一个变量,它用于存储编译C++源文件时的编译器标志。这行CMake代码是修改这个变量的值的命令,通过将-stdlib=libc++添加到现有的编译器标志中。

这行代码的作用是告诉C++编译器(比如Clang)使用libc++作为标准的C++库而不是默认的libstdc++libc++是LLVM项目的一部分,它是C++标准库的一个实现,旨在提供对最新C++标准的良好支持。

测试

最后用一个小文件测试:

1
2
3
4
5
6
7
#include<iostream>
#include <format> //format是C++20引入的

int main()
{
std::cout<<std::format("hello world!");
}

cmakelist.txt如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
cmake_minimum_required(VERSION 3.28)
project(test)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)

add_compile_options(-std=c++20)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")

add_executable(test
main.cpp)

如果成功输出了hello world!,那么就配置成功了。