conan 默认优先拉取匹配环境的预编译二进制包,仅当远程无对应二进制(因os、编译器、选项等哈希不匹配)时才回退本地构建;源码包非独立类型,而是recipe加未构建source缓存。

Conan 里 conan install 默认拉的是二进制包
Conan 的设计哲学是「优先复用预编译的二进制」,而不是每次下载源码再编译。当你执行 conan install 时,Conan 会根据当前环境(profile 中定义的 OS、arch、compiler、build_type 等)计算一个唯一哈希值,然后去远程仓库(如 conancenter)查找匹配的二进制包。如果找到,直接下载解压;没找到,才回退到源码构建(前提是 recipe 中定义了 source() 和 build())。
这意味着:同一份 conanfile.py,在 Ubuntu + GCC 11 + Release 下运行一次,和在 Windows + MSVC 19.3 + Debug 下运行一次,请求的是完全不同的二进制——它们互不兼容,也不会混用。
- 二进制包本质是
package()方法打包出来的文件集合(含头文件、lib、dll、cmake 配置等),路径结构固定,可直接被 CMake 的find_package()或conan_basic_setup()消费 - 源码包只是原始代码(
source()下载或解压的内容),不包含任何编译产物,必须经过build()才能生成可用的库 - Conan 不提供“纯源码分发”的独立包类型;所谓“源码包”,其实是 recipe + 未构建的 source 缓存,它本身不是安装目标
conan create 和 conan export-pkg 的产出差异
conan create 是标准流程:从 recipe 出发,依次执行 source() → build() → package(),最终生成一个带完整元信息(conaninfo.txt、conanmanifest.txt)的二进制包,并上传到本地缓存或远程。
conan export-pkg 则跳过 source 和 build,直接把本地已编译好的文件(比如你手动用 CMake 编好的 build/ 目录)打包成 Conan 二进制包。它适合已有构建产物、不想重复编译的场景,但要求你手动保证 ABI 兼容性(比如不能拿 GCC 编的 lib 给 Clang 项目用)。
-
conan create可重现、可审计,适合 CI 流水线 -
conan export-pkg快但脆弱,容易因路径硬编码或缺失依赖导致下游conan install失败 - 两者产出的包在缓存中结构一致,但
export-pkg包缺少conanbuildinfo.txt等构建时生成的辅助文件(除非你手动补全)
为什么有时 conan install 还是会编译源码?
常见原因不是 Conan “想编译”,而是它找不到匹配的二进制。典型触发条件包括:
- 远程仓库没上传对应配置的二进制(比如你用的是 Clang 15,但 conancenter 只有 Clang 14 的包)
-
profile里启用了自定义选项(如shared=True),而官方包只提供了shared=False版本 - recipe 中设置了
default_options = {"fPIC": True},但远程二进制是按默认fPIC=False构建的 - 本地
conan.conf启用了general.revisions_enabled = True,但远程仓库未启用 revisions 支持,导致哈希不匹配
此时 Conan 会 fallback 到本地构建,但不会自动上传结果——除非你显式执行 conan upload。这也是很多团队误以为“Conan 总在编译”的根源:其实它只是在填补二进制空白。
源码修改后如何安全更新二进制包
直接改 recipe 里的 source() URL 或 commit hash 并重新 conan create 是最干净的做法。但要注意:
- 修改
version字段或增加revision,否则新包会覆盖旧包,导致依赖锁定失效 - 若仅改
build()步骤(比如加个编译宏),必须同步调整package_id(),否则 Conan 认为“包没变”,不会触发重构建 - 私有仓库中,建议用
conan upload --force覆盖同名包,但需提前通知所有下游用户清理本地缓存(conan remove <ref></ref>),否则他们仍会用旧二进制
真正容易被忽略的点是:Conan 的二进制兼容性判断极度严格,哪怕 profile 里多了一个空格、少了一个 -D 宏,都会导致全新哈希和全新二进制——这不是 bug,是它保障 ABI 安全的核心机制。











