【问题标题】:How to compile OpenSSL with relative rpath如何使用相对 rpath 编译 OpenSSL
【发布时间】:2012-03-13 01:39:21
【问题描述】:

我一直在尝试使用以下 rpath 编译 openssl 1.0.0g:

$ORIGIN/../lib64

每次我readelf -d apps/openssl 时,我都会得到如下结果,具体取决于我尝试的转义变化:

\RIGIN/../lib64
RIGIN/../lib64
ORIGIN/../lib64

我想在不使用 chrpath 等外部工具的情况下设置我的 rpath。有可能吗?我基本上会接受任何不涉及使用外部工具(如 chrpath)的东西(尽管我已经完成了)。

理想情况下,我想通过在命令行上传递选项来实现(-Wl,-rpath,$ORIGIN/../lib64 的任何形式)。

我不介意编辑生成的 Makefile,这是我最后尝试的。如果我能得到它打印一个愚蠢的美元符号!我尝试在 BUILDENV= 块下修改 LIBRPATH ,但没有成功。迄今为止我的最佳成绩:

LIBRPATH=$$'ORIGIN/../lib64 # result: /../lib64
LIBRPATH=$$$$'ORIGIN/../lib64 # result: 12345<pid>/../lib64 

我已经阅读了各种与 rpath 相关的问题,并尝试了各种转义和引用技巧,但到目前为止没有任何效果!

【问题讨论】:

  • 另见A description of RPATH $ORIGIN LD_LIBRARY_PATH and portable linux binaries。这篇文章基本上说,makefile 和链接器脚本中的这种愚蠢的转义规则见鬼去吧。文章使用XORIGIN,然后在构建二进制后使用chrpathXORIGIN改为$ORIGIN
  • 所以,我知道这个问题已经有将近十年的历史了,但它还没有被接受的答案。我想我已经设法提出了这里提出的最佳答案。它不需要使用chrpath 进行复杂的转义或构建后任务。也许您可以考虑接受它,因为我相信它肯定会解决您的问题,尽管我承认这为时已晚。

标签: makefile openssl rpath


【解决方案1】:

在你的 makefile 中尝试:

-Wl,-rpath,${ORIGIN}/../lib64

我假设 ORIGIN 是一个 shell 变量。

编辑

我刚刚找到了您问题的答案(迟到总比不做好): 您需要防止 make 插入变量,为此您需要使用 $$(双圆号):

-Wl,-rpath,'$$ORIGIN/../lib64'

我知道它可以工作,因为我已经用我自己的应用程序对其进行了测试,享受:)

【讨论】:

  • 它不是,这是整个问题的一部分。我需要将文字字符串 '$ORIGIN/../lib64' 写入可执行文件中。不得有任何替代品。
  • 您能否说明您使用的是什么版本的openssl以及您更改了Makefile的哪一行?
  • OpenSSL 有一个 Makefile.org 和一堆递归 makefile。而且他们不尊重CFLAGSLDFLAGS 等。所以“在你的makefile 中尝试...”并不听起来那么简单。跨度>
【解决方案2】:

我选择了 chrpath 的方式。 http://enchildfone.wordpress.com/2010/03/23/a-description-of-rpath-origin-ld_library_path-and-portable-linux-binaries/

在 openssl 中对抗 `$$ORIGIN` 的 shell 扩展是相当复杂的。迟早,它会因为美元符号而扩大。如果你真的想走这条路,你可以做到。我发现以下内容可以在 Linux 上使用 openssl 1.0.1g。在 Makefile.shared 中,查找这一行:

DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)"

将其替换为以下内容。这个引用符中和了$ 的扩展。双 $$ 是在 makefile 中获取单个美元符号的方法。

DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,'"'$$'"ORIGIN/../lib64'"

编译后:

readelf -d apps/openssl | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: ['$ORIGIN/../lib64']

