linux 静态库使用经验
在编写程序的过程中,对于一些接口往往抽象成lib库的形式,甚至有些程序只有一个主程序,其他接口的调用都是库的形式存在。较多的使用库会比较利于程序的维护,因为我们的程序都可以被其他的人使用,但是往往库的存在会增加一些编译上的问题。
在linux中有静态库和动态库两种,两者各有优劣,对于后端伺服的服务器来说,我们更倾向于静态库,因为它部署方便,效率更高,而后端的服务器并不在意那些静态库多占用的内存。
对于静态库我们要先理解其原理,静态库是一些目标文件的集合,通常为后缀为.o的文件,通过ar命令打包而成,一般命名的格式为libXXX.a。在用户创建可执行程序的过程中,同-L指定静态库的地址,通过-lxxx指定静态库的名称,完成静态库到主程序的链接。静态库只在程序链接的时候起作用,最终的程序脱离静态库运行。对于静态库我们有下面的理解:
1) 静态库的生成过程是一个编译的过程,即只要.o文件生成了,就可以生成静态库。如果.o文件中依赖了其他静态库或者动态库,在编译静态库的时候不需要指定;
2) 鉴于1)在可执行程序编译使用静态库的时候,必须自己指定静态库依赖的其他库,否则链接的时候会报错,找不到一些函数。(这个地方不合理,静态库的产生者才更清楚它依赖哪些库,现在反到要使用者关心?)
3) 编译依赖库的依赖关系,越基础依赖的在后面,比如liba.a依赖libb.a,则在gcc中应该先 -la 再-lb。可以通过xlinker参数来控制不考虑库的访问顺序:-Xlinker "-(" –L ./lib –la –b -Xlinker "-)", 链接器在处理”-(”和”-)”之间的静态库时,会重复查找这些静态库,从而解决了静态库的查找顺序问题。这种方式比人工提供链接顺序的方式效率会低很多,但是在较大的项目里面,我们仍然建议使用这个参数。
4) 如果一个可执行程序需要依赖几个静态库,而这些静态库的一些头文件声明了相同的函数,链接的时候会产生冲突报错,即使你的可执行程序即没有使用这些函数也没有引用它们的头文件。一个解决的办法就是使用命名空间。
5) 既有动态也有静态的同名库的时候,优先调用的是动态库;如果是只是使用静态库可以通过参数–Bstatic 指定,它等价于-dn、-non_shared、-static。