gcc后续——链接时的静态库和动态库

简介: gcc后续——链接时的静态库和动态库

1 . 库

库:

分为静态库和动态库(本质也是文件)

静态库:libXXXX.a

动态库:libXXXX.so

检测linux所用库

ldd 可执行程序,检测可执行程序被形成的时候依赖那些库

[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. 静态库和静态链接

  • 链接的时候,如果是静态链接,找到静态库,拷贝静态库中的我所需要的代码到自己的可执行程序中
  • 静态链接成功:我们的程序,不依赖任何库,自己就可以独立运行

2. 动态库和动态链接

  • 链接的时候,如果是动态链接,找到动态库,拷贝动态库中的我所需要的代码地址到自己的可执行程序中
  • 静态链接成功:我们的程序,还是依赖动态库,一旦动态库缺失,我们的程序就无法运行

2. 动态库和动态链接

  • 链接的时候,如果是动态链接,找到动态库,拷贝动态库中的我所需要的代码地址到自己的可执行程序中
  • 静态链接成功:我们的程序,还是依赖动态库,一旦动态库缺失,我们的程序就无法运行

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
• 1

使用后缀为 -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多万
  • 说明静态库所需的体积远比动态库的体积多得多
相关文章
|
3月前
|
NoSQL 编译器 开发工具
006.gcc编译器
gcc是什么?
45 0
006.gcc编译器
|
4月前
|
存储 NoSQL 算法
从一个crash问题展开,探索gcc编译优化细节
问题分析的过程也正是技术成长之路,本文以一个gcc编译优化引发的crash为切入点,逐步展开对编译器优化细节的探索之路,在分析过程中打开了新世界的大门……
428 1
|
15天前
|
C语言
转载 - gcc/ld 动态连接库和静态连接库使用方法
本文介绍了如何在GCC中实现部分程序静态链接、部分动态链接。使用`-Wl`标志传递链接器参数,`-Bstatic`强制链接静态库,`-Bdynamic`强制链接动态库。
21 0
|
1月前
|
编译器 C语言 C++
列举gcc 常见和有用的编译警告选项
列举gcc 常见和有用的编译警告选项
13 0
|
1月前
|
编译器 C语言
gcc编译警告:warning: suggest parentheses around assignment used as truth value
gcc编译警告:warning: suggest parentheses around assignment used as truth value
23 0
|
1月前
|
编译器 Linux C语言
gcc编译器的使用方法
gcc编译器的使用方法
22 1
|
2月前
|
编译器 C语言
gcc/g++语法
gcc/g++语法
|
4月前
|
C语言
gcc静态编译/usr/bin/ld: cannot find -lc
gcc静态编译/usr/bin/ld: cannot find -lc
|
5月前
|
编译器 程序员 C语言
gcc的编译过程和gcc与g++的区别
gcc的编译过程和gcc与g++的区别
55 0
|
6月前
|
C语言
编译安装gcc
编译安装gcc