-l:libsomething.so.1.1.1不链接精确库

时间:2014-11-19 10:54:56

标签: gcc ld

所以我有以下代码:

#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

如果我检查了excutable,它仍然与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

1 个答案:

答案 0 :(得分:0)

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

中读取

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