GCC和GDB命令使用详解

HarderHeng Lv5

一、GCC介绍

GCC是Linux平台默认的编译器,全称是GNU Compiler Collection。GCC是GNU项目开发的编译器合集,包含了多种不同语言的编译器前端还有汇编器、链接器等等,能够编译C、Cpp、Objective-C,Fortran、Ada、GoOpenCL等等语言。GCC本身有多个平台的版本,并且可以编译出多个平台和操作系统的可执行文件。GCC还有交叉编译工具链可以用来编译其他平台的可执行文件。

其中编译C语言的编译器叫做gcc,编译Cpp的叫做g++。

一般来说GCC是默认安装在Linux系统的。如果需要安装GCC的交叉编译工具链,可以使用包管理器或者直接下载二进制文件进行编译。

二、gcc的基本使用

1、编译程序的基本过程

编译一个程序大致分为以下几个过程:

  • 预编译:将头文件包含进源文件,处理宏定义、预编译和注释等等,生成**.i**文件
  • 编译:进行词法分析、语法分析、语义分析,前端过程生成中间代码,然后对中间代码进行平台无关的优化,最后后端生成目标代码的汇编形式,在这个生成汇编的过程中也会进行平台相关的优化,得到**.S**汇编文件。
  • 汇编:将编译阶段生成的汇编代码变成可以在实际硬件平台上运行的机器码,在这一步后得到的是目标文件**.o**。
  • 链接:链接器根据编译过程生成的重定位信息,将不同的目标文件和静态链接库中的信息进行链接起来最终生成可执行文件。

2、gcc在每个阶段的行为

  • -E 只执行预处理,不进行后序的操作,得到**.i**文件。
  • -S 执行编译后停止,不进行汇编和链接,得到**.s**汇编文件。
  • -c 执行汇编后停止,不进行链接,得到**.o**目标文件。
  • -o 后面跟生成的可执行文件名称,直接生成可执行文件。

以上的每个命令都可以单独对源文件进行使用。

  • -E 默认会预编译后的文件输出在命令行,需要指定-o name.i将信息存储到name.i中。
  • 每一步都可以使用-o对生成的文件进行命名。
  • 最后一步-o命令生成可执行文件时,一定会执行链接的过程,需要所有的文件一起使用并进行链接。

并且在整个编译的过程中,任何一步得到的文件,都可以使用下一步的命令进行处理。

例如gcc -c test1.i test2.c,该命令会将一个**.i文件和一个.c文件直接变成.s**汇编文件。

  • 任何一步得到的文件,只要使用-o的命令,就会立刻得到可执行文件。(不缺少文件的情况下)

3、编译优化选项

  • -O0 不使用优化
  • -O1 默认优化,不会增加编译的时间
  • -O2 更多优化,平衡执行效率和编译时间
  • -O3 最高优化,尽可能提高程序的执行性能
  • -Os 优化代码占用空间, 可能会降低性能,适合嵌入式的平台
  • -Ofast 启用最激进的优化,可能会改变程序运行的可移植性和正确性
  • -Og 调试优化,启用优化但是保留足够的信息进行调试

在这里只介绍基本的优化等级,更多细分的优化选项,以及在链接阶段开启的链接时优化,会在另一篇文章中详细说明。

4、编译生成库和链接库

关于可执行文件和库文件,在另一篇文章中详细说明。

  • -l<lib> 链接指定的静态库
  • -L<dir> 指定静态链接库的位置
  • -I<dir> 指定include头文件的目录
  • -static 强制链接静态库
  • -share 尽可能使用动态链接库
  • -shared 使用目标文件编译出动态库

要使用目标文件打包成静态库需要使用ar工具而不是gcc。

5、其他的一些

  • -g 编译时生成调试信息

  • -w 不显示任何警告信息

  • -Wall 显示所有警告选项

  • -ggdb 生成专为gdb优化过的调试信息

生成调试信息时可以使用调试等级,来生成更多更详细的优化信息,例如-ggdb3

使用GCC标准构建流程

这里尝试编写一个CmakeLists.txt进行项目的构建,需要的编译器选项有

  • -Wall 显示所有的警告
  • -Wextra 显示-Wall以外的警告
  • -pedantic 禁止扩展语法,遵循ANSI的C标准
  • -Werror 将所有的警告视为错误,发生时会终止编译

三、GDB介绍

GDB是GNU项目中的调试工具,一般和GCC配套使用,是Linux系统的标准调试工具。

1、调试信息格式

目前一个程序调试信息的表示格式是DWARF,在对源代码进行编译时,不管使用哪种编译工具,不管是交叉编译还是本地编译,都可以加上生成调试信息的选项,最后DWARF信息将被嵌入到可执行文件中。

对嵌入式平台来说,最终烧录的文件并不会有调试信息,而是在编译过程中生成一个有调试信息和ELF格式的文件和另一个用来烧录bin文件,IDE可以使用调试文件以及调试器和嵌入式平台进行交互调试。

对主流的编译器来说,生成的调试信息格式都是DWARF,不同的编译器生成相同格式的调试信息,不同的调试器都可以使用这同一种格式的调试信息。

2、GDB基本使用

1、调试器使用前提

要使用GDB或者其他的调试器,首先要在编译时期加上-g选项来生成调试信息,也可以适当的降低优化等级,减少编译器对源代码的优化。

在安装了GDB的机器上,使用gdb program,就可以开始调试了,其中Program就是要调试的程序。

2、调试器的使用

启动GDB之后,进入到和GDB交互的命令行中。

  • 按下l也就是list命令,从第一行开始显示源码,每一次显示出10行,刚开始显示的是main函数所在的文件。
  • 使用b或者break命令,后面加上行号或者函数名,就会在对应的位置打上断点,
  • Title: GCC和GDB命令使用详解
  • Author: HarderHeng
  • Created at : 2024-11-29 11:34:49
  • Updated at : 2025-03-06 20:53:52
  • Link: https://harderheng.life/2024/11/29/GCC和GDB命令使用详解/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments