目录
一,gcc简介
二,C语言源文件的编译过程
1.预处理
2.编译
3.汇编
4.链接
5.动静态库
一,gcc简介
相信有不少的小白和我一样在学习Linux之前只听说过visual studio。其实这个gcc这个编译器实现的功能便是和visual studio一样的功能,但是gcc只能够支持c语言。如果要支持C++的话便要用到g++。
二,C语言源文件的编译过程
1.预处理
在C源文件运行时做的第一步便是预处理,在预处理的过程中要做的便是:
1.头文件展开。
2.去掉注释。
3.条件编译。
4.宏替换。
这上面的四步便是预处理时要做的四步。那我们在Linux中要如何的去观察这一个过程呢?这个时候便要使用到一个Linux的指令了。这个指令便是——gcc -E:代表的意思便是开始编译C源文件等到预处理结束以后便停止翻译。可以来段代码来看看效果。如以下代码:
#include<stdio.h> //头文件 2 #define M 123 //宏定义 3 #define v1 1 4 #define v2 0 5 #define v3 0 6 int main() 7 { 8 printf("hello Linux:%d \n",M); 9 printf("hello C++ :%d \n",M); 10 11 // printf("hello Linux:%d \n",M);//注释 12 // printf("hello C++ :%d \n",M); 13 // 14 // printf("hello Linux:%d \n",M); 15 // printf("hello C++ :%d \n",M); 16 17 #if(v1) //条件编译 18 printf("普通版本\n"); 19 #elif(v2) 20 printf("会员版本\n"); 21 #else 22 printf("超级会员版本\n"); 23 #endif 24 25 return 0 ; 26 }
当我执行如下指令时:gcc -E texe2.c -o code.i。当我们输入这条指令时便会得到一个code.i文件。当用vim进到这个文件里面是便会看到头文件被展开了,宏被替换掉了,注释被删掉了,预处理指令只有条件成立的那一部分被留下来。
2.编译
这个编译便是代码翻译的第二步,在这个过程中我们要做的便是将英文代码变成汇编代码。在Linux 系统下输入gcc -S ,这条指令便可以生成一个经过编译后的汇编文件。比如对上述的code.i文件进行编译-gcc -S code.i -o code.s,便会得到这样一个汇编文件:
这样子便将c源文件给弄成了汇编文件了。
3.汇编
在这个过程中要做到的便是将汇编文件翻译为重定向的二进制文件。在Linux系统下输入指令:gcc -c便可。如对上述的code.s文件进行翻译便可以输入指令-code -c code.s -o code.o。在执行完这个指令以后便会形成一个code.o文件。用vim打开该文件便会是这样一个光景:
因为vim是文本编辑器,但是code.o文件却是二进制文件所以就会出现这样的错误。要打开二进制文件要调用另一个指令——od。打开后便是这样的:
我们自然是看不懂的,但是计算机就能看懂。在进行到这一步以后一个二进制文件也就是目标文件便生成了。但是此时我们还不能运行。
4.链接
生成目标文件以后,如果要运行的话便要经过链接这一步。经过了链接这一步以后代码才可以变成一个可执行文件。在Linux环境下就是输入指令gcc 。对于上述的code.o文件也就是输入指令 ——gcc code.o -o mybin:
5.动静态库
1.库的分类
其实可执行文件 = 头文件+代码+库。在这里头文件相当于一个功能函数声明的集合,代码就是我们调用功能函数的指令,库便是各种功能函数的定义。在这里的库便分为两种库,一种叫做动态库,一种叫做静态库。动态库的后缀是so,静态库的后缀是.a。在Linux环境下输入指令ls /usr/lib64/libc.so.6便可以查看这个动态库。
得到这个蓝色的路径便是动态库的路径。lib表示库,c表示动态库的名字,so表示是动态库,6表示版本。
2.链接方式
在Linux中有两种链接方式。一种是动态连接方式,一种是静态链接方式。这两种不同的链接方式各自有各自的优点。动态链接形成的可执行程序比较小,静态链接形成的可执行序比较大。这两种差别是因为这两种链接调用库中功能函数的方式的不同导致的。
1.动态链接是通过函数的地址来调用的,静态链接是通过将函数拷贝到可执行文件中来调用的。
2.动态库的函数调用会受到动态库的存在与否影响,但是静态库则不受这个影响。