【Linux】彻底搞懂gcc,makefile与gdb使用(超详细解析,小白必看系列)

1 Linux编译器-gcc/g++使用

在Linux环境下,GCC(GNU Compiler Collection)是最常用的编译器之一,支持多种编程语言,包括C和C++。以下是GCC和G++的基本使用方法:

基本命令

GCC和G++的基本语法如下:

gcc [options] [filenames]
g++ [options] [filenames]

其中,[options]表示编译选项,[filenames]表示源文件名。

常用选项

  • -o [outputfile]:指定输出文件名。
  • -c:只编译,不链接。
  • -E:只进行预处理。
  • -S:只进行编译,生成汇编代码。
  • -g:生成调试信息。
  • -O:优化代码(可以使用-O1, -O2, -O3等不同级别)。
  • -Wall:开启所有警告。

编译过程示例

假设有一个简单的C程序文件hello.c,内容如下:

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

编译并运行这个程序的步骤如下:

  1. 预处理

    gcc -E hello.c -o hello.i
    

    生成预处理后的文件hello.i

  2. 编译

    gcc -S hello.i -o hello.s
    

    生成汇编代码文件hello.s

  3. 汇编

    gcc -c hello.s -o hello.o
    

    生成目标文件hello.o

  4. 链接

    gcc hello.o -o hello
    

    生成可执行文件hello

  5. 运行

    ./hello
    

    输出结果为Hello, World!

2 详解makefile

Makefile 是一个用于自动化编译过程的工具,特别适用于大型项目。它定义了一系列规则来指定哪些文件需要先编译,哪些文件需要后编译,以及如何重新编译。以下是 Makefile 的基本使用方法:

Makefile 的基本结构

一个基本的 Makefile 文件由以下几部分组成:

  • 目标(target):要生成的文件或执行的动作。
  • 依赖(prerequisites):生成目标所需的文件或中间过程生成的目标。
  • 命令(command):通过执行命令对依赖操作生成目标。

每条规则的基本格式如下:

target: prerequisites
    command

注意:命令行前必须是一个Tab字符,而不是空格。

示例

假设有以下三个文件:main.cadd.cfun.h。我们希望编译生成一个名为 math 的可执行文件。

文件内容

fun.h:

int add(int a, int b);

add.c:

#include "fun.h"

int add(int a, int b) {
    return a + b;
}

main.c:

#include <stdio.h>
#include "fun.h"

int main() {
    int a = 12, b = 6;
    printf("%d\n", add(a, b));
    return 0;
}
Makefile

编写一个简单的 Makefile 文件:

# 定义编译器
CC = gcc

# 定义编译选项
CFLAGS = -Wall -g

# 定义目标文件
TARGET = math

# 定义依赖关系和生成规则
$(TARGET): main.o add.o
    $(CC) $(CFLAGS) -o $(TARGET) main.o add.o

main.o: main.c fun.h
    $(CC) $(CFLAGS) -c main.c

add.o: add.c fun.h
    $(CC) $(CFLAGS) -c add.c

# 定义清理规则
clean:
    rm -f *.o $(TARGET)

使用 make 命令

  1. 编译:在终端中运行 make 命令,它会根据 Makefile 中的规则编译生成可执行文件。
    make
    
  2. 清理:运行 make clean 命令,删除生成的目标文件和中间文件。
    make clean
    

变量和自动变量

  • 变量:可以使用变量来简化 Makefile 的编写,如 CCCFLAGS
  • 自动变量:如 $@ 表示规则中的目标,$< 表示第一个依赖文件,$^ 表示所有的依赖文件。

3 详解gdb

GDB(GNU Debugger)是一个功能强大的调试工具,主要用于调试C和C++程序。它可以帮助你在程序执行期间查看程序的行为,或者在程序崩溃时分析问题。以下是GDB的详细解释:

GDB的基本功能

  1. 启动程序:可以按照自定义的要求运行程序。
  2. 设置断点:在指定的地方或条件下暂停程序。
  3. 检查状态:当程序暂停时,可以检查程序的状态。
  4. 修改变量:在程序执行过程中修改变量的值。

使用GDB调试程序

要使用GDB调试某个程序,该程序编译时必须加上编译选项 -g,以包含调试信息。例如:

gcc -g example.c -o example

启动GDB

有三种方式启动GDB:

  1. 直接调试目标程序
    gdb ./example
    
  2. 附加到正在运行的进程
    gdb attach <pid>
    
  3. 调试core文件
    gdb example core
    

常用命令

  • 运行程序
    run (r)
    
  • 继续执行
    continue (c)
    
  • 单步执行
    next (n)
    step (s)
    
  • 设置断点
    break (b) <location>
    
  • 查看断点信息
    info breakpoints (i b)
    
  • 打印变量值
    print (p) <variable>
    
  • 查看调用堆栈
    backtrace (bt)
    
  • 切换堆栈帧
    frame (f) <frame-number>
    
  • 查看源码
    list (l)
    

示例

假设有一个简单的C程序example.c

#include <stdio.h>

int main() {
    int a = 5;
    int b = 10;
    int sum = a + b;
    printf("Sum: %d\n", sum);
    return 0;
}

编译并启动GDB:

gcc -g example.c -o example
gdb ./example

在GDB中设置断点并运行程序:

(gdb) break main
(gdb) run

程序会在main函数处暂停。可以使用nextstep命令逐行执行代码,并使用print命令查看变量的值:

(gdb) next
(gdb) print a
$1 = 5
(gdb) next
(gdb) print b
$2 = 10
(gdb) next
(gdb) print sum
$3 = 15

退出GDB

可以使用以下命令退出GDB:

quit (q)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值