如何将静态库链接到共享库 [英] How do you link a static library to a shared library

查看:210
本文介绍了如何将静态库链接到共享库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试通过

 命令将静态库链接到共享库。g ++ -shared obj.o archive.a -o libLib.so 

但是在运行时,我会得到未解决的系统,在编译时从archive.a。我试过了

  g ++ -shared obj.o -Wl,-Bstatic archive.a -Wl,-Bdynamic -o libLib .so 

  g ++ -shared obj.o -Wl,-whole-archive archive.a -Wl,-no-whole-archive -o libLib.so 

没有成功。我觉得我在这里缺少一些基本的东西...

解决方案

你几乎不能(即应该)这样做。 共享库应为位置无关代码,但静态库不是。



想要将 libaa 链接到 libfoo.so 中构建或获取共享 libaa.so ,而不是静态(非PIC)库 libaa.a



因此,一个文件 foo1.cc 进入共享库 libfoo.so 应编译为

  g ++ -c -fPIC -Wall -O foo1.cc -o foo1.pic.o 

,并且库将链接为

  g ++ -shared foo1.pic.o foo2.pic.o -o libfoo.so 

您可以将另一个共享库 libsmiling.so 链接到 libfoo.so 通过在上面的命令中添加 -lsmiling 。但是你不能将库链接到静态库,只是复制它们的成员。

但是一个文件进入一个 static libfoo.a 刚刚编译为

  g ++ -Wall -O foo1 .cc -o foo1.o 

所以当你解压缩 foo1.o 成员来自 libfoo.a 不是 PIC(这是非常低效的)



原则上,你可以把非PIC对象代码放在共享库中。实际上,您不应该这样做,因为重新定位的数量太大它违反了共享库的目的。如果你这样做,文本内存将不会共享,动态链接器将有一个很多重定位工作。



.so 中的代码应该是PIC允许 ld.so



因此,您可以找到一系列命令将静态库链接到一个共享一个,例如使用 ar x 提取 libbar.a 的所有成员,然后链接所有这些提取的 bar * .o foo * .pic.o 但是这将是一个错误。不要将静态非PIC库或目标文件链接到PIC共享库。



有关详细信息(重点介绍Linux),请阅读 ld.so(8) ld(1) ELF wikipage, Levine的书:链接器和加载程序 Drepper的论文:如何写入共享库



PS。一些非常少的静态库包含PIC代码,因为它们可以用于创建共享库。例如我的Debian提供 libc6-pic 包,特别是 /usr/lib/x86_64-linux-gnu/libc_pic.a 静态PIC库 - 可用来构建 libc.so -eg的一些变体如果我想把 malloc 放在 libc.so 中! - 无需重新编译每个 glibc 源文件。


I'm trying to link a static library to a shared library via a command like

g++ -shared obj.o archive.a -o libLib.so

But at run time I keep getting unresolved system that should be link at compile time from archive.a. I've tried

 g++ -shared obj.o -Wl,-Bstatic archive.a -Wl,-Bdynamic -o libLib.so

and

g++ -shared obj.o -Wl,-whole-archive archive.a -Wl,-no-whole-archive -o libLib.so

with no success. I feel like I'm missing something basic here...

解决方案

You practically cannot (i.e. should never) do that. Shared libraries should be position independent code, but static libraries are not.

If you want to link libaa into libfoo.so build or get a shared (PIC) library libaa.so, not a static (non-PIC) library libaa.a

So a file foo1.cc going into a shared library libfoo.so should be compiled as

g++ -c -fPIC -Wall -O foo1.cc -o foo1.pic.o

and the library will be linked as

g++ -shared foo1.pic.o foo2.pic.o -o libfoo.so 

You could link another shared library libsmiling.so into libfoo.so e.g. by appending -lsmiling to the above command. But you can't link libraries into static libraries, just copy their members.

But a file going into a static library libfoo.a is just compiled as

g++ -Wall -O foo1.cc -o foo1.o

so when you extract that foo1.o member from libfoo.a it is not PIC (and that is very inefficient)

In principle you could put a non-PIC object code in a shared library. In practice, you should never do that, because the amount of relocation is so large that it defeats the purpose of shared libraries. If you did that, text memory won't be sharable and the dynamic linker would have a lot of relocation work.

Code inside .so shared objects should be PIC to permit ld.so to mmap it at different address segments in different processes.

So you could find a sequence of commands to link a static library into a shared one, e.g. extract using ar x all the members of the libbar.a then link all these extracted bar*.o with foo*.pic.o but that would be a mistake. Don't link static non-PIC libraries or object files to PIC shared libraries.

For details (with a focus on Linux) read ld.so(8), ld(1), ELF wikipage, Levine's book: Linkers and loaders, Drepper's paper: How To Write Shared Libraries

PS. Some very few static libraries contain PIC code because they could be used to make shared libraries. For example my Debian provides the libc6-pic package giving notably the /usr/lib/x86_64-linux-gnu/libc_pic.a static PIC library -usable to build some variant of libc.so -e.g. if I wanted to put my own malloc in libc.so! - without recompiling every glibc source file.

这篇关于如何将静态库链接到共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