【问题标题】:-l:libsomething.so.1.1.1 not linking exact library-l:libsomething.so.1.1.1 不链接确切的库
【发布时间】:2014-11-19 10:54:55
【问题描述】:

所以我有以下代码:

#include <pcre.h>
#include <stdio.h>
#include <string.h>

int main(const int argc, const char * const * const argv) {
  if (argc != 3) {
    fprintf(stderr, "Usage: %s reg_exp string\n", argv[0]);
  }
  const char * const reg_exp = argv[1];
  const char * const string = argv[2];
  const char * pcre_error_str;
  int pcre_error_offset;

  // Compile
  pcre * const compiled = pcre_compile(reg_exp, 0,  &pcre_error_str, &pcre_error_offset, NULL);
  if (NULL == compiled) {
    const int size = pcre_error_offset + 1;
    char * const indent = (char*)malloc(size);
    memset(indent, ' ', size);
    indent[size - 1] = '\0';
    fprintf(stderr, "Failed to compile: %s\n%s\n%s^\n", pcre_error_str, reg_exp, indent);
    free(indent);
    return EXIT_FAILURE;
  }

  // Optimise
  pcre_extra * const extra = pcre_study(compiled, 0, &pcre_error_str);
  if (NULL == extra) {
    fprintf(stderr, "Failed to study: %s\n%s\n", pcre_error_str, reg_exp);
    return EXIT_FAILURE;
  }

  // Match
  int sub_strs[30];
  const int status = pcre_exec(compiled, extra, string, strlen(string), 0, 0, sub_strs, 30);
  if(status < 0) {
    #define Case(code, msg) \
      case code: \
        fprintf(stderr, msg ": %s %s\n", reg_exp, string); \
        break
    switch(status) {
      Case(PCRE_ERROR_NOMATCH, "String did not match the pattern");
      Case(PCRE_ERROR_NULL, "Something was null");
      Case(PCRE_ERROR_BADOPTION, "A bad option was passed");
      Case(PCRE_ERROR_BADMAGIC, "Magic number bad (compiled re corrupt?)");
      Case(PCRE_ERROR_UNKNOWN_NODE, "Something kooky in the compiled re");
      Case(PCRE_ERROR_NOMEMORY, "Ran out of memory");
      default: fprintf(stderr, "Unknown error: %s %s\n", reg_exp, string);
    }
    return EXIT_FAILURE;
  }

  // Win!
  printf("Matched: %s %s\n", reg_exp, string);
  return EXIT_SUCCESS;
}

使用以下命令行构建它:

gcc -s -O3 -std=c11 -Werror -Wall -Wextra -o main main.c -l:libpcre.so.1.2.4

如果我检查可执行文件,它仍然链接到 libpcre.so.1:

$ ldd main
    linux-vdso.so.1 (0x00007fff341fe000)
    libpcre.so.1 => /usr/lib/libpcre.so.1 (0x00007fe90d508000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007fe90d165000)
    libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fe90cf49000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe90d777000)
$ objdump -x main | grep pcre
  NEEDED               libpcre.so.1

但我已指定我想使用 -l:libpcre.so.1.2.4 链接特定版本的 PCRE

为什么存储的 NEEDED 条目不是 `libpcre.so.1.2.4?

我在 Arch Linux x86_64 上,在撰写本文时有 gcc 4.9.2ldconfig

$ ldconfig -p | grep pcre
    libpcre32.so.0 (libc6,x86-64) => /usr/lib/libpcre32.so.0
    libpcre32.so (libc6,x86-64) => /usr/lib/libpcre32.so
    libpcre16.so.0 (libc6,x86-64) => /usr/lib/libpcre16.so.0
    libpcre16.so (libc6,x86-64) => /usr/lib/libpcre16.so
    libpcreposix.so.0 (libc6,x86-64) => /usr/lib/libpcreposix.so.0
    libpcreposix.so (libc6,x86-64) => /usr/lib/libpcreposix.so
    libpcrecpp.so.0 (libc6,x86-64) => /usr/lib/libpcrecpp.so.0
    libpcrecpp.so (libc6,x86-64) => /usr/lib/libpcrecpp.so
    libpcre.so.1 (libc6,x86-64) => /usr/lib/libpcre.so.1
    libpcre.so (libc6,x86-64) => /usr/lib/libpcre.so

【问题讨论】:

  • -l: 只是说应该将什么文件名添加到查找列表中。在后期阶段添加/删除版本。例如。与-lpcre 链接将产生相同的效果(如果libpcre.so 指向libpcre.so.1,则指向libpcre.so.1.2.4)。是常见的行为;它甚至可能是标准规定的。我不知道提供您自己的完整库名称的方法(除了修补生成的 ELF),所以这里没有答案。

标签: gcc ld


【解决方案1】:

正如@keltar 指出的那样,直接指定库名称不会对添加到NEEDED 的最终名称产生任何影响。始终从SONAME 读取。

我很困惑,因为它适用于 boost,但 boost 库的 SONAME 是完全限定的库名称(非标准)

【讨论】:

    猜你喜欢
    • 2013-01-30
    • 1970-01-01
    • 2018-04-05
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多