Ubuntu 安裝 clang,clang 多版本切換

本篇介紹 Ubuntu 安裝 clang 以及 clang 多版本切換方式,

使用 apt-get 安装最新版本的 clang

使用 apt-get 安装最新版本的 clang 指令如下,安裝前記得 apt-get update 一下,

1
2
sudo apt-get update
sudo apt-get install clang

使用 apt-get 安装指定的 clang 版本

以我 ubuntu 16.04 為例,可以安裝的版本如下,

1
2
3
4
5
6
sudo apt-get install clang-3.8
sudo apt-get install clang-3.9
sudo apt-get install clang-4.0
sudo apt-get install clang-5.0
sudo apt-get install clang-6.0
sudo apt-get install clang-8

那怎麼看可以安裝哪幾種版本呢?
apt-cache showpkg clang 列出來的資訊不太準,我用 apt-cache search clang 列出來以後自己慢慢看比較準,不過需要一些經驗,用 apt-cache showpkg clang | grep ^clang- 列出 clang- 開頭,或者 apt-cache showpkg clang | grep ^clang-[0-9] 列出 clang-0 開頭 ~ clang-9 開頭的選項,這樣看會比較輕鬆。

切換不同版本的 clang

假如你系統已經裝了兩個版本或以上的 clang,例如已經裝了 clang-3.8 與 clang-6.0,你可以直接使用 clang++-3.8clang++-6.0 來編譯 C++ 程式,或者你可以透過下列方式來選擇預設 clang 要使用哪個版本,假設我要把 clang-6.0 作為我的預設 clang,就輸入這樣的指令,把 clang-3.8 優先權設定為 38,clang-6.0 優先權設為 60 (越高越優先),

1
2
3
4
# clang-3.8
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.8 38 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-3.8
# clang-6.0
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-6.0 60 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-6.0

這邊我是一起設定 clang 與 clang++ 一起作動,你可以單獨分開設定,後面不要加 --slave 就可,

這時候你可以用 clang --versionclang++ --version 指令來檢查確認一下當前 clang 使用的版本,

1
2
3
4
5
6
7
8
9
10
11
$ clang --version
clang version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

$ clang++ --version
clang version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

輸入 sudo update-alternatives --config clang 來選擇使用哪一種版本

1
2
3
4
5
6
7
8
9
10
$ 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-6.0 60 auto mode
1 /usr/bin/clang-3.8 38 manual mode
2 /usr/bin/clang-6.0 60 manual mode

Press <enter> to keep the current choice[*], or type selection number:

然後在 selection number: 輸入 1 按 enter 的話,會手動切換成 clang-3.8(原本為 0 自動模式是按優先權決定)之後再用 clang --version 去確認一下當前 clang 使用的版本應該就切換成 clang-3.8 了,

1
2
3
4
5
$ clang --version
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

clang update-alternatives 連動更多相關程式的版本

稍早有介紹將 clang 與 clang++ 的版本使用 update-alternatives 一起連動,但通常還有更多的 clang 相關工具也要一起連動,例如:clang-format、llvm-ar、llvm-link 等等,以下提供一個方便的腳本來連動這些事情,有些執行檔舊版本不一定有,可以註解掉,挑選你想要連動的相關程式就好,

update-alternatives-clang.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/env bash

