发布:admin2025-05-05 13:35:15 4594条浏览分类:世界杯日本爆冷
目录
前言
一.GCC编辑器
二.编译过程
2.1 预处理
2.2 编译步骤
2.3 汇编步骤
2.4 链接步骤
三.多文件编译
3.1 只有.c文件
3.2 含有.c和.h文件
3.3 标准化.c和.h文件
前言
详细讲解gcc编译过程:预处理,编译,汇编,链接;
使用gcc生成对源文件.c和.h文件进行编译运行,带大家区分它们的区别。
一.GCC编辑器
以下是常用的编辑器选项,不同的选项可以指导编译器有不同的行为表现,具体如下
二.编译过程
gcc编译过程分为四个步骤:预处理,编译,汇编,链接;接下来逐个进行介绍
2.1 预处理
预处理是指在编译代码之前先进行预先的处理工作,这些工作包含哪些内容: 头文件被包含进来(复制):
#include 宏定义会被替换:
#define 取消宏定义:
#undef 条件编译:
#if #ifdef #ifndef #else #elif #endif
修改行号以及文件名:#line 998 "Hello.c"
清除注释
预处理大部分的工作是在处理以 # 开头的一些语句,从严格意义来讲这些语句并不属于C语言的范 畴, 它们在编译的第一个阶段被所谓的 预处理器 来处理。
以下演示预处理步骤:
linux系统安装gcc后,当前文件夹存放main.c文件
输入以下命令,则生成main.i文件
gcc main.c -o main.i -E
gcc hello.c -o hello.i -E
加上一个编译选项 -E 就可以使得 GCC 在进行完第一阶段的预处理之后停下来,生成
一个默认后缀名为.i 的文本文件
2.2 编译步骤
加上一个编译选项 -S 就可以使得 gcc 在进行完第一和第二阶段之后停下来,生成一 个默认后缀名为.s 的文本文件。打开此文件看一看,你会发现这是一个符合 x86 汇编语言 的源程序文件。
经过预处理之后生成的.i 文件依然是一个文本文件,不能被处理器直接解释,我们需要 进一步的翻译。接下来的编译阶段是四个阶段中最为复杂的阶段,它包括词法和语法的分析, 最终生成对应硬件平台的汇编语言(不同的处理器有不同的汇编格式)。 汇编文件取决于所采用的编译器,如果用的是 GCC,那么将会生成 x86 格式的汇编文件, 如果用的是针对 ARM 平台的交叉编译器,那么将会生成 ARM 格式的汇编文件。
2.3 汇编步骤
则会生成一个扩展名为.o 的文件,这个文件是一个 ELF 格式的可重定位(relocatable)文件,所谓的可重定位,指的是该文件虽然已经包含可以让处理器直接运行的指令流,但是程序中的所有的全局符号尚未定位,所谓的全局符号,就是指函数和全局变量,函数和全局变量默认情况下是可以被外部文件引用的,由于定义和调用可以出现在不同的文件当中,因此他们在编译的过程中需要确定其入口地址,比如 a.c 文件里面定义了一个函数 func( ),b.c 文件里面调用了该函数,那么在完成第三阶段 汇编之后,b.o 文件里面的函数 func( )的地址将是 0,显然这是不能运行的,必须要找到 a.c 文件里 面函数 func( )的确切的入口地址,然后将 b.c 中的“全局符号”func重新定位为这个地址,程序才能正确运行。因此,接下来需要进行第四个阶段:链接
可以看出.o文件是打不开的
我们需要观察里面的内容,可以输入以下命令
readelf main.o -a
上图可以看出,为什么它数据段地址都为0,是因为程序中的所有的全局符号尚未定位,后面的链接步骤就可以进行定位。
2.4 链接步骤
链接:
gcc main.o -o main -lc -lgcc
gcc main.o -o main -lc -lgcc
gcc c语言编辑器
main.o 需要编译的源码
-o 指定文件输出格式名字
main 可执行文件的名字
-lc -l 链接 c 标准库
-lgcc -l 链接 gcc 链接GCC的库
再次执行,则可以看出有函数入口了,它们的地址不再为0
readelf main.o -a
三.多文件编译
3.1 只有.c文件
当前文件夹中的文件:
输入以下代码: gcc *.c -o main
注意:需要在含有主函数的.c文件夹中,对其它文件夹的函数进行声名
这里再main.c 中声名了max.c和sum.c中的函数,所以才能链接成功生成新的main文件。
gcc *.c -o main
运行main文件
./main
3.2 含有.c和.h文件
以当前文件夹为例:含有3个.c文件和3个.h文件
对它进行编译
gcc *.c -o main -I./
-I./ -I 指定头文件路径 后面必须接头文件所在的路径
3.3 标准化.c和.h文件
我们可以这样创建
src 存放.c
inc 存放.h
bin 存放二进制,可执行文件
编译命令:生成可执行文件
gcc src/*.c -o bin/main1 -I./inc
gcc src/*.c -o bin/main1 -I./inc 命令解析
运行可执行文件
以上是本期内容,若有错误,欢迎评论或私信!!!