Clang安装后不会自动成为默认编译器,需用update-alternatives显式配置:先注册clang和clang++(含--slave同步c++),再通过--config手动选择,确保clang --version与c++ --version版本一致。

Clang 安装后不会自动成为系统默认编译器,gcc 和 g++ 仍会被调用;必须显式配置才能让 cc、c++ 或构建工具(如 CMake)实际使用 Clang。
Ubuntu/Debian 上用 update-alternatives 切换默认 clang
这是最干净、可逆、且被系统级工具(如 apt)认可的方式。它不改软链接,而是通过统一接口管理多版本共存。
- 先确认已安装多个版本(如
clang-15、clang-16),路径通常在/usr/bin/下 - 为
clang注册选项:sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-16 100 - 为
clang++同步注册(关键!否则c++命令仍走g++):sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-16 100 --slave /usr/bin/c++ c++ /usr/bin/clang++-16 - 执行
sudo update-alternatives --config clang和sudo update-alternatives --config clang++手动选择,默认会同时更新c++符号链接 - 验证:
clang --version和c++ --version应显示相同版本号
直接修改 /usr/bin/c++ 软链接的风险
有人用 sudo ln -sf /usr/bin/clang++ /usr/bin/c++ 强行覆盖,这看似简单,但容易出问题:
Clang 22.1.3 Windows 64 位历史版本安装包,适合旧项目兼容、LLVM/Clang 工具链回退、编译行为对比、链接问题复现和 C/C++ 构建环境维护。
-
update-alternatives管理的软链接会被绕过,后续用apt升级或重装gcc可能意外覆盖该链接,导致编译器“消失” -
c++和clang++行为不完全等价:比如clang++默认启用-std=gnu++17,而某些项目依赖g++的 ABI 或库搜索路径,硬替换后链接失败很常见 - 不解决
cc(C 编译器)的对应问题,make或configure脚本仍可能调用gcc
CMake 项目中指定 clang 编译器(不改系统全局)
这是推荐做法——只影响当前项目,避免污染系统环境,也适配 CI 或多版本开发场景。
- 不要在
CMakeLists.txt里用set(CMAKE_C_COMPILER "clang"):它必须在project()之前执行,且若缓存存在,会被忽略 - 正确方式是命令行传参:
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .. - 若需指定具体版本或路径(如自编译的 Clang):
cmake -DCMAKE_C_COMPILER=/path/to/clang-16 -DCMAKE_CXX_COMPILER=/path/to/clang++-16 .. - 注意:CMake 不会自动继承
update-alternatives的选择,它只认你传入的路径或 PATH 中第一个匹配的可执行文件
Dev-C++ 中添加并设为默认 Clang 编译器
Dev-C++ 是 Windows 下老旧但仍有用户使用的 IDE,其配置不走系统 PATH,必须手动绑定路径和参数。
- 在 “工具 → 编译选项 → 程序” 页点击 “添加”,命名如 “Clang 16”
-
Compiler字段必须指向clang.exe(不是clang++.exe),路径如C:\Program Files\LLVM\bin\clang.exe -
Linker推荐填lld.exe(同目录下),避免 MinGW 的ld链接 Clang 生成的目标文件时报错 - 在 “编译器选项” 字段加
-std=c17 -Wall -Wextra,C++ 项目则额外加-x c++或改用clang++.exe作为编译器(需另建配置) - 切到 “编译器” 选项卡,从 “编译器集” 下拉菜单选刚建的配置,点确定——此时新建文件才默认用 Clang,已有项目需右键 “项目选项” 手动切换
真正麻烦的不是切换动作本身,而是 Clang 和 GCC 在默认标准(gnu99 vs gnu89)、头文件搜索路径、链接器行为上的细微差异;一次切换后,务必用 -v 参数看实际调用的链接命令,再检查是否漏了 -lc++ 或混用了 libstdc++。

