function update-alternatives-clang() {
local version=$1
local priority=$2

update-alternatives \
--install /usr/bin/clang clang /usr/bin/clang-${version} ${priority} \
--slave /usr/bin/clang++ clang++ /usr/bin/clang++-${version} \
--slave /usr/bin/asan_symbolize asan_symbolize /usr/bin/asan_symbolize-${version} \
--slave /usr/bin/c-index-test c-index-test /usr/bin/c-index-test-${version} \
--slave /usr/bin/clang-check clang-check /usr/bin/clang-check-${version} \
--slave /usr/bin/clang-cl clang-cl /usr/bin/clang-cl-${version} \
--slave /usr/bin/clang-cpp clang-cpp /usr/bin/clang-cpp-${version} \
--slave /usr/bin/clang-format clang-format /usr/bin/clang-format-${version} \
--slave /usr/bin/clang-format-diff clang-format-diff /usr/bin/clang-format-diff-${version} \
--slave /usr/bin/clang-import-test clang-import-test /usr/bin/clang-import-test-${version} \
--slave /usr/bin/clang-include-fixer clang-include-fixer /usr/bin/clang-include-fixer-${version} \
--slave /usr/bin/clang-offload-bundler clang-offload-bundler /usr/bin/clang-offload-bundler-${version} \
--slave /usr/bin/clang-query clang-query /usr/bin/clang-query-${version} \
--slave /usr/bin/clang-rename clang-rename /usr/bin/clang-rename-${version} \
--slave /usr/bin/clang-reorder-fields clang-reorder-fields /usr/bin/clang-reorder-fields-${version} \
--slave /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-${version} \
--slave /usr/bin/lldb lldb /usr/bin/lldb-${version} \
--slave /usr/bin/lldb-server lldb-server /usr/bin/lldb-server-${version} \
--slave /usr/bin/llvm-ar llvm-ar /usr/bin/llvm-ar-${version} \
--slave /usr/bin/llvm-as llvm-as /usr/bin/llvm-as-${version} \
--slave /usr/bin/llvm-bcanalyzer llvm-bcanalyzer /usr/bin/llvm-bcanalyzer-${version} \
--slave /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${version} ${priority} \
--slave /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-${version} \
--slave /usr/bin/llvm-diff llvm-diff /usr/bin/llvm-diff-${version} \
--slave /usr/bin/llvm-dis llvm-dis /usr/bin/llvm-dis-${version} \
--slave /usr/bin/llvm-dwarfdump llvm-dwarfdump /usr/bin/llvm-dwarfdump-${version} \
--slave /usr/bin/llvm-extract llvm-extract /usr/bin/llvm-extract-${version} \
--slave /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-${version} \
--slave /usr/bin/llvm-mc llvm-mc /usr/bin/llvm-mc-${version} \
--slave /usr/bin/llvm-mcmarkup llvm-mcmarkup /usr/bin/llvm-mcmarkup-${version} \
--slave /usr/bin/llvm-nm llvm-nm /usr/bin/llvm-nm-${version} \
--slave /usr/bin/llvm-objcopy llvm-objcopy /usr/bin/llvm-objcopy-${version} \
--slave /usr/bin/llvm-objdump llvm-objdump /usr/bin/llvm-objdump-${version} \
--slave /usr/bin/llvm-profdata llvm-profdata /usr/bin/llvm-profdata-${version} \
--slave /usr/bin/llvm-ranlib llvm-ranlib /usr/bin/llvm-ranlib-${version} \
--slave /usr/bin/llvm-readobj llvm-readobj /usr/bin/llvm-readobj-${version} \
--slave /usr/bin/llvm-rtdyld llvm-rtdyld /usr/bin/llvm-rtdyld-${version} \
--slave /usr/bin/llvm-size llvm-size /usr/bin/llvm-size-${version} \
--slave /usr/bin/llvm-stress llvm-stress /usr/bin/llvm-stress-${version} \
--slave /usr/bin/llvm-strip llvm-strip /usr/bin/llvm-strip-${version} \
--slave /usr/bin/llvm-symbolizer llvm-symbolizer /usr/bin/llvm-symbolizer-${version} \
--slave /usr/bin/llvm-tblgen llvm-tblgen /usr/bin/llvm-tblgen-${version}
}

update-alternatives-clang $1 $2

例如我要將 clang-6.0、clang++-6.0、lldb-6.0、llvm-ar-6.0、llvm-link-6.0 … 加入 update-alternatives --config clang 的選項裡的話,執行 update-alternatives-clang.sh 腳本後面接上版本優先權這樣就可以了!

1
sudo update-alternatives-clang.sh 6.0 60

如果是要將 clang-8、clang++-8 … 加入 update-alternatives --config clang 的選項裡的話,就這樣下,

1
sudo update-alternatives-clang.sh 8 80

其他參考
update-alternatives-clang.sh · GitHub
https://gist.github.com/junkdog/70231d6953592cd6f27def59fe19e50d

其它相關文章推薦
Ubuntu 安裝 gcc/g++,gcc/g++ 多版本切換