gcc源码如何编译-[C/C++] GCC编译过程介绍

gcc语言编译的整个过程:预处理->编译->汇编->链接

1. GCC 快速入门

Gcc 命令的常用格式是: Gcc [选项] 要编译的文件 [选项] [目标文件]

其中,目标文件可以默认,Gcc默认生成的可执行文件名是:a.out

我们来看看经典的入门程序“HelloWorld!”

#vihello.c

#包括

#包括

无效主(无效)

printf("你好世界!rn");

用gcc编译来执行程序。

#gcchello.c

该命令会直接从hello.c生成最后的二进制补码可执行程序a.out

该命令意味着执行(1)预处理,(2)汇编,(3)编译和(4)链接以生成最终的二进制补码可执行程序。 这里没有指定输出文件,默认输出为a.out。

如何指定最后的二进制补码可执行程序名称,因此使用-o选项来指定名称。 例如需要生成执行程序hello.exe

所以

#gcchello.c - ohello.exe

二、GCC命令分析——四步

gcc源码如何编译-[C/C++] GCC编译过程介绍

从前面我们知道GCC编译源代码生成最终可执行的二进制补码程序,GCC后台包括四个阶段的步骤。

GCC编译C源代码分四步:

预处理----->编译---->汇编---->链接

现在我们利用GCC命令选项来一一分析GCC的流程。

1)预处理

此阶段,编译器编译出C源代码中包含的stdio.h等头文件,用户可以使用gcc选项“-E”查看。

用法:#gcc-Ehello.c-ohello.i

功能:预处理hello.c并输出hello.i文件。

[root]#gcc-Ehello.c-ohello.i

[根]#ls

你好.chello.i

[root]#vihello.i

#1“你好.c”

#1""

#1""

#1“你好.c”

#1“/usr/include/stdlib.h”13

#25 “/usr/include/stdlib.h”3

#1“/usr/include/features.h”13

#291 “/usr/include/features.h”3

#1“/usr/include/sys/cdefs.h”13

#292 “/usr/include/features.h”23

#314 “/usr/include/features.h”3

#1“/usr/include/gnu/stubs.h”13

#315“/usr/include/features.h”23

#26“/usr/include/stdlib.h”23

#3“你好.c”2

无效主(无效)

printf("你好世界!rn");

2)编译阶段(Compiling)

第二步是编译阶段。 在这个阶段,Gcc首先需要检测代码的规范性,是否存在语句错误等,以确定代码中实际要做的工作。 检测正确后,Gcc将代码翻译成汇编语言。 用户可以使用“-S”选项查看,该选项只编译不汇编,生成汇编代码。

选项

用法:[root]#gcc –Shell.i –ohello.s

功能:将预处理输出文件hello.i编译成hello.s文件。

[root@richardhello-gcc]#ls

你好.chello.ihello.s

hello.s的汇编代码如下

[root@richardhello-gcc]#vihello.s

.文件“你好.c”

.section.rodata

.LC0:

.string“你好世界!rn”

。文本

.globlmain

.typemain,@function

主要的:

推入%ebp

movl%esp,%ebp

低于 8 美元,%esp

andl$-16, %esp

movl$0,%eax

subl%eax,%esp

低于 12 美元,%esp

Pushl$.LC0

调用printf

addl $16,%esp

movl$0,%eax

离开

雷特

.Lfe1:

.sizemain、.Lfe1-main

.ident“GCC:(GNU)3.2.220030222(RedHatLinux3.2.2-5)”

3)组装阶段(Assembling)

汇编阶段是将编译阶段生成的“.s”文件转换为二补码目标代码。

选项-c

用法:[root]#gcc –chello.s –ohello.o

功能:编译汇编输出文件test.s,输出test.o文件。

[root]#gcc-chello.s-ohello.o

[根]#ls

你好.chello.ihello.ohello.s

4)链接阶段(Link)

编译成功后,进入链接阶段。

没有选项链接

用法:[root]#gcchello.o – ohello.exe

功能:将编译后的输出文件hello.o链接成最终的可执行文件hello.exe。

[根]#ls

你好.chello.exehello.ihello.ohello.s

运行可执行文件gcc源码如何编译,正确结果如下。

[root@localhostGcc]#./你好

你好世界!

这里涉及到一个重要的概念:函数库。

读者可以回顾一下这个小程序。 在这个程序中,没有定义“printf”的函数实现gcc源码如何编译,而预编译中包含的“stdio.h”只有这个函数的声明,但没有定义该函数的实现。 那么,“printf”函数是在哪里实现的呢? 最终的答案是:系统将这个函数实现到一个名为libc.so.6的库文件中。 如果没有特殊说明,gcc会到系统默认的搜索路径“/usr/lib”去搜索,即链接到libc.so.6库函数,这样就可以实现“printf”这个函数了,这就是链接的功能。

可以使用ldd命令查看动态库加载状态:

[root]#lddhello.exe

libc.so.6=>/lib/tls/libc.so.6(0x42000000)

/lib/ld-linux.so.2=>/lib/ld-linux.so.2(0x40000000)

函数库通常分为静态库和动态库。 静态库是指在编译链接时,将库文件的所有代码都添加到可执行文件中,因此生成的文件比较大,但运行时不再需要库文件。 它的后缀通常是“.a”。 相反,动态库在编译链接时并不将库文件的代码添加到可执行文件中,而是在程序执行时从运行时链接文件中加载库,这样可以节省系统开支。 动态库通常带有“.so”后缀。 如上所述,libc.so.6是一个动态库。 gcc编译时默认使用动态库。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 gcc源码如何编译-[C/C++] GCC编译过程介绍 https://www.wkzy.net/game/167030.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务