到前 14 天為止,我們都是從「消費者」的角度來用套件管理器,輕鬆寫幾行設定,就能近乎無痛的導入第三方函式庫,然後心存感激的一邊開發,一邊謝謝 Conan 幫我們扛掉麻煩的編譯和設定。
但如果今天要用的函式庫,是我自己寫的呢?也能用 Conan 管理我自己的函式庫嗎?
答案是:當然可以!而且這正是 Conan 管理器的標準用法之一。
套件打包完就可以直接用了嗎?是喔。
需要先上傳套件到 ConanCenter 才能用嗎?不需要。
那今天我們就來學怎麼打包自己的 Conan Package 套件吧!

今天的目標:
conan create 指令。Conan 其實有個
conan new指令可以一鍵產生專案。但是產生的東西有點雜,剛開始一下子看只會頭暈。所以今天我們先全部手搓,用最少的檔案,搞懂核心概念。
假設今天你寫了一個超級好用的函式庫,你給他取名叫 super-lib!
雖然 super-lib 超好用,但是以檔案結構來看,就是一個極為尋常普通的 CMake 專案,函式庫本身相當迷你。
super-lib/
├── conanfile.py
├── CMakeLists.txt
├── include/
│ └── super_lib.h
└── src/
└── super_lib.cpp
include/super_lib.h:
#pragma once
void super_init();
src/super_lib.cpp:
#include <iostream>
#include "super_lib.h"
void super_init() {
std::cout << "Hello from super-lib/0.1.0\n";
}
CMakeLists.txt 也非常普通,裡面沒有出現任何 Conan 的字眼:
cmake_minimum_required(VERSION 3.23)
project(super-lib CXX)
add_library(super-lib src/super_lib.cpp)
target_include_directories(super-lib PUBLIC include)
install(TARGETS super-lib)
install(FILES include/super_lib.h DESTINATION include)
好了,到此為止,這個函式庫的檔案就準備好了。

