Linux库文件知识总结
2014-10-30 17:14
183 查看
Linux库文件知识
基本知识
库文件是一组预先编译好的函数集合,这些函数都是按照可重用的原则编写的。
库文件一般存在于/lib和/usr/lib目录中
库文件一般以lib开头
.a代表静态库
创建静态库:ar crv libfoo.a bill.o
fred.o
部分系统创建好了静态库后需要创建一个内容表:ranlib libfoo.a
解压静态库:ar x libfoo.a,可以将一个.a解压成多个.o,用于合并多个静态库。
.so代表动态库(共享库,类似于Windows的dll),它在linux中也叫做共享库
动态库在编译时加上-shared选项来创建
动态库名真正的库一般以libm.so.N来表示,最后一个N代表主版本号,一般使用固定文件名如libm.so链接到库的最新版本,这样可以实现库的动态升级,并且可以看到版本号。
使用ldd可以查看到程序需要的动态库。
使用库文件
直接使用路径引用:gcc -o fred fred.c /usr/lib/libm.a
使用简称引用,库文件需要在库路径下:gcc -o fred fred.c -lm:-l[库名]相当于引用库路径下的lib[库名].a或者lib[库名].so
增加库路径:gcc -o fred fred.c -L./libs -lm
库的依赖
gcc对于库的加载是从后往前进行的,因此,最基础(最被依赖)的库应该放在后面。
使用动态库
使用dlopen、dlsym、dlclose操作.so文件。可以打开库文件,读取库中的函数或者其他变量数据。(TODO:dlsym读取符号失败后会返回NULL,那么dlerror()会不会返回错误信息?是否读取到的dlerror()为NULL就代表dlsym执行成功了?也就是,如何确定dlsym是否执行成功?)
dlopen:打开动态链接库,成功返回动态链接库的索引ID,失败返回NULL。
dlsym:解析动态链接库中的符号资源,成功返回函数指针或者全局变量指针。
dlerror:返回动态链接库的出错信息,如果成功,返回NULL。
查看库中的信息
使用nm查看程序或者库中包含的函数
Linux软件从源代码安装的3个步骤,这也是大部分库的生成方法
./configure
--prefix=/home/user/local #自定义安装路径
--prefix=$HOME #当用户不是root用户时,需要安装软件到自己可写的目录,则使用这条语句进行配置,可以在make完成后将软件安装到用户目录。
make
make install
库路径
查找顺序介绍: http://blog.csdn.net/xuzhihong_gdut/article/details/3836262
动态库的安装
放入/use/lib或者其他的默认库路径中即可,注意32位和64位的区别,库路径存放于:/etc/ld.so.conf
或者将路径放到环境变量LD_LIBRARY_PATH中。
执行ldconfig重载库。
注意:如果需要其他用户使用这个库文件,需要给库文件加上读权限,否则会提示:cannot open shared object file: Permission denied
如果同时存在动态库和静态库,默认情况下会优先使用动态库
-static 在链接时强制使用静态库
--static-libgcc 链接静态libgcc库(其他库这样使用无效)
--shared-libgcc 链接动态libgcc库
指定特定库链接为动态库或者静态库
在动态库前加上-Bdynamic
在静态库前加上-Bstatic
-Wl,-dn后面是静态链接-Wl,-dy后面是动态连接
cc -g -o test_server main_server.o main_db.o err_me.o -Wl,-dn -L/usr/local/mysql/lib/ -lmysqlclient -Wl,-dy -lpthread -lm -ldl -lcrypt
库版本
设计库的时候,如果需要匹配库版本与头文件,可以在头文件中使用库版本作为一个变量名,在cpp文件中定义这个变量名,在头文件中声明这个变量名。如果库与头文件不一致,则编译期间会提示找不到变量。
头文件:
#define SESSION_API_VER 1_0_0
#ifdef GET_STR
#undef GET_STR
#endif // GET_STR
#define GET_STR(tempname) #tempname
#ifdef TO_STR
#undef TO_STR
#endif // TO_STR
#define TO_STR(tempname) GET_STR(tempname)
#ifdef TEXTCAT
#undef TEXTCAT
#endif // TEXTCAT
#define TEXTCAT(text1,text2) text1##text2
#ifdef TEXTCAT2
#undef TEXTCAT2
#endif // TEXTCAT2
#define TEXTCAT2(text1,text2) TEXTCAT(text1,text2)
Cpp文件:
string TEXTCAT2(V, SESSION_API_VER) = TO_STR(SESSION_API_VER);
静态库和动态库的优缺点?动态库和静态库的优缺点,这里只讲优点,优点即是对方的缺点。
动态库的优点:
可以动态替换升级而不改变依赖它的程序,也就是说,程序无需重新编译。
可以作为框架程序的一项扩展,提高扩展性,让其他开发者按照指定的接口开发自己的动态库。
可多个程序共享,降低程序大小。
如上一个问题,可以避免多个库同名函数的冲突。
静态库的优点:
省去一项加载耗时。
大量发布时比较方便,无需加载各种依赖的动态库。
避免了一些动态库兼容问题,比如动态库版本不对导致程序运行异常,提高可控性。
适用于一些无root权限的机器发布,如果安装动态库,需要root权限。
如何选择?
可以根据上述优点,在不同的场合使用不同的库。
为便于可控,在后台服务中,个人比较喜欢使用静态库。
2个库中函数名冲突的解决办法:
可使用动态库的解决方法:可以使用动态库封装2个静态库,程序只加载动态库。
具体动态库为什么可以屏蔽符号名,可能与链接静态库时会寻找符号名写入程序有关,具体细节作为遗留问题再研究研究
不可使用动态库的解决方法:
有库的源文件
修改其中一个库文件的冲突函数。
给其中一个库加入命名空间。
基本知识
库文件是一组预先编译好的函数集合,这些函数都是按照可重用的原则编写的。
库文件一般存在于/lib和/usr/lib目录中
库文件一般以lib开头
.a代表静态库
创建静态库:ar crv libfoo.a bill.o
fred.o
部分系统创建好了静态库后需要创建一个内容表:ranlib libfoo.a
解压静态库:ar x libfoo.a,可以将一个.a解压成多个.o,用于合并多个静态库。
.so代表动态库(共享库,类似于Windows的dll),它在linux中也叫做共享库
动态库在编译时加上-shared选项来创建
动态库名真正的库一般以libm.so.N来表示,最后一个N代表主版本号,一般使用固定文件名如libm.so链接到库的最新版本,这样可以实现库的动态升级,并且可以看到版本号。
使用ldd可以查看到程序需要的动态库。
使用库文件
直接使用路径引用:gcc -o fred fred.c /usr/lib/libm.a
使用简称引用,库文件需要在库路径下:gcc -o fred fred.c -lm:-l[库名]相当于引用库路径下的lib[库名].a或者lib[库名].so
增加库路径:gcc -o fred fred.c -L./libs -lm
库的依赖
gcc对于库的加载是从后往前进行的,因此,最基础(最被依赖)的库应该放在后面。
使用动态库
使用dlopen、dlsym、dlclose操作.so文件。可以打开库文件,读取库中的函数或者其他变量数据。(TODO:dlsym读取符号失败后会返回NULL,那么dlerror()会不会返回错误信息?是否读取到的dlerror()为NULL就代表dlsym执行成功了?也就是,如何确定dlsym是否执行成功?)
dlopen:打开动态链接库,成功返回动态链接库的索引ID,失败返回NULL。
dlsym:解析动态链接库中的符号资源,成功返回函数指针或者全局变量指针。
dlerror:返回动态链接库的出错信息,如果成功,返回NULL。
查看库中的信息
使用nm查看程序或者库中包含的函数
Linux软件从源代码安装的3个步骤,这也是大部分库的生成方法
./configure
--prefix=/home/user/local #自定义安装路径
--prefix=$HOME #当用户不是root用户时,需要安装软件到自己可写的目录,则使用这条语句进行配置,可以在make完成后将软件安装到用户目录。
make
make install
库路径
查找顺序介绍: http://blog.csdn.net/xuzhihong_gdut/article/details/3836262
动态库的安装
放入/use/lib或者其他的默认库路径中即可,注意32位和64位的区别,库路径存放于:/etc/ld.so.conf
或者将路径放到环境变量LD_LIBRARY_PATH中。
执行ldconfig重载库。
注意:如果需要其他用户使用这个库文件,需要给库文件加上读权限,否则会提示:cannot open shared object file: Permission denied
如果同时存在动态库和静态库,默认情况下会优先使用动态库
-static 在链接时强制使用静态库
--static-libgcc 链接静态libgcc库(其他库这样使用无效)
--shared-libgcc 链接动态libgcc库
指定特定库链接为动态库或者静态库
在动态库前加上-Bdynamic
在静态库前加上-Bstatic
-Wl,-dn后面是静态链接-Wl,-dy后面是动态连接
cc -g -o test_server main_server.o main_db.o err_me.o -Wl,-dn -L/usr/local/mysql/lib/ -lmysqlclient -Wl,-dy -lpthread -lm -ldl -lcrypt
库版本
设计库的时候,如果需要匹配库版本与头文件,可以在头文件中使用库版本作为一个变量名,在cpp文件中定义这个变量名,在头文件中声明这个变量名。如果库与头文件不一致,则编译期间会提示找不到变量。
头文件:
#define SESSION_API_VER 1_0_0
#ifdef GET_STR
#undef GET_STR
#endif // GET_STR
#define GET_STR(tempname) #tempname
#ifdef TO_STR
#undef TO_STR
#endif // TO_STR
#define TO_STR(tempname) GET_STR(tempname)
#ifdef TEXTCAT
#undef TEXTCAT
#endif // TEXTCAT
#define TEXTCAT(text1,text2) text1##text2
#ifdef TEXTCAT2
#undef TEXTCAT2
#endif // TEXTCAT2
#define TEXTCAT2(text1,text2) TEXTCAT(text1,text2)
Cpp文件:
string TEXTCAT2(V, SESSION_API_VER) = TO_STR(SESSION_API_VER);
静态库和动态库的优缺点?动态库和静态库的优缺点,这里只讲优点,优点即是对方的缺点。
动态库的优点:
可以动态替换升级而不改变依赖它的程序,也就是说,程序无需重新编译。
可以作为框架程序的一项扩展,提高扩展性,让其他开发者按照指定的接口开发自己的动态库。
可多个程序共享,降低程序大小。
如上一个问题,可以避免多个库同名函数的冲突。
静态库的优点:
省去一项加载耗时。
大量发布时比较方便,无需加载各种依赖的动态库。
避免了一些动态库兼容问题,比如动态库版本不对导致程序运行异常,提高可控性。
适用于一些无root权限的机器发布,如果安装动态库,需要root权限。
如何选择?
可以根据上述优点,在不同的场合使用不同的库。
为便于可控,在后台服务中,个人比较喜欢使用静态库。
2个库中函数名冲突的解决办法:
可使用动态库的解决方法:可以使用动态库封装2个静态库,程序只加载动态库。
具体动态库为什么可以屏蔽符号名,可能与链接静态库时会寻找符号名写入程序有关,具体细节作为遗留问题再研究研究
不可使用动态库的解决方法:
有库的源文件
修改其中一个库文件的冲突函数。
给其中一个库加入命名空间。
相关文章推荐
- 记 Linux 学习知识总结 -- 寒江老师视频(六) - 文件查找与文件管理
- Linux学习笔记之权限与命令之间的关系(重要)及文件与目录知识总结
- 记 Linux 学习知识总结 -- 寒江老师视频(六) - 文件的统计与文件的压缩
- Linux基础知识总结-文件管理
- Linux文件查找及压缩常用知识总结
- Linux基础知识总结(2): 文件的压缩与打包
- linux文件属性知识总结
- Linux运维学习笔记-文件系统知识体系总结
- Linux知识总结05(日志文件+Linux中的网络配置)
- 【Linux基础学习之四】文件系统的基础知识总结(主要目录结构、文件类型、mount、硬连接)
- Linux学习笔记之权限与命令之间的关系(重要)及文件与文件夹知识总结
- Linux基础知识总结-文件
- 记 Linux 学习知识总结 -- 寒江老师视频(三) 文件
- Linux基础知识总结(1): 用户组与文件权限
- linux文件系统基础知识
- Windows与Vmware下的Linux文件共享方式总结
- Linux操作系统文件系统基础知识详解
- linux文件系统基础知识
- Windows与Vmware下的Linux文件共享方式总结
- Linux操作系统文件系统基础知识详解