使用Conan、CMake链接CURL、OpenSSL与AWS SDK S3的版本冲突问题
解决CURL、OpenSSL与AWS SDK S3链接时的libcrypto版本冲突问题
环境
- Conan 2.0管理的依赖:
openssl/3.1.4、libcurl/8.4.0 - 手动编译安装aws-sdk-cpp-s3(执行
make install完成部署)
项目结构
$ tree . ├── build ├── CMakeLists.txt ├── CMakeUserPresets.json ├── conanfile.txt ├── include ├── LICENSE ├── README.md └── src └── main.cc
配置文件
conanfile.txt
[requires] openssl/3.1.4 libcurl/8.4.0 [tool_requires] cmake/3.27.0 [generators] CMakeDeps CMakeToolchain
CMakeLists.txt
cmake_minimum_required(VERSION 3.27) project(AWSS3Test VERSION 0.0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) find_package(CURL REQUIRED) find_package(OpenSSL REQUIRED) find_package(AWSSDK REQUIRED COMPONENTS s3) add_executable( ${PROJECT_NAME} src/main.cc ) target_link_libraries( ${PROJECT_NAME} CURL::libcurl OpenSSL::Crypto ${AWSSDK_LINK_LIBRARIES} )
main.cc
#include <iostream> #include <optional> #include <openssl/hmac.h> #include <aws/core/Aws.h> #include <aws/s3/S3Client.h> #include <aws/core/auth/AWSCredentialsProviderChain.h> int main() { Aws::SDKOptions options; options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Debug; Aws::InitAPI(options); int result = 0; { Aws::Client::ClientConfiguration clientConfig; clientConfig.endpointOverride = "XXX.XXX.XXX.XXX:XXXX"; clientConfig.scheme = Aws::Http::Scheme::HTTP; clientConfig.verifySSL = false; Aws::Auth::AWSCredentials credentials; credentials.SetAWSAccessKeyId("____________"); credentials.SetAWSSecretKey("_____________________"); Aws::S3::S3Client client = Aws::S3::S3Client(credentials, clientConfig, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never, false); auto outcome = client.ListBuckets(); if (outcome.IsSuccess()) { std::cout << "SUCCESS!" << std::endl; for (auto&& b : outcome.GetResult().GetBuckets()) { std::cout << b.GetName() << std::endl; } } else { std::string errorMsg("Failed with error: " + outcome.GetError().GetMessage()); std::cerr << errorMsg << std::endl; } } ShutdownAPI(options); }
构建步骤
$ conan install . --output-folder=build --build=missing -s compiler.libcxx="libstdc++11" $ cd build/ $ cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release $ cmake --build . --parallel 9 $ ./AWSS3Test
问题描述
运行程序时触发崩溃,核心错误信息:
s2n_init() failed: 402653268 (The libcrypto major version number seen at compile-time is different from the major version number seen at run-time)
移除CURL::libcurl链接后程序可正常运行,但业务功能必须依赖CURL库。
解决方案
原因分析
手动编译的AWS SDK默认链接系统自带的OpenSSL版本,而Conan管理的CURL、OpenSSL是独立部署的版本,两者的libcrypto版本不匹配,导致AWS SDK依赖的s2n TLS库初始化失败。
方案1:重新编译AWS SDK,指定使用Conan的OpenSSL
找到Conan安装openssl的路径(可通过conan info openssl/3.1.4或build目录下的conan_install.json查询),然后重新编译AWS SDK:
# 进入AWS SDK源码目录,清空之前的构建 rm -rf build && mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release \ -DOPENSSL_ROOT_DIR=<CONAN_OPENSSL_INSTALL_PATH> \ -DOPENSSL_INCLUDE_DIR=<CONAN_OPENSSL_INSTALL_PATH>/include \ -DOPENSSL_LIBRARIES=<CONAN_OPENSSL_INSTALL_PATH>/lib \ -DBUILD_ONLY=s3 \ .. make -j9 && make install
替换<CONAN_OPENSSL_INSTALL_PATH>为实际路径,比如~/.conan2/p/openssXXXXXX/p开头的目录。
方案2:调整CMake配置,强制AWSSDK使用Conan的OpenSSL
修改CMakeLists.txt,在查找AWSSDK前先传递Conan的OpenSSL变量:
cmake_minimum_required(VERSION 3.27) project(AWSS3Test VERSION 0.0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # 优先加载Conan管理的OpenSSL find_package(OpenSSL REQUIRED) # 传递OpenSSL路径给AWSSDK set(AWSSDK_OPENSSL_INCLUDE_DIR ${OpenSSL_INCLUDE_DIR}) set(AWSSDK_OPENSSL_LIBRARIES ${OpenSSL_LIBRARIES}) find_package(CURL REQUIRED) find_package(AWSSDK REQUIRED COMPONENTS s3) add_executable( ${PROJECT_NAME} src/main.cc ) target_link_libraries( ${PROJECT_NAME} CURL::libcurl OpenSSL::Crypto ${AWSSDK_LINK_LIBRARIES} )
方案3:改用Conan管理AWS SDK(推荐)
直接在conanfile.txt中添加AWS SDK依赖,让Conan自动处理所有依赖的版本一致性:
[requires] openssl/3.1.4 libcurl/8.4.0 aws-sdk-cpp/1.11.267 # 可根据需求指定版本 [tool_requires] cmake/3.27.0 [generators] CMakeDeps CMakeToolchain
重新执行构建步骤,Conan会自动下载编译匹配版本的AWS SDK,无需手动安装,彻底避免版本冲突。
内容的提问来源于stack exchange,提问作者TyeolRik
相关产品推荐
相关产品推荐

