目录
背景知识
gcc如何完成
格式
预处理(进行宏替换)
编译(生成汇编)
汇编(生成机器可执行码)
连接(生成可执行文件或库文件)
函数库
静态库
静态链接优势
动态库
动态链接优势
区别
区分动静态链接
指定静态链接
指令记忆
背景知识
1.预处理(进行宏替换)
2.编译(生成汇编)
3.汇编(生成机器可执行码)
4.连接(生成可执行文件或库文件)
gcc如何完成
格式
gcc [选项] 被编译文件 [选项] [目标文件]
预处理(进行宏替换)
预处理的功能主要包括宏定义,文件包含,条件编译,去注释
预处理指令是以#号开头的代码行
实例: gcc -E code.c -o code.i
选项 -E,让gcc在预处理结束后停止编译过程
选项 -o是指目标文件
.i是指文件已经进行预处理的c原始程序
编译(生成汇编)
在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在
检查 无误后,gcc 把代码翻译成汇编语言
用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码
汇编(生成机器可执行码)
汇编阶段就是把编译阶段生成的".s"文件转换成目标文件,这个文件是二进制文件,里面都是0和1
实例:gcc -C code.s -o code.o
连接(生成可执行文件或库文件)
在成功编译之后就如链接阶段,文件经过链接,通过函数地址,找到相对应的函数合并到一起生成可执行文件
实例:gcc code.o -o code
函数库
系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到
静态库
这类库的名字一般是libxxx.a;
1、利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了
2、即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点
3、因为如果静态函数库改变了,那么你的程序必须重新编译
静态链接优势
不受库的影响,可移植性比较好,没有与库链接的过程,节省时间
缺点:
如果多个文件都用了同一个库函数,就要拷贝多次,代码冗余量高
因为有大量的拷贝内容,所以静态链接形成的可执行程序比较大
动态库
这类库的名字一般是libxxx.so;
相对于静态函数库
1、动态函数库在编译的时候 并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小
2、由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库,动态函数库的改变并不影响你的程序
3、所以动态函数库的升级比较方便
动态链接优势
1.生成的可执行程序小
2.加载到内存中的速度快
3.节省资源(包括磁盘,网络,内存)
缺点在于:过于依赖动态库,导致程序的可移植性差。
区别
1、静态库是.o文件的合集,动态库是.o文件链接过后的产物。动态库链接过后的产物跟可执行文件是一个等级
2、静态库链接时需要拷贝一份完整的文件到目标文件中,然后一起链接生成可执行文件,而动态库不需要,动态库分动态加载库和动态链接库,动态加载库是程序运行时需要的时候才会被加载到内存中,动态链接库是项目生成的可执行文件被加载到内存中时,顺带着也会将动态链接库加载到内存中,这种方式会导致系统资源浪费。
3、依赖静态库的可执行文件体积较大,而且修改静态库之后需要重新编译生成,而依赖动态库的可执行文件和动态库实际是分开的,动态库改变之后只需要将动态库重新编译链接生成即可,不影响可执行文件
区分动静态链接
file+文件名 查看文件属性
ldd+可执行程序 查看文件所依赖的库
动态链接:前缀为lib,后缀为.so
静态链接:前缀为lib,后缀为.a
指定静态链接
当我不指定时Linux将自动采用动态链接,如果要使用动态链接就要在编译生成可执行文件时加上static 选项gcc test.c -o mytest -static
静态链接比动态链接产生的文件大得多
如果系统中没有动态库只有静态库,那么即使不指定-static,生成的可执行文件也是动态链接的
指令记忆
ESC
iso