conan为同一库生成多个二进制包,因c++无统一abi,os、compiler、compiler.version、compiler.libcxx、build_type、arch或options(如shared)任一变化均导致abi不兼容,故每个唯一配置组合生成独立二进制包。

Conan 为什么对同一个库生成多个二进制包?
因为 C++ 没有统一 ABI,settings(如 os、compiler、compiler.version、build_type、arch)的任意组合都可能导致二进制不兼容。Conan 不假设“能跑就行”,而是默认每个配置组合产出一个独立二进制包。
哪些 settings 变动会触发新二进制包生成?
只要以下任一字段不同,Conan 就认为是不同二进制 —— 即使源码完全一样:
-
os:Linux vs Windows vs macOS -
compiler:gccvsclangvsmsvc -
compiler.version:gcc-11和gcc-12生成的.a文件通常不能混用 -
compiler.libcxx:libstdc++和libc++互不兼容 -
build_type:Debug和Release的符号、优化、断言差异足以破坏链接 -
arch:x86_64和armv8二进制无法跨架构运行
例如:glog/0.5.0 在 linux/gcc-11/x86_64/Release 下的包哈希是 3710a465...,换到 linux/gcc-12/x86_64/Release 就是另一个哈希、另一个目录、另一个二进制文件。
conan create 时 --build=missing 为什么常被误用?
这个参数本意是“只构建缺失的二进制”,但新手常忽略它依赖本地 profile 和远程已存在包的匹配精度。常见问题包括:
- profile 中写了
compiler.version=12,但远程只有gcc-11的包 → Conan 强制从源码构建,哪怕你只想用现成二进制 - 没显式指定
--profile:build和--profile:host→ 交叉编译时混淆构建机与目标机环境,导致生成错误 ABI 的包 - 修改了
conanfile.py中的settings范围(比如新增compiler.cppstd=17),但旧包没包含该字段 → 所有旧包被视为“不匹配”,全部重编
真正安全的做法是:先用 conan search <ref> --table</ref> 看远程有哪些可用组合,再确保本地 profile 完全对齐。
如何避免无谓的重复构建?
关键不是减少包数量,而是让包复用更精准:
- 团队内统一 profile 文件,用
conan profile install分发,而不是每人手写 - 在
conanfile.py中显式声明settings,不要依赖默认值;删掉不用的项(比如嵌入式项目不需要os) - 用
conan upload --skip-upload预检上传内容,确认 hash 是否和预期一致 - 对预编译第三方库(如闭源 SDK),直接用
conan export-pkg,跳过 build 步骤 —— 它不校验源码,只打包已有文件,且保留原始 ABI 属性
最易被忽略的一点:Conan 的 hash 不仅算 settings,还包含 options(如 shared=True)和 conf(如 tools.build:cxxflags)。哪怕只加了一个 -fPIC,也会生成新包 —— 这不是 bug,是设计使然。











