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 查找其依赖项
CMake find_package 找不到 WebSockets