在用c c++编程时经常用到库,库有静态的,和共享库。在这里我只是说linux系统下的静态库和共享库。有人把共享库称为“动态库”,这是相对于“静态库”而言的,是为了说明在程序链接它时的不同。不过从更宏观的层次上叫它共享库更贴切。
用例子说明吧:
现在有这几个文件:
zerg.h zerg.cpp hydralisk.h hydralisk.cpp
需要用库的形式提供。
制作静态库:
1.编译
gcc -c zerg.cpp hydralisk.cpp
编译出zerg.o hydralisk.o。
然后用一个命令“ar”,把所有的.o文件打包,生成静态库libzerg.a
2.打包
ar -qcs -o libzerg.a zerg.o hydralisk.o
总结:可见,静态库就是对一些.o文件的打包而已。只编译,不链接。提供静态库其实不太实用,一般都是提供共享库,如果需要调试的话,就直接提供源码好了。静态库的优势仅仅是比共享库效率高一小点。
制作共享库:
1.编译
g++ -fPIC -c zerg.cpp hydralisk.cpp
编译出zerg.o hydralisk.o。 和上面编译静态库时不同的是,需要指定"-fPIC"选项。 PIC(position indepedent code) , 共享库在运行时链接,不能预先知道装载的内存地址,所以要用-fPIC告诉编译器。
2. 链接
g++ -shared -o libzerg.so.1.0.0 zerg.o hydralisk.o
这样就生成了共享库libzerg.so.1.0.0
这两步都是用g++完成的,所以两步可以合成一步,如下命令可以直接把源码编译成共享库:
一步生成:
g++ -shared -fPIC -o libzerg.so.1.0.0 zerg.cpp hydralisk.cpp
共享库的版本控制:
参考资料:
共享库的版本控制段落摘自:
http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246091138e0b924260d57938327365ff8540abdb6652969423db39bcc8849dbb8866d72c8713b3547da174f9658b8cb3732b12b872ae9b86893ad874484afa2c4af2044bd53127af1e7fb581763ce7880172693d18e49654860cefa466fe82f733eee27&p=c96ad615d9c044e90be290121100&user=baidu&fm=sc&query=windows+%B9%B2%CF%ED%BF%E2+%B0%E6%B1%BE%BF%D8%D6%C6&qid=d6505642138c09ac&p1=10
linux下的so文件不具有像windows下的额外属性。为了标识一个so的版本,gcc链接生成so目标时一般都采用libxxx.so.1.0.0的方式。
这样把so的版本信息记录在文件名里面。这个带版本信息的文件名就是realname。
那么exe可执行文件如何记录自己依赖的so呢,如果记录的是so的realname,那么so有新版本升级时,新的so必定具有不同的realname,exe就无法自动使用更新的so了。
好在linux下有软链这样的机制可以解决该问题。exe中不必记录依赖的so的realname,exe中记下一个指向实际realname的软链即可,这个软链就是soname啦。soname一般采用这样的名字 libxxx.so.1(保留大版本号1)
当有一个功能更新的so发布时,只需修改soname软链,指向升级后的realname文件即可。
比如我发布了xxx动态库的升级版 libxxx.so.1.0.1, 使软链libxxx.so.1指向libxxx.so.1.0.1即可。
soname是我们在编译其他程序时,往其他程序的二进制映像里面写入的共享库的名字。
那么什么是linkname呢?顾名思义,就是编译代码时的链接阶段使用的,比如我有一个程序需要链接libxxx.so.1.0.0库,
makefile需这样写 -lxxx.so.1.0.0,这r样写实在很长也很丑,而且如果后续libxxx有更新时,必须修改makefile文件才能链接到新的库上。
所以出现了一个新的链接到realname的软链,这个软链就叫 linkername。通常lingkername是不带任何版本信息的,取名如下 libxxx.so
这样makefile就变成了 -lxxx.so
这其中有一个问题,动态库的使用者(比如exe)是通过linkername链接的,而lingkername指向的是so的realname,我们前文说为了解决升级so重新编译的问题,exe文件里面记录的是其依赖的so的soname名字,而不是真实的realname,
那么exe是如何知道realname对应的soname呢?
答案在realname文件里面,在编译链接生成realname时, 同事也指定了其对应的soname,这个soname存储在realname的文件里面。
eg 如下编译命令:
gcc -g -Wall -shared -Wl,-soname,liberr.so.1 -o liberr.so.1.0.0 liberr.o -lc // liberr.so.1是soname,将记录在生成的liberr.so.1.0.0文件里面
可以通过如下工具查看一个realname的so的对应的soname:
readelf -d ./liberr.so.1.0.0
Dynamic section at offset 0xf10 contains 22 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000e (SONAME) Library soname: [liberr.so.1] ===============< 其soname
分享到:
相关推荐
在Linux操作系统中,库扮演着至关重要的角色,它们是预先编译的代码集合,允许开发者重用和集成已经实现的功能,而无需从零开始编写代码。...理解和掌握静态库与共享库的使用和管理对于任何Linux开发者都是至关重要的。
1. 工程中包含静态库A,动态库B,可执行程序C。C依赖于A和B,而B依赖于A。在A中定义有全局变量X(或类的静态成员变量),则在动态库B中访问的X,与可执行程序C中访问的X是同一个变量还是两个不同的变量? 答案:是两...
库通常分为两种主要类型:静态库和动态库(共享库)。这两种库各有优缺点,适用于不同的场景。 静态库,通常以.lib文件格式存在,其特点是将库中的函数和数据直接嵌入到最终的可执行文件中。这意味着当编译程序时,...
### 静态库、共享库、动态库的创建与使用 #### 一、静态库的理解与使用 **定义:** 静态库(Static Library)是一系列预编译的目标文件(Object Files)的集合,通常以`.a`为扩展名。在程序链接阶段,链接器会根据...
GCC 静态库和共享库的生成及调用 GCC 编译器为我们提供了两种类型的库:静态库(archive,扩展名.a)和共享库(又叫动态库,扩展名.so)。无论是静态库还是共享库,都是由.o 文件创建的。每个.o 文件都包含这个编译...
本教程将深入探讨如何在Windows XP环境下,利用Qt 4和MinGW编译器创建和使用静态库与动态库。 首先,让我们理解静态库和动态库的基本概念。静态库(.lib文件)是将库函数编译到目标代码中,形成一个完整的可执行...
### Linux静态库与动态库详解 #### 一、引言 在Linux环境下,库是一种重要的软件组件,用于封装一组相关的函数或数据结构,以便于在不同的应用程序之间共享代码。库通常分为两大类:静态库(static libraries)和...
创建静态库的流程与动态库类似,但不需要最后一步生成动态库。使用静态库的程序在运行时体积较大,但不受系统动态库版本影响。 使用动态库和静态库的方式有所不同。对于动态库,需要确保目标系统上已经安装了相应的...
标题提到的"opencv-1.1静态库"是针对早期OpenCV 1.1版本的一个特殊构建,通常OpenCV会提供动态库(.dll文件),但在这个情况下,提供了静态库(.lib文件)。 静态库和动态库是两种不同的库文件类型。静态库在编译时...
本篇将深入探讨如何使用CMakeLists来生成静态库、动态库,并创建测试程序进行验证。 首先,我们要理解静态库和动态库的区别。静态库(.a 或 .lib)是在编译时将库代码直接嵌入到目标程序中,形成一个完整的可执行...
本资料主要探讨的是Linux中的静态库与动态库的链接装载过程,以及如何理解和使用它们。 静态库,通常以`.a`文件格式存在,它将所有依赖的代码直接嵌入到目标程序中。当编译程序时,链接器会将静态库中的函数和数据...
3. **动态库与静态库**: - **动态库**(.dll文件):在程序运行时由操作系统加载,多个程序可以共享同一份库副本,节省内存。但是,动态库的缺失或版本不匹配可能导致运行时错误。 - **静态库**(.lib文件):在...
动态库(Dynamic Link Library,简称DLL)是一种共享库,程序运行时才加载到内存中,多个程序可以共享同一份库的拷贝,节省内存。而静态库(Static Library)则是在编译时将库代码直接链接到目标程序中,使得程序...
- 静态库:每个使用静态库的程序都有库的副本,可能导致更大的内存占用,但避免了共享库可能导致的竞争条件或同步问题。 **3. 体积与发布**: - 动态库:生成的可执行文件较小,便于分发,但需要确保目标环境有...
与静态库不同,动态库在运行时被加载到进程内存中,多个程序可以共享同一份库文件,节省系统资源。当程序运行时,需要动态库的函数和数据是在运行时通过动态链接器(Loader)加载的。动态库的文件扩展名通常是.dll或...
### Linux静态库的生成与使用 #### 一、概述 在Linux环境下,静态库是一种非常重要的资源管理方式,它能够帮助开发者将多个模块或者组件整合到一个可重用的库中,进而提升软件开发的效率和质量。本文将详细介绍...
与静态库相比,动态库可以减少内存占用,多个程序可以共享同一份库代码。但在Windows系统上,如果目标机器缺少相应的动态库,程序可能无法运行。因此,当使用动态库时,记得将它们部署到系统路径或应用程序目录下。 ...
Linux平台上静态库和共享库的使用方法 Linux 函数库介绍 函数库可以看做是事先编写的函数集合,它可以与主函数分离,从而增加程序开发的复用性。Linux 中函数库可以有 3 种使用的形式:静态、共享和动态。 静态库...