如何为C ++代码制作64个共享的64位Linux兼容库(* .so)

时间:2012-03-09 12:54:11

标签: c++ linux 64-bit shared-libraries

我的要求是处理一些接口.h文件。现在我的项目中有.h和.cpp / .cc文件。

我需要在Linux Fedora上使用NetBeans / Eclipse将其编译为共享的64位Linux兼容库(* .so)。

2 个答案:

答案 0 :(得分:3)

由于GCC C ++ ABI约定从一个GCC版本到下一个(例如从g++-4.4g++-4.6)稍有变化(特别是因为C ++标准库演变或名称修改惯例)共享库可能取决于用于构建它的g++的版本

(实际上,g ++中的更改通常很小,因此您可能不受影响)

如果您希望使用dlsym公开访问该符号,最好在头文件中声明extern "C"(否则您应该mangle its name)。

关于如何制作共享库,请阅读Program Library Howto等文档。

另见this question

我建议使用普通的命令行工具(例如Makefile - s)构建共享库。不要依赖像NetBeans / Eclipse这样复杂的IDE来构建它们(无论如何它们都在调用命令行实用程序)。

答案 1 :(得分:2)

如果您正在分别从名为a.cc,b.cc和c.cc的3 C ++源文件编译库;


g++ -fpic -Wall -c a.cc

g++ -fpic -Wall -c b.cc

g++ -fpic -Wall -c c.cc

g++ -shared -Wl,-soname,libmylib.so.0 -o libmylib.so.0.0.0 a.o b.o c.o

然后使用ldconfig安装库,请参阅

man 8 ldconfig

然后您可以编译使用该库的程序,如下所示( 但请务必加上前缀

extern "C"
在使用库的源代码中包含的头文件中的类声明之前。)

g ++ -o myprog main.cc -lmylib

我已经使用自己的示例代码尝试了这些编译选项,并且已经成功。

基本上Shared Libraries中涵盖的内容适用于C ++,只需用g ++替换gcc。

所有这一切背后的理论是;

首次加载程序时动态加载库,这可以通过对正在运行的程序执行系统调用跟踪来确认,例如, strace -o trace.txt ls将程序在执行期间进行的系统调用列表转储到名为trace.txt的文件中。在文件的顶部,您将看到程序(在本例中为ls)确实已将所有库映射到内存中。

由于库是动态加载的,因此在链接时不知道库代码在运行时是否存在于程序的虚拟地址空间中。因此,库代码必须使用与位置无关的代码进行编译 - 因此-fpic选项告诉转换阶段生成已经使用位置无关代码编码的汇编代码。如果您在翻译阶段后使用gcc/g++(大写字母S)选项告诉-S停止,然后使用-fpic选项查看生成的“.s”文件,一旦没有,你会看到差异(即动态代码有@GOTPCREL和@PLT,至少在x86_64上)。

当然必须告诉链接器将所有ELF可重定位对象类型链接到适合用作Linux共享库的可执行代码中。