openssl/boost升级后undefined reference增多,主因是abi不兼容:openssl 3.x重排ssl_ctx结构体字段、evp_cipher_ctx强制堆分配,boost 1.8x调整resolver构造函数签名;conan仅部署文件,不自动适配api变更。

Conan 升级包版本后编不过,大概率不是代码问题,而是 ABI 兼容性、头文件路径或链接符号被悄悄改掉了。
为什么 OpenSSL/Boost 升级后 undefined reference 突然变多
OpenSSL 3.x 和 1.1.x 的 API/ABI 不兼容:比如 SSL_CTX_new() 返回类型没变,但内部结构体字段重排了; EVP_CIPHER_CTX 从栈上分配变成必须用 EVP_CIPHER_CTX_new()。Boost 1.8x 对 asio::ip::tcp::resolver 的构造函数签名也做了调整。
Conan 不会自动帮你做适配 —— 它只管把头文件和库放对位置,不管你的代码调用是否合法。
- 检查错误里具体是哪个符号未定义,去对应新版本的头文件里搜一遍声明,确认参数/返回值是否变化
- 用
nm -C libssl.a | grep SSL_CTX_new看实际导出的符号名,比对旧版 - 别只看
#include <openssl></openssl>,还要确认OPENSSL_VERSION_NUMBER宏值,条件编译逻辑可能失效
conan install 没报错,但 CMake 找不到 find_package(OpenSSL) 模块
这是 CMakeDeps 生成器没生效或路径没对上。Conan 2.x 默认不生成 FindOpenSSL.cmake,它生成的是 openssl-config.cmake,供 find_package(OpenSSL CONFIG) 使用。
- 确保
conanfile.txt或conanfile.py里写了[generators]→CMakeDeps,不是cmake_find_package(后者是 Conan 1.x 风格) - CMakeLists.txt 中必须写
find_package(OpenSSL CONFIG REQUIRED),漏掉CONFIG就会 fallback 到系统自带的 FindOpenSSL.cmake,路径和头文件全错 -
include(${CMAKE_BINARY_DIR}/generators/conan_toolchain.cmake)要在project()之后、find_package()之前
升级后编译通过但运行时 SSL_connect() failed: error:0A000086:SSL routines::certificate verify failed
这不是链接问题,是 OpenSSL 3.x 默认启用了更严格的证书验证策略,且不再默认加载系统 CA 路径。老项目常靠 SSL_CTX_set_default_verify_paths() 撑住,但新版本里这个调用可能静默失败。
- 先跑
openssl version -d看 Conan 安装的 OpenSSL 实际证书目录在哪(通常是res/ssl/certs) - 用
conan install时加--build=missing确保 OpenSSL 是按 profile 重新构建的,否则可能混用 host 和 target 的 certs - 代码里显式调用
SSL_CTX_load_verify_locations(ctx, nullptr, "/path/to/conan/openssl/res/ssl/certs"),路径得从CONAN_USER_HOME或self.package_folder动态读取
private 依赖没锁住,导致下游项目意外升级了子依赖
比如你封装了一个 my_crypto 包,它 require openssl/1.1.1w,但上层项目又 require openssl/3.2.1,Conan 默认会“合并”成新版 —— 除非你明确说不。
- 在
my_crypto/conanfile.py的requires里写成requires = [("openssl/1.1.1w@", "private")],不是"openssl/1.1.1w@" -
private模式下,该 openssl 只供my_crypto自己链接,不会暴露给消费者,也不会参与全局版本解析 - 如果用了
conan create打包,记得加--build=missing,否则 private 依赖的二进制可能根本没生成
最麻烦的不是编不过,而是「看着过了,跑着崩了」——OpenSSL 和 Boost 这类底层库升级,往往要同时动头文件包含方式、链接选项、运行时资源路径、甚至线程模型。别急着改代码,先用 conan info . 看清楚整个依赖图里到底拉了哪个版本、哪个 profile 构建的、有没有混用 host/target 二进制。











