Conan复用二进制包严格基于settings+options+profile的精确哈希匹配,任一字段(如compiler.version、build_type、shared)不同即视为新包,不复用;conan install仅检查本地缓存中是否存在完全匹配的package_id,不主动同步远程,需--update才拉取。

Conan 复用二进制包的判断逻辑完全基于 settings + options + profile 的精确匹配,不是“差不多就行”,而是“一字不差才复用”。只要 compiler.version、arch、build_type、shared、fPIC 中任一值不同,它就认为是全新二进制,不会复用——哪怕你只改了 compiler.libcxx=libstdc++11 到 libc++,也会触发重建或重新下载。
conan install 时怎么决定是否复用本地缓存中的二进制
执行 conan install 时,Conan 会按以下顺序查证:
- 先解析当前命令行或
conanfile.py中声明的settings(如os=Linux arch=x86_64 compiler=gcc compiler.version=12 compiler.libcxx=libstdc++11 build_type=Release)和options(如shared=True) - 再检查本地缓存中是否存在完全匹配的二进制 ID(即
package_id),这个 ID 是由 settings/options 经哈希生成的固定字符串 - 若存在且状态为
Cache(非Missing或Build),则直接复用;否则走下载/构建流程 - 注意:即使远程仓库有匹配二进制,但本地缓存里没有,也不会“自动同步”——它只看本地有没有,不主动拉取,除非你加了
--update
conan create 和 conan export-pkg 对二进制复用的影响差异
conan create 默认强制 clean build,每次都会生成新二进制(除非你显式指定 --build=cache 或用 conan lock 锁定);而 conan export-pkg 完全跳过 build 阶段,直接把本地已编译好的文件打包进缓存,此时:
- 你必须手动确保传入的
--settings与目标环境一致,比如交叉编译 ARM 库时写--settings arch=armv7 --settings compiler=gcc --settings compiler.version=11 - 如果 settings 写错(例如漏了
compiler.libcxx),生成的 package_id 就和实际使用场景不匹配,下游conan install时必然找不到,报ERROR: Missing prebuilt package -
conan export-pkg不校验头文件/库文件 ABI 兼容性,只认路径和 settings —— 所以你塞进去一个 x86_64 的.a却标成arch=armv8,Conan 也照收不误,但链接阶段必崩
为什么有时 conan install 明明有缓存却还是提示 missing
常见真实原因包括:
- profile 文件里写了
[settings],但命令行又用--settings覆盖了部分字段,导致最终 settings 实际组合与缓存中 package_id 不一致 - Conan 2.x 默认启用
compatible_packages机制,但你的缓存中没配置compatibility.py,所以不会 fallback 到近似二进制(比如compiler.version=12缺失时,不会尝试用11的) - 你用了
self.info.settings.compiler.version = "ANY"这类放宽逻辑,但上游依赖没做同样处理,导致依赖树中某一层 package_id 仍严格绑定版本,断掉了复用链 - Windows 下 MSVC 的
compiler.runtime(MD/MT)被忽略或设错,这是最常踩的坑之一 ——conan install找不到包,其实只是 runtime 不匹配
真正关键的是:Conan 的“复用”不是智能推测,而是机械比对。它不会猜测你想要什么,只忠实地执行你声明的 settings 和 options。一旦出现复用失败,第一反应不该是怀疑网络或权限,而是立刻用 conan list "pkg/1.0@" --graph=file.json 或 conan search pkg/1.0@ -r=remote 查 package_id 是否真存在,再反向核对 settings 输出是否和缓存中的一致。


















