使用 RPATH 构建 OpenSSL?

2024-10-23 08:47:00
admin
原创
344
摘要:问题描述:我有 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,因为它可以很好地检查当前环境以查看要创建哪种二进制文件。

我希望这有用。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用