Conan是一個專為C/C++設計的開源、去中心化、跨平臺的包管理器,致力于簡化依賴管理和二進制分發流程。Conan基于Python進行開發,支持與主流的構建系統集成,提供了強大的跨平臺和交叉編譯能力。通過Conan,開發者可以高效的創建、共享和使用預編譯的二進制包,提升開發效率和協作體驗,尤其適合于復雜項目和多環境部署的場景。
下文將結合一個cmake構建系統的C++ Demo工程介紹conan安裝、基本概念及簡單使用,更多的示例和更復雜的應用需求建議查詢Conan用戶文檔。
Conan用戶文檔:https://docs.conan.io/2/index.html
一、安裝
pipx install conan
驗證安裝結果:
$ conan -v
Conan version 2.20.0
Conan1.x和Conan2.x不兼容,默認是conan2.x,如果使用Conan1.x可以指定版本安裝
pipx install conan==1.66.0
二、概念和配置
1、常用命令(commands)
- conan config: 管理conan的配置(遠程、設置、插件等)
# 指定目錄安裝conan配置文件: conan config install <config_path>
- conan profile: 顯示和管理profile文件
# 查看所有的profile文件 conan profile list
- conan remove: 移除包從本地緩存或遠程
# 移除指定的包 conan remove <name> # 移除指定版本的包 conan remove <name>/<version>
- conan version: 查看conan客戶端的版本信息
$ conan version version: 2.20.0 conan_path: /root/.local/bin/conan pythonversion: 3.12.3sys_version: 3.12.3 (main, Aug 14 2025, 17:47:21) [GCC 13.3.0]sys_executable: /root/.local/share/pipx/venvs/conan/bin/pythonis_frozen: Falsearchitecture: x86_64 systemversion: #149~20.04.1-Ubuntu SMP Wed Apr 16 08:29:56 UTC 2025platform: Linux-5.15.0-139-generic-x86_64-with-glibc2.39system: Linuxrelease: 5.15.0-139-genericcpu: x86_64
- conan create: 從一個配方文件創建一個包
# 當二進制不存在時構建 conan create <project_path> -pr=<profile_file> --build=missing
2、配方文件(conanfile.py)
conanfile.py是一個包的配方,負責定義怎么定義和消費一個包。
from conan import ConanFileclass HelloConan(ConanFile):...
conanfile.py使用了多種屬性(attributes)和方法(methods)用于操作。為了避免沖突,請遵循一下規則:
- 公共屬性和方法,像build(),self.package_folder,是conan保留的。不要在配方中使用這些公共成員作為自定義屬性或方法。
- 對你自己的成員使用“protected”訪問,像self._my_data或def _my_helper(self):。Conan只保留“_conan”作為保護成員的開始。
(1)屬性(attributes)
conanfile.py Attributes文檔:https://docs.conan.io/2/reference/conanfile/attributes.html
Attribute | 說明 |
---|---|
name | 包的名字 |
version | 包的版本 |
description | 包的描述信息 |
license | 包的license信息 |
author | 包的作者信息 |
setting | 列舉第一層的配置信息(來自setting.yml),這些值將被用于計算package id |
options | 定義option的名字及允許的值,默認任何值改變都將影響package id |
default_options | 定義options的默認值 |
generators | 描述所需的生成器名字 |
… |
注:Attribute一般提供簡單的功能,對于復雜的需求可以使用功能相似的Method實現。
(2)方法(methods)
conanfile.py Methods文檔:https://docs.conan.io/2/reference/conanfile/methods.html
Mathod | 說明 |
---|---|
build() | 包含了從源碼構建包的構建指令 |
build_requirements() | 定義了tool_requires和test_requires |
configure() | 允許在計算依賴時進行配置和選擇 |
deploy() | 從package中復制指定文件到特定目錄 |
generate() | 生成構建包時所必須的文件 |
layout() | 定義工程相關的源文件夾、build文件夾等 |
package() | 從build文件夾copy文件到package文件夾 |
requirements() | 定義依賴的包 |
set_name() | 動態定義包的名字 |
set_version() | 動態定義包的版本 |
system_requirements() | 調用系統包管理(比如apt)安裝系統包 |
test() | 運行簡單的包測試 |
… | … |
(3)Running命令
對于系統命令,Conan提供了self.run()方法,支持在指定環境中運行相應的系統命令,并且當命令執行錯誤時,支持拋出異常以便錯誤能夠被及時發現。
run(self, command: str, stdout=None, cwd=None, ignore_errors=False, env='', quiet=False, shell=True, scope='build', stderr=None)
- command – 待運行的命令字符串.
- stdout – 支持將標準輸出重定向,默認輸出到標準輸出流。
- stderr – 支持將錯誤輸出重定向,默認輸出到標準錯誤流。
- cwd – 指定運行命令的工作空間。
- ignore_errors – 如果為Ture,命令執行錯誤也將不拋出異常。
- env – 要使用的環境文件,當scope為build時默認為conanbuild,否則scope為run默認使用conanrun。如果明確設置為None則不會使用任何環境文件。
- quiet – 如果為True,將屏蔽該命令的輸出。
- shell – 如果為True,將在一個shell中運行該命令。這將會被傳遞給底層的popen函數。
- scope – 這個命令的范圍,只能是“build”或者“run”。用于指定命令執行時所處的環境作用域。它們決定了命令執行時使用的環境變量集合。(這些環境變量通常在generate()階段生成并保存在相應腳本中)
(4)從配方輸出文本
Conan建議使用self.output代替print()從配方中輸出文本信息。self.output下的成員方法有:
error(self, msg:str, error_type:str=None)
warning(self, msg:str, warn_tag:str=None)
info(self, msg:str, fg:str=None, bg:str=None)status(self, msg:str, fg:str=None, bg:str=None)
verbose(self, msg:str, fg:str=None, bg:str=None)
debug(self, msg:str, fg:str='\x1b[35m',bg:str=None)
trace(self, msg:str)success(self, msg:str)
highlight(self, msg:str)
(5)配方工具
配方工具文檔:https://docs.conan.io/2/reference/tools.html
配方工具是指能夠在conan配方中引用的工具,比如:
from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake, cmake_layout
from conan.tools.env import Environment, EnvVars, VirtualBuildEnv, VirtualRunEnv
from conan.tools.files import *
from conan.tools.scm import Git, Version
from conan.tools.system import Apt
注:conanfile.py還有一個對功能簡單的版本:conanfile.txt,便于對依賴項的簡單管理使用,不能用于創建軟件包。
3、配置文件
(1)global.conf
global.conf文件位于Conan的家目錄,~/.conan2/global.conf。如果不存在將自動創建一個。global.conf文件的目標是存在一些核心(core)、工具(tool)及用戶(user)的配置變量,這些變量也將會被Conan使用。
- core.*:旨在配置 Conan 核心行為的參數(下載重試次數、包標識模式等)。僅能在global.conf文件中進行定義。
- tool.*: 旨在配置 Conan 工具(工具鏈、構建輔助程序等)在您的配方中所使用的值。可在global.conf和配置文件中進行定義。
- user.*: 旨在定義個人用戶配置。用戶可以自行設定任何所需內容。這些配置可在global.conf文件和配置文件中進行設定。
使用命令conan config list
可以查看當前的所有配置。
(2)profiles
Conan配置文件允許用戶在文件中為設置、選項、環境變量(包括構建時和運行時環境)以及工具需求和配置變量設定一個完整的配置集。
[settings]
arch=x86_64
build_type=Release
os=Macos[options]
mylib/*:shared=True[tool_requires]
tool1/0.1@user/channel
*: tool4/0.1@user/channel[buildenv]
VAR1=value[runenv]
EnvironmentVar1=My Value[conf]
tools.build:jobs=2[replace_requires]
zlib/1.2.12: zlib/[*][replace_tool_requires]
7zip/*: 7zip/system[platform_requires]
dlib/1.3.22[platform_tool_requires]
cmake/3.24.2
注:對不需要特定設置section,可以不在profile中聲明。
(3)settings.yml
# This file was generated by Conan. Remove this comment if you edit this file or Conan
# will destroy your changes.
os:Windows:subsystem: [null, cygwin, msys, msys2, wsl]WindowsStore:version: ["8.1", "10.0"]WindowsCE:platform: [ANY]version: ["5.0", "6.0", "7.0", "8.0"]Linux:iOS:version: &ios_version["7.0", "7.1", "8.0", "8.1", "8.2", "8.3", "8.4", "9.0", "9.1", "9.2", "9.3","10.0", "10.1", "10.2", "10.3","11.0", "11.1", "11.2", "11.3", "11.4","12.0", "12.1", "12.2", "12.3", "12.4", "12.5","13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7","14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7", "14.8","15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6", "15.7", "15.8","16.0", "16.1", "16.2", "16.3", "16.4", "16.5", "16.6", "16.7","17.0", "17.1", "17.2", "17.3", "17.4", "17.5", "17.6", "17.8","18.0", "18.1", "18.2", "18.3", "18.4", "18.5", "18.6"]sdk: ["iphoneos", "iphonesimulator"]sdk_version: [null, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4","13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7","14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "15.0", "15.2", "15.4","15.5", "16.0", "16.1", "16.2", "16.4", "17.0", "17.1", "17.2", "17.4", "17.5","18.0", "18.1", "18.2", "18.4", "18.5"]watchOS:version: ["4.0", "4.1", "4.2", "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2", "6.3","7.0", "7.1", "7.2", "7.3", "7.4", "7.5", "7.6","8.0", "8.1", "8.3", "8.4", "8.5", "8.6", "8.7","9.0","9.1", "9.2", "9.3", "9.4", "9.5", "9.6","10.0", "10.1", "10.2", "10.3", "10.4", "10.5", "10.6","11.0", "11.1", "11.2", "11.3", "11.4", "11.5", "11.6"]sdk: ["watchos", "watchsimulator"]sdk_version: [null, "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2","7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.0.1", "8.3", "8.5", "9.0", "9.1","9.4", "10.0", "10.1", "10.2", "10.4", "10.5","11.0", "11.1", "11.2", "11.4", "11.5"]tvOS:version: ["11.0", "11.1", "11.2", "11.3", "11.4","12.0", "12.1", "12.2", "12.3", "12.4","13.0", "13.2", "13.3", "13.4","14.0", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7","15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6","16.0", "16.1", "16.2", "16.3", "16.4", "16.5", "16.6","17.0", "17.1", "17.2", "17.3", "17.4", "17.5", "17.6","18.0", "18.1", "18.2", "18.3", "18.4", "18.5", "18.6"]sdk: ["appletvos", "appletvsimulator"]sdk_version: [null, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4","13.0", "13.2", "13.3", "13.4", "14.0", "14.2", "14.3", "14.4", "14.5", "15.0","15.2", "15.4", "15.5", "16.0", "16.1", "16.4", "17.0", "17.1", "17.2", "17.4", "17.5","18.0", "18.1", "18.2", "18.4", "18.5"]visionOS:version: ["1.0", "1.1", "1.2", "1.3", "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6"]sdk: ["xros", "xrsimulator"]sdk_version: [null, "1.0", "1.1", "1.2", "1.3", "2.0", "2.1", "2.2", "2.4", "2.5"]Macos:version: [null, "10.6", "10.7", "10.8", "10.9", "10.10", "10.11", "10.12", "10.13", "10.14", "10.15","11.0", "11.1", "11.2", "11.3", "11.4", "11.5", "11.6", "11.7","12.0", "12.1", "12.2", "12.3", "12.4", "12.5", "12.6", "12.7","13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7","14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7","15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6"]sdk_version: [null, "10.13", "10.14", "10.15", "11.0", "11.1", "11.2", "11.3", "12.0", "12.1","12.3", "12.4", "13.0", "13.1", "13.3", "14.0", "14.2", "14.4", "14.5","15.0", "15.1", "15.2", "15.4", "15.5"]subsystem:null:catalyst:ios_version: *ios_versionAndroid:api_level: [ANY]ndk_version: [null, ANY]FreeBSD:SunOS:AIX:Arduino:board: [ANY]Emscripten:Neutrino:version: ["6.4", "6.5", "6.6", "7.0", "7.1"]baremetal:VxWorks:version: ["7"]
arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64,armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, arm64ec,sparc, sparcv9,mips, mips64, avr, s390, s390x, asm.js, wasm, wasm64, sh4le,e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7,riscv64, riscv32,xtensalx6, xtensalx106, xtensalx7,tc131, tc16, tc161, tc162, tc18]
compiler:sun-cc:version: ["5.10", "5.11", "5.12", "5.13", "5.14", "5.15"]threads: [null, posix]libcxx: [libCstd, libstdcxx, libstlport, libstdc++]gcc:version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9","5", "5.1", "5.2", "5.3", "5.4", "5.5","6", "6.1", "6.2", "6.3", "6.4", "6.5","7", "7.1", "7.2", "7.3", "7.4", "7.5","8", "8.1", "8.2", "8.3", "8.4", "8.5","9", "9.1", "9.2", "9.3", "9.4", "9.5","10", "10.1", "10.2", "10.3", "10.4", "10.5","11", "11.1", "11.2", "11.3", "11.4", "11.5","12", "12.1", "12.2", "12.3", "12.4", "12.5","13", "13.1", "13.2", "13.3", "13.4","14", "14.1", "14.2", "14.3","15", "15.1", "15.2"]libcxx: [libstdc++, libstdc++11]threads: [null, posix, win32, mcf] # Windows MinGWexception: [null, dwarf2, sjlj, seh] # Windows MinGWcppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]msvc:version: [170, 180, 190, 191, 192, 193, 194]update: [null, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]runtime: [static, dynamic]runtime_type: [Debug, Release]cppstd: [null, 14, 17, 20, 23]toolset: [null, v110_xp, v120_xp, v140_xp, v141_xp]cstd: [null, 11, 17]clang:version: ["3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4.0","5.0", "6.0", "7.0", "7.1","8", "9", "10", "11", "12", "13", "14", "15", "16", "17","18", "19", "20", "21"]libcxx: [null, libstdc++, libstdc++11, libc++, c++_shared, c++_static]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]runtime: [null, static, dynamic]runtime_type: [null, Debug, Release]runtime_version: [null, v140, v141, v142, v143, v144]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]apple-clang:version: ["5.0", "5.1", "6.0", "6.1", "7.0", "7.3", "8.0", "8.1", "9.0", "9.1","10.0", "11.0", "12.0", "13", "13.0", "13.1", "14", "14.0", "15", "15.0","16", "16.0", "17", "17.0"]libcxx: [libstdc++, libc++]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]intel-cc:version: ["2021.1", "2021.2", "2021.3", "2021.4", "2022.1", "2022.2","2022.3", "2023.0", "2023.1", "2023.2", "2024.0", "2024.1","2025.0", "2025.1"]update: [null, ANY]mode: ["icx", "classic", "dpcpp"]libcxx: [null, libstdc++, libstdc++11, libc++]cppstd: [null, 98, gnu98, "03", gnu03, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]runtime: [null, static, dynamic]runtime_type: [null, Debug, Release]qcc:version: ["4.4", "5.4", "8.3"]libcxx: [cxx, gpp, cpp, cpp-ne, accp, acpp-ne, ecpp, ecpp-ne]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17]mcst-lcc:version: ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24", "1.25"]libcxx: [libstdc++, libstdc++11]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]emcc:# From https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md# There is no ABI compatibility guarantee between versionsversion: [ANY]libcxx: [null, libstdc++, libstdc++11, libc++]threads: [null, posix, wasm_workers]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]build_type: [null, Debug, Release, RelWithDebInfo, MinSizeRel]
通過settings.yml文件,設置的可能值都在同一個文件中定義。這樣做是為了確保名稱和拼寫的一致性,并在用戶和開源軟件社區之間建立一個統一的設置模型。
對于設置的一些特殊信息:
- 如果某個設置允許設置為任意值,那么就可以使用“ANY”這個選項。
- 如果某個設置允許設置為任意值,或者也可以不進行設置,那么您可以使用 [null, ANY] 這種組合。
這個配置文件可以根據任何需求進行修改,包括添加新的設置或子設置及其值。如果希望使用工程中的settings.yml文件,可以使用conan config install
命令將指定的setting.yml文件安裝(覆蓋)到Conan家目錄。
4、環境變量
可用于配置 Conan 某些行為的環境變量非常少。這些環境變量屬于例外情況,對于自定義和配置控制,Conan使用global.conf配置以及profile文件的[conf]部分。
環境變量 | 說明 |
---|---|
CONAN_HOME | 控制Conan的家目錄,默認沒有定義,使用~/.conan2 |
CONAN_DEFAULT_PROFILE | 指定一個不同于“default” 的默認profile名 |
… |
5、二進制模型
二進制模型是Conan包管理的核心。它通過對profile配置(setting + options + dependencies versions)進行哈希運算獲取package_id,確定了包的唯一性。
而profile中,各配置項保證了C/C++ API接口的兼容性,ABI接口的兼容性,從而實現對二進制文件的管理和分發。
另外Conan二進制模型具有可擴展性,用戶可以定義自定義設置、選項和配置,以塑造其自身二進制文件的特性。
三、一個完整的工程demo
1、創建cmake工程
(1)創建工程
- C++源文件
// source/main.cpp
#include <iostream>
#include <cstdint>std::int32_t main(void)
{std::cout << "Hello World!" << std::endl;return 0;
}
- C++測試文件
// test/main.cpp
#include <gtest/gtest.h>TEST(ExampleTest, StringTest) {std::string str = "Hello";EXPECT_EQ(str, "Hello");EXPECT_NE(str, "World");
}int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
- cmake文件
# CMakeLists.txt
cmake_minimum_required(VERSION 3.28)project(ConanDemo VERSION 1.0.0 LANGUAGES CXX)set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)add_executable(${PROJECT_NAME})
target_sources(${PROJECT_NAME}PRIVATEsource/main.cpp
)set_target_properties(${PROJECT_NAME}PROPERTIESRUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)find_package(GTest)add_executable(${PROJECT_NAME}_test)
target_sources(${PROJECT_NAME}_testPRIVATEtest/main.cpp
)target_link_libraries(${PROJECT_NAME}_testPRIVATEGTest::gtest_main
)set_target_properties(${PROJECT_NAME}_testPROPERTIESRUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)enable_testing()
add_test(NAME ${PROJECT_NAME}_testCOMMAND ${PROJECT_NAME}_test
)
- 當前工程結構
$ tree
.
|-- CMakeLists.txt
|-- source
| `-- main.cpp
`-- test`-- main.cpp
(2)基于cmake構建驗證
# 配置cmake
cmake -S . -B build
# 構建目標
cmake --build build
# 運行test
cmake --build build --target test
2、添加conan管理
(1)設計conan配置文件
- setting.yml文件
os:Linux:platform: [null, host, pi4]
arch: [x86_64, armv7, armv7hf, armv8, armv8_32, riscv64, riscv32]
compiler:gcc:version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9","5", "5.1", "5.2", "5.3", "5.4", "5.5","6", "6.1", "6.2", "6.3", "6.4", "6.5","7", "7.1", "7.2", "7.3", "7.4", "7.5","8", "8.1", "8.2", "8.3", "8.4", "8.5","9", "9.1", "9.2", "9.3", "9.4", "9.5","10", "10.1", "10.2", "10.3", "10.4", "10.5","11", "11.1", "11.2", "11.3", "11.4", "11.5","12", "12.1", "12.2", "12.3", "12.4", "12.5","13", "13.1", "13.2", "13.3", "13.4","14", "14.1", "14.2", "14.3","15", "15.1", "15.2"]libcxx: [libstdc++, libstdc++11]threads: [null, posix, win32, mcf] # Windows MinGWexception: [null, dwarf2, sjlj, seh] # Windows MinGWcppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]clang:version: ["3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4.0","5.0", "6.0", "7.0", "7.1","8", "9", "10", "11", "12", "13", "14", "15", "16", "17","18", "19", "20", "21"]libcxx: [null, libstdc++, libstdc++11, libc++, c++_shared, c++_static]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]runtime: [null, static, dynamic]runtime_type: [null, Debug, Release]runtime_version: [null, v140, v141, v142, v143, v144]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]build_type: [null, Debug, Release, RelWithDebInfo]
- profile文件
# host_x86_64
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux
os.platform=host
# pi4_aarch64
[settings]
arch=armv8
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux
os.platform=pi4
(2)添加conanfile.py文件
# conanfile.py
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDepsclass ConanDemo(ConanFile):name = "hello"version = "1.0"# Optional metadatalicense = "<Put the package license here>"author = "<Put your name here> <And your email here>"url = "<Package recipe repository url here, for issues about the package>"description = "<Description of hello package here>"topics = ("<Put some tag here>", "<here>", "<and here>")# Binary configurationsettings = "os", "compiler", "build_type", "arch"options = {"shared": [True, False], "fPIC": [True, False]}default_options = {"shared": False, "fPIC": True}# Sources are located in the same place as this recipe, copy them to the recipeexports_sources = "CMakeLists.txt", "source/*", "test/*"def config_options(self):passdef layout(self):cmake_layout(self)def generate(self):deps = CMakeDeps(self)deps.generate()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 = ["hello"]
(3)安裝配置文件
- 當前的工程結構
$ tree
.
|-- CMakeLists.txt
|-- conan
| |-- profiles
| | |-- host_x86_64
| | `-- pi4_aarch64
| `-- settings.yml
|-- conanfile.py
|-- source
| `-- main.cpp
`-- test`-- main.cpp
- 安裝Conan配置
# 創建默認的profile
conan profile detect
# 安裝指定的conan配置
conan config install conan
注:conan config install conan
會將conan文件下的所有文件復制到Conan的家目錄。
- 檢查安裝的profile
$ conan profile list
Profiles found in the cache:
default
host_x86_64
pi4_aarch64
(4)基于conan創建包
- 執行命令
# 清除已有構建
conan remove hello# 使用默認的profile創建包
conan create .
# 使用host_x86_64創建包
conan create . -pr=host_x86_64
# 使用pi4_aarch64創建包
conan create . -pr=pi4_aarch64
- 檢查conan包
$ tree ~/.conan2/p -L 2
/root/.conan2/p
|-- b
| |-- hello97f3ea6988f96
| |-- hello9cf30133a2f6d
| `-- hellob394c1d27f95b
|-- cache.sqlite3
|-- hello066c562205912
| |-- d
| |-- e
| |-- es
| `-- s
`-- t
conan cache中還是包含挺多文件:工程的源碼文件、conan的生成文件、構建后的輸出文件等,可以在自己本地搭建環境運行后自行查看。