23

我正在尝试建立一个共享库。让我们说 libabc.so。它使用另一个 .so 文件,比如 lib123.so(/usr/local/lib 中的一个库)。现在我在我的应用程序中使用我的共享库 libabc.so。说 my-app。我想知道我应该如何链接这些二进制文件?我不想直接将 my-app 与 lib123.so 链接。my-app 应该只与 libabc.so 链接。我怎样才能做到这一点?

提前致谢。我正在使用 g++ 编译器

4

3 回答 3

29

假设libabc.so从与位置无关的目标代码文件中获得,abc1.pic.o并且abc2.pic.o;然后你用例如构建它们

 gcc -Wall -fPIC -O -g abc1.c -c -o abc1.pic.o
 gcc -Wall -fPIC -O -g abc2.c -c -o abc2.pic.o

libabc.so

gcc -shared  abc1.pic.o  abc2.pic.o -L/usr/local/lib -l123 -o libabc.so

-L/usr/local/lib 之前 -l123添加了,因为我假设您有一个/usr/local/lib/lib123.so共享库。

另请阅读程序库 HowTo

如您所见,您可以将共享库链接lib123.so到您自己的共享库libabc.so

然后检查ldd libabc.so

您可能希望通过在链接命令中添加和来设置一些rpath 。libabc.so-Wl,-rpath-Wl,$RPATHDIR

有关更多详细信息,请阅读 Drepper 的论文如何编写共享库

PS。不要使用静态库lib123.a(它应该是 PIC)。如果您将非 PIC 代码链接到共享对象,您将失去共享对象的大部分优势,并且动态链接器ld.so必须进行无数次重定位。

于 2013-10-17T10:47:22.793 回答
2

遵循Basile Starynkevitch指出的相同程序,例如,我有一个依赖于的库libm.so,因此库对象的编译是:

gcc -fPIC -Wall -g -I include -I src -c src/wavegen.c  -o build/arm/wavegen.o                                                                                          
gcc -fPIC -Wall -g -I include -I src -c src/serial.c  -o build/arm/serial.o

然而,为了编译库,在某些版本的 gcc 中,库引用的放置顺序很重要,所以我建议,为了确保兼容性,将这些引用放在命令的末尾:

gcc -shared -Wl,-soname,libserial.so.1 -o lib/libserial.so.1.0 build/arm/wavegen.o build/arm/serial.o -lm

我已经在 PC (gcc v.8.3.0) 和 ARM (gcc v.4.6.3) 中进行了测试。

于 2019-05-10T20:06:36.353 回答
1

在尝试创建我自己的使用 Berkeley DB 的共享库时,我发现我必须将 -ldb 放在 gcc 命令的末尾,否则它会爆炸说找不到符号“db_create”。这是在 Cygwin 下。

具体来说,这有效:

gcc -shared -o $b/$libfile nt_*.o -ldb

这不起作用:

gcc -ldb -shared -o $b/$libfile nt_*.o

于 2017-01-28T03:19:38.657 回答