makefile&GDB使用

一、makefile

1、make && makefile

makefile带来的好处就是——自动化编译,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率

下面我们通过如下示例来进一步体会它们的作用:

①编写makefile文件

touch makefile
vim makefile

使用vim编辑器编辑makefile文件:

image-20230407150615108

#makefile文件中的内容
hello.exe:hello.c  
	gcc hello.c -o hello.exe
.PHONY:clean
clean:
	rm -f hello.exe

此时我们只需一个make命令即可完成自动编译:

make

image-20230407151005413

make命令的作用,即是执行makefile中的命令,此处执行的命令是:

gcc hello.c -o hello.exe

当我们输入:

make clean

image-20230407145636879

此处就执行了:

rm -f hello.exe

2、make执行步骤

当我们在Linux中输入并执行make命令时,make会干些什么呢?

step 1:make会在当前目录下寻找Makefile文件,找到了就会用这个文件作为后续操作的依据;如果没找到Makefile,就会寻找名为makefile的文件;两个都没找到就报错;

step 2:找到Makefile或者makefile之后,默认文件中第一行作为第一个目标;make命令会分析第一个目标的依赖关系,并且执行该目标的依赖方法**;

2.1 依赖关系

hello.exe:hello.c                #依赖关系

makefile文件中hello.exe就是目标(期望生成的内容);我们编译文件hello.c期望生成它对应的可执行文件hello.exe,而你要编译生成这个目标文件,需要依赖hello.c这个文件,这就是依赖关系

2.2 依赖方法

有了依赖关系,我们就知道了生成目标可执行文件hello.exe需要依赖hello.c这个文件,那么我们该怎么利用hello.c文件生成hello.exe文件呢?我们是不是还缺少一个方法,而这个使用目标的依赖关系文件生成期望的目标文件的方法就是依赖方法

gcc hello.c -o hello.exe         #依赖方法

image-20230407151439095

需要注意的是,依赖文件列表可以为空

3、项目清理

# makefile文件中的清理部分
.PHONY:clean
clean:
	rm -f code

image-20230407151637813

上述makefile文件中,该部分即为项目清理部分;在上述介绍中,我们知道需要显式输入make clean才能实现清除编译好的文件hello.exe以便重新编译:

image-20230407151932323

其中.PHONY的使用,是将它设置为伪目标,伪目标的特性是:总是被执行的

4、伪目标 .PHONY

👉 怎样理解总是被执行的?我们试着多次输入make指令,发现结果如下:

image-20230407152245884

结果:当第一次使用make命令时,目标被执行生成了一个可执行文件,而当我们再使用make命令时发现make虽然不会报错但是会告诉我们生成的文件的已经是最新的了,目标并没有被执行


那么多次输入make clean指令呢?结果如下:

image-20230407152336502

可以一直执行rm -f hello.exe这条指令!(即使已经重复执行了)


我们将生成可执行文件过程更改为伪目标(使用vim编辑器):

# 修改makefile文件
.PHONY:hello.exe
hello.exe:hello.c
	gcc hello.c -o hello.exe

image-20230407152918399

再测试一下:

image-20230407153021133

二、GDB

GDB是命令行模式的调试工具,能够让用户在程序运行时观察程序的内部结构和内存的使用情况。

1、准备工作

gdb_test.c:

#include<time.h>

void Print(int sum)
{
    long long timestamp=time(NULL);
    printf("result=%d,timestamp:%lld\n",sum,timestamp);
}

int AddtoVal(int from,int to)
{
    int sum=0;
    for (int i = from; i <= to; i++)
    {
        sum+=i;
    }
    return sum;
}

int main()
{
    int sum=AddtoVal(0,100);
    Print(sum);
    return 0;
}

生成可执行文件:

1、debug版本:程序本身会被加入更多的调试信息,以便于进行调试。
 2、release版本:不会添加任何调试信息,是不可调试的。

在Linux当中gcc/g++默认生成的可执行程序是release版本的,是不可被调试的。如果想生成debug版本,就需要在使用gcc/g++生成可执行程序时加上-g选项

gdb_test_g.exe:gdb_test.c
	gcc gdb_test.c -o gdb_test_g.exe -g
.PHONY:clean
clean:
	rm -rf gdb_test_g.exe

可使用工具读取可执行程序符号表debug部分:

[Kevin@VM-8-13-centos code1]$ readelf -S gdb_test_g.exe | grep debug
  [26] .debug_aranges    PROGBITS         0000000000000000  00001095
  [27] .debug_info       PROGBITS         0000000000000000  000010c5
  [28] .debug_abbrev     PROGBITS         0000000000000000  00001536
  [29] .debug_line       PROGBITS         0000000000000000  000016af
  [30] .debug_str        PROGBITS         0000000000000000  000017d5

总结:要用gdb调试,首先要进行给编译器添加-g

2、正式调试

调试命令:

进入gdb:gdb 文件名

显示代码:l n 显示从第n行开始的源代码,每次显示10行,若n未给出则默认从上次的位置往下显示。

打一个断点:b n在第n行设置断点。

查看已打断点:info b

去掉打的断点:d 断点编号 删除指定编号(不是行号)的断点。

开始调试运行:r(run)

逐过程:n(next)

逐语句:s(step)会进入函数体中

运行到下一个断点处:c(continue)

查看函数调用堆栈:bt

直接运行完当前函数:finish 个性化跑完自定义的一个个函数,方便定位代码错误的位置

打印变量的值/地址:p(print)变量/&变量

将变量的值/地址加入常显示:display 变量/&变量

取消指定编号变量的常显示:undisplay 编号

跳出循环/跳转至指定行:until 行号

修改变量值:set var 变量=x 将变量的值修改为x

退出gdb:quit/ql
continue)

查看函数调用堆栈:bt

直接运行完当前函数:finish 个性化跑完自定义的一个个函数,方便定位代码错误的位置

打印变量的值/地址:p(print)变量/&变量

将变量的值/地址加入常显示:display 变量/&变量

取消指定编号变量的常显示:undisplay 编号

跳出循环/跳转至指定行:until 行号

修改变量值:set var 变量=x 将变量的值修改为x

退出gdb:quit/ql

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值