ubuntu系统上的软件相比CentOS更新还是比较快的,但是还是难免有一些软件更新得不那么快,比如LLVM Clang编译器,目前ubuntu 22.04版本最高还只能安装LLVM 15,而LLVM 18 rc版本都出来了。参见 https://github.com/llvm/llvm-project/releases

这里笔者就以最新稳定版本 clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz来说明如何使用LLVM官方发布的tar.xz文件来安装Clang编译器。

一、下载安装clang+llvm

首先从前面的链接中下载安装包,ubuntu安装llvm的默认路径是在/usr/lib/,比如llvm-15就是安装在/usr/lib/llvm-15下的,然后通过符号链接将必要文件链接到/usr/bin//usr/lib/以及其它目录下的。我们也遵循这样的规则。

1sudo tar xvf clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz 
2sudo mv clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04 /usr/lib/llvm-17
3sudo ln -s /usr/lib/llvm-17/bin/clang /usr/bin/clang -f
4sudo ln -s /usr/lib/llvm-17/bin/clang++ /usr/bin/clang++ -f

即可。

如果要使用libc++库,则需要将路径/usr/lib/llvm-17/lib/x86_64-unknown-linux-gnu添加到ldconfig中,在/etc/ld.so.conf.d/中新建一个libcpp.conf文件,内容为:/usr/lib/llvm-17/lib/x86_64-unknown-linux-gnu,然后执行sudo ldconfig即可。

号外,在Ubuntu系统中还可以使用下面的方式来安装LLVM,比如安装llvm-21中编译器、链接器、调试器等组件:

1wget https://apt.llvm.org/llvm.sh
2chmod +x llvm.sh
3sudo ./llvm.sh 21 clang lldb lld clangd libc++
4sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-21 100
5sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-21 100
6sudo update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-21 100
7sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-21 100

也可以使用下面命令安装llvm-21中的所有组件:

1sudo ./llvm.sh 21 all

在Ubuntu系统中笔者更推荐使用此方式安装。

二、测试clang

这里笔者以前文 C++ 20 Module中的示例来使用clang 17编译,并且使用libc++库,而不是stdlibc++

这里使用CMakePresets.json来配置CMake:

 1{
 2  "version": 3,
 3  "configurePresets": [
 4    {
 5      "name": "linux-debug",
 6      "displayName": "Linux Debug",
 7      "generator": "Ninja",
 8      "binaryDir": "${sourceDir}/out/build/${presetName}",
 9      "installDir": "${sourceDir}/out/install/${presetName}",
10      "cacheVariables": {
11        "CMAKE_BUILD_TYPE": "Debug",
12        "CMAKE_C_COMPILER": "clang",
13        "CMAKE_CXX_COMPILER": "clang++"
14      },
15      "condition": {
16        "type": "equals",
17        "lhs": "${hostSystemName}",
18        "rhs": "Linux"
19      },
20      "vendor": {
21        "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
22          "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
23        }
24      }
25    }
26  ],
27  "buildPresets": [
28    {
29      "name": "linux-debug",
30      "displayName": "linux-debug",
31      "description": "自定义生成预设说明",
32      "configurePreset": "linux-debug",
33      "verbose": true,
34      "jobs": 8
35    }
36  ]
37}

由于示例中使用到了C++20的模块,所以需要在CMakeLists.txt中设置CMake的最低版本要求为3.28:

1cmake_minimum_required(VERSION 3.28)

此时CMake会使用clang-scan-deps来扫描依赖,目前clang-scan-deps由于头文件搜索路径问题,会报错:

1/usr/bin/../include/c++/v1/stddef.h:17:15: fatal error: 'stddef.h' file not found

是找不到头文件。

对于clang可以使用下面的命令来看clang的头文件搜索路径:

1echo | clang -x c++ -v -E -

在这里插入图片描述 如果使用了libc++库,则需要添加上,使用:

1echo | clang -x c++ -v -E - -stdlib=libc++

在这里插入图片描述 如果是GCC,则为:

1echo | gcc -x c++ -v -E -

在这里插入图片描述

如果使用了libc++则需要添加/usr/lib/llvm-17/include/c++/v1,由于libc++库有使用libstdc++库的一些头文件,所以还需要添加stdc++的头文件路径:/usr/lib/gcc/x86_64-linux-gnu/11/include,其中11为版本号,根据安装的版本不同可能有所不同。可能还会有找不到__config_site文件的情况,该文件在/usr/lib/llvm-17/include/x86_64-unknown-linux-gnu/c++/v1

可以在CMakePresets.json中使用环境变量来设置:

1 "environment": {
2   "CPLUS_INCLUDE_PATH": "/usr/lib/llvm-17/include/c++/v1:/usr/lib/gcc/x86_64-linux-gnu/11/include:/usr/lib/llvm-17/include/x86_64-unknown-linux-gnu/c++/v1"
3 }

