前幾天我們自己打包的套件並沒有上傳到 ConanCenter 或任何伺服器,那套件到底是放在哪裡呢?去可以哪裡可以找到 super-lib/0.1.0 呢?
答案就是 Conan 的 本機快取(Local Cache)。
今天就來看看本機快取是什麼東西。今日目標:

Conan 的「本機快取」就像你電腦上有一個私有的小套件倉庫。
(你可以想像成 Git 版控的 .git 資料夾或者 Java Maven 的 ~/.m2)
「本機快取」裡面會保存一組讓你本機操作的資料,就像 git 一樣,平常沒有網路也可以進行基本操作,只有需要跟其他人協作時才需要去跟遠端伺服器溝通。
本機快取的預設位置在 ~/.conan2/p/,是一個使用者家目錄下的子目錄。(Windows 就是 C:\Users\YOUR_NAME\.conan2\p\)
我們之前用 conan create 指令打包套件,打包好之後,不論是 recipe 或者編譯好的二進位檔都會放進去本機快取。
想看 super-lib 躺在本機快取裡的哪個角落嗎?用以下指令就可以查到
conan cache path super-lib/0.1.0
想查詢本機快取裡面有哪些套件版本嗎?用 conan list 就行了
conan list "openssl/*"
當你呼叫 conan install 命令來安裝套件時,Conan 的第一優先是去翻找本機快取裡面的套件。

所以就算完全沒有網路,專案一樣可以用 conan install 安裝本機快取裡的套件,或者打包套件放進本機快取。
當然,沒網路就沒辦法跨機器分享給同事或者 CI 機器,這得靠 Remote 伺服器,之後會講。
「本機優先原則」有個陷阱:如果 Conan 在本機快取裡面找到套件,就不會去問遠端伺服器上的新版本。
舉例來說,假設我們用了 zlib,並且設了以下版本範圍:
[requires]
zlib/[>=1.2 <2]
本機快取裡面有 zlib/1.2.13,但是 ConanCenter 上有新版 zlib/1.3.2。那麼下達安裝套件的指令的時候,會抓到哪一版呢?
答案是本機快取上的 1.2.13!
Requirements
zlib/1.2.13#9df41c65e2c2b6ef47633dc32e0b699a - Cache
Resolved version ranges
zlib/[>=1.2 <2]: zlib/1.2.13
咦,明明伺服器上有更新的版本,Conan 卻拿了快取裡的 1.2.13,完全沒問伺服器。
如果要強迫 Conan 去允端伺服器檢查,就要加上 --update 這個參數:
conan install . --update
Requirements
zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb - Downloaded (conancenter)
Resolved version ranges
zlib/[>=1.2 <2]: zlib/1.3.2
這次就有跑去問遠端伺服器並且拿到 zlib/1.3.2 囉。
請注意,--update 不會清除本機已經安裝的套件或者修改任何東西,只是要求 Conan 解析版本範圍時,特意去伺服器看看有沒有新的內容,加上這個選項,安裝時會花多一點時間。
好,回到開頭的問題。編譯好的一包 super-lib 套件只躺在我的本機快取裡,要怎麼給同事呢?
答案是 Remote。
Conan Remote 就是一台放套件的伺服器,大家預設用的 ConanCenter 就是其中一台 remote。
公司也可以自己架一台給同事共享套件用,用 Conan 的簡易版伺服器 conan_server 或是 JFrog Artifactory 都行。
假設公司的伺服器在 http://conan.company-com:9300
我們可以用以下指令加入伺服器,並且幫它取名叫 mycompany:
conan remote add mycompany http://conan.company-com:9300
conan remote login mycompany YOUR_NAME -p YOUR_PW
用 conan upload 就可以上傳到 remote 伺服器。
conan upload "super-lib/0.1.0" -r mycompany --confirm
看到了這個輸出,recipe 加上兩個 package(Debug 和 Release),通通上去了。
-------- Uploading artifacts --------
super-lib/0.1.0: Uploading recipe 'super-lib/0.1.0#3be5256d36c2aa67a2662bd503e29eea' (1.4KB)
super-lib/0.1.0: Uploading package 'super-lib/0.1.0#3be5256d36c2aa67a2662bd503e29eea:1c144980be8c0fb2eae6beafa245995736ac235d#a0542159742c5b8b1b653ee285a4fcaf' (21.2KB)
super-lib/0.1.0: Uploading package 'super-lib/0.1.0#3be5256d36c2aa67a2662bd503e29eea:38b8b2863892fd9462affa45e40edf183b436246#b8ea55c200632fd47bb7c55977b6cea0' (1.1KB)
Upload completed in 0s
上傳之後,同事就可以透過 remote 伺服器下載你的套件。
一樣先用這個命令添加遠端伺服器: conan remote add mycompany ...
然後 conanfile.txt 寫:
[requires]
super-lib/0.1.0
接著呼叫平常的安裝指令
conan install . -r mycompany --update
看到以下輸出,就表示套件已經從伺服器上抓下來,安裝到同事電腦的本機快取裡了。
super-lib/0.1.0: Not found in local cache, looking in remotes...
super-lib/0.1.0: Checking remote: conancenter
super-lib/0.1.0: Checking remote: mycompany
super-lib/0.1.0: Downloaded recipe revision 3be5256d36c2aa67a2662bd503e29eea
...
super-lib/0.1.0: Retrieving package 38b8b2863892fd9462affa45e40edf183b436246 from remote 'mycompany'
super-lib/0.1.0: Package installed 38b8b2863892fd9462affa45e40edf183b436246
...
Install finished successfully
仔細看 Conan 的尋找順序,它先去本機快取找,沒找到才去問 remote,先找第一個 ConanCenter 找不到,最後才在 mycompany 找到。
下載的就是剛剛編譯好上傳的那一包,revision 一模一樣,同事就不用再編譯一次了。
Conan 有內建 server 嗎?
有喔,裝 Conan 的時候就一起裝好了 conan_server 這個指令,直接執行就是一台最陽春的 remote。不過官方的定位比較偏向練習和測試用。
跟 JFrog Artifactory 差在哪?
conan_server 沒有網頁介面,帳號權限都寫在設定檔裡。Artifactory 是 Conan 開發公司的專用伺服器軟體,有網頁介面可以管權限,也能把 ConanCenter 的套件快取一份到公司內部,正式商業專案開發大家多半用它。JFrog 也有免費的 Community Edition for C/C++。
小團隊可以直接用 conan_server 嗎?
幾個人、套件不多的話,可以。只是備份、HTTPS 都要自己處理,人多了權限也很難管。
先用它跑起來,以後再換 Artifactory 也很簡單,因為指令都一樣,同事只要改一下 remote 網址就好。
本機快取常常隨著時間越來越大,佔用越來越多空間,想要刪除本機快取裡面的套件?用 conan remove 指令就可以了:
conan remove "super-lib/0.1.0" -c