首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用RPATH构建OpenSSL?

使用RPATH构建OpenSSL?
EN

Stack Overflow用户
提问于 2015-04-25 06:58:05
回答 2查看 5.3K关注 0票数 4

我有Ubuntu 14.04。它与openssl 1.0.1f一起提供。我想安装另一个openssl版本(1.0.2),并且我想自己编译它。

我按如下方式进行配置:

代码语言:javascript
复制
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 \
zlib-dynamic shared --with-zlib-lib=/home/myhome/programs/zlib/i/lib \
--with-zlib-include=/home/myhome/programs/zlib/i/include

make 

make install

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

代码语言:javascript
复制
...
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时,结果是:

代码语言:javascript
复制
...
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007fac70930000)
...

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

我的问题是如何配置构建,使其可以硬编码共享库的所有二进制和库依赖项,而不使用LD_LIBRARY_PATH或类似的东西。

EN

回答 2

Stack Overflow用户

发布于 2015-04-27 04:35:05

我的问题是如何配置构建,这样它就可以在不使用LD_LIBRARY_PATH或类似的东西的情况下硬编码共享库的所有二进制和库依赖项。

OpenSSL支持RPATH的开箱即用的BSD目标(但不支持其他目标)。

代码语言:javascript
复制
# 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

代码语言:javascript
复制
./config -Wl,-rpath=/usr/local/ssl/lib

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

代码语言:javascript
复制
"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

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

代码语言:javascript
复制
$ ./Configure linux-x86_64-rpath shared no-ssl2 no-ssl3 no-comp \
    --openssldir=/usr/local/ssl enable-ec_nistp_64_gcc_128

最后,在make之后,验证被卡住的设置:

代码语言:javascript
复制
$ 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 install后,ldd将产生预期的结果:

代码语言:javascript
复制
$ 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在其维基上有一个Compilation and Installation。现在已将其添加到Compilation and Installation | Using RPATHs的维基中

票数 2
EN

Stack Overflow用户

发布于 2019-05-17 17:40:38

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

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

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

代码语言:javascript
复制
./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中,以查看它是否在那里工作,但我怀疑它会。如果我没有尝试使用停靠容器进行交叉编译,我会更喜欢使用./config而不是./Configure,因为它可以很好地检查当前环境,了解要创建哪种类型的二进制文件。

我希望这是有用的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29858870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档