【问题标题】:Link against shared library with SONAME使用 SONAME 链接到共享库
【发布时间】:2017-02-25 16:02:19
【问题描述】:

如何强制 gcc 链接器链接到系统上共享库的给定版本(soname)?

我需要这个来强制在任何系统上,#include'ed 的 openssl 版本与链接的版本相匹配,即使安装了多个版本的 openssl。为了找到 ABI 版本,我的配置脚本首先编译并运行一个从标头中提取 SONAME 的程序:

#include <openssl/opensslv.h>
#include <stdio.h>

int main () {
  printf(SHLIB_VERSION_NUMBER);
  return 0;
}

SHLIB_VERSION_NUMBER 包含 so 版本字符串,例如0.9.8 或 1.0.2k 或 1.1.0。但是我如何告诉gcc 链接到这个版本的libssl 或libcrypto 而不仅仅是任何-lssl?

我尝试了"in situ" linking,所以我们使用以下链接而不是gcc main.c -lcrypto:

gcc main.c libcrypto.so.1.1.0

但似乎找不到链接器libcrypto.so.1.1.0:

gcc: error: libcrypto.so.1.1.0: No such file or directory

我猜系统只在使用-l 标志时搜索标准位置。有没有更好的方法让我的软件链接到libcrypto.so.1.1.0?

【问题讨论】:

  • 我认为你写的要求 gcc 尝试编译 libcrypto.so.1.1.0,而不是链接它。有一种方法可以分阶段编译文件,然后进行链接。
  • @ThomasHedden:你的假设是错误的。如果您将绝对路径传递给共享对象,它将完美地链接到它。
  • 当这样链接时:gcc main.c libcrypto.so.1.1.0,那么libcrypto.so.1.1.0 需要在路径和链接/加载器路径上。您可以执行gcc main.c /usr/local/lib64/libcrypto.so.1.1.0 -o my_prog 来帮助解决编译问题,但我不确定运行时会发生什么。在运行时,您可能需要像LD_LIBRARY=/usr/local/lib64/libcrypto.so.1.1.0 ./my_prog 这样的技巧。我也知道使用 staic 存档按预期工作:gcc main.c /usr/local/lib64/libcrypto.a -o my_prog。我经常使用它来避免所有运行时链接问题。

标签: gcc linker openssl clang ld


【解决方案1】:

要选择正确版本的 openssl 共享库,请使用:

gcc main.c -l:libssl.so.1.0.0 -l:libcrypto.so.1.0.0

回答这个问题的关键是“我如何控制 ld 以便链接正确版本的共享库?”。

使用 gnu 编译器(gcc、g++、gdc 等)传递链接器标志(命令行参数)的正确方法是使用以“-l”为前缀的普通 ld 参数。例如 -lssl 或 -L/usr/local/lib。

编辑:根据How to specify the library version to use at link time?,您可以阅读 ld 的手册:man ld。

【讨论】:

    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2017-05-29
    相关资源
    最近更新 更多