使用 RPATH 构建 OpenSSL?

2024-10-23 08:47:00
admin
原创
86
摘要:问题描述:我有 Ubuntu 14.04。它附带 openssl 1.0.1f。我想安装另一个 openssl 版本(1.0.2)并想自己编译它。我配置如下:LDFLAGS='-Wl,--export-dynamic -L/home/myhome/programs/openssl/i/lib...

问题描述:

我有 Ubuntu 14.04。它附带 openssl 1.0.1f。我想安装另一个 openssl 版本(1.0.2)并想自己编译它。

我配置如下:

LDFLAGS='-Wl,--export-dynamic -L/home/myhome/programs/openssl/i/lib 
-L/home/myhome/programs/zlib/i/lib'

CPPFLAGS='-I/home/myhome/programs/openssl/i/include 
-I/home/myhome/programs/zlib/i/include'

./config --prefix=/home/myhome/programs/openssl/i \nzlib-dynamic shared --with-zlib-lib=/home/myhome/programs/zlib/i/lib \n--with-zlib-include=/home/myhome/programs/zlib/i/include

make 

make install

安装后,当我使用检查二进制文件时ldd openssl,结果是:

...
libssl.so.1.0.0 => /home/myhome/programs/openssl/i/lib/libssl.so.1.0.0 (0x00007f91138c0000)
libcrypto.so.1.0.0 => /home/myhome/programs/openssl/i/lib/libcrypto.so.1.0.0 (0x00007f9113479000)
...

看起来不错。但是当我检查 ldd 时libssl.so,结果是:

...
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007fac70930000)
...

它仍然使用系统版本的 libcrypto。我尝试了不同的构建方法,但结果始终相同。

我的问题是如何以某种方式配置构建,使其可以在不使用LD_LIBRARY_PATH或类似的东西的情况下对共享库的所有二进制文件和库依赖项进行硬编码。


解决方案 1:

我的问题是如何以某种方式配置构建,使其可以在不使用LD_LIBRARY_PATH或类似的东西的情况下对共享库的所有二进制文件和库依赖项进行硬编码。

OpenSSL 支持RPATHBSD 目标(但不支持其他目标)。从 Configure 开始:

# Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
# linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
# .so objects. Apparently application RPATH is not global and does
# not apply to .so linked with other .so. Problem manifests itself
# when libssl.so fails to load libcrypto.so. One can argue that we
# should engrave this into Makefile.shared rules or into BSD-* config
# lines above. Meanwhile let's try to be cautious and pass -rpath to
# linker only when --prefix is not /usr.
if ($target =~ /^BSD-/)
    {
    $shared_ldflag.=" -Wl,-rpath,$(LIBRPATH)" if ($prefix !~ m|^/usr[/]*$|);
    }

对于 OpenSSL 1.0.2 来说,最简单的方法似乎是将其添加为CFLAG

./config -Wl,-rpath=/usr/local/ssl/lib

对于 OpenSSL 1.0.2,下一个最简单的方法似乎是添加一个配置行并硬编码rpath。例如,我正在使用 Debian x86_64。因此,我Configure在编辑器中打开文件,复制linux-x86_64,将其命名为linux-x86_64-rpath,然后进行以下更改以添加-rpath选项:

"linux-x86_64-rpath",   "gcc:-m64 -DL_ENDIAN -O3 -Wall -Wl,-rpath=/usr/local/ssl/lib::
-D_REENTRANT::-Wl,-rpath=/usr/local/ssl/lib -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:
${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.$(SHLIB_MAJOR).$(SHLIB_MINOR):::64",

上面,字段 2 和 6 已更改。它们对应于OpenSSL 构建系统中的$cflag和。$ldflag

然后,使用新配置进行配置:

$ ./Configure linux-x86_64-rpath shared no-ssl2 no-ssl3 no-comp \n    --openssldir=/usr/local/ssl enable-ec_nistp_64_gcc_128

最后,make验证设置是否正确:

$ readelf -d ./libssl.so | grep -i rpath
 0x000000000000000f (RPATH)              Library rpath: [/usr/local/ssl/lib]
$ readelf -d ./libcrypto.so | grep -i rpath
 0x000000000000000f (RPATH)              Library rpath: [/usr/local/ssl/lib]
$ readelf -d ./apps/openssl | grep -i rpath 
 0x000000000000000f (RPATH)              Library rpath: [/usr/local/ssl/lib]

一旦执行make installldd就会产生预期的结果:

$ ldd /usr/local/ssl/lib/libssl.so
    linux-vdso.so.1 =>  (0x00007ffceff6c000)
    libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007ff5eff96000)
    ...

$ ldd /usr/local/ssl/bin/openssl 
    linux-vdso.so.1 =>  (0x00007ffc30d3a000)
    libssl.so.1.0.0 => /usr/local/ssl/lib/libssl.so.1.0.0 (0x00007f9e8372e000)
    libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007f9e832c0000)
    ...

OpenSSL 在其 wiki 上有一个编译和安装。现已将其添加到 wiki 的编译和安装 | 使用 RPATH

解决方案 2:

现在是 2019 年了,OpenSSL 可能发生了一些变化,所以我将描述我是如何解决这个问题的,希望其他人可能会发现它有用(以防我需要自己再次弄清楚这个命令行参数)。

我想以一种可以交叉编译的方式构建 OpenSSL(使用 docker 容器,因为我正在处理非常古老的 Linux 内核和现代编译器),但提供不依赖于绝对路径的安装,就像使用 rpath 的情况一样,正如我在 jww 的回答中看到的那样。

我发现我可以通过这种方式运行 OpenSSL 的配置脚本来实现我想要的效果(从 bash 提示符):

./Configure linux-x86 zlib shared -Wl,-rpath=\\$$ORIGIN/../lib

这会导致生成的 Makefile 以一种方式构建可执行文件和共享对象,使得加载器首先在“./../lib”(相对于可执行文件或共享对象的位置),然后在 LD_LIBRARY_PATH 等中查找依赖项。这种古怪的字符组合正确地越过了 bash 命令行、脚本和 Makefile 组合,根据链接器对它的要求($ORIGIN/../lib)来创建 -rpath 参数。

(显然,选择对您有意义的其他选项..这里的关键在于选项-Wl,-rpath=\$$ORIGIN/../lib)。

因此,如果我使用前缀“--prefix=/opt/spiffness”调用 ./Configure,然后决定将“spiffness”重命名为“guttersnipe”,一切仍将正常工作,因为路径是相对的而不是绝对的。

由于我的用例有点特殊,我还没有尝试将参数传递到 ./config 中以查看它是否在那里有效,但我怀疑它会起作用。如果我不尝试与 dockerized 容器进行交叉编译,我更喜欢使用 ./config 而不是 ./Configure,因为它可以很好地检查当前环境以查看要创建哪种二进制文件。

我希望这有用。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用