find_package(OpenSSL) 无法找到特定的 libssl 版本

Posted

技术标签:

【中文标题】find_package(OpenSSL) 无法找到特定的 libssl 版本【英文标题】:find_package(OpenSSL) unable to find specific libssl version 【发布时间】:2020-06-08 15:38:22 【问题描述】:

我正在使用安装了 OpenSSL 版本 1.0.2k 和 0.9.8e 的 RHEL7 系统:

$ ll /usr/lib64/libssl.so*   
lrwxrwxrwx 1 root root     16 Feb 28 19:32 /usr/lib64/libssl.so -> libssl.so.1.0.2k
-rwxr-xr-x 1 root root 340832 Mar  4  2016 /usr/lib64/libssl.so.0.9.8e
-rwxr-xr-x 1 root root 470360 Apr  9  2019 /usr/lib64/libssl.so.1.0.2k
lrwxrwxrwx 1 root root     16 Feb 28 19:31 /usr/lib64/libssl.so.10 -> libssl.so.1.0.2k
lrwxrwxrwx 1 root root     16 Jun 22  2018 /usr/lib64/libssl.so.6 -> libssl.so.0.9.8e

出于兼容性原因,我的程序需要链接旧的 0.9.8e 版本,但 find_package() for OpenSSL 似乎无法找到它。 如果我使用find_package(OpenSSL 0.9.8 REQUIRED COMPONENTS SSL Crypto),它会找到更新的版本:

-- Found OpenSSL: /usr/lib64/libcrypto.so (found suitable version "1.0.2k", minimum required is "0.9.8") found components: SSL Crypto

如果我添加EXACT 选项,CMake 会告诉我找不到该版本:

CMake Error at /path/to/cmake/data/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:164 (message):
  Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
  system variable OPENSSL_ROOT_DIR: Found unsuitable version "1.0.2k", but
  required is exact version "0.9.8" (found /usr/lib64/libcrypto.so)

查看输出很明显FindOpenSSL.cmake 只查看指向新库的符号链接。提供OPENSSL_ROOT_DIR 也不是选项,因为两个库都位于同一个目录中。是否可以告诉命令查找特定的库/SONAME?

我不想直接链接到正确的库。我应该向 KitWare 报告错误吗?在我看来,这方面的命令似乎被破坏了。

【问题讨论】:

您可能需要查看 OpenSSL finder 模块的源代码。我不得不为其他模块做类似的事情。 find_package 查找libssl.so 链接。你的指向 1.0.2。即使您手动更改它,除非您还安装了头文件,否则它将无法正常工作。您需要安装 openssl 0.9.8 的完整开发环境。我不记得 RHEL7 是否提供 0.9.8 的开发包。他们可能只发布运行时 0.9.8 库,以支持仅为早期版本的 RHEL 构建的软件。在这种情况下,您唯一的选择是自己从头开始构建 openssl,并以不会将您的 RHEL7 系统变成无法启动的砖块的方式安装它。 @drescherjm 不幸的是,这不起作用。这里不(从语法上)支持所谓的字母发布。如果我添加“e”,则会出错。 @SamVarshavchik 假设我是这样做的。这不会仍然是一个问题,因为我的二进制文件在执行时将搜索libssl.so 而不是libssl.so.0.9.8e?实际上,这是我在 RHEL5 机器上构建的二进制文件所面临的另一个问题,其中 0.9.8.e 是默认版本。在 RHEL7 系统上运行时,它会加载错误的 libssl 版本和段错误。 您的二进制文件不会搜索libssl.so。在链接时,从.so 文件中读取完整的共享库版本,这里应该是libssl.so.6,这就是运行时要搜索的内容。这里有所有这些符号链接的原因。我不知道 RHEL5 上发生了什么,可能是当时的 openssl 没有正确构建。 【参考方案1】:

我建议您升级您的应用程序以与 openssl 1.0.x 或 1.1.x 兼容。

话虽如此,本着回答这个问题的精神,您可以执行以下操作:

mkdir $HOME/openssl0.9.8e && cd $_
wget http://vault.centos.org/5.11/os/x86_64/CentOS/openssl-0.9.8e-27.el5_10.4.x86_64.rpm
wget http://vault.centos.org/5.11/os/x86_64/CentOS/openssl-devel-0.9.8e-27.el5_10.4.x86_64.rpm
for i in *.rpm; do rpm2cpio $i | cpio -idmv; done
cd ..

# If you are using CMake 2.x
cmake -S /path/to/your/project -Bbuild \
   -DOPENSSL_INCLUDE_DIR=$HOME/openssl0.9.8e/usr/include \
   -DOPENSSL_SSL_LIBRARY=$HOME/openssl0.9.8e/usr/lib64/libssl.so \
   -DOPENSSL_CRYPTO_LIBRARY=$HOME/openssl0.9.8e/usr/lib64/libcrypto.so

# If you are using CMake 3.x
cmake3 -S /path/to/your/project -Bbuild -DOPENSSL_ROOT_DIR=$HOME/openssl0.9.8e/usr

OPENSSL_ROOT_DIR 不能在 2.x 中正确使用,因为 fix 仅在 3.x 中可用。

CMakeLists.txt 的示例内容:

cmake_minimum_required(VERSION 3.0.0)

project(so)

find_package(OpenSSL 0.9.8 REQUIRED COMPONENTS SSL Crypto EXACT)

add_executable(main main.x.c)
target_link_libraries(main PRIVATE $OPENSSL_LIBRARIES)
target_include_directories(main PRIVATE $OPENSSL_INCLUDE_DIR)

要在构建后运行二进制文件,您可以在 CentOS7/RHEL7 上安装兼容包:openssl098e 或使用:

LD_LIBRARY_PATH=$HOME/openssl0.9.8e/lib64 /path/to/build/main

请注意,您还需要安装 krb5-devel,因为它是使用 libssl 的依赖项。

您还可以将库与您的应用程序一起提供,并在RPATH 中使用$ORIGIN,但我将把它作为练习(为了好玩)并且强烈不推荐它,因为您应该更新您的应用程序来制作它对 openssl 1.0.x 或 1.1.x 的投诉,因为您永远不会获得 0.9.8 库的任何更新,所以这是一个巨大的安全问题。

【讨论】:

以上是关于find_package(OpenSSL) 无法找到特定的 libssl 版本的主要内容,如果未能解决你的问题,请参考以下文章

为 CMake 项目创建一个配方,使用 find_package 查找其依赖项

ubuntu find_package 找不到 qt5

CMake find_package 找不到 WebSockets

visualstudio2019 集成vcpkg,find_package找不到模块问题

Cmake命令之find_package介绍

Cmake中find_package命令的搜索模式之配置模式(Config mode)