尝试在 GCC 4.4 和 GCC 4.5 上执行相同操作时,我观察到了差异。因为我正在使用的代码是专有的,所以我无法提供它,但我发现这个简单的测试用例也发生了类似的失败。
我基本上想做的是让一个共享库(libb)依赖于另一个共享库(liba)。加载 libb 时,我假设也应该加载 liba - 即使 libb 不一定使用 liba 中的符号。
我观察到的是,当我使用 GCC 4.4 编译时,我观察到 liba 已加载,但如果我使用 GCC 4.5 编译,则未加载 libb。
我有一个包含两个文件 ac 和 bc 的小测试用例。文件内容:
//a.c
int a(){
return 0;
}
//b.c
int b(){
return 0;
}
//c.c
#include <stdio.h>
int a();
int b();
int main()
{
printf("%d\n", a()+b());
return 0;
}
//test.sh
$CC -o liba.so a.c -shared
$CC -o libb.so b.c -shared -L. -la -Wl,-rpath-link .
$CC c.c -L. -lb -Wl,-rpath-link .
LD_LIBRARY_PATH=. ./a.out
这是我使用不同版本的 GCC 的输出
$ CC=gcc-4.4 ./test.sh
1
$ CC=gcc-4.5 ./test.sh
/tmp/cceJhAqy.o: In function `main':
c.c:(.text+0xf): undefined reference to `a'
collect2: ld returned 1 exit status
./test.sh: line 4: ./a.out: No such file or directory
$ CC=gcc-4.6 ./test.sh
/tmp/ccoovR0x.o: In function `main':
c.c:(.text+0xf): undefined reference to `a'
collect2: ld returned 1 exit status
./test.sh: line 4: ./a.out: No such file or directory
$
谁能解释发生了什么?另一个额外的信息是 libb.so 上的 ldd 确实在 GCC 4.4 上显示 liba.so,但在 GCC 4.5 上不显示。
编辑
我将 test.sh 更改为以下内容:
$CC -shared -o liba.so a.c
$CC -L. -Wl,--no-as-needed -Wl,--copy-dt-needed-entries -la -shared -o libb.so b.c -Wl,-rpath-link .
$CC -L. c.c -lb -Wl,-rpath-link .
LD_LIBRARY_PATH=. ./a.out
这给出了 GCC 4.5 的以下输出:
/usr/bin/ld: /tmp/cc5IJ8Ks.o: undefined reference to symbol 'a'
/usr/bin/ld: note: 'a' is defined in DSO ./liba.so so try adding it to the linker command line
./liba.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
./test.sh: line 4: ./a.out: No such file or directory