conan.lock 是强制保障构建一致性的核心文件,它通过记录精确的 rrev 和 prev 指纹锁定依赖,避免因 profile、远程状态等差异导致 abi 不兼容;必须配合 conan lock create 和 --lockfile 使用,并在 ci 中校验 sha256 与强制构建。

conan.lock 文件不是可选配件,而是构建一致性的强制开关——没它,不同机器上跑 conan install 就可能拉到不同版本的包,哪怕 conanfile.txt 里写死了版本号。
conan.lock 是怎么生成和更新的
它不是手动写的,而是由 Conan 在解析依赖树后自动生成的快照。关键点在于:只有显式调用 conan lock 或带 --lockfile 参数的命令才会读写它。
-
conan lock create .:从当前目录的conanfile.py或conanfile.txt解析出完整依赖图,生成初始conan.lock -
conan install . --lockfile:强制只安装conan.lock里记录的精确版本、修订号(rrev)和包 ID(prev),跳过任何版本解析逻辑 - 如果后续改了
conanfile里的requires,必须重新运行conan lock create,否则conan install --lockfile会报错并拒绝执行
为什么只写版本号还不够,非得用 lockfile
Conan 的版本号(如 zlib/1.2.13)只是“约束”,不是“承诺”。实际安装时,Conan 会根据 profile、远程仓库可用性、已缓存包等动态选择满足该约束的最新 rrev 和 prev。这在开发中方便,但在 CI 或发布时就是隐患。
- 现象:本地
conan install成功,CI 报undefined reference to 'inflate'—— 很可能是 zlib 的二进制包在两个环境用了不同prev(比如一个用了 shared 构建,另一个是 static) - 根本原因:
conanfile.txt没锁定rrev(配方修订)和prev(二进制包修订),而 ABI 兼容性取决于这两者 -
conan.lock里明确记录了每个依赖的"rrev": "87a3f2"和"prev": "a1b2c3",相当于给每个包打了唯一指纹
CI/CD 中必须 enforce lockfile 的典型流程
不检查 lockfile 是否过期或是否被绕过,就等于没锁。
- CI 脚本开头加
conan lock create . --lockfile=conan.lock,再对比生成结果与现有conan.lock的 SHA256;不一致就 fail,防止开发者忘记提交更新后的 lockfile - 构建命令必须用
conan install . --lockfile=conan.lock --build=missing,禁用任何自动解析行为 - 如果项目用了多个 profile(比如
linux-gcc-x86_64和win-msvc-x64),每个 profile 都要对应一个独立 lockfile(如conan.lock-linux),不能共用
容易被忽略的兼容性陷阱
lockfile 不是银弹,它只保证“按记录安装”,但不保证“能运行”。几个硬伤点必须人工盯住:
- profile 变更不会触发 lockfile 自动失效 —— 比如把
compiler.version=12改成14,旧 lockfile 还会强行装 GCC 12 编译的包,链接时报错 - 远程仓库下线某个
prev后,conan install --lockfile会直接失败,而不是降级;得提前用conan download把关键prev拉到本地缓存或私有 remote -
conan.lock里不记录settings的完整值,只记 profile 名;所以 profile 文件本身也得进 Git,且不能用相对路径或环境变量引用











