Conan 默认按 profile 和 settings/options 计算唯一二进制 ID 实现复用;二进制存于本地缓存(~/.conan2/p/),非项目 build 目录;复用失败主因是 profile 或 options 微小不一致,如 compiler.version=12 与 12.3 视为不同包。

Conan 默认就能复用二进制包,前提是不同项目使用**完全一致的 settings + options + profile**。不是“需要配置才能复用”,而是“稍有不一致就彻底不复用”。
为什么 conan install 后 build 目录里没看到二进制文件?
这是最常被误解的一点:Conan 的二进制包不放在你的项目 build/ 目录里,而是统一存放在本地缓存(~/.conan2/p/ 下按 hash 分目录)。conan install 只生成构建系统所需的 glue 文件(如 CMakeDeps 输出的 fmt-config.cmake),并不复制 .so/.dll 到项目中。
- 运行
conan install . --build=missing时,若远程已有匹配二进制,它会直接下载并解压到本地缓存,不会重新编译 - 下次另一个项目执行相同命令(相同 profile、相同
compiler.version、相同shared=True等),Conan 会直接命中缓存,跳过下载和构建 - 验证是否复用:看终端输出是否出现
Cache hit或Downloading—— 前者表示复用,后者表示新下载
profile 不一致是复用失败的头号原因
Conan 用 profile 计算二进制唯一 ID。哪怕只是 compiler.version=12 写成 12.3,或漏写 compiler.libcxx=libstdc++11(GCC 场景),ID 就完全不同,缓存失效。
- 检查当前 profile:运行
conan profile show default,确认[settings]和[options]完整且显式 - 跨项目必须共用同一 profile 文件,不要依赖隐式 default;推荐用
--profile=./myproject.profile显式指定 - 特别注意 Windows 上的
compiler.runtime(MD/MT)和 Linux 上的compiler.libcxx,它们直接影响 ABI 兼容性 - 避免在
conanfile.py中硬编码settings,应全部收口到 profile
如何让 zlib 静态链接、fmt 动态链接,还能复用?
可以,但必须明确声明每个包的 options,否则 Conan 会按包作者定义的默认值(可能不一致)构建,导致二进制 ID 分裂。
- 在
conanfile.txt中写:[requires] zlib/1.2.13 fmt/10.2.1 [options] zlib:shared=False fmt:shared=True
- 或在
conanfile.py的default_options里固定:default_options = { "zlib:shared": False, "fmt:shared": True } - 关键点:只要两个项目声明了完全相同的
zlib:shared=False和fmt:shared=True,且 profile 一致,它们就会共享 zlib 的静态版和 fmt 的动态版二进制
企业级复用:私有远程 + lockfile 锁定
仅靠本地缓存不够稳定——重装系统、CI 清理缓存、团队协作时,二进制就丢了。真正可靠的复用依赖远程仓库 + conan lock。
- 上传二进制到私有 Artifactory/Nexus:用
conan upload "*" -r=myremote --force - 生成锁定文件:
conan lock create . --profile=myprofile,它记录每个依赖的 exact revision 和二进制 ID - 其他项目用
conan install . --lockfile=conan.lock --profile=myprofile,强制走锁定路径,彻底规避解析歧义 - CI 中建议始终加
--lockfile,否则不同时间跑conan install可能拉到不同二进制(比如远程新上传了 patch 版本)
复用本身不难,难的是对 settings/options 的精确控制——差一个字符,Conan 就当它是全新包。profile 和 lockfile 不是高级功能,而是生产环境复用的底线配置。

















