我注意到在尝试在GCC 4.4和GCC 4.5上进行相同操作时存在差异。由于我正在处理的代码是专有的,因此无法提供它,但我通过这个简单的测试案例观察到了类似的失败情况。
基本上,我的目标是让一个共享库(libb)依赖于另一个共享库(liba)。当加载libb时,我假设也应该加载liba,即使libb不一定使用liba中的符号。
我所观察到的是,当我使用GCC 4.4编译时,我会发现会加载liba,但如果我使用GCC 4.5编译,则不会加载libb。
我有一个小的测试用例,包括两个文件a.c和b.c。它们的内容如下:
//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
$
有人能解释一下发生了什么吗?另外一个额外的信息是,对于GCC 4.4上的libb.so的ldd确实显示了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