尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

C++依赖管理革命:Conan包管理器从入门到企业级实战

C++依赖管理革命:Conan包管理器从入门到企业级实战 1. 项目概述为什么C开发者需要Conan如果你是一名C开发者无论是刚入门的新手还是摸爬滚打多年的老手大概率都经历过“依赖地狱”的折磨。想用个第三方库第一步不是写代码而是花上半天甚至几天时间去折腾环境下载源码、解决它自身的依赖、处理平台和编译器的差异、链接正确的库文件……好不容易在一个项目里搞定了换台机器或者换到另一个项目一切又得重来。这种体验跟Python的pip install、JavaScript的npm install比起来简直是一个天上一个地下。C生态的碎片化是出了名的。一个库在Windows上用MSVC编译是一个结果在Linux上用GCC编译又是另一个结果更别提还有静态链接、动态链接、Debug/Release版本、不同C标准C11/14/17/20带来的ABI兼容性问题。长期以来社区缺乏一个像样的、公认的包管理标准导致每个项目、每个团队都在重复造轮子或者用着五花八门的土办法。这就是Conan诞生的背景。它不是一个简单的“下载器”而是一个去中心化、跨平台的C/C包管理器。它的核心目标是把你从繁琐、易错、不可复现的依赖管理工作中解放出来让你能像现代语言开发者一样通过一行命令声明和获取依赖并且确保在任何机器、任何平台上都能得到一致的构建结果。简单来说Conan帮你做了三件事定义依赖用一个简单的文本文件conanfile.txt或Python脚本conanfile.py声明你的项目需要哪些库、什么版本。解决依赖Conan会根据你当前的操作系统、编译器、架构等设置Profile自动计算并下载兼容的二进制包。如果服务器上没有现成的预编译包它会根据配方Recipe自动从源码构建。集成构建它生成标准的构建系统文件如conanbuildinfo.cmake让你的CMake、MSBuild、Makefile等能够无缝找到并链接这些依赖库。我经历过从手动管理include和lib文件夹到尝试vcpkg最终在大型跨平台项目中选择Conan的整个过程。实话说Conan的学习曲线初期有点陡峭但一旦掌握其带来的可复现性、团队协作效率和CI/CD集成便利性是革命性的。这篇指南就是我结合多年实战踩过的坑、总结的经验为你准备的一份从入门到精通的深度解析。2. Conan核心概念与工作流全解析在动手敲命令之前我们必须先理解Conan的几个核心概念。这就像学开车先要认识方向盘、油门和刹车一样理解了它们后面的操作才会顺畅。2.1 核心概念四要素1. 包引用 (Package Reference)这是Conan中唯一标识一个包的“身份证”格式为名称/版本用户/渠道。名称/版本很好理解比如zlib/1.2.11。用户通常是包的创建者或维护者例如官方团队conan或社区贡献者bincrafters。它类似于GitHub的用户名。渠道用于区分包的成熟度常见的是stable稳定版和testing测试版。所以一个完整的包引用看起来像这样boost/1.81.0conan/stable。在私有仓库中你可能会看到myutils/2.1.0mycompany/stable。2. 配方 (Recipe)conanfile.py这是Conan的灵魂。它不仅仅是一个依赖声明文件更是一个构建说明书。一个conanfile.py定义了settings影响包二进制兼容性的“环境变量”如操作系统os、编译器compiler、编译器版本、架构arch、构建类型build_type即Debug/Release。这些设置不同Conan会认为它们是不同的二进制包。options包本身的构建选项不影响ABI但影响功能比如是否构建为动态库sharedTrue/False、是否开启某个特性。requires这个包依赖的其他Conan包。source()方法如何获取源代码如git clone, 下载压缩包。build()方法如何编译源代码如调用cmake, make。package()方法编译后哪些头文件、库文件需要被打包。package_info()方法告诉消费者你的项目如何链接和使用这个包比如库名、编译定义、链接路径。conanfile.txt是conanfile.py的简化版只包含[requires]和[generators]等部分用于纯消费者场景。3. ProfileProfile文件定义了上述的settings和一部分options。它描述了你当前的构建环境。Conan安装后会自动检测生成一个默认的profileconan profile show default。你可以为不同的环境创建不同的profile比如linux_gcc11windows_msvc2019_release。这是实现跨平台一致性的关键。4. 远程仓库 (Remote) 与本地缓存 (Cache)远程仓库存放包配方和二进制包的服务端。最著名的是ConanCenter官方中心仓库。你也可以添加社区源如bincrafters或者搭建自己的私有仓库如使用Artifactory。本地缓存默认位于~/.conanLinux/macOS或%USERPROFILE%\.conanWindows。所有下载的配方、源码和构建好的二进制包都存储在这里。这避免了不同项目重复下载和构建极大提升了效率。2.2 Conan核心工作流理解了概念我们来看Conan是如何工作的。整个过程可以分为“创建包”和“消费包”两条主线。消费包作为库的使用者工作流你在项目根目录创建一个conanfile.txt写入[requires]。执行conan install .或conan install . --buildmissing。Conan读取你的profile确定环境。Conan检查本地缓存是否有匹配该环境的二进制包。有直接解压到缓存生成构建系统文件如conanbuildinfo.cmake。没有根据配方conanfile.py中的source()下载源码然后根据build()方法在本地构建构建成功后放入缓存再生成构建系统文件。你的CMakeLists.txt通过include()引入Conan生成的文件即可使用target_link_libraries(myapp CONAN_PKG::Boost)这样的方式链接库。创建包作为库的提供者工作流为你的库或第三方库编写一个conanfile.py配方。在配方目录下执行conan create . myuser/channel。Conan会执行source(),build(),package()等一系列动作并在test_package文件夹下进行测试。测试通过后这个包就被创建并存储在了本地缓存中。你可以通过conan upload命令将其上传到远程仓库供团队或社区使用。这个工作流的核心优势在于二进制包的管理。对于像Boost、OpenSSL这样编译耗时的库团队中只需要有一个人在某个特定环境如Linux GCC 11 Release下构建一次上传到私有仓库其他所有人在相同环境下就都可以直接下载使用这个现成的二进制包无需重复编译节省了大量时间。3. 从零开始Conan环境搭建与基础命令实战理论说再多不如动手做一遍。我们从一个最干净的环境开始一步步搭建并感受Conan的基础操作。3.1 安装与初始化配置Conan基于Python所以首先确保你的系统有Python 3.5。安装非常简单pip install conan注意强烈建议在虚拟环境venv中安装避免污染系统Python环境。对于生产环境或团队协作可以考虑使用pipx或容器化安装来保证版本一致。安装完成后执行conan --version验证。第一次运行Conan命令如conan profile list时它会自动在用户目录下创建.conan文件夹并初始化默认配置。关键配置项默认远程仓库执行conan remote list你应该能看到一个指向https://center.conan.io的conancenter源。这是官方的中心仓库。默认Profile执行conan profile show default。Conan会自动检测你的系统环境编译器、架构等并生成这个profile。仔细查看它的内容特别是compiler和compiler.version是否正确。一个必须的Profile调整针对Linux GCC用户如果你在Linux上使用GCC默认的Profile可能使用的是旧的libstdcABI。为了支持C11及更高标准你需要更新它# 首先确保default profile已生成通常自动完成 # 然后将libcxx设置为新的C11 ABI conan profile update settings.compiler.libcxxlibstdc11 default这个操作至关重要否则你链接的库可能使用旧的ABI导致运行时出现std::string等标准库组件不兼容的诡异错误。3.2 基础命令实战搜索、安装与项目管理让我们通过一个具体例子来熟悉命令。假设我们要创建一个使用fmt库一个流行的格式化库和spdlog库基于fmt的日志库的控制台项目。1. 搜索包在决定使用哪个版本前可以先在ConanCenter上搜索# 搜索名字中包含‘fmt’的包 conan search fmt* -rconancenter # 搜索特定用户的包比如社区维护的版本 conan search spdlog/*conan/stable -rconancenter2. 创建项目并编写conanfile.txt创建一个项目文件夹my_logger并在其中创建conanfile.txt[requires] fmt/9.1.0 spdlog/1.11.0 [generators] CMakeDeps CMakeToolchain这里我们引入了两个新的GeneratorCMakeDeps这是现代Conan1.40推荐的方式它会为每个依赖生成独立的PackageNameConfig.cmake文件更符合CMake的find_package范式集成更优雅。CMakeToolchain它会生成一个conan_toolchain.cmake文件自动将Conan的profile设置如编译器路径、标准、编译选项传递给CMake无需手动在CMakeLists.txt中设置。3. 安装依赖在项目根目录my_logger下执行安装命令mkdir build cd build conan install .. --buildmissing我们来分解这个命令conan install ..从上一级目录..读取conanfile.txt。--buildmissing这是一个非常重要的参数。它告诉Conan如果在本地缓存和远程仓库中找不到完全匹配当前Profile的二进制包那么就自动从源码构建。对于fmt和spdlog这种纯头文件库或源码简单的库ConanCenter通常提供了主流平台的预编译包可能不需要构建。但对于一些复杂的库或者你的环境比较特殊比如用了特定的编译器版本这个参数就能保证依赖被成功解决。执行后Conan会输出一系列信息检查远程、下载配方、下载二进制包或执行构建、生成文件。最终在build目录下你会看到conan_toolchain.cmake和conan_deps.cmake等文件。4. 编写CMakeLists.txt现在回到项目根目录创建CMakeLists.txtcmake_minimum_required(VERSION 3.15) project(MyLoggerApp) # 引入Conan生成的工具链和依赖文件 list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}) list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) # 启用CMakeDeps生成的文件 find_package(fmt REQUIRED) find_package(spdlog REQUIRED) add_executable(my_logger_app main.cpp) # 使用现代CMake的target_link_libraries方式 target_link_libraries(my_logger_app PRIVATE fmt::fmt spdlog::spdlog) # 设置C标准Conan Toolchain也可能设置这里显式声明更安全 set_target_properties(my_logger_app PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON )5. 编写代码并构建创建main.cpp#include spdlog/spdlog.h int main() { spdlog::info(Hello, Conan! The answer is {}., 42); return 0; }回到build目录使用CMake构建# 使用Conan生成的toolchain文件来配置CMake cmake .. -DCMAKE_TOOLCHAIN_FILEconan_toolchain.cmake -DCMAKE_BUILD_TYPERelease cmake --build . --config Release运行生成的可执行文件你应该能看到漂亮的日志输出。至此你完成了第一个使用Conan管理依赖的C项目整个过程你完全没有手动下载源码、编译库、设置包含路径和库路径所有依赖都被自动、正确地处理了。4. 进阶实战搭建私有仓库与创建自定义包对于企业开发或个人私有项目将二进制包上传到公共的ConanCenter是不合适的。这时搭建私有仓库就成了刚需。同时很多优秀的第三方库可能还没有Conan官方支持我们需要自己为其创建配方conanfile.py。4.1 使用Artifactory搭建私有Conan仓库JFrog Artifactory是功能最全的企业级制品仓库对Conan有原生支持。社区版CE对于小团队和个人开发者完全免费。这里我们使用Docker方式快速部署。1. 部署Artifactory# 拉取Artifactory Community Edition for C/C 镜像 docker pull docker.bintray.io/jfrog/artifactory-cpp-ce:latest # 创建数据目录并设置权限Artifactory容器内默认以1030用户运行 sudo mkdir -p /opt/artifactory/data sudo chown -R 1030:1030 /opt/artifactory/data # 运行容器 docker run -d \ --name artifactory \ --restartalways \ -p 8081:8081 \ -p 8082:8082 \ -v /opt/artifactory/data:/var/opt/jfrog/artifactory \ docker.bintray.io/jfrog/artifactory-cpp-ce:latest访问http://你的服务器IP:8081按照向导设置管理员密码。初始化时选择“Conan”作为主要包类型它会自动创建好Conan所需的本地、远程、虚拟仓库。2. 配置Conan客户端连接私有仓库在Artifactory界面进入“Application” - “Artifactory” - “Artifacts”找到名为“conan”的虚拟仓库。点击右上角“Set Me Up”选择“Conan”你会看到配置命令。在你的开发机上执行# 添加私有远程仓库命名为 my_company可自定义 conan remote add my_company http://你的服务器IP:8081/artifactory/api/conan/conan # 由于Artifactory使用Conan v2协议需要启用修订功能 # 编辑 ~/.conan/conan.conf确保有或添加以下行 # 或者使用命令修改 conan config set general.revisions_enabled13. 上传和下载私有包现在你可以将本地构建的包上传到私有仓库了# 假设你本地有一个包 mylib/1.0.0myteam/stable conan upload mylib/1.0.0myteam/stable --all -rmy_company--all参数表示上传配方和所有构建配置的二进制包。其他团队成员在他们的conanfile.txt中引用mylib/1.0.0myteam/stable并添加my_company远程后执行conan install时就会优先从你的私有仓库下载。实操心得缓存与代理Artifactory的强大之处在于它可以作为远程仓库如ConanCenter的缓存代理。你可以将conan-center配置为Artifactory内部的一个“远程仓库”。这样当团队首次请求一个公共包时Artifactory会从ConanCenter拉取并缓存在本地后续所有团队成员再请求时都直接从内网的高速缓存获取速度极快并且减少了对外网依赖。4.2 为第三方库创建Conan配方conanfile.py以将单头文件库nlohmann/json一个著名的C JSON库打包为例演示如何编写一个简单的配方。1. 创建配方项目结构json-conan-recipe/ ├── conanfile.py └── test_package/ ├── CMakeLists.txt ├── conanfile.py └── example.cpp可以使用conan new json/3.11.2 -t命令生成模板然后修改。2. 编写核心conanfile.pyfrom conan import ConanFile from conan.tools.files import copy, download from conan.tools.cmake import CMake, cmake_layout from conan.tools.scm import Version import os class JsonConan(ConanFile): name nlohmann_json version 3.11.2 description JSON for Modern C topics (json, header-only) homepage https://github.com/nlohmann/json url https://github.com/nlohmann/json license MIT # 对于纯头文件库settings和options通常可以省略或简化因为它不产生二进制文件 # 但为了通用性我们保留settings并设置header_only选项 settings os, compiler, build_type, arch options {header_only: [True, False], multiple_headers: [True, False]} default_options {header_only: True, multiple_headers: False} no_copy_source True # 头文件库通常不需要复制源码到构建目录 def source(self): # 下载单个头文件版本 if self.options.header_only and not self.options.multiple_headers: download(self, f{self.homepage}/releases/download/v{self.version}/json.hpp, os.path.join(self.source_folder, json.hpp)) else: # 或者克隆整个仓库多文件版本 self.output.info(Cloning full repository...) # 这里可以使用 conan.tools.scm.Git为简化示例我们假设下载单文件 pass def package(self): # 将头文件复制到包的include目录 copy(self, *.hpp, srcself.source_folder, dstos.path.join(self.package_folder, include)) def package_info(self): # 对于头文件库需要设置 cpp_info.bindirs 和 cpp_info.libdirs 为空 self.cpp_info.bindirs [] self.cpp_info.libdirs [] # 如果提供了 CMake 配置文件可以设置 cmake_module_file 或 cmake_target_name # 这里我们简单设置 include 目录 self.cpp_info.includedirs [include] # 定义一个 CMake 目标别名方便消费者使用 self.cpp_info.set_property(cmake_file_name, nlohmann_json) self.cpp_info.set_property(cmake_target_name, nlohmann_json::nlohmann_json) # 如果是单文件可以定义一个预处理器宏方便用户知道 if self.options.header_only and not self.options.multiple_headers: self.cpp_info.defines.append(JSON_HEADER_ONLY1) def package_id(self): # 对于纯头文件库不同的settings如编译器版本不应该产生不同的二进制包ID # 因此我们可以清空settings的影响 if self.options.header_only: self.info.clear()这个配方做了几件关键事source(): 从GitHub Release页面下载单个json.hpp头文件。package(): 将头文件复制到包的include目录。package_info(): 告诉消费者这是一个头文件库没有.lib/.a/.dll/.so并设置了CMake相关的属性方便find_package查找。package_id(): 重写了包ID的计算逻辑。对于header_onlyTrue的选项我们调用self.info.clear()这意味着无论settings编译器、架构等如何变化这个包都被视为同一个ID。这是头文件库的常见优化避免为不同环境生成重复的包。3. 创建并测试包在json-conan-recipe目录下执行conan create . --buildmissing这个命令会执行source()下载源码。执行package()打包对于头文件库build()步骤被跳过。进入test_package目录用刚创建的包编译并运行测试程序验证包是否可用。4. 上传到私有仓库测试通过后就可以上传了conan upload nlohmann_json/3.11.2你的用户/渠道 --all -rmy_company注意事项复杂库的打包对于像OpenCV、Boost这样的大型复杂库其conanfile.py会非常复杂需要处理大量的可选依赖、平台特定的补丁、复杂的构建系统调用等。建议先从社区寻找现有的配方如ConanCenter或bincrafters仓库中的在其基础上修改而不是从头开始。理解conan.tools模块Conan 2.0的新API提供的各种工具如CMake,Meson,PkgConfig,Autotools能极大简化配方编写。5. 高级主题Profile、交叉编译与CI/CD集成当项目需要覆盖多个平台Windows, Linux, macOS、多种编译器MSVC, GCC, Clang、多种架构x86_64, armv8时Conan的威力才真正显现。5.1 多环境Profile管理为每个环境创建独立的Profile文件是最佳实践。例如创建~/.conan/profiles/linux_gcc11_release[settings] osLinux archx86_64 compilergcc compiler.version11 compiler.libcxxlibstdc11 build_typeRelease [options] # 可以在这里为所有包设置默认选项例如所有库都编译为静态库 *:sharedFalse [env] # 可以设置环境变量例如指定编译器路径 # CC/usr/bin/gcc-11 # CXX/usr/bin/g-11然后在安装依赖时指定Profileconan install . --profilelinux_gcc11_release --buildmissing在团队中可以将这些Profile文件纳入版本控制确保所有开发者构建环境一致。5.2 交叉编译支持Conan对交叉编译有很好的支持。核心思想是创建两个ProfileBuild Profile描述构建机的环境你正在运行的机器。Host Profile描述目标机的环境程序最终运行的环境如ARM嵌入式设备。假设我们在x86_64的Linux上为ARMv7的Linux设备交叉编译。首先创建host profile (armv7_linux):# ~/.conan/profiles/armv7_linux [settings] osLinux archarmv7hf # 带硬浮点的ARMv7 compilergcc compiler.version9 compiler.libcxxlibstdc11 build_typeRelease [env] CONAN_CMAKE_TOOLCHAIN_FILE/path/to/your/arm-toolchain.cmake # 或者直接指定交叉编译工具链 # CCarm-linux-gnueabihf-gcc # CXXarm-linux-gnueabihf-g然后使用--profile:host和--profile:build参数conan install . --profile:hostarmv7_linux --profile:builddefault --buildmissingConan会为host profileARM计算依赖并在build profilex86_64上执行可能的构建工具如CMake。对于依赖库Conan会尝试从远程获取ARM架构的预编译包如果没有则在构建机上交叉编译出ARM版本的库。这要求你的conanfile.py配方支持交叉编译通常通过正确使用CMake toolchain文件实现。5.3 集成到CI/CD流水线在CI/CD中集成Conan可以实现依赖缓存和二进制包复用极大加速构建过程。以下是GitLab CI的一个示例# .gitlab-ci.yml variables: CONAN_USER_HOME: ${CI_PROJECT_DIR}/.conan # 将Conan缓存放在项目目录便于CI缓存 CONAN_REVISIONS_ENABLED: 1 # 定义一个缓存键缓存Conan的本地缓存目录 cache: key: ${CI_COMMIT_REF_SLUG} paths: - .conan/data stages: - create_packages - build create-package-job: stage: create_packages script: - conan remote add my_company ${CONAN_REMOTE_URL} # 添加私有仓库 - conan user -p ${CONAN_PASSWORD} -r my_company ${CONAN_LOGIN_USER} # 认证 # 仅为变更的库创建并上传包 - | if [ -f conanfile.py ]; then conan create . ${CONAN_USER}/${CONAN_CHANNEL} --buildmissing conan upload * -r my_company --all --confirm --retry 3 fi only: - tags # 仅在打tag时创建稳定版包 - master # 或者在master分支创建开发版包 build-job: stage: build script: - conan remote add my_company ${CONAN_REMOTE_URL} - mkdir build cd build - conan install .. --profile${CONAN_PROFILE} --buildmissing - cmake .. -DCMAKE_TOOLCHAIN_FILEconan_toolchain.cmake -DCMAKE_BUILD_TYPERelease - cmake --build . --config Release --parallel artifacts: paths: - build/*.exe # 或Linux下的可执行文件路径 expire_in: 1 week关键点缓存Conan数据通过CONAN_USER_HOME和CI的缓存机制避免每次流水线都重新下载所有依赖。认证使用conan user命令在CI环境中向私有仓库认证。选择性构建--buildmissing确保缺失的包被构建而已有的二进制包被复用。并行构建在conan create和cmake --build中使用-j或--parallel参数加速。6. 常见问题、性能调优与避坑指南即使理解了所有概念在实际项目中大规模使用Conan时你依然会遇到各种问题。以下是我从多个项目中总结出的高频问题和解决方案。6.1 依赖冲突与版本覆盖这是最常见的问题。你的项目依赖A库和B库A库依赖C库的1.0版本B库依赖C库的2.0版本。Conan默认不允许一个包有两个不同版本存在于依赖图中。解决方案版本覆盖首选在你的项目conanfile.txt或conanfile.py中显式声明对C库版本的依赖。Conan会优先使用根项目你的项目指定的版本并强制提升整个依赖图中的C库版本。# conanfile.txt [requires] A/1.0user/stable B/2.0user/stable C/2.0user/stable # 显式声明强制使用2.0使用版本范围在包的配方中可以使用版本范围来声明依赖如C/[1.0 3.0]user/stable给予更大的灵活性。但需谨慎使用避免引入不兼容的版本。conan graph info命令这是诊断依赖冲突的神器。运行conan graph info .会生成一张清晰的依赖关系图明确显示冲突发生在哪里。6.2 二进制包兼容性与ID计算Conan通过settings和options的哈希值来计算package_id。但有时两个环境在逻辑上是兼容的比如不同的小版本GCC却生成了不同的ID导致二进制包无法复用。调整ID计算规则在conanfile.py中可以重写package_id()方法来微调ID计算。def package_id(self): # 忽略编译器版本的小版本差异只认主版本 self.info.settings.compiler.version self.info.settings.compiler.version.full_version.split(.)[0] # 如果某个option对二进制兼容性无影响可以将其从ID计算中移除 del self.info.options.my_option注意此操作风险很高必须确保被忽略的差异确实不会影响二进制兼容性ABI。对于编译器版本通常只有主版本变化才可能破坏ABI但这不是绝对的。6.3 构建速度优化充分利用二进制包这是最大的性能提升点。确保团队有稳定的私有仓库并将常用库的所有常用配置如Windows MSVC Release/Debug, Linux GCC预先构建并上传。并行构建在conan install或conan create时使用-j参数如-j 8来并行构建多个包。优化配方build()方法对于CMake项目使用cmake.configure()和cmake.build()工具Conan 2.0它们会自动利用多核。避免在build()中执行不必要的操作如运行测试除非必要。使用--buildmissing而非--buildall--buildall会强制所有包从源码构建即使有可用的二进制包。除非你在调试配方否则不要用它。6.4 网络问题与仓库配置ConanCenter服务器在国外国内直接访问可能很慢甚至超时。解决方案使用镜像或代理通过conan.conf配置HTTP代理。# ~/.conan/conan.conf [proxies] http http://your-proxy:port https http://your-proxy:port搭建本地缓存代理如前所述使用Artifactory搭建私有仓库并将其配置为ConanCenter的远程仓库代理。所有流量经过内网Artifactory它会缓存下载过的包。调整远程仓库顺序将速度快的源如内网私仓放在前面。conan remote add my_fast_repo http://... --insert06.5 与现有CMake项目的融合对于庞大的遗留CMake项目可能无法立即将整个构建系统切换到Conan生成的文件。渐进式迁移策略部分依赖使用Conan只为新引入的或易于管理的库使用Conan。在conanfile.txt中声明这些依赖运行conan install生成conanbuildinfo.cmake或xxxConfig.cmake文件。在CMake中混合使用在你的主CMakeLists.txt中同时使用find_package查找系统包或Conan生成的包和传统的include_directories/link_directories。# 引入Conan生成的文件 include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup(TARGETS) # 使用TARGETS模式它会创建导入目标(imported targets) # 现在你可以像链接普通目标一样链接Conan包 target_link_libraries(my_legacy_target PRIVATE CONAN_PKG::MyNewLib) # 同时原有的依赖查找方式保持不变 find_package(OpenSSL REQUIRED) # 可能是系统安装的OpenSSL target_link_libraries(my_legacy_target PRIVATE OpenSSL::SSL)逐步替换随着时间推移将更多的系统依赖迁移到Conan管理最终实现统一。Conan不是银弹它引入了一套新的工作流和概念。初期可能会觉得复杂但一旦团队熟悉并建立起规范的私有仓库和Profile管理它所带来的构建一致性、依赖清晰度和团队效率的提升是巨大的。它让C项目终于有了接近现代软件开发体验的依赖管理能力。
返回列表