【讨论】:

  • DO_GNU_APP=LDFLAGS ... - 我认为这将允许libssl.so仍然加载错误的libcrypto.so
  • Plus One...您设法获得了一个相对的 RPATH with shell 变量。 ldd 是否尊重 shell 变量?它会膨胀吗?我要为这个问题添加书签,因为我以前从未见过......
  • $ORIGIN 是一个特殊的 ldd 令牌。如果你问我,这是一个糟糕的选择,因为美元符号是一个特殊字符,它会被 shell 扩展,如果不是 makefile 的话。这就是为什么将 $ORIGIN 粘贴到可执行文件中如此复杂的原因。使用 chrpath 更明智。这种相对 rpath 使您的 openssl 位置独立,并允许您在不同位置维护多个版本。
【解决方案3】:

好吧,我花了几个小时来解决同样的问题并尝试各种疯狂的逃避方式,有一次我达到了八个 $ 标志,此时我决定必须有另一种方法。

事实上,至少在 GNU ld 中似乎存在。

不要使用-Wl,-rpath,\\$$$\$\$\$$$\$\\\\$ 或其他召唤怪物的上古神,只需这样做:

echo '-rpath=$ORIGIN/../lib64' > rpathorigin
./config -Wl,@$(pwd)/rpathorigin ...

我没有看到ld.gold 记录了@ 标志,我也不知道lld。但是如果你使用的是 GCC 并且它正在调用 BFD ld,那么上面的方法可能对你有用。

当然,与origin一起使用的实际路径应该根据需要自定义,我对./config vs ./Configure没有意见。但是使用响应文件的技巧似乎完全避开了 shell/使逃避噩梦。

【讨论】:

  • 为了提供一些背景信息,说明为什么我不只是使用 chrpath 作为另一个答案建议,chrpath 没有安装在我需要构建 OpenSSL 的机器上,我没有在系统上没有 root 才能安装它。我不想等待管理员为我安装它,所以我找到了这个解决方法。当然,我可以从源代码构建chrpath,但实际上我很难找到代码的规范源代码。很多断开的链接。
  • 转义,最终递归。
【解决方案4】:

我不介意编辑生成的 Makefile,这是我上次尝试的...

我不确定您是否可以使用 shell 变量和相对路径来设置它。我认为ldd 扩展了$ORIGIN/../lib64 中的$ORIGIN。在这种情况下,我认为您需要使用ldconfig添加 $ORIGIN/../lib64 到库搜索路径。有关详细信息,请参阅服务器故障上的 finding ldd search path

由于我不确定,我还是会提供说明。您不需要更改 Makefile。事实上,过去我没有任何运气这样做,因为事情会被覆盖,而其他事情(如 CFLAGSLDFLAGS 会被忽略)。

另请参阅Build OpenSSL with RPATH?您的问题和引用的问题是不同的问题,它们的答案相似(它们之间没有重复)。但它提供了 OpenSSL 开发人员在 RPATH 上的位置。这是一封私人电子邮件,所以我分享了相关的细节而不是整个邮件。

如果您设法在 ELF 部分中嵌入 $ORIGIN/../lib64 并且它有效,那么请报告。下面,我使用/usr/local/ssl/lib 作为我的 RPATH。您应该将$ORIGIN/../lib64 替换为/usr/local/ssl/lib


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

# 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 最简单的方法似乎是add it to linker flags during configuration

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

您还可以编辑配置行并硬编码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 \
    --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 install,那么ldd就会产生预期的结果:

$ 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)
    ...

【讨论】:

    【解决方案5】:

    不要问我为什么,但这对我在 OpenSSL 1.1.1i 中解决 $ 符号问题很有用:

    \$\$\$$ORIGIN
    

    例子:

    ./Configure linux-x86_64 '-Wl,-rpath,\$\$\$$ORIGIN'
    

    或者,如果此命令行技巧与您不相符,您可以在构建后始终使用chrpath,如其他人建议的那样:

    ./Configure linux-x86_64 '-Wl,-rpath,XORIGIN'
    make depend
    make all
    chrpath -r "\$ORIGIN" libssl.so
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2019-07-13
      相关资源
      最近更新 更多