精确版本如cjson/1.7.13严格匹配,语义化范围如fmt/[~10.2]等价于>=10.2.0且

conanfile.txt 中怎么写版本号
Conan 支持多种版本表达式,但最常用、最稳妥的是精确版本(如 fmt/10.2.1)或语义化版本范围(如 fmt/[~10.2])。直接写死版本号是新手推荐做法,避免隐式升级导致构建不一致。
常见写法及效果:
-
cjson/1.7.13:严格匹配该版本,不兼容任何其他版本 -
fmt/[~10.2]:等价于>=10.2.0, ,允许 patch 升级 openssl/[>=3.0.0 :显式区间,适合对 ABI 兼容性敏感的库-
boost/[*]:通配符,仅用于临时调试,**生产环境禁止使用**——它会拉取最新可用版本,破坏可复现性
注意:conanfile.txt 不支持条件逻辑或变量替换,所有版本必须静态声明。
conanfile.py 里怎么动态控制版本
当你需要根据 profile、选项或环境切换依赖版本时,conanfile.py 是唯一选择。它本质是 Python 脚本,requires 属性可接受字符串、元组或函数返回值。
典型用法:
- 按构建类型区分:
self.requires("gtest/1.14.0" if self.settings.build_type == "Debug" else "gtest/1.14.0")(实际中常统一版本,此例仅为示意) - 用选项控制:定义
options = {"use_new_crypto": [True, False]},然后self.requires("openssl/3.1.3" if self.options.use_new_crypto else "openssl/1.1.1w") - 从环境变量注入:
os.getenv("CONAN_OPENSSL_VERSION", "3.1.3")—— 适合 CI 场景,但需确保环境变量已设好
⚠️ 避免在 requires 中调用网络请求或复杂计算,Conan 解析阶段要求快速确定依赖图。
为什么 conan install 后版本被“改写”了
执行 conan install 后,当前目录下会生成 conan.lock 文件,里面记录的是解析后的**传递依赖全图 + 精确版本 + revision ID**。你写的 fmt/[~10.2] 可能最终锁为 fmt/10.2.1+sha256:abc...。
这是正常行为,不是 bug。原因有二:
- Conan Center 的包可能有多个 revision(例如修复了某个平台编译问题),lockfile 锁定的是确切二进制来源
- 传递依赖(如
A → B → fmt)可能引入更高或更低版本,Conan 自动做版本协商并写入 lockfile
后续运行 conan install 默认读取 conan.lock,不再重新解析 conanfile.txt。想强制重算,加 --lockfile-preserve=false;想更新某依赖,用 conan lock update --requires="fmt/10.2.2"。
指定版本时最容易忽略的点
版本号本身只是表象,真正影响链接结果的是 **profile + options + 依赖的 binary 匹配度**。
比如你写了 zlib/1.3.1,但本地没有对应 compiler=gcc、compiler.libcxx=libstdc++11、shared=True 的预编译包,Conan 就会 fallback 到源码编译——这时实际构建行为由 zlib 的 recipe 决定,和你写的版本字符串无关。
所以比“怎么写版本”更重要的是:
- 用
conan remote list确认远程仓库可用(尤其是国内用户要检查是否配置了https://center.conan.io) - 用
conan profile show default核对 profile 是否匹配你的编译器和标准库设置 - 首次运行时加
--build=missing,否则遇到无二进制包会直接报错退出
版本字符串再准确,也救不了 profile 错配导致的找不到包。











