conan报“binary not found”主因是id不匹配:id由profile/settings全量决定,编译器版本、c++标准、libc类型等任一变更均导致id重算,旧二进制失效;需统一profile、验证id一致性,并避免abi混用。

conan install 报 “Binary not found” 是 id 不匹配
Conan 的二进制缓存是靠 id 唯一标识兼容性的,不是靠包名或版本号。升级依赖后如果出现 ERROR: Binary for xxx/1.2.3 doesn't exist,大概率是 profile 或 settings 变了导致 id 重算——比如你改了 compiler.version、加了 compiler.cppstd=20,或者从 libstdc++ 切到 libstdc++11,都会让旧二进制失效。
验证方法:运行 conan info . --graph=deps.html,打开生成的 HTML,看每个依赖节点右下角显示的 ID 字段是否一致;或者直接比对两次 conan install 输出开头的 Configuration 区块。
- 临时绕过:加
--build=missing强制重编(但慢,且可能暴露底层问题) - 根治办法:确保所有环境用同一份 profile 文件,并在 CI 中显式指定
--profile=profiles/linux-gcc11,别依赖默认 - 特别注意:交叉编译时,
sysroot路径哪怕多一个斜杠,也会导致 id 变化
链接失败 undefined reference 或 symbol not found
这不是 Conan 没装对,而是 ABI 层面不兼容。常见于 OpenSSL、gRPC、Boost 等重度依赖 ABI 的库——比如你项目里同时拉了 openssl/1.1.1q 和 openssl/3.0.12,Conan 默认允许共存,但 CMake 链接时只会 pick 其中一个头文件 + 一个库,结果头文件声明了函数 A,而链接的却是没导出 A 的旧版 so。
查法:用 conan list * --graph=deps.html(Conan 2.0+)或 conan graph build-order .(Conan 1.x)确认实际解析出的版本树;再用 nm -D ~/.conan2/p/b/xxx/.../lib/libssl.so | grep -i newfunc 看符号是否存在。
- 锁定单一版本:在
conanfile.txt里写死requires = openssl/1.1.1q,并删掉其他间接引入它的依赖项 - 禁用 override 行为:若某依赖强制拉新版本(如 DBoW 要求 opencv/2.x),把它改成
requires = ("opencv/2.4.13", "private"),避免污染全局版本 - 检查 CMakeLists.txt 是否误用了
find_package(OpenSSL)—— 这会绕过 Conan,必须删掉或注释掉
头文件能 include 但编译报错类型不识别或宏未定义
典型现象是 error: 'SSL_CTX' was not declared in this scope 或 unknown type name 'EVP_PKEY_CTX'。这说明头文件路径对了,但实际包含的是另一套不兼容的 OpenSSL 头(比如系统自带的 /usr/include/openssl),而非 Conan 下载的那份。
原因:CMake 的 include_directories() 或 target_include_directories() 顺序错了,系统路径排在 Conan 路径前面;或者 Conan 生成的 CMakeToolchain 没被正确加载。
- 确认 CMakeLists.txt 开头有
cmake_minimum_required(VERSION 3.23)(Conan 2.x 要求),且第一行是project(...) - 构建前必须执行
conan install . -of=build -g=CMakeToolchain -g=CMakeDeps,然后cmake -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake ... - 检查
build/conan_toolchain.cmake里是否有set(CMAKE_CXX_FLAGS "... -I${CONAN_DEPS_OPENSSL_INCLUDE_DIRS}"),没有就说明生成器没生效
升级后出现 internal 包导入失败
Conan 本身不拦 internal,但 Go 风格的模块设计正越来越多地影响 C++ 生态(如某些现代 C++ 库把实现细节放进 src/internal/ 并只 expose public headers)。如果你看到 fatal error: xxx/internal/util.h: No such file or directory,说明上游库重构时把原来公开的头移到了 internal 目录下,而你的代码还直连它。
这不是 Conan 的 bug,是语义版本违规(v2.x 升级不该破坏 public API)。但现实里常发生,尤其在非主流库或 pre-1.0 版本中。
- 用
conan search "xxx/*"查该库所有可用版本,回退到上一个没动 internal 的版本(如从mylib/0.8.0降到mylib/0.7.5) - 加
replaces或requires锁定:在conanfile.txt写[requires]\nmylib/0.7.5,并确认conan list mylib/*显示加载的就是这个 - 如果必须用新版,只能改代码:找到对应功能的 public 替代头(比如
util.h→api.h),或提 issue 给作者要求恢复导出
Conan 升级失败最麻烦的地方不在命令怎么敲,而在它把“编译器设置、头文件路径、链接库顺序、ABI 兼容性”全耦合进一个 id 里——改任何一环都可能让整个缓存失效,且错误提示往往不指向真实原因。