接下來是重點,我們要來寫食譜了!
為什麼叫食譜呢?因為打包套件就像做菜:準備食材、照步驟烹煮、最後裝盤上菜。
Conan 把這份「怎麼做」的說明叫做 Recipe (食譜),而 Recipe 最核心的檔案,就是我們熟悉的 conanfile.py。
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
class SuperLibRecipe(ConanFile):
name = "super-lib"
version = "0.1.0"
settings = "os", "compiler", "build_type", "arch"
exports_sources = "CMakeLists.txt", "src/*", "include/*"
def layout(self):
cmake_layout(self)
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
def package_info(self):
self.cpp_info.libs = ["super-lib"]
注意喔,這次的 conanfile.py 是「生產端」,目的是產生套件,跟之前裝套件的「消費端」寫法不太一樣。
這份「食譜」的內容,用比喻來看就很好看懂了:
name、version:套件名稱跟版本號碼,合起來就是 super-lib/0.1.0,別人用這個名字來點菜。settings:作業系統、編譯器、Debug/Release、CPU 架構不同,二進位檔就不同,這些會拿來算 Package ID。同一道菜,換個鍋子煮出來味道就不一樣。exports_sources:要一起帶走的原始碼和 CMakeLists.txt,也就是食材。layout()、generate()、build():依序備料、開火、下鍋,實際編譯套件。package():呼叫 cmake --install 把成果放進套件目錄,料理成品裝盤。package_info():告訴使用者要連結的 lib 名單,也就是告訴客人該怎麼吃。好,食譜寫完了,接下來就開火吧!
開始打包套件,請到 CMake 專案的目錄下執行以下命令:
conan create .
請注意,conan create 指令最後的參數是個路徑,必須是個目錄,裡面要能找到 conanfile.py。
conan create 這個指令其實一口氣做了三件事:匯出、編譯、打包。
第一步「匯出」,就是把 conanfile.py 跟你列的原始碼,全部複製到一個乾淨的目錄下編譯(注意,不是在當前的專案目錄喔),所以 exports_sources 一定要寫全。
匯出這個步會看到類似下面輸出 log:
Exported: super-lib/0.1.0#3be5256d36c2aa67a2662bd503e29eea (2026-10-13 08:08:32 UTC)
第二步「編譯」,Conan 依序呼叫食譜中的 layout()、generate()、build() 這三個方法,分別對應到 CMake 的建置步驟。
你會在終端機看到一堆熟悉的 CMake 輸出,就是在編譯原始碼了。
最後一步「打包」,呼叫食譜中的 package() 方法。這裡其實就是呼叫 cmake --install:打包一個標頭檔,一個靜態庫。
package(): Packaged 1 '.h' file: super_lib.h
package(): Packaged 1 '.a' file: libsuper-lib.a
Full package reference: super-lib/0.1.0#3be5256d36c2aa67a2662bd503e29eea:38b8b2863892fd9462affa45e40edf183b436246#b8ea55c200632fd47bb7c55977b6cea0
仔細看最後一行 Full package reference,這就是我們昨天講解的四段結構:名稱/版本、Recipe Revision、Package ID、Package Revision。
看到了嗎?不過這次的長字串,是我們自己「煮」出來的喔。
剛剛打包的是 Conan Profile 指定的 Release 版。如果需要 Debug 版的話怎麼辦呢?很簡單,再編譯一包 Debug 二進位檔就好了。
conan create . -s build_type=Debug
Full package reference: super-lib/0.1.0#3be5256d36c2aa67a2662bd503e29eea:1c144980be8c0fb2eae6beafa245995736ac235d#a0542159742c5b8b1b653ee285a4fcaf
用指令 conan list "super-lib/0.1.0:*" 去查,你就會發現同一個 recipe revision 底下,現在有兩個 package ID:一個是 Release,一個是 Debug。
正好驗證了昨天講的,只要有一項編譯設定不同,就會產生另一份二進位檔,Conan 不會搞混這兩包。
好啦,現在我們切換到另一個專案,要透過 Conan 導入剛剛打包好的 super-lib 套件。
該怎麼做呢?
第一步就是在另一個專案的 conanfile.txt requires 區塊寫上我們自己的套件:
[requires]
super-lib/0.1.0
[generators]
CMakeDeps
CMakeToolchain
接著就是 CMakeLists.txt 要寫入 find_package() 以及 target_link_libraries():
cmake_minimum_required(VERSION 3.15)
project(app CXX)
find_package(super-lib REQUIRED)
add_executable(app src/main.cpp)
target_link_libraries(app PRIVATE super-lib::super-lib)
接下來的指令就跟之前一模一樣了。
conan install . --output-folder=build --build=missing
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build
吼吼~這次的 super-lib/0.1.0 是從我們自己的本機快取拿的,沒有從 ConanCenter 下載。
這次套件打包從頭到尾都是在本機進行的。打包完的套件會放在使用者家目錄下 ~/.conan2/p/ (Windows平台就是 C:\Users\YOUR_NAME\.conan2\p)
想知道 super-lib 套件確切放在哪,可以跑 conan cache path 命令:
$ conan cache path super-lib/0.1.0
/home/USER_NAME/.conan2/p/superec118a2baba2f/e
$ conan cache path super-lib/0.1.0:38b8b2863892fd9462affa45e40edf183b436246
/home/USER_NAME/.conan2/p/b/super9ca390f972d8d/p
只給套件名稱,印出的是食譜(recipe)的目錄。後面加上 package ID 才是二進位檔目錄。在這個目錄底下就能看到 include/ 和 lib/ 目錄以及實際的 .h 和 .a/.lib。
這個範例裡面我們用 CMake 來編譯套件函式庫,那麼一定要用 CMake 嗎?當然不是,你也可以用 Makefile, Autotools, MSBuild, Xcode, SCons 等等,Conan 支援非常多不同的建構系統來編譯套件,這裡我們就不一一細講,你只需要知道這事做得到,然後請 AI 協助你寫。