GCC概述
————翻译官、翻译组织
gcc -o 输出的文件名 输入的文件名
示例:
-
通过vi建立一个新文件【test.c】并编写代码
-
注意:GCC会根据不同文件后缀来调用具体的编译程序
-
vi test.c
————编写代码
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
补充:在Linux系统中,返回值为0代表成功,一切不为0的返回值都是失败
-
使用GCC编译代码并运行
gcc -o Hello test.c
————将test.c文件编译并生成名为Hello的文件(不需要有后缀名)
此时使用【ls】命令可以看到不仅有test.c文件,还有编译生成的Hello文件
./Hello
————通过【./】命令使shell程序在当前目录下寻找文件,使其具备执行能力以进行代码的解释执行
得到输出:
Hello World!
以上示例可知:通过【gcc -o】可以直接调用gcc进行翻译服务
但还需要更深层次地了解GCC这个翻译组织有哪些成员为此进行了服务
-
查看gcc完整翻译过程
命令:gcc -v
此处查看刚刚示例程序的完整翻译过程
gcc -v -o Hello test.c
得到:
![](https://i-blog.csdnimg.cn/blog_migrate/cc6194f16b30bce9cabac2381a049839.png)
-
版本信息
![](https://i-blog.csdnimg.cn/blog_migrate/981d8b8e213971fc6631f237cc08f88b.png)
-
GCC调用的第一个翻译命令(编译)
![](https://i-blog.csdnimg.cn/blog_migrate/ea523341bfb47e93c09690a37f23073d.png)
-
GCC调用的第二个翻译命令(汇编)
![](https://i-blog.csdnimg.cn/blog_migrate/d898bd9ff043aa21f4fec36c8abf6244.png)
-
GCC调用的第三个翻译命令(链接)
![](https://i-blog.csdnimg.cn/blog_migrate/5b9fa0f204197d6d24e6f01d80c378b9.png)
引入:
原理上,GCC并不是简单的通过调用【gcc -o】就可以完成翻译,其内部有着许多翻译官(命令)来帮助工作
C语言编译过程介绍
之前用【gcc -v】简单看了gcc的翻译过程,本节具体研究这些工具集起了什么作用,怎么由【test.c】一步步生成【Hello】可执行文件
预处理
(不一定有)——宏定义,文件包含include……
cpp -o test.i test.c
输入为【.c】文件,输出得到【.i】文件
等效于命令【gcc -E】
//可以跳过该命令直接到编译及之后过程
示例:
修改test.c文件,新增宏定义
![](https://i-blog.csdnimg.cn/blog_migrate/ac7702f393bc2dc0be4f70a6f2de0666.png)
打开预处理之后生成的【test.i】文件
![](https://i-blog.csdnimg.cn/blog_migrate/78b26689dcc7c86704984d51019d5dfc.png)
在文件的最后一行可以看到宏定义去除并已在程序中替换
![](https://i-blog.csdnimg.cn/blog_migrate/613f7812da6b3210935076a076739ceb.png)
编译
![](https://i-blog.csdnimg.cn/blog_migrate/fd1e405b087a7de0537bedddb8d64b71.png)
-
/usr/lib/gcc/x86_64-linux-gnu/11/cc1(编译器)实际上也算是一个命令
-
输入为【.c】文件,输出得到【.s】文件
-
等效于命令【gcc -S】
简化这个工具集可以得到以下示例:
调用命令——
gcc -S -o test.s test.c
目的——看看使用这个命令能输出什么
![](https://i-blog.csdnimg.cn/blog_migrate/96416e59f658876a08170763f4f2bacd.png)
可以看到
命令【gcc -S】
将【test.c】文件编译成了【test.s】文件
并且【test.s】文件可以看出是汇编语言(X86)
//之后还会接触到ARM汇编语言
总结:/usr/lib/gcc/x86_64-linux-gnu/11/cc1
命令【gcc -S】的实际作用——将【.c】文件编译成【.s】文件
汇编
-
as实际上也算是一个命令,输入是刚刚编译生成的【.s】文件,输出得到【.o】文件
-
等效于命令【gcc -c】
注意:使用
命令【gcc -c】可以直接将【.c】文件生成【.o】文件(包括编译生成【.s】文件的过程)
简化这个工具集可以得到以下示例:
调用命令——
gcc -c -o test.o test.s
目的——看看使用这个命令能输出什么
![](https://i-blog.csdnimg.cn/blog_migrate/7f80c62ce88be74dc6a61d644f057fb1.png)
可以看到
命令【gcc -c】
将【test.s】文件汇编成了二进制【test.o】文件
总结:
命令【gcc -c】的实际作用——将【.s】文件汇编成【.o】文件
链接
-
/usr/lib/gcc/x86_64-linux-gnu/11/collect2(链接器)实际上也算是一个命令
-
输入是刚刚汇编生成的【.o】文件,输出得到【可执行】文件
-
等效于命令【gcc -o】
注意:使用
命令【gcc -o】可以直接将【.c】文件生成【可执行】文件(包括编译生成【.s】文件和汇编生成【.o】文件的过程)
简化这个工具集可以得到以下示例:
调用命令——
gcc -o Test test.o
目的——看看使用这个命令能输出什么
![](https://i-blog.csdnimg.cn/blog_migrate/2aec455f35c9f657adadca45794ad027.png)
可以看到
命令【gcc -o】
将【test.o】文件汇编成了可执行【Test】文件
总结:
命令【gcc -c】的实际作用——将【.o】文件汇编成可执行文件
//也可以直接将【.c】文件生成可执行文件(跳过了编译生成【.s】文件和汇编生成【.o】文件的过程)
总结流程:预处理【.i】——编译【.s】——汇编【.o】——链接【可执行】