关于Linux共享库的一点儿知识
浏览:2923次 出处信息
链接时使用-l指定的库文件都会记录到elf文件里面的,程序加载前的动态链接一定会加载的,不管你的程序是否会用到;如:
======= phpor.c ============
- #include <stdlib.h>
- void phpor_hello() {
- printf("hello\n");
- }
#include <stdlib.h> void phpor_hello() { printf("hello\n"); }
======= phpor_test.c =============
- //void phpor_hello();
- int main(int ac, char **av) {
- // phpor_hello();
- printf("no dependent \n");
- return 0;
- }
//void phpor_hello(); int main(int ac, char **av) { // phpor_hello(); printf("no dependent \n"); return 0; }
----------------------------------
# gcc -o phpor_test -l phpor -L. phpor_test.c
# LD_LIBRARY_PATH=. ./phpor_test
no dependent
# LD_LIBRARY_PATH=. ldd ./phpor_test
libphpor.so => ./libphpor.so (0x00e4f000)
libc.so.6 => /lib/tls/libc.so.6 (0x00865000)
/lib/ld-linux.so.2 (0x00846000)
你可以把libphpor.so 删掉,执行的时候就报错了
2. 关于共享库的版本号:
我创建了一个so文件 libphpor.so.1 ,现在我要编译一个phpor_test的文件,该文件依赖libphpor.so.1,于是有如下命令:
gcc -o phpor_test -l phpor -L. phpor_test.c
我的libphpor.so.1 是在当前目录下的,所以 -L.
如果我不创建软连接 libphpor.so => libphpor.so.1 的话,则是无法连接的。 为什么不能直接使用 libphpor.so.1 呢? 关键是:
# ldd /bin/ls
librt.so.1 => /lib/tls/librt.so.1 (0x00ce9000)
libacl.so.1 => /lib/libacl.so.1 (0x00f7f000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00a22000)
libc.so.6 => /lib/tls/libc.so.6 (0x00865000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x009f5000)
/lib/ld-linux.so.2 (0x00846000)
libattr.so.1 => /lib/libattr.so.1 (0x00502000)
为什么ls这个命令就能依赖一个带有主版本号的库,而我就不能依赖指定的主版本号?
我只好创建一个软连接 libphpor.so => libphpor.so.1 ,因为该so文件没有在LD_LIBRARY_PATH 下,所以,这里测试时临时指定一下:
LD_LIBRARY_PATH=. ./phpor_test
3. 关于共享库、静态库和动态链接、静态链接的概念
共享库、静态库
强调的是:动态链接、静态链接:
我能否被其它程序动态加载特点:
- 静态库(不是静态链接的可执行程序)可能(也可能不)依赖别的未定义的符号,但是,自己不知道(也不会说明)这些符号在那里可以找到,即: 不描述依赖关系
- 共享库可能(也可能不)依赖别的未定义的符号,但是,自己会说明这些符号可能在哪里可以找到,即:描述依赖关系
- 其实,静态库实际是没有经过链接的,只是一些目标文件的打包;共享库是经过了链接这个步骤了的
强调的是:库类型与链接类型之间的关系:
我(就是链接的结果文件,可能是一个可执行文件,也可能是一个共享库so文件,注意,so文件有的也可以直接执行,但一定不是静态库文件)在运行的时候,是否依赖别的动态库文件。特点:
- 动态链接的文件一定依赖其他的so文件,至少要依赖 ld.so
- 静态链接的文件一定不依赖其他的so文件
- 共享库也可以是静态链接的,如:
# ldd /lib/ld-linux.so.2
statically linked - 可以使用共享库来静态链接生成一个静态的可执行程序,如:
LD_LIBRARY_PATH=. gcc -o phpor_test -static -l phpor -L. phpor_test.c - 你也可以使用静态库来动态链接生成一个动态的可执行程序, 如:
# gcc -o phpor_test phpor_test.c ./libphpor.a
# ./phpor_test
hello
# ldd phpor_test
libc.so.6 => /lib/tls/libc.so.6 (0x00b9a000)
/lib/ld-linux.so.2 (0x00b7b000)
4. 我们说,共享库也可以是静态链接的,下面我们做一个实验,把上面的phpor.c 编译成一个静态链接的共享库文件:
因为linux几乎所有程序都依赖libc.so, 现在要静态链接,就需要指定需要的.a 文件 libc.a, 在/usr/lib下; 一般默认是动态链接的,如果要静态连接,就需要使用 -static 选项指定,命令如下:
gcc -shared -static -o libphpor.so.2 /usr/lib/libc.a phpor.c
但是,这样编译的结果还是动态链接的,为什么? -static 没有起作用吗?
使用如下命令:
# gcc -shared -nodefaultlibs -o libphpor.so.2 /usr/lib/libc.a phpor.c
# ldd libphpor.so.2
statically linked
当然,您可以同时使用 -nodefaultlibs和 -static ; 不明白的是: 难道static不是用来屏蔽其它的动态库文件的吗?
先生成目标文件,自己使用ld命令来做静态连接:
# gcc -o phpor.o -c phpor.c
# ld -shared -dn -o libphpor.so.3 phpor.o
# ldd libphpor.so.3
statically linked
# ln -s libphpor.so.3 libphpor.so
# LD_LIBRARY_PATH=. ./phpor_test
hello
又有问题了,为什么我没有指定/usr/lib/libc.a , 这里却能链接完成,而且还能用了呢?难道ld帮我做了?
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:什么是导出(export)环境变量
后一篇:Vim(gVim)对排序的妙用 >>
文章信息
- 作者:phpor <lijunjie1982@yahoo.com.cn> 来源: PHPor 的blog
- 标签: 共享库
- 发布时间:2012-01-29 20:47:14
近3天十大热文
- [55] IOS安全–浅谈关于IOS加固的几种方法
- [54] android 开发入门
- [54] 如何拿下简短的域名
- [54] 图书馆的世界纪录
- [52] Go Reflect 性能
- [52] Oracle MTS模式下 进程地址与会话信
- [49] 【社会化设计】自我(self)部分――欢迎区
- [48] 读书笔记-壹百度:百度十年千倍的29条法则
- [41] 程序员技术练级攻略
- [35] 视觉调整-设计师 vs. 逻辑