conanfile.py支持通过self.settings.os等条件动态声明依赖,而conanfile.txt不支持任何逻辑分支;必须使用requirements()方法配合self.requires()实现平台差异化依赖管理。

conanfile.py 里用 self.settings.os 做条件判断
Conan 不支持在 conanfile.txt 里写逻辑分支,必须换用 conanfile.py 才能按平台启用不同依赖。核心是读取 self.settings.os、self.settings.arch 或 self.settings.compiler,再在 requirements() 方法里动态调用 self.requires()。
常见错误现象:在 conanfile.txt 里写 [requires] + 注释或条件语法,结果被完全忽略——Conan 解析器根本不识别这些。
- Windows 下加
winflexbison,Linux/macOS 下加flex和bison - ARM64 嵌入式目标禁用 GUI 相关依赖(如
qt),x86_64 桌面环境才启用 - Android 平台强制要求
android-ndk作为 build-require,其他平台跳过
示例片段:
def requirements(self):
if self.settings.os == "Windows":
self.requires("winflexbison/2.5.25")
elif self.settings.os in ["Linux", "Macos"]:
self.requires("flex/2.6.4")
self.requires("bison/3.8.2")
if self.settings.arch == "armv8":
self.requires("openssl/3.1.3", override=True)
Profile 控制依赖是否实际构建(--build=missing 不够用)
光靠 conanfile.py 判断还不够:某些平台依赖(比如 Windows-only 的 directx)可能根本没上传到 ConanCenter,强行 requires() 会导致 conan install 报错 ERROR: Missing binary。这时候得靠 Profile 配合 conf 关闭自动构建。
使用场景:你有一套通用 conanfile.py,但想让 CI 在 macOS 上跳过某个 Linux-only 库的解析,避免触发网络拉取或版本冲突。
- 在 Profile 文件里加:
tools.info.package_files:disabled=True(不常用) - 更稳妥的是用
conf控制生成器行为:tools.cmake.cmaketoolchain:generator=Ninja只影响 CMake,不影响依赖解析 - 真正起作用的是
--conf tools.build:skip_deps=openssl,libusb(Conan 2.3+ 支持)
注意:--conf 必须和 conan install 一起传,不能只写在 Profile 里就生效。
CMakeLists.txt 中对应做 find_package() 条件链接
Conan 只管把包下下来、生成 xxx-config.cmake,但如果你在 CMakeLists.txt 里无条件写 find_package(openssl REQUIRED),而当前平台其实没装这个依赖,CMake 就会报错找不到。所以 CMake 层也得配合。
性能影响:多一层 if() 判断几乎零开销;但若漏掉,整个构建直接中断,比编译慢更致命。
- 用
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/build/generators/openssl-config.cmake")检查文件是否存在 - 或者更推荐 Conan 官方方式:
find_package(openssl QUIET)+if(openssl_FOUND) - 别用
OPTION或cmake -DENABLE_OPENSSL=ON手动开关——这和 Conan 的声明式管理逻辑冲突
示例:
find_package(fmt REQUIRED)
find_package(openssl QUIET)
if(openssl_FOUND)
target_link_libraries(myapp PRIVATE OpenSSL::SSL)
endif()
交叉编译时 platform-specific 依赖容易混进 sysroot
嵌入式场景下最常踩的坑:你在 arm64-release Profile 里启用了 zlib,但宿主机(x86_64 Linux)上也装了系统级 zlib-dev。Conan 默认不会屏蔽系统路径,CMake 可能误链宿主机的 libz.so,导致运行时报 ELF file OS ABI invalid。
为什么这样做:Conan 的 CMakeToolchain 生成器默认不清理 CMAKE_SYSTEM_PREFIX_PATH,它信任 profile 里写的 sysroot,但不阻止 CMake 自己去扫 /usr/lib。
- 确保 Profile 里明确写了
tools.build:sysroot=/path/to/arm64/sysroot - 在
CMakeLists.txt开头加:set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - 验证是否生效:
conan install .. -pr:h=arm64-release -pr:b=default --build=missing,注意-pr:h(host)和-pr:b(build)要分清
容易被忽略的地方:conan install 命令里漏掉 -pr:b=default,Conan 就会用 host profile 同时编译 build-require 和 host 依赖,导致工具链污染。











