目录
gcc 是一个将C语言文件变成可执行文件的工具。
在Linux中,如果需要将一个C语言文件变得可以执行,那么除了这个文件本身的内容是C语言编写的内容外,还需要gcc这个编译工具进行编译才行。
gcc 使用的格式方法:
gcc 要编译的文件
//在该代码下,gcc默认会将编译后的可执行文件改名为 a.out
//但是这种编译方式是最新版本的,老版本可能不支持,所以在编译的过程中需要一点改变
gcc 需要编译的文件 -std=c99
//而若想要换一个名字,使得编译出的文件不在是a.out 则需要使用以下代码
gcc 需要编译的文件 -o 新名字 -std=c99
//或是
gcc -o 新名字 需要编译的文件 -std=c99
默认用法
改名用法
另外,用于编译c++的g++命令也可以编译C语言,且g++编译c++的方法和gcc编译C语言的方法大致相同,但不同的是gcc并不能编译c++
gcc的翻译(编译)过程:
gcc的翻译过程总共可以分为四步,分别是预处理、编译、汇编、链接。
预处理:
以 test.c文件为例进行预处理,需要注意的test.i是自己定义的文件名字,而且.i一般是预处理文件的后缀
gcc -E tset.c -o test.i
//-E的含义是从现在开始进行程序的翻译,预处理完成就停下
如图所示,左边是原本的文件内容,而右边是经过预处理后的文件,可以注释的消失,以及有着八百多行的代码,除去主函数,另外八百多行代码其实是头文件的展开部分,预处理过程中会将头文件进行展开然后挑选出合适的粘贴在文件代码上方。
条件编译:
而预处理也可以执行条件的编译,在文件代码中设置了条件限制,而我们需要调用条件来进行摘取代码内容时,通常使用的代码是 gcc -D执行的条件 需要裁剪的文件
但是我们可以在文件中设置条件,直接使用预处理的方法,就可以进行条件的裁剪了!
裁剪前
预处理裁剪后
编译:
当然编译的时也可以直接从.c文件从头开始,或者如下代码一样从预处理的文件开始
gcc -S tset.i -o test.s
//-S 的意思就是从现在开始进行程序的编译,编译完成就停下来
编译后的代码
汇编&链接:
汇编:
gcc -c test.s -o test.o
从现在开始进行程序的汇编,汇编完成就停下来,而汇编之后的文件并不是最终的文件,文件若是要正常的执行则需要两个条件:
- 本身就是可以执行的文件
- 文件的内容必须是可执行的
上文讲诉过,汇编之后的文件是二进制的目标文件,而二进制的目标文件本身就是不可以被执行的文件,所以需要将这个文件进一步的转化,也就说最后一步,链接!
链接:
gcc test.o -o my.exe
所以连接是最重要的,而链接又是什么呢?
什么是链接?
链接是库和程序的结合,当一个语言被发明的时候是有一套标准的,而这个库也就表示着语言的标准库。
使用ldd命令查看文件所用的库
当然,库也分类,在Linux中分为两种,第一种是动态库,通常以.so为后缀,且链接一般默认使用的库就是动态库,而另一种是静态库,是以.a为后缀的,并且在Linux中默认是没有静态库的存在,所以需要自己安装。
安装静态库:
sudo yum install -y glibc-static libstdc++-static
静态库的使用:
gcc -o 指定名字 链接的文件 -static
动态静态的对比:
占用空间大小的对比,前者是动态,后者是静态
库的链接对比,前者是动态,后者是静态
优缺对比:
- C动态库,默认提供的
- gcc默认形成的可执行程序,默认采用动态链接
动态库&&动态链接的优缺点:
- 不能丢失
- 节省资源
静态库&&静态链接的优缺点:
- 一旦形成,和库无关
- 浪费资源
小总结:
-c 汇编完成后停止,不进行链接
-E 预处理完成后停止,不进行编译
-S 编译完成后停止,不进行汇编
-o 用于指定目标文件名称