如何在CMake中构建旧版本OpenSSL(1.0.2u)?
在CMake中使用旧版OpenSSL的优化方案
你的问题整理
- 需要在Fedora上使用OpenSSL 1.0.2u(比系统包提供的3.2.2版本旧)
- 当前用
ExternalProject构建并创建接口库,想换成FetchContent配合FindOpenSSL实现,询问可行性 - 疑惑:
FindOpenSSL是否必须依赖已构建完成的OpenSSL?如果是,使用它的意义何在?
逐一解答
1. FetchContent + FindOpenSSL完全可行
当然可以实现,核心是要让CMake优先查找你自行构建的旧版OpenSSL,而非系统自带版本。具体操作如下:
- 用
FetchContent拉取OpenSSL 1.0.2u源码,沿用它的传统Makefile流程完成构建和安装 - 在调用
find_package(OpenSSL)之前,将OPENSSL_ROOT_DIR设为你的自建OpenSSL安装目录,同时把该目录加入CMAKE_PREFIX_PATH,强制CMake优先扫描这个路径 - 这套逻辑和你当前
ExternalProject的构建思路本质一致,但FetchContent会把源码放到CMake统一的缓存目录中,项目结构更整洁规范
2. FindOpenSSL确实需要已构建的OpenSSL,但价值显著
没错,FindOpenSSL本身不会帮你编译OpenSSL,它的作用是查找已安装/已构建完成的OpenSSL库和头文件。但使用它的优势很明显:
- 统一接口:自动生成标准CMake变量(如
OPENSSL_INCLUDE_DIR、OPENSSL_LIBRARIES)和目标(OpenSSL::SSL、OpenSSL::Crypto),后续代码直接调用即可,无需手动设置-I、-L等编译/链接选项,减少人为错误 - 适配性强:自动识别库类型(静态/动态)、系统架构等细节,不用手动处理适配逻辑
- 灵活切换:后续如果不需要旧版OpenSSL,只需移除
OPENSSL_ROOT_DIR的配置,CMake就会自动查找系统自带版本,无需修改大量链接代码
优化后的FetchContent实现代码
替换你当前的ExternalProject方案,使用以下代码:
include(FetchContent) # 配置OpenSSL版本和安装路径 set(OPENSSL_VERSION "1_0_2u") set(OPENSSL_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/openssl-install") # 拉取OpenSSL源码 FetchContent_Declare( openssl_src GIT_REPOSITORY https://github.com/openssl/openssl.git GIT_TAG OpenSSL_${OPENSSL_VERSION} GIT_SHALLOW ON ) FetchContent_GetProperties(openssl_src) if(NOT openssl_src_POPULATED) FetchContent_Populate(openssl_src) # 执行OpenSSL的配置、编译、安装步骤 execute_process( COMMAND ./config no-shared --prefix=${OPENSSL_INSTALL_DIR} WORKING_DIRECTORY ${openssl_src_SOURCE_DIR} RESULT_VARIABLE OPENSSL_CONFIG_ERR ) if(NOT OPENSSL_CONFIG_ERR EQUAL 0) message(FATAL_ERROR "OpenSSL配置失败!") endif() execute_process( COMMAND make -j${CMAKE_BUILD_PARALLEL_LEVEL} WORKING_DIRECTORY ${openssl_src_SOURCE_DIR} RESULT_VARIABLE OPENSSL_BUILD_ERR ) if(NOT OPENSSL_BUILD_ERR EQUAL 0) message(FATAL_ERROR "OpenSSL编译失败!") endif() execute_process( COMMAND make install WORKING_DIRECTORY ${openssl_src_SOURCE_DIR} RESULT_VARIABLE OPENSSL_INSTALL_ERR ) if(NOT OPENSSL_INSTALL_ERR EQUAL 0) message(FATAL_ERROR "OpenSSL安装失败!") endif() endif() # 强制FindOpenSSL查找我们自行构建的版本 set(OPENSSL_ROOT_DIR ${OPENSSL_INSTALL_DIR}) set(CMAKE_PREFIX_PATH ${OPENSSL_INSTALL_DIR} ${CMAKE_PREFIX_PATH}) # 调用FindOpenSSL获取标准目标 find_package(OpenSSL REQUIRED) # 后续直接用标准目标链接即可,示例: # target_link_libraries(你的目标名 PRIVATE OpenSSL::SSL OpenSSL::Crypto)
相比当前实现的优势
FetchContent是现代CMake推荐的依赖管理方式,源码存储更规范,无需手动维护目录结构- 借助
FindOpenSSL的标准目标,无需手动设置大量INTERFACE属性,代码更简洁,降低出错概率 - 后续切换版本或改用系统库时,只需修改几行配置,无需调整核心链接逻辑
额外提醒
- OpenSSL 1.0.2u已停止维护多年,存在安全漏洞,非必要场景不建议使用
- 构建前确保Fedora系统已安装依赖:
perl、make、gcc等工具必须齐全 - 如果需要动态库,将
no-shared改为shared即可,但要注意运行时的库路径配置问题
内容的提问来源于stack exchange,提问作者John Graham
相关产品推荐
相关产品推荐

