Linux下的gdb调试makefile的编写

1.gdb调试
gdb就是用于调试可执行文件,要想让程序在调试的时候有提示信息在生成文件时加上-g
(1)启动gdb:gdb +包含调试信息的应用程序
(2)l(只能查询包含在可执行程序里边的.c文件):查看第一个有主函数的文件的前十行带码
也可以在l后边加.c文件再加:加想要参看的函数名或者行数
(3)断点:b/break +行数:当程序运行到断点会停下
在断点也可以设置条件比如:b+行数(有个for循环)+if i==9(不会停在fo循环哪一行只会停在for循环里边)
(4)info/i+b/brea:查看断点,可以看到断点的编号和一些其他的相关信息
(5)调试语法:
run或start:开始运行程序
n:运行一步
c:运行直到遇到断点
s:当断点是一个函数输入s就可以打开函数里边的内容
ptype +变量:查看变量信息
display+变量名:追踪变量的值
undisplay+追踪变量的编号(可以用info display查看:不再追踪该变量
d+断点编号(同样用info查看):删除断点
finish:当进入函数体内部时,假设该函数在另一个文件里那么可以用finish跳出
set var+给变量赋值:产看变量等于你设置的值的时候时的状态
u:退出当前循环
p+变量:产科变量当前的值
quit:退处gdb

2.makefile的编写:管理程序的源代码
(1) makefile 的规则:
最终目标:依赖条件
命令:
例如:
main.out:a.c b.c c.c d.c main.c
(必须有tab缩进)gcc a.c b.c c.c d.c main.c -o main.out

以上便是最简单的makefile
(2)以上makefile有一个较大缺陷,如果有一个.c文件被修改那么重新用makefile时就会重新编译所有的.c文件那么改进:
在这里插入图片描述
系统会先找终极目标所需要的依赖发现没有便会在下边的规则中找到对应的依赖然后执行规则中的代码,等所有依赖找到后执行生成最终目标的代码,也就可以说所有的规则是为生成最终目标而服务的。
那么为啥会解决刚开始的问题呢:如果a中的.c经过修改后那么.c的最终生成时间就会晚于旧的.o,而旧的.o文件就是由.c文件编译而来,那么如果.c文件晚于.o文件说明.c文件需要更新,进而不需要更新别的.o文件避免造成不必要的在编译时间上的浪费
(3)改进后的makefile任由较大缺陷,经过再次改进:
在这里插入图片描述
以上解决了很多操作相同的但是只是参数不同带来的冗余问题

$:代表取值的意思
以下是只能在规则命令中使用的自动变量
$<:代表第一个依赖,当依赖目标是以%定义的那么其代表的是符号模式的一系列文件集
$@:规则中的目标
$^:规则中的所有依赖
一般大写的是系统维护的一些变量
%.o:%.c:生成最终目标的依赖是a.o等,那么就会与%.o:%.c就会匹配成a.o:a.c然后依次类推
(4)makefile中常用的两个函数(makefile所有函数都有返回值):
wildcard:获取到指定目录下的所有.c文件
patsubst:匹配替换函数(注意匹配是%)
在这里插入图片描述
makefile第个规则的目标是最终目标其余其余的规则要么是为终极目标服务的要么与终极目标无关
make指令得到最终的目标上图就是app
make clean就是执行clean的目标代码
-:在makefile中执行时只要有错误就不会往下边执行,-的目的就是遇到错误直接跳过继续执行
-f:如果你已经执行过一次clean再执行就会报错,-f对于上图来说就是即使删除过一遍不管有没有再一次删除也不会报错,继续执行
.PHONY:clean(对于上图来说):用.PHONY修饰是一个为目标,其实每条规则都会有一个最终目标,对于clean最终目标就是clean但是又不会生成clean文件,这时候如果makefile所在目录下有clean文件那么由于更新系统即使make clean也不会执行,磁盘下的clean文件永远是最新的,这时候就可以用伪目标来不进行更新系统直接执行

发布了37 篇原创文章 · 获赞 52 · 访问量 1821

猜你喜欢

转载自blog.csdn.net/qq_45737068/article/details/104668684