【问题标题】:Why doesn't ld find some symbols from shared libs为什么 ld 没有从共享库中找到一些符号
【发布时间】:2015-07-24 09:14:02
【问题描述】:

我有以下文件:

文件 liba.c

#include <stdio.h>

void foo() {printf("foo\n"); }
void bar() {printf("bar\n"); }

文件 libb.c

void foo();
void abc() { foo(); }

ma​​in.c

void abc();
void foo();
void bar();

int main()
{
   abc();
   foo();
   bar();
}

我正在编译文件如下:

gcc -shared -fPIC -o liba.so liba.c
gcc -shared -fPIC -Wl,-rpath,. -Wl,--no-undefined -o libb.so libb.c liba.so
gcc -Wl,-rpath,. main.c libb.so

现在链接器在链接可执行文件时报错:

/usr/bin/ld: /tmp/cc4De1Xu.o: undefined reference to symbol 'bar'  
./liba.so: error adding symbols: DSO missing from command line  
collect2: error: ld returned 1 exit status  

现在的问题是:为什么链接器找不到符号barmain.clibb.so 相关联,而 libb.so 又与 liba.soliba.so 相关联> 确实有符号 barmain.c 使用符号 foo 并且它也驻留在 liba.so 中,并且在链接过程中可以找到。

所以 foobar 这两个符号都在 liba.so 中定义,但只找到 foo在链接期间。为什么?

似乎只有 liba.so 中的符号在 libb.so 中使用。但是为什么会这样呢?

【问题讨论】:

  • 无需进一步分析,最后一行应为gcc -L. -Wl,-rpath,. -lb main.c
  • 这更糟糕,因为它报告 abc、foo 和 bar 为未定义,因为 main.c 列在 -lb 之后。在 main.c 之后移动 -lb 会导致与上面的调用相同的错误消息。

标签: c gcc linker shared-libraries


【解决方案1】:

我认为这与符号bar 未包含在libb.so 的导出表中但仅包含在liba.so 中有关。为什么不将 main.c 也链接到 liba.so? 否则,在 libb.c 中声明 void bar(); 应该会有所帮助..

【讨论】:

  • 是的,这将修复链接器错误,但我想知道为什么会这样。
  • 正如我所写,我认为符号 void bar() 不是由模块 libb.so 导出的......并且从 main.c 到 liba.so 没有关系......
  • 存在从 libb.so 到 liba.so 的关系,因为符号 foo 在链接期间被解析。所以 ld 在链接时确实知道 liba.so 并且它确实从中解析符号(符号 foo)。现在既然它知道 liba.so 并且它知道它的符号(例如符号 foo),那么它为什么不解析符号 bar 呢?
猜你喜欢
  • 2013-09-09
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多