Ubuntu 22.04 更新 C++ 编译器
Ubuntu 22.04 默认使用 g++-11
和 clang++-14
作为默认的 g++
和 clang++
。
本文说明如何升级 C++ 编译器并设置默认版本,从而使用最新的 C++ 语言特性。
安装最新版本的 C++ 编译器
安装最新的 g++
sudo apt update
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt install gcc-12 g++-12 -y
sudo apt install gcc-13 g++-13 -y
安装最新的 clang++
参见 LLVM Debian/Ubuntu Packages 中的安装指南:
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
# sudo ./llvm.sh <version number> all
# or
# sudo ./llvm.sh all
sudo ./llvm.sh 18 all
切换编译器的默认版本
上述命令执行之后,我们会发现,g++
仍然是 g++11
,clang++
仍然是 clang++-14
。
这里介绍一下 update-alternatives
,由于管理 Ubuntu 上软件版本的切换,使其多版本共存。语法:
注册可选的软件版本:
sudo update-alternatives --install link name path priority \
[--slave link name path]
切换默认的软件版本:
sudo update-alternatives --config name
注意
切换编译器 软件包可能有风险,建议只在个人计算机上使用。
切换 g++ 的默认版本
注册 gcc
/ g++
版本:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 11 --slave /usr/bin/g++ g++ /usr/bin/g++-11
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12 --slave /usr/bin/g++ g++ /usr/bin/g++-12
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13 --slave /usr/bin/g++ g++ /usr/bin/g++-13
选择默认 gcc
/ g++
版本:
sudo update-alternatives --config gcc
会弹出以下选项:
There are 3 choices for the alternative gcc (providing /usr/bin/gcc).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/gcc-13 13 auto mode
1 /usr/bin/gcc-11 11 manual mode
2 /usr/bin/gcc-12 12 manual mode
3 /usr/bin/gcc-13 13 manual mode
Press <enter> to keep the current choice[*], or type selection number:
输入序号即可。
切换 clang++ 的默认版本
clang
/ clang++
是 LLVM 工具链的一部分,更新的时候,建议把 llvm 所有工具一起更新。
这里使用以下脚本 update-alternatives-clang.sh
进行批量注册:
#!/usr/bin/env bash
# Colors
RESET=$(tput sgr0)
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
BOLD=$(tput bold)
# Get available versions from /lib/llvm-*
# You can also use specific versions, e.g. VERSIONS=("14" "17" "18"), but not recommend
VERSIONS=()
for dir in /lib/llvm-*; do
if [[ -d "$dir" ]]; then
version=$(basename "$dir" | cut -d'-' -f2)
VERSIONS+=("$version")
fi
done
# Loop through versions
for VERSION in "${VERSIONS[@]}"; do
# Check if /lib/llvm-${VERSION} directory exists
if [[ -d "/lib/llvm-${VERSION}" ]]; then
# Scan paths and generate string
alternative_string=""
alternative_cmds=()
for cmd in "/lib/llvm-${VERSION}/bin/"*; do
if [[ -x "$cmd" ]] && [[ "$(basename "$cmd")" != "clang" ]]; then
base_cmd=$(basename "$cmd")
symlink="/usr/bin/${base_cmd}-${VERSION}"
if [[ -x "${symlink}" ]]; then
alternative_cmds+=($(basename ${symlink}))
alternative_string+="--slave /usr/bin/${base_cmd} ${base_cmd} ${symlink} "
fi
fi
done
# Remove specific alternative configuration
sudo update-alternatives --remove clang "/usr/bin/clang-${VERSION}" > /dev/null
# Install alternatives
install_command="sudo update-alternatives \
--quiet \
--install /usr/bin/clang clang /usr/bin/clang-${VERSION} ${VERSION} \
${alternative_string}"
# Print the concatenated string
echo "${BOLD}${GREEN}[Adding alternative /usr/bin/clang-${VERSION} ...]${RESET}"
echo "Master command: clang-${VERSION}"
echo "Slave commands: ${alternative_cmds[*]}"
eval "$install_command"
# Check eval command's return value
if [[ $? -eq 0 ]]; then
echo "${BOLD}${GREEN}[Adding alternative /usr/bin/clang-${VERSION}: succeeded]${RESET}"
else
echo "${BOLD}${RED}[Adding alternative /usr/bin/clang-${VERSION}: failed]${RESET}"
fi
echo ""
else
# Remove specific alternative configuration if /lib/llvm-${VERSION} directory does not exist
sudo update-alternatives --remove clang "/usr/bin/clang-${VERSION}" &> /dev/null
fi
done
clang_path=$(sudo update-alternatives --get-selections | grep ^clang | awk '{print $NF}')
echo "======================================================================"
echo "${GREEN}clang alternative is set to: ${clang_path}${RESET}"
echo "======================================================================"
# print helps
echo ""
echo "Info:"
num_versions=${#VERSIONS[@]}
if [[ num_versions -gt 1 ]]; then
echo " use '${GREEN}sudo update-alternatives --config clang${RESET}' to change default clang alternative"
fi
echo " use '${GREEN}sudo update-alternatives --remove clang /usr/bin/clang-*${RESET}' to delete a clang alternative"
echo " use '${GREEN}sudo update-alternatives --remove-all clang${RESET}' to delete all clang alternatives"
sudo bash update-alternatives-clang.sh
结果如下:
[Adding alternative /usr/bin/clang-14 ...]
Master command: clang-14
Slave commands: analyze-build-14 bugpoint-14 ...
[Adding alternative /usr/bin/clang-14: succeeded]
[Adding alternative /usr/bin/clang-18 ...]
Master command: clang-18
Slave commands: amdgpu-arch-18 analyze-build-18 ...
[Adding alternative /usr/bin/clang-18: succeeded]
======================================================================
clang alternative is set to: /usr/bin/clang-18
======================================================================
...
同上面的 gcc
/g++
版本切换,切换 clang
/ llvm
工具链版本命令如下:
sudo update-alternatives --config clang
会弹出以下选项:
There are 2 choices for the alternative clang (providing /usr/bin/clang).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/clang-18 18 auto mode
1 /usr/bin/clang-14 14 manual mode
2 /usr/bin/clang-18 18 manual mode
Press <enter> to keep the current choice[*], or type selection number:
输入序号即可。