一、编译的过程
1、背景知识
-
- 预处理(进行宏替换)
-
- 编译(生成汇编)
-
- 汇编(生成机器可识别代码即二进制目标文件)
-
- 链接(生成可执行文件或库文件)
2、gcc如何完成
2.1、预处理(进行宏替换)
(1)预处理功能——包括宏定义,文件包含,条件编译,去注释等
gcc –E test.c –o test.i
-E 让 gcc 在预处理结束后停止编译过程。
-o 指明生成的临时文件的名称(.i)。Linux系统不认后缀,.i后缀是给用户看的。
预处理指令是以 # 号开头的代码行。
(2)外部定义宏(-D选项)
gcc test.c -Dc=5 #在外部给test.c定义c=5
gcc test.c -DJLY #在外部给test.c定义宏JLY
2.2、编译(生成汇编)
gcc –S test.i –o test.s
-S表示进行程序的编译工作,编译完成之后就停止。
在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
2.3、汇编(生成机器可识别代码)
gcc –c test.s –o test.o
-c 选项进程程序的翻译,做完汇编工作,变成可重定向目标二进制,就停下来
2.4、链接(生成可执行文件或库文件)
gcc test.o –o test
链接的过程,形成可执行程序,可执行的二进制程序(库+自己的代码)
二、动态链接和静态链接
1、静态链接
静态链接是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。
静态链接的优缺点
优点:不依赖第三方库,程序的运行可移植性较好。
缺点:形成的可执行程序体积大。
2、动态链接
在编译链接时
并没有把库文件的代码加入到可执行文件中,而是在程序执行时
由运行时链接文件加载库。
简单的说就是建立动态链接需要去C标准库等外部库里找对应的函数等。
动态链接的优缺点
优点:形成的可执行程序较小,加载到内存的时间快,下载便捷。节省磁盘存储空间
缺点:依赖动态库,程序的可移植性比较差。(运行时问题)
3、程序动、静态链接的区分
3.1查看程序是何种链接
file 可执行程序
这是动态链接
这是静态链接
3.2 查看程序依赖的动态库
ldd 可执行程序
动态库以 “.so” 作后缀
静态库以 “.a” 作后缀
Linux中库的命名:去掉前缀lib,去掉后缀.so,剩下的就是库的名称。例如libc.so.6中所依赖的库为c库。
3.3静态程序的生成
Linux中可执行程序默认使用动态链接,需要静态程序可以在后加上 -static。
sudo yum install glibc-static #安装C静态库
sudo yum install libstdc++-static #安装c++静态库
gcc test.c -o test_s -static #生成静态程序 mytest_static
如果系统中没有动态库,仅有静态库,那么即便不加-static,生成的可执行程序也是静态链接的。
Windows下动、静态库的区分
.dll//动态
.lib//静态