如果没有使用libc++,则添加/usr/lib/gcc/x86_64-linux-gnu/11/include即可。

这样就可以正常使用新版本的clang编译器了,如果还有找不到的文件,也可以通过这样的方式添加路径。

编译器搜索路径有几个环境变量:C_INCLUDE_PATHCPLUS_INCLUDE_PATH以及CPATH。它们常被用于在编译C/C++时的搜索头文件的路径,其中C_INCLUDE_PATH仅对预处理C有效,CPLUS_INCLUDE_PATH仅对预处理C++有效,而CPATH对C和C++语言均有效。

这些环境变量可以在每个项目的CMakePresets.json来中使用如上方式设置,如果想一劳永逸地设置一次,则可以在~/.bashrc中使用export 指令来设置,比如:

1export CPLUS_INCLUDE_PATH=/usr/lib/llvm-17/include/c++/v1:/usr/lib/gcc/x86_64-linux-gnu/11/include:/usr/lib/llvm-17/include/x86_64-
2unknown-linux-gnu/c++/v1:${CPLUS_INCLUDE_PATH}

三、额外事项

1. 卸载从ubuntu的apt系统安装的clang和llvm

安装llvm-17后,如果不再使用llvm-15,则可以将之卸载掉:

1sudo apt autoremove llvm-15
2sudo apt autoremove clang-15

2、更新cmake和ninja

由于要使用C++ 20的模块特性,需要cmake 3.28版本及以上,ninja也需要更新,之前ubuntu中使用apt安装的cmake和ninja也可以一并卸载掉了。

1. 卸载

1sudo apt autoremove cmake
2sudo apt autoremove ninja-build

2. 下载安装cmake

从官方网站下载最新的版本进行安装。目前最新稳定版本为: cmake-3.28.3-linux-x86_64.sh

1sudo mv cmake-3.28.3-linux-x86_64.sh  /usr/local
2cd /usr/local
3chmod +x cmake-3.28.3-linux-x86_64.sh 
4./cmake-3.28.3-linux-x86_64.sh

Do you accept the license? [yn]: 时输入y

1By default the CMake will be installed in:
2  "/usr/local/cmake-3.28.3-linux-x86_64"
3Do you want to include the subdirectory cmake-3.28.3-linux-x86_64?
4Saying no will install in: "/usr/local" [Yn]: 

输入n安装到/usr/local目录,不用再建议软链接了。

3. 下载安装ninja

https://github.com/ninja-build/ninja/releases下载最新的ninja版本,它是一个zip文件,解压后放到PATH路径中,建议为/usr/local/bin:

1sudo mv ninja /usr/local/bin

3、更新安装lldb-mi

由于前面已经卸载掉了llvm-15,如果之前安装的lldb-mi是基于llvm-15构建的,那就会报错:

1lldb-mi: error while loading shared libraries: liblldb-15.so.1: cannot open shared object file: No such file or directory

https://github.com/lldb-tools/lldb-mi下载最新的源码,然后进行源码编译安装。

源码使用的是cmake构建系统,在源码根目录中执行下面的命令:

1mkdir build
2cd build
3cmake ..

如果系统中没有相应的依赖库,在执行cmake ..的时候可能会报错:

 1CMake Error at /usr/lib/llvm-17/lib/cmake/llvm/LLVMExports.cmake:64 (set_target_properties):
 2  The link interface of target "LLVMSupport" contains:
 3
 4    ZLIB::ZLIB
 5
 6  but the target was not found.  Possible reasons include:
 7
 8    * There is a typo in the target name.
 9    * A find_package call is missing for an IMPORTED target.
10    * An ALIAS target is missing.
11
12Call Stack (most recent call first):
13  /usr/lib/llvm-17/lib/cmake/llvm/LLVMConfig.cmake:356 (include)
14  CMakeLists.txt:15 (find_package)
报的依赖项 ubuntu的安装包名
ZLIB::ZLIB zlib1g-dev
zstd::libzstd_shared libzstd-dev
Terminfo::terminfo libncurses5-dev libncursesw5-dev
LibXml2 libxml2-dev

最后一项LibXml2报的不一样: Could NOT find LibXml2 (missing: LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)

可以使用:

1sudo apt install -y zlib1g-dev libzstd-dev libncurses5-dev libncursesw5-dev libxml2-dev

一次安装上述所有依赖库。

使用cmake ..配置好项目后,就可以使用cmake --build .构建了。

构建完成使用下面命令安装即可:

1sudo cp ./src/lldb-mi /usr/local/bin/lldb-mi
2sudo cp ./src/lldb-mi /usr/lib/llvm-17/bin/lldb-mi

复制到/usr/lib/llvm-17/bin/lldb-mi,是因为VSCode中的cmake插件启动调试器时是会检测该路径。

如果本文对你有所帮助,可以点赞收藏!