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

标签 c++ g++ linker-errors

我有一个共享库,我用它来创建一个可执行的二进制文件。我只能控制库和可执行二进制文件的构建过程,而不能控制所涉及的源文件。正如预期的那样,可执行二进制文件中的源文件引用了库中的许多函数。

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

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

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

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

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

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

根据我的理解,如果我们直接使用 .o 文件或包含所有 .o 文件的存档创建共享库,应该没有关系,但显然这是不可能的,或者我可能会丢失一些东西。

最佳答案

共享库libfoo.so应包含PIC代码和静态库 libfoo.a 包含普通的非 PIC 代码。因此您无法从静态库创建共享库。

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

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

你可以(如果你真的坚持)做一个 ELF由非PIC代码组成的共享对象,但结果会导致性能非常差;动态链接器会有很多 relocations ,因此大多数片段将不共享,并且动态链接会非常慢。

将共享库的foo.cc编译为PIC目标文件foo.pic.o:

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

将其编译为静态库 int 普通非 PIC 目标文件 foo.o :

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

foo.pic.obar.pic.o的共享库制作成libfoobar.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 链接一些目标文件(也许您可以尝试使用 -u symb 取消定义某些符号 symb 但我不这样做建议这样做)。

foo.obar.o的静态库制作成libfoobar.a:

ar cv libfoobar.a foo.o bar.o

请注意 ranlib (创建文件索引)不再需要,因为 GNU ar 完成了它的工作。

另请阅读ld.so(8) , ldd(1) , ld(1) , ar(1) , objdump(1) , readelf(1) , dlopen(3) (通常,如果主程序在运行时加载 dlopen-ed 插件,则需要将主程序与 -rdynamic 链接,以使插件能够在主程序中查找某些符号) .

注意:我只会构建一个共享库,根本不关心静态链接。请注意,在某些系统上,PIC 具有轻微的成本(代码稍大和/或较慢)。据我所知,x86-64 上的 PIC 开销比 32 位 Linux x86 代码上的开销要低。在某些架构和 ABI 上,PIC 的开销可以忽略不计(或者甚至可能比非位置无关代码更有效)。

引用文献:Drepper's paper: How to Write Shared Libraries & Levine's book: Linkers and Loaders & Program Library HowTo

关于c++ - 如何使用静态库(.a 文件)而不是一组目标文件(.o)来创建共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25689480/

相关文章:

c++ - 某些类(class)文件无法正确使用 Makefile

c++ - 检查空指针

c++ - 如何使用静态对象和方法!? C++ 挫败感

php - PHP与C++之间的通信

gcc - 我可以在枚举上使用 gcc 可见性属性吗?

c++ - 体系结构 x86_64 的 undefined symbol ,链接器命令失败

c++ - 什么是 undefined reference /未解析的外部符号错误,我该如何解决?

c++ - 选择退出复制构造函数

C++ : gcc compiler warning for large stack allocation

c++ - 与Boost Filesystem的静态链接不起作用