在linux学习2中,我们完成对main.c、hello.c和hello.h这三个文件的编写,并且通过gcc编译器实现对perintf()中的内容进行打印输出。下面对gcc编译文件的具体流程进行解读:
1:预处理阶段:主要内容为将代码文件预处理指令翻译为编译器可识别形式。
将main.c和hello.c文件转化为main.i和hello.i文件(通过gcc -E 命令来实现)
.i文件可通过vscode软件对其进气查看:具体内容如下:
2:编译阶段:预处理后的编译文件代码转化为编译代码:
将main.i和hello.i转化为main.s和hello.s文件形式(通过gcc -S(s为大写)命令来实现)
.s文件通过vscode查看,可表示为:
3:汇编阶段:将编译代码(汇编代码)转变为机器语言代码
将main.s和hello.s转化为main.o和hello.o形式。(通过gcc -c(c为小写)命令来实现)
.o文件为二进制代码,无法通过vscode软件进行查看。但是可在系统终端通过命令(objdump命令对其进行查看)
4:链接文件:将main.o与运行时需要用到的其他.o文件和头文件进行连接。
hello.c中用到printf()函数,而其在stdio.h中进行声明,却来自于glibc库中。
链接方式有:静态链接、动态链接和混合链接
(1) 静态链接:将目标文件和所需的库一起打包到可执行文件中,不需要在运行时加载外部库。
实现:通过gcc -static 命令来进行实现(main可执行文件)
(2)动态链接:需要在运行程序时加载外部库
实现1:直接使用gcc 对main.c 和hello.c进行处理,即为动态链接。(main1可执行文件)
实现2:对hello.o生成动态库libhello.so。
将main.o和hello.so动态库进行连接生成main2
运行main2报错:需要将动态库libhello.so的路径进行添加。之后即可实现
3:混合链接:某些库使用静态链接、某些库使用动态链接:
在第一个程序中:对上述生成的hello.o进行静态链接(静态库:.a结尾)
对stdio.h进行动态链接(动态库:.so结尾)
hello.o生成静态库:ar crv命令操作,生成静态库libhello.a
将main.o链接libhello.a静态库,可直接生成可执行文件main3,执行main3,打印输出结果: