這幾天我們已經用 Conan 搭配過好幾種不同的作業系統、編譯器,甚至是不同的 Build System 了。你有沒有想過,如果你的電腦上同時裝了好幾個不同的編譯器時,該怎麼辦呢?
Linux 電腦上,為了支援老舊專案,同時有 gcc10 和 gcc13 是很正常的。macOS 上面,同時有 Xcode 15 和 Xcode 26 也非常普遍。
Conan 要怎麼處理這樣的問題呢?這個就要談到 Conan Profile 了。
我們在 D03 時有稍微提過一下 Conan Profile,但是沒有深談。今天就來好好聊聊。

安裝完 Conan之後,打開你的家目錄,應該會看到 .conan2 目錄,往下有個 profiles 子目錄。
C:\Users\YOUR_NAME\.conan2\profiles
~/.conan2/profiles
注意是
.conan2不是.conan。~/.conan是舊版的 Conan 1 的家目錄,如果你的電腦上兩個都有,代表你以前用過 Conan 1。
第一次用 Conan 的人,裡面應該只有一個檔案,名為 default (沒有副檔名)。
懶得自己找的話,直接問 Conan 也可以:
conan profile path default
它會印出 default profile 的完整路徑,例如:
/home/matt/.conan2/profiles/default
簡單講 Conan profile 就是一份「怎麼編譯套件」的設定檔。
今天我們拿到一份 C++ 原始碼,不管要編譯成函式庫或可執行檔,要做的選擇可多了。
哪個作業系統?哪個 CPU 架構?哪個編譯器?哪個編譯器版本?Debug 還是 Release?要編譯成靜態庫還是動態庫?要用 C++14 還是 C++20 當標準?
這些設定全部會寫在 Profile 裡面。Conan 會拿這些資訊去找對應的二進位檔。所以 gcc10 跟 gcc13 編出來的套件,在 Conan 眼中是兩個不同的東西,不會混在一起用。
把 default 用文字編輯器打開來看看,就可以看到這些設定。
以下是兩個 Conan Profile 的例子,跟你的可能會有些微不同,端看你電腦當下安裝的是哪款編譯器。
Windows (X86架構 64位元 MSVC 2022編譯器 語言標準是C++14):
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=14
compiler.runtime=dynamic
compiler.version=194
os=Windows
Linux (X86架構 64位元 GCC編譯器 語言標準是gnu17):
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux
這份 default 就是預設的編譯器設定,當我們下達 Conan 指令又沒有指定其他選項時,就會自動套用 default profile 裡面的設定去編譯原始碼。
Profile 的檔案格式是常見的 INI,裡面可以有多個區塊,區塊下則是用 KEY=Value 的格式,每一個設定一行。
[settings] 區塊底下就是編譯器的各項設定:作業系統、CPU 架構、編譯器與版本、C++ 標準、Debug 還是 Release。使用 conan profile detect 指令自動產生的就是 [settings] 區塊。
但 profile 常用的區塊不只這樣,還有這幾個:
[settings]:編譯環境。[options]:套件選項。[conf]:各種工具的設定,例如 tools.build:jobs=8 控制平行編譯數量。[buildenv]:編譯時要注入的環境變數,例如 CC、CXX、PATH。這些現在先知道一下就好了。
profile 可以寫註解,只能寫在獨立一行,以
#開頭,不能寫在行尾。
OK,現在有一個非常實際的情境:電腦上有兩個公司專案,我都想用 Conan 來管理依賴套件。但是一個專案必須用 gcc10 搭配 C++14 編譯,另一個必須用 gcc13 搭配 C++17 編譯,該怎麼辦呢?
答案就是:再寫一份 profile。

假設我的 Linux 預設值是 gcc13,那就複製 default 檔案,改檔名叫 gcc10,然後修改如下:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu14
compiler.libcxx=libstdc++11
compiler.version=10
os=Linux
我把 compiler.version 的值改成 10,compiler.cppstd 也改成 gnu14,這樣子就符合舊專案的編譯器設定了。
接著就是最重要的一步了:安裝套件時請用 --profile 指定 profile!
conan install . --build=missing --profile gcc10
不指定時,Conan 會默認用 default profile。所以前幾天我們其實一直都在用 default profile。而指定了特定 Profile 之後,Conan 就會使用你給定的編譯器設定來安裝依賴套件。
macOS 也是同樣的道理,你可以準備兩份 Profile 一份指定使用 Xcode 15 (compiler.version=15),另一份指定使用 Xcode 26 (compiler.version=17),就可以在不同專案之間切換編譯器了。
# 舊專案用這個
conan install . --build=missing --profile xcode15
# 新專案用這個
conan install . --build=missing --profile xcode26
有時候只是想臨時編個 Debug 版除錯,為了這點小事再寫一份 profile 太麻煩了。
我要怎麼快速地安裝一套 Debug 函式庫呢?
這時候在安裝命令加 -s,臨時覆蓋單一個 setting 就行了:
conan install . --build=missing -s build_type=Debug
-s build_type=Debug 這個選項,就把編譯選項換成 Debug 版本了。
回頭看第四天的 Visual Studio 專案,我當時說 conan install 指令要打兩次,一次 Release、一次 Debug,就是因為要分別產生兩種組態的套件。
--profile 和 -s 也可以組合一起用,例如用 gcc10 profile 再加上 Debug:
conan install . --build=missing --profile gcc10 -s build_type=Debug
從這個系列一開始,我們只要呼叫 conan install 後面都一定帶著 --build=missing,我們現在終於可以解釋清楚了。
我們前面提過,C++ 有非常多的編譯器設定,這些不同的編譯器版本跟設定,產生出來的二進位檔通常都是互不相容的。
所以假設我們撰寫了一份特別的 Profile,然後呼叫 conan install 去安裝依賴套件,請問會發生什麼事呢?
首先,Conan 會拿著手上的這個 Profile,去試著找看看有沒有預先編譯好的二進位檔可以用:
Cache
Download
Built
像我們之前示範的 fmt/12.2.0,官方倉庫上剛好有預先編譯好的 gcc13 的套件二進位檔,可以直接下載來用。
但 ConanCenter 不可能把所有組合都預先編好。
像 gcc10+gnu14 的組合,就沒有現成的二進位檔。此時 --build=missing,就是告訴 Conan,找不到的套件就「現場從原始碼編譯」吧。
如果沒有指定 --build=missing,Conan 會回報安裝錯誤,說找不到預編好的套件(Missing prebuilt package)。
編好的套件二進位檔會放進本機快取,下次同樣的組合就直接從本機抓取,不用再編譯一次。
所以剛剛換 profile 或者換 options 之後,第一次安裝會耗時特別久,通常就是 Conan 在背後幫你編譯套件。