Conan 实战:从零开始使用第三方包

📅 发布时间:2026/8/17 16:56:12
Conan 实战:从零开始使用第三方包 原文Conan Documentation — Release 2.29.0本节展示了如何使用 Conan 管理依赖项来构建你的项目。我们将从一个使用 CMake 并依赖 zlib 库的基础 C 项目示例开始。该项目将使用一个 conanfile.txt 文件来声明其依赖项。我们还将介绍如何不仅在 Conan 中使用“常规”库还能管理你在构建过程中可能需要使用的工具例如 CMake、msys2、MinGW 等。然后我们将解释不同的 Conan 概念如 settings 和 options以及如何使用它们为不同的配置如 Debug、Release、使用静态库或动态库等构建项目。此外我们还将解释如何从我们在第一个示例中使用的 conanfile.txt 文件过渡到功能更强大的 conanfile.py。之后我们将介绍 Conan 的构建build和宿主hostprofile 的概念并解释如何使用它们将你的应用程序交叉编译到不同的平台。然后在“版本控制简介”中我们将了解如何使用不同的版本、使用版本范围定义需求、修订版revisions的概念以及对 lockfile锁定文件的简要介绍以实现依赖关系图的可复现性。第一步环境准备安装 Conan# 推荐使用 pip 安装$ pipinstallconan# 检查是否安装成功$ conan--versionConan version2.29.0新手常见错误如果提示conan: command not found说明 Python 脚本目录不在 PATH 中。Linux/macOS 尝试source ~/.profileWindows 尝试重启终端或手动将 Python Scripts 目录加入 PATH创建默认 profileConan 需要一个配置文件来知道你的编译器信息$ conan profile detect--force输出示例macOSFound apple-clang 14.0 apple-clang13, using the major as version Detected profile: [settings] archx86_64 build_typeRelease compilerapple-clang compiler.cppstdgnu17 compiler.libcxxlibc compiler.version14 osMacos输出示例WindowsFound msvc 19.38 Detected profile: [settings] archx86_64 build_typeRelease compilermsvc compiler.cppstdgnu17 compiler.runtimedynamic compiler.version193 osWindows查看生成的 profile 文件$ conan profile path default /Users/user/.conan2/profiles/default# Linux/macOSC:\Users\user\.conan2\profiles\default# Windows注意如果系统有多个编译器如 GCC 和 Clangconan profile detect会选一个。你可以手动编辑 profile 文件来切换编译器。第二步第一个 Conan 项目 — 字符串压缩器我们创建一个使用 zlib 库进行字符串压缩的 C 语言程序。获取示例代码$gitclone https://github.com/conan-io/examples2.git $cdexamples2/tutorial/consuming_packages/simple_cmake_project项目结构. ├── CMakeLists.txt ├── src │ └── main.c查看项目文件src/main.c— 使用 zlib 压缩字符串#includestdlib.h#includestdio.h#includestring.h#includezlib.hintmain(void){charbuffer_in[256]{Conan is a MIT-licensed, Open Source package manager for C and C development...};charbuffer_out[256]{0};z_stream defstream;defstream.zallocZ_NULL;defstream.zfreeZ_NULL;defstream.opaqueZ_NULL;defstream.avail_in(uInt)strlen(buffer_in);defstream.next_in(Bytef*)buffer_in;defstream.avail_out(uInt)sizeof(buffer_out);defstream.next_out(Bytef*)buffer_out;deflateInit(defstream,Z_BEST_COMPRESSION);deflate(defstream,Z_FINISH);deflateEnd(defstream);printf(Uncompressed size is: %lu\n,strlen(buffer_in));printf(Compressed size is: %lu\n,strlen(buffer_out));printf(ZLIB VERSION: %s\n,zlibVersion());returnEXIT_SUCCESS;}CMakeLists.txt— 构建配置cmake_minimum_required(VERSION 3.15) project(compressor C) find_package(ZLIB REQUIRED) add_executable(${PROJECT_NAME} src/main.c) target_link_libraries(${PROJECT_NAME} ZLIB::ZLIB)创建 conanfile.txt在项目根目录创建conanfile.txt[requires] zlib/1.3.1 [generators] CMakeDeps CMakeToolchain字段说明[requires]声明项目需要的依赖包格式为包名/版本号[generators]告诉 Conan 生成哪些辅助文件CMakeDeps生成 CMake 的find_package()配置文件CMakeToolchain生成 CMake 工具链文件传递编译设置安装依赖$ conaninstall.--output-folderbuild--buildmissing参数说明.使用当前目录下的conanfile.txt--output-folderbuild生成的辅助文件放到build目录--buildmissing如果本地没有缓存的二进制包则从源码构建完整输出-------- Computing dependency graph ---------- zlib/1.3.1: Not found in local cache, looking in remotes... zlib/1.3.1: Checking remote: conancenter zlib/1.3.1: Trying with conancenter... Downloading conanmanifest.txt Downloading conanfile.py Downloading conan_export.tgz Decompressing conan_export.tgz zlib/1.3.1: Downloaded recipe revision f1fadf0d3b196dc0332750354ad8ab7b Graph root conanfile.txt: .../simple_cmake_project/conanfile.txt Requirements zlib/1.3.1#f1fadf0d3b196dc0332750354ad8ab7b - Downloaded (conancenter) -------- Computing necessary packages ---------- Requirements zlib/1.3.1#f1fadf0d3b196dc0332750354ad8ab7b:cdc9a35e010a17fc90bb845108cf86cfcbce64bf #dd7bf2a1ab4eb5d1943598c09b616121 - Download (conancenter) -------- Installing packages ---------- Installing (downloading, building) binaries... zlib/1.3.1: Retrieving package cdc9a35e0... from remote conancenter Downloading conanmanifest.txt Downloading conaninfo.txt Downloading conan_package.tgz Decompressing conan_package.tgz zlib/1.3.1: Package installed cdc9a35e0... zlib/1.3.1: Downloaded package revision dd7bf2a1ab4eb5d1943598c09b616121 -------- Finalizing install (deploy, generators) ---------- conanfile.txt: Generator CMakeToolchain calling generate() conanfile.txt: Generator CMakeDeps calling generate() conanfile.txt: Generating aggregated env files发生了什么Conan 从远程仓库 ConanCenter 下载了 zlib 的 recipe配方文件下载了与你的平台/配置匹配的预编译二进制包在build/目录生成了 CMake 工具链和依赖配置文件常见错误ERROR: zlib/1.3.1 not found in remotes— 网络问题检查能否访问center2.conan.ioERROR: Package binary could not be found— 你的平台没有预编译包尝试加上--buildmissing构建项目WindowsVisual Studio$cdbuild $ cmake..-GVisual Studio 17 2022-DCMAKE_TOOLCHAIN_FILEconan_toolchain.cmake$ cmake--build.--configRelease...[100%]Built target compressor $ Release\compressor.exe Uncompressed size is:233Compressed size is:147ZLIB VERSION:1.3.1Linux/macOS$cdbuild $ cmake..-DCMAKE_TOOLCHAIN_FILEconan_toolchain.cmake-DCMAKE_BUILD_TYPERelease $ cmake--build....[100%]Built target compressor $ ./compressor Uncompressed size is:233Compressed size is:147ZLIB VERSION:1.3.1成功了你刚刚用 Conan 管理了第一个 C 项目的外部依赖。使用 CMake Presets可选CMake 3.23Conan 的CMakeToolchain生成器还会生成 CMake presets 文件。如果使用较新版本的 CMake可以更简洁地构建# 查看可用的 presets$ cmake --list-presets# 直接使用 preset 构建$ cmake--presetdefault $ cmake--build--presetdefault第三步使用构建工具作为 Conan 包有时你需要使用特定版本的工具如 CMake来构建项目。Conan 可以通过tool_requires管理构建工具。切换到示例目录$cdexamples2/tutorial/consuming_packages/tool_requiresconanfile.txt[requires] zlib/1.3.1 [tool_requires] cmake/3.27.9 [generators] CMakeDeps CMakeToolchain注意[tool_requires]中的工具只用于当前项目的构建。如果 zlib 需要从源码构建Conan 不会用这个 CMake 版本来构建 zlib——它会用系统 CMake。CMakeLists.txt新增版本显示cmake_minimum_required(VERSION 3.15) project(compressor C) find_package(ZLIB REQUIRED) message(Building with CMake version: ${CMAKE_VERSION}) add_executable(${PROJECT_NAME} src/main.c) target_link_libraries(${PROJECT_NAME} ZLIB::ZLIB)安装依赖$ conaninstall.--output-folderbuild--buildmissing输出-------- Computing dependency graph ---------- cmake/3.27.9: Not found in local cache, looking in remotes... cmake/3.27.9: Checking remote: conancenter cmake/3.27.9: Trying with conancenter... Downloading conanmanifest.txt Downloading conanfile.py cmake/3.27.9: Downloaded recipe revision 3e3d8f3a848b2a60afafbe7a0955085a Graph root conanfile.txt: .../tool_requires/conanfile.txt Requirements zlib/1.3.1#f1fadf0d3b196dc0332750354ad8ab7b - Cache Build requirements cmake/3.27.9#3e3d8f3a848b2a60afafbe7a0955085a - Downloaded (conancenter) -------- Installing packages ---------- cmake/3.27.9: ... - Download (conancenter) ... zlib/1.3.1: Already installed! -------- Finalizing install ---------- conanfile.txt: Generator CMakeToolchain calling generate() conanfile.txt: Generator CMakeDeps calling generate()可以看到 Conan 自动生成了一个conanbuild.{sh,bat}环境激活脚本。激活环境并使用指定的 CMake 版本Windows$cdbuild $ conanbuild.bat# 或者 if using Powershell: conanbuild.ps1Linux/macOS$cdbuild $sourceconanbuild.sh Capturing current environmentindeactivate_conanbuildenv-release-x86_64.sh Configuring environment variables验证 CMake 版本$ cmake--versioncmake version3.27.9构建项目Windows$ cmake..-GVisual Studio 17 2022-DCMAKE_TOOLCHAIN_FILEconan_toolchain.cmake $ cmake--build.--configRelease... Building with CMake version:3.27.9...[100%]Built target compressor $ Release\compressor.exe Uncompressed size is:233Compressed size is:147ZLIB VERSION:1.3.1Linux/macOS$ cmake..-DCMAKE_TOOLCHAIN_FILEconan_toolchain.cmake-DCMAKE_BUILD_TYPERelease $ cmake--build.... Building with CMake version:3.27.9...[100%]Built target compressor $ ./compressor Uncompressed size is:233Compressed size is:147ZLIB VERSION:1.3.1还原环境# Windows$ deactivate_conanbuild.bat# Linux/macOS$sourcedeactivate_conanbuild.sh Restoring environment $ cmake--versioncmake version3.22.0第四步多配置构建 — Debug / Release / 静态 / 共享查看默认 profile$ conan config home Current Conan home: /Users/user/.conan2 $cat/Users/user/.conan2/profiles/default[settings]osMacosarchx86_64compilerapple-clangcompiler.version14.0compiler.libcxxlibccompiler.cppstdgnu11build_typeRelease创建 Debug profile创建文件conan home/profiles/debug[settings] osMacos archx86_64 compilerapple-clang compiler.version14.0 compiler.libcxxlibc compiler.cppstdgnu11 build_typeDebug使用命令行设置构建配置不创建 profile切换目录$cdexamples2/tutorial/consuming_packages/different_configurations安装 Debug 配置$ conaninstall.--output-folderbuild--buildmissing--settingsbuild_typeDebug安装 Release 配置$ conaninstall.--output-folderbuild--buildmissing--settingsbuild_typeRelease使用共享库shared libraries$ conaninstall.--output-folderbuild--buildmissing--optionszlib/*:sharedTrue运行共享库版本时注意共享库在运行时需要能找到.dll/.dylib/.so文件。Conan 会自动生成conanrun.{sh,bat}脚本来设置环境变量# Linux/macOS$sourceconanrun.sh $ ./compressor# Windows$ conanrun.bat $ Release\compressor.exe如果忘记激活环境会报错WindowsThe code execution cannot proceed because zlib1.dll was not foundLinuxerror while loading shared libraries: libz.so.1: cannot open shared object filemacOSLibrary not loaded: rpath/libz.1.dylibSettings vs Options — 关键区别SettingsOptions范围项目全局由客户端机器定义包级别可在 recipe 中设置默认值示例操作系统、架构、编译器、构建类型shared共享/静态、fPIC能否在 recipe 中设默认值不能由消费者决定能比如默认静态链接Package ID 是如何工作的Conan 根据 settings、options 和依赖计算出一个哈希值作为package_id不同配置 → 不同的 package_id → 不同的二进制包 build_typeRelease → package_id abc123... build_typeDebug → package_id def456... sharedTrue → package_id ghi789...这就是为什么 zlib 的 Release 和 Debug 版本是不同的二进制包。以下是该过程的详细说明确定设置和选项Conan 首先检索用户输入的设置和选项。这些可以来自命令行或配置文件例如 –settingsbuild_typeDebug 或 –profiledebug。计算 Package ID利用当前的 settings、options 和依赖项的值Conan 计算出一个哈希值。该哈希值用作 package_id代表二进制包的唯一身份。获取二进制文件然后Conan 检查其缓存或指定的远程仓库查找具有计算出的 package_id 的二进制包。如果找到匹配项它就会检索该二进制文件。如果没有Conan 可以从源码构建该包或指示二进制文件缺失。第五步从 conanfile.txt 升级到 conanfile.pyconanfile.txt简单但功能有限conanfile.py可以用 Python 代码实现条件依赖、动态配置等高级功能。切换到示例目录$cdexamples2/tutorial/consuming_packages/conanfile_py对比conanfile.txt vs conanfile.pyconanfile.txt[requires] zlib/1.3.1 [tool_requires] cmake/3.27.9 [generators] CMakeDeps CMakeToolchain等效的 conanfile.pyfromconanimportConanFileclassCompressorRecipe(ConanFile):settingsos,compiler,build_type,archgeneratorsCMakeToolchain,CMakeDepsdefrequirements(self):self.requires(zlib/1.3.1)defbuild_requirements(self):self.tool_requires(cmake/3.27.9)conanfile.py 的优势 — 条件依赖fromconanimportConanFileclassCompressorRecipe(ConanFile):settingsos,compiler,build_type,archgeneratorsCMakeToolchain,CMakeDepsdefrequirements(self):self.requires(zlib/1.3.1)ifself.settings.osWindows:self.requires(base64/0.4.0)defbuild_requirements(self):ifself.settings.os!Windows:self.tool_requires(cmake/3.27.9)第六步交叉编译交叉编译就是在一个平台上构建另一个平台能运行的程序。Conan 使用两个 profile 来实现--profile:build当前构建机器的 profile--profile:host目标运行平台的 profile例如从 x86_64 Linux 为 ARMv7 交叉编译$ conan profile detect--force--profileprofile_armv7 $ conaninstall.--profile:builddefault--profile:hostprofile_armv7完整示例从 x86_64 Linux 编译到 ARM Raspberry Pibuild profile (default)[settings] osLinux archx86_64 compilergcc compiler.version12 compiler.libcxxlibstdc11 compiler.cppstdgnu17 build_typeReleasehost profile (raspberry)[settings] osLinux archarmv7hf compilergcc compiler.version12 compiler.libcxxlibstdc11 compiler.cppstdgnu17 build_typeRelease [buildenv] CCarm-linux-gnueabihf-gcc-12 CXXarm-linux-gnueabihf-g-12 LDarm-linux-gnueabihf-ld安装依赖$ conaninstall.--buildmissing-pr:bdefault-pr:h./profiles/raspberry构建$cdbuild $sourceRelease/generators/conanbuild.sh Capturing current environmentindeactivate_conanbuildenv-release-armv7hf.sh Configuring environment variables $ cmake..-DCMAKE_TOOLCHAIN_FILERelease/generators/conan_toolchain.cmake-DCMAKE_BUILD_TYPERelease $ cmake--build.... -- The C compiler identification is GNU12.4.0 -- Checkforworking C compiler: /usr/bin/arm-linux-gnueabihf-gcc-12 - skipped...[100%]Built target compressor验证$filecompressor compressor: ELF32-bit LSB shared object, ARM, EABI5 version1(SYSV), dynamically linked,...第七步版本管理介绍版本范围defrequirements(self):self.requires(zlib/[~1.2])范围解析示例$ conaninstall.Graph root conanfile.py:.../conanfile.py Requirements zlib/1.2.12#87a7211557b6690ef5bf7fc599dd8349 - DownloadedResolved version ranges zlib/[~1.2]: zlib/1.2.12常用范围表达式表达式含义匹配示例[1.0 2.0]在范围内1.0, 1.5, 1.9[~1.2]近似 1.2.x1.2.8, 1.2.12[~1]近似 1.x1.3, 1.8[^2.5]2.5 ❤️.02.5.0, 2.9[3.10]大于 3.103.11, 3.27.9Revisions修订版本$ conan listzlib/1.2.12#*-rconancenter conancenter zlib zlib/1.2.12 revisions 82202701ea360c0863f1db5008067122(2022-03-2915:47:45 UTC)bd533fb124387a214816ab72c8d1df28(2022-05-09 06:59:58 UTC)...Lockfiles锁定文件# 生成 lockfile$ conan lock create.-------- Computing dependency graph ---------- Graph root conanfile.py:.../conanfile.py Requirements zlib/1.2.11#4524fcdd41f33e8df88ece6e755a5dcc - CacheGenerated lockfile:.../conan.lock# conan.lock 内容{version:0.5,requires:[zlib/1.2.11#4524fcdd41f33e8df88ece6e755a5dcc%1650538915.154],build_requires:[],python_requires:[]}即使 recipe 改为zlib/[~1.2]版本范围lockfile 会强制使用zlib/1.2.11$ conaninstall.Graph root Requirements zlib/1.2.11#4524fcdd41f33e8df88ece6e755a5dcc - Cache常见错误排查错误信息原因解决conan: command not foundConan 未在 PATH 中source ~/.profile或重启终端Package binary could not be found没有对应平台的预编译包加--buildmissing从源码构建Library not loaded: rpath/libz.1.dylib共享库未找到source conanrun.sh激活运行环境ERROR: Version conflict依赖版本冲突使用 lockfile 或版本范围解决error: externally-managed-environmentLinux 系统禁止 pip 全局安装使用pipx或虚拟环境ERROR: profile not found没有创建 profile运行conan profile detect