如何使用静态库(.a文件)而不是一组目标文件(.o)创建共享库

Kanishka khandelwal

我有一个共享库,并使用它来创建可执行二进制文件。我只能控制库和可执行二进制文件的构建过程,而不能控制所涉及的源文件。不出所料,可执行二进制文件中的源文件引用了库中的许多功能。

当前,共享库是直接使用objectfiles(.o)构建的。

g++ -shared ${OBJECT_FILES} -o ${SHARED_LIBRARY}

我也想通过将对象文件分组到静态库(.a文件或achive)中来发布对象文件。

为了节省空间,我在创建存档文件时删除了所有.o文件。所以现在,build命令是

g++ -shared ${ACRCHIVE_FILE} -o ${SHARED_LIBRARY}

该库构建良好。
但是,当我尝试通过链接到此共享库来构建可执行二进制文件时,二进制文件所引用的符号未定义,并且无法链接。(对的未定义引用Context::Get()

根据我的理解,我们直接使用.o文件还是由所有.o文件组成的档案库创建共享库都没有关系,但是显然这是不可能的,或者我可能会丢失一些东西。

巴西尔·斯塔林凯维奇

共享库libfoo.so应包含PIC代码,而静态库应libfoo.a包含普通的非PIC代码。因此,您不能从静态库创建共享库。

共享库需要位置无关代码,因为它们的段是mmap(2)-在几乎任意且可变的地址处编入的,而没有MAP_FIXED...请参见ASLR

原则上,您可以从PIC对象文件构建静态库,但实际上没有人这样做。

您可能(如果真的坚持的话)可以使ELF共享对象由非PIC代码构成,但是结果将导致非常糟糕的性能。动态链接器将有很多重定位,因此大多数段将是不共享的,并且动态链接将非常慢。

要将foo.cc共享库编译为PIC目标文件,请执行以下操作foo.pic.o

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

要将其编译为普通的非PIC对象文件中的静态库,请执行以下操作foo.o

g++ -Wall -c -O foo.cc -o foo.o 

为了使共享库foo.pic.o,并bar.pic.olibfoobar.so一些链接libdep.so共享库:

g++ -shared foo.pic.o bar.pic.o -ldep -o libfoobar.so

像上面那样创建共享库时,例如-Wl,-rpath,...或-Wl,-soname,... ,您通常想添加更多的链接选项

顺便说一句,不可能将归档文件libfoobar.a(即使它是由PIC文件组成)链接到中,libfoobar.so因为没有名称是未定义的,并且需要从中链接某些目标文件libfoobar.a(也许您可以尝试用来取消定义一些符号symb-u symb但我不建议这样做)这样做)。

为了使静态库foo.obar.olibfoobar.a

ar cv libfoobar.a foo.o bar.o

请注意,由于GNU会执行ranlib,因此不再需要ranlib(创建档案的索引)ar

另请参阅ld.so(8)ldd(1)ld(1)ar(1)objdump(1)readelf(1)dlopen(3)(通常,您需要将主程序与-rdynamicif它会dlopen在运行时加载-ed插件,以使插件能够在主程序中找到一些符号。

注意:我只是建立一个共享库,根本不关心静态链接。请注意,在某些系统上,PIC成本较低(代码较大和/或较慢)。AFAIK,x86-64上的PIC开销比32位Linux x86代码便宜。在某些体系结构和ABI上,PIC的开销可以忽略不计(甚至比非位置无关的代码更有效)。

参考:Drepper的文章:如何编写共享库Levine的书:链接器和加载器程序库HowTo

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在 Makefile 中:给定一组源文件,如何创建静态库而不是可执行文件?

使用g ++从cpp文件和静态库创建共享库

如何强制链接器使用共享库而不是静态库?

如何使用CMake将自己的.o文件与第三方静态库合并,以创建新的合并静态库?

构建共享库创建了一个静态库

将一组给定的文件提取到存储库

如何用C中的一组目标文件编译一组C文件

从cpp文件创建动态库,并使用clang创建静态库

GCC始终尝试使用静态libc库而不是共享库

从 C 文件创建共享库文件

如何链接静态库 .o 文件?

如何使用qmake使中间目标文件不是库?

如何使用Bazel Build从生成的源文件构建静态库

如何使用CMake在Android Studio 3.2中创建静态库(.a文件)

生成ELF而不是目标文件的Tizen gcc汇编器-无法创建静态库

如何使用libtool从大量静态库中创建静态库

如何从一组图像文件创建HDR文件?

过滤csv文件并使用数据创建一组新的.csv文件

如何从静态C和C ++库创建共享C库?

在iOS中使用所选文件创建静态库

从静态库列表创建共享库

创建一个最小的共享库

如何链接从 C 代码生成的目标文件、静态库和 NASM 生成的目标文件?

从一组手动归档文件构建git存储库

如何让R降价模板共享同一组支持文件?

如何在Apache中与两个不同的域共享一组文件?

使用静态库(.a)中的头文件(.h)

静态库(.a)和共享库(.so)之间的文件格式差异?

使用Cmake创建一个依赖dlib的共享库