【Linux系统】gcc编译器的使用

发布于:2025-05-21 ⋅ 阅读:(19) ⋅ 点赞:(0)


一、C程序编译的过程

  1. 预处理(进行宏替换/去注释/条件编译/头文件展开等)
  • 预处理指令是以#号开头的代码行。
  • 头文件展开是指:把头文件中的相关内容直接拷贝到源文件中(所以预处理完毕后就不需要用到头文件了)
  • 预处理后的文件以 “.i”为后缀。
  1. 编译(生成汇编代码)
  • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
  • 编译后的文件以 “.s”为后缀
  1. 汇编(生成机器可识别代码)
  • 在这个阶段中,gcc 把汇编代码转化为二进制代码目标文件
  • 汇编后的文件以 “.o”为后缀。
  1. 链接(生成可执行文件或库文件)
  • 链接多个目标文件(至少一个)和 库文件 形成可执行文件

二、gcc编译C程序

1.一步到位(直接从c程序文件到可执行程序)

首先得写一个c程序:

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 4
-rw-rw-r-- 1 zh zh 75 May 10 16:35 code.c
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ vim code.c

在这里插入图片描述

  1. gcc c程序(对c程序进行编译生成名为 a.out 的可执行程序)
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ gcc code.c
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 16
-rwxrwxr-x 1 zh zh 8360 May 10 16:54 a.out
-rw-rw-r-- 1 zh zh   75 May 10 16:35 code.c
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ./a.out
hello world

  1. gcc c程序 -o 指定生成的文件名(对c程序进行编译生成指定文件名的可执行程序)
    或 gcc -o 指定生成的文件名 c程序(两种写法都能达到同样效果)
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 4
-rw-rw-r-- 1 zh zh 75 May 10 16:35 code.c
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ gcc code.c -o code
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 16
-rwxrwxr-x 1 zh zh 8360 May 10 16:58 code
-rw-rw-r-- 1 zh zh   75 May 10 16:35 code.c
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ./code
hello world

2.分步骤拆解(预处理—>编译—>汇编—>链接)

2.1 预处理

gcc -E c文件 -o 生成的文件
(-E 的作用:开始进行c程序的翻译,当预处理阶段完毕后翻译就停止)

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 4
-rw-rw-r-- 1 zh zh 75 May 10 16:35 code.c
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ gcc -E code.c -o code.i 
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 24
-rw-rw-r-- 1 zh zh    75 May 10 16:35 code.c
-rw-rw-r-- 1 zh zh 16872 May 10 17:11 code.i

我们怎么知道生成的 code.i 到底是不是c程序预处理后的文件,打开看看就知道了:

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ vim code.i

在这里插入图片描述
发现 code.i 文件竟然变成足足843行,这就是预处理过程中头文件<stdio.h>展开的作用;而且 code.i 文件仍然是c代码,证明还没经过 编译阶段;种种迹象表明 code.i 就是 code.c 只经过预处理后的文件

2.2 编译

gcc -S c文件/预处理后的c文件 -o 生成的文件
(-S 的作用:开始进行c程序的翻译,当编译阶段完毕后翻译就停止)

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 24
-rw-rw-r-- 1 zh zh    75 May 10 16:35 code.c
-rw-rw-r-- 1 zh zh 16872 May 10 17:11 code.i
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ gcc -S code.i -o code.s
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 28
-rw-rw-r-- 1 zh zh    75 May 10 16:35 code.c
-rw-rw-r-- 1 zh zh 16872 May 10 17:11 code.i
-rw-rw-r-- 1 zh zh   447 May 10 19:38 code.s

打开 code.s 文件观察:

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ vim code.s

在这里插入图片描述
code.s 文件中的内容是汇编代码,表明 code.s 是 c程序 经过编译阶段后的文件

2.3 汇编

(1)gcc -c c文件/预处理后的c文件/编译后的c文件 -o 生成的文件
(-c 的作用:开始进行c程序的翻译,当汇编阶段完毕后翻译就停止)
(2)gcc -c c文件/预处理后的c文件/编译后的c文件
(汇编后自动生成以 .o 为后缀的同名文件)

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 28
-rw-rw-r-- 1 zh zh    75 May 10 16:35 code.c
-rw-rw-r-- 1 zh zh 16872 May 10 17:11 code.i
-rw-rw-r-- 1 zh zh   447 May 10 19:38 code.s
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ gcc -c code.s -o code.o
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 32
-rw-rw-r-- 1 zh zh    75 May 10 16:35 code.c
-rw-rw-r-- 1 zh zh 16872 May 10 17:11 code.i
-rw-rw-r-- 1 zh zh  1496 May 10 19:45 code.o
-rw-rw-r-- 1 zh zh   447 May 10 19:38 code.s

打开 code.o 文件观察:

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ vim code.o

在这里插入图片描述
code.o 文件中的内容全是乱码,实际上就是二进制代码,二进制文件得使用专门的方式查看,否则看到得就是乱码。这表明 code.o 是 c程序 经过汇编阶段后的文件

2.4 链接

gcc c文件/预处理后的c文件/编译后的c文件/汇编后的c文件 -o 生成的文件

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 32
-rw-rw-r-- 1 zh zh    75 May 10 16:35 code.c
-rw-rw-r-- 1 zh zh 16872 May 10 17:11 code.i
-rw-rw-r-- 1 zh zh  1496 May 10 19:45 code.o
-rw-rw-r-- 1 zh zh   447 May 10 19:38 code.s
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ gcc code.o -o code.exe
[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ls -l
total 44
-rw-rw-r-- 1 zh zh    75 May 10 16:35 code.c
-rwxrwxr-x 1 zh zh  8360 May 10 20:10 code.exe
-rw-rw-r-- 1 zh zh 16872 May 10 17:11 code.i
-rw-rw-r-- 1 zh zh  1496 May 10 19:45 code.o
-rw-rw-r-- 1 zh zh   447 May 10 19:38 code.s

链接后形成可执行文件,可以直接运行:

[zh@iZbp1dr1jtgcuih41mw88oZ ~]$ ./code.exe
hello world


网站公告

今日签到

点亮在社区的每一天
去签到