本篇文章是链接阶段静动态库的理解,/font点击查看gcc四个阶段@TOC 1 . 库 库: 分为静态库和动态库(本质也是文件)静态库:libXXXX.a动态库:libXXXX.so 检测linux所用库 ldd 可执
本篇文章是链接阶段静动态库的理解,</font>点击查看gcc四个阶段 @TOC
1 . 库
库:
分为静态库和动态库(本质也是文件)
静态库:libXXXX.a
动态库:libXXXX.so
检测linux所用库
ldd 可执行程序
,检测可执行程序被形成的时候依赖那些库</font>
[yzq@VM-8-8-centos my]$ gcc -o testc test.c
[yzq@VM-8-8-centos my]$ ldd testc
linux-vdso.so.1 => (0x00007ffe309cd000)
libc.so.6 => /lib64/libc.so.6 (0x00007f42b7c37000)
/lib64/ld-linux-x86-64.so.2 (0x00007f42b8005000)
使用gcc 编译一个可执行程序 testc,并检测出testc所依赖的库 libc.so.6 => /lib64/libc.so.6 (0x00007f42b7c37000)
查找库的位置
[yzq@VM-8-8-centos my]$ ldd testc
linux-vdso.so.1 => (0x00007ffd62f34000)
libc.so.6 => /lib64/libc.so.6 (0x00007f0db8e70000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0db923e000)
[yzq@VM-8-8-centos my]$ ls /lib64/libc.so.6
/lib64/libc.so.6
[yzq@VM-8-8-centos my]$ ls /lib64/libc.so.6 -l
lrwxrwxrwx 1 root root 12 Jul 25 16:58 /lib64/libc.so.6 -> libc-2.17.so
使用 ls 指令找到库的位置,
实际上是一个软链接,指向c-.217
以后缀.so为例
前缀lib.XXXX后缀.so,在是识别库时,一般去掉前缀和后缀,只剩下XXXX 所以c语言的c标准库为 c-2.17
2. 动静态库的感性理解
1. 动态库的理解
- 假设你为准高中学生,刚进行完中考,
你就提前问了学长学校附近的网吧在哪里,学长告诉你在学校北门200米的地方
等到开学某一天,你先写了一上午的作业,有些累了,所以想去上网放松一下,到了网吧,你选了个靠窗户的座位happy了一会后,回到了学校,继续完成了剩下的作业我们想好要做什么的清单,可以看作一个程序,
在清单中我们可以自己实现如:数学作业、语文作业等价于代码实现for循环、while循环但总有一些我们无法完成,所以只能跳转过去由库中执行
如:上网这个操作,我们无法在学校内执行,只能去网吧
,网吧就相当于动态库的存在,进入网吧需要跟网管说开那台机器,就好比库的查找方式,帮你快速找到你想要的方法,
上网happy这个过程,就相当于调用库函数,上完网后,回到程序中继续执行程序
- 假设学校南门有一个派出所,已查明北门的网吧是一个黑网吧,所以小太阳网吧就被查封了,学校内的学生除了我之外,还有很多人也问过学长,学长也都给他们建立了链接
- 说明网吧提供的上网的能力是被所有人共享的等价于
动态库可以被共享,而共享的库只需要一个就够了, 好比网吧在附近只有一个存在此时包括我在内的学校的学生就无法通过北门去网吧上网了 共享库被取缔,所有依赖于这个库的程序都无法运行了动态链接:将你所需要的库中的代码的地址拷贝到你的程序中
2. 静态库的理解
- 假设你在期末考试考的比较好,你爸问你要什么奖励,你说你想要一台电脑,于是等到开学时你爸就去了网吧,在网吧中购置了一台,并给你买到了宿舍中,当放假你的舍友喊你去上网,你说你有电脑了不去网吧了
- 你爸就充当了链接器,程序中要用printf函数等时,就在库中寻找到,并将代码拷贝一份到程序
- 静态链接:将你所需要的库中的代码拷贝到你的程序中
假设南门有个派出所,将黑网吧取缔了,此时我因为自己有电脑,所以依旧可以上网
一旦静态链接成功,就不会依赖于库
3. 静动态库整体理解
动态库为专门让编译器,对用户的程序进行动态链接 静态库为专门让编译器,对用户的程序进行静态链接
1. 静态库和静态链接
- 链接的时候,如果是静态链接,找到静态库,拷贝静态库中的我所需要的
代码到自己的可执行程序中静态链接成功:我们的程序,不依赖任何库,自己就可以独立运行
- 动链接的时候,如果是动态链接,找到动态库,拷贝动态库中的我所需要的
- 静态链接成功:我们的程序,还是依赖动态库,一旦动态库缺失,我们的程序就无法运行
3. 静动态库对比
- 静态库:因为自身拷贝问题,比较浪费空间
- 动态库:因为可以被共享,所以真正的实现永远都是在库中,程序内部只有地址,比较节省空间
1.查询当前linux所用库
使用 file+可执行程序
查询动/静态库
[yzq@VM-8-8-centos me]$ file mytest
mytest: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0f75ec79d4816fd89e85de04b8bb48f9897dcc6f, not stripped
dynamically linked (uses shared libs) , 说明 mytest 可执行程序,动态链接使用动态库 说明linux默认使用动态库和动态链接
2. 查看动态库体积
[yzq@VM-8-8-centos me]$ ls -l
total 20
-rw-rw-r-- 1 yzq yzq 73 Jan 10 12:47 makefile
-rwxrwxr-x 1 yzq yzq 8560 Jan 10 15:41 mytest
-rw-rw-r-- 1 yzq yzq 245 Jan 10 12:59 test.c
说明mytest可执行程序的动态库下的体积为8000多
3. 静态库安装
云服务器默认只会安装动态库,静态库需要自己下载
[yzq@VM-8-8-centos me]$ sudo yum install -y glibc-static
4. 查看静态库体积
gcc -o mytest-static test.c -static
使用后缀为 -static ,切换成静态库
[yzq@VM-8-8-centos me]$ ls -l
total 864
-rw-rw-r-- 1 yzq yzq 73 Jan 10 12:47 makefile
-rwxrwxr-x 1 yzq yzq 8560 Jan 10 15:41 mytest
-rwxrwxr-x 1 yzq yzq 861752 Jan 10 15:57 mytest-static
-rw-rw-r-- 1 yzq yzq 245 Jan 10 12:59 test.c
- 动态库体积只有8000多,而动态库体积80多万
- 说明静态库所需的体积远比动态库的体积多得多