Conan本身不编译代码,仅负责下载、缓存和复用二进制包;判断是否重编需查看终端输出:[build]表示源码构建,[cached]/[remote]表示复用成功。

Conan 本身不编译代码,它只负责下载、缓存、复用已构建的二进制包。所谓“减少重复编译”,本质是让 conan install 尽可能命中本地缓存或远程预构建包,跳过源码编译阶段。这取决于你是否正确配置了 profile、是否复用二进制包、以及是否误触发了源码构建(–build=missing 或 –build=outdated)。
怎么判断当前 conan install 是否在重新编译
执行 conan install 时,终端输出中每行开头带 [build] 标记的就是正在从源码构建;带 [cached] 或 [remote] 的才是复用了已有二进制包。如果你看到大量 [build],说明 Conan 正在本地重编——这不是预期行为,而是配置或环境出了问题。
- 检查是否无意中加了
--build=missing或--build=outdated参数(CI 脚本里常被硬编码) - 确认当前 profile 中的
compiler.version、compiler.libcxx、arch、build_type等设置,和远程仓库中已存在的二进制包签名完全一致(哪怕libcxx=libstdc++11和libstdc++都算不同配置) - 运行
conan search <ref> -r <remote>查看目标包在远程是否有匹配当前 profile 的二进制(例如conan search zlib/1.2.12@ -r conancenter)
profile 配置错一个字段,就等于换了一套包
Conan 的二进制兼容性模型非常严格:compiler、compiler.version、compiler.libcxx、arch、build_type、os 六个字段共同构成一个二进制包的唯一标识(即 settings)。只要其中任一值不同,Conan 就认为这是另一个包,不会复用。
- 常见坑:Linux 下默认
compiler.libcxx=libstdc++11,但某些旧项目 profile 写成libstdc++,导致 zlib、openssl 等基础包全量重编 - Windows 上 MSVC 的
compiler.runtime(MD/MT)必须和你的项目链接方式一致,否则找不到包 - 建议用
conan profile show default检查当前 profile,并与conan remote list_ref中对应包的settings对比
什么时候必须本地编译?怎么限制范围
不是所有包都有预编译二进制。Conan Center 提供的主流库(如 zlib、openssl、fmt)通常覆盖主流组合;但私有包、新版本、或冷门配置(如 armv7 + clang 15)往往没有现成二进制,这时 Conan 默认会 fallback 到源码编译。
- 用
--build=missing是显式允许编译缺失包,但应仅在开发机或 CI 构建节点上启用,**禁止在日常开发命令中默认带上** - 更安全的做法是:先跑一次
conan install . --build=missing -if build生成所有所需二进制,再上传到私有远程(如 Artifactory),后续所有人直接复用 - 若只想编译自己的包、跳过所有第三方,用
--build=your_package_name,避免污染整个依赖树
缓存路径和二进制复用的物理依据
Conan 的本地缓存路径(默认 ~/.conan2)下,每个二进制包按 pkgname/version/_/_/package_id 存储,而 package_id 是由 settings + options + requires 共同 hash 得出的。这意味着:即使你改了一个 option(比如 shared=True → False),也会生成全新 package_id,无法复用。
- 检查缓存是否存在某包:直接看
~/.conan2/p/b/<hash>/p/目录下是否有conaninfo.txt和bin/等内容 - 清理无效缓存:用
conan remove "*" --cache要谨慎;更推荐conan remove <ref> --packages -r <remote>清远程无效包 - CI 中建议挂载
~/.conan2为持久卷,避免每次流水线都清空缓存
最常被忽略的一点:Conan 不会自动推断你想要什么 ABI,它只忠实地执行你声明的 settings。哪怕你只是把 compiler.version=12 手动改成 12.3,也会导致全部重编——因为 12.3 这个组合在远程大概率没二进制。所以 profile 不是写一次就完事,它得和你的工具链、CI 镜像、发布目标对齐,差一位数字,就是两套世界。


















