linux系统编程——Makefile、GDB调试

Makefile

makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile文件就像一个shell脚本一样,也可以执行操作系统的命令。

自动化编译,只要一个make命令,整个工程完全自动编译。

规则

一个makefile文件中可以有一个或者多个规则

复制代码
目标 ... : 依赖 ...
	命令(shell命令)
	...

目标:最终要生成的文件(伪目标除外)

依赖:生成目标所需要的文件或是目标

命令:通过执行命令对依赖操作生成目标(命令前必须Tab缩进)

Makefile中的其它规则一般都是为第一条规则服务的

命令在执行之前,需要先检查规则中的依赖是否存在

检查更新,在执行规则中的命令时,会比较目标和依赖文件的时间

如果依赖的时间比目标的时间晚,需要重新生成目标

如果依赖的时间比目标的时间早,目标不需要更新,对应规则中的命令不需要被执行。

变量

复制代码
自定义变量
	变量名=变量值		var=hello     			$(var)
预定义变量
	AR:归档维护程序的名称,默认值为ar			  app:main.c a.c b.c
	CC:C编译器的名称,默认值为cc					gcc -c main.c a.c b.c
	CXX:C++编译器的名称,默认值为g++
	$@:目标的完整名称						#自动变量只能在规则的命令中使用
	$<:第一个依赖文件的名称				   app:main.c a.c b.c
	$^:所有的依赖文件							$(CC) -c $^ -o $@
获取变量的值
	$(变量名)

模式匹配

复制代码
%.o:%.c
	-%:通配符,匹配一个字符串
	-两个%匹配的是同一个字符串
%.o:%.c
	gcc -c $< -o $@

函数

复制代码
$(wildcard PATTERN...)
	功能:获取指定目录下指定类型的文件列表
	参数:PATTERN指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
	返回:得到的若干个文件的文件列表,文件名之间使用空格间隔
	示例:
		$(wildcard *.c ./sub/*.c)
		返回值格式:a.c b.c c.c d.c e.c f.c
$(patsubst <pattern>,<replacement>,<text>)
	功能:查找<text>中的单词(单词以"空格"、"Tab"或"回车""换行"分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换
	<pattern>可以包括通配符'%',表示任意长度的字串。如果<replacement>中也包含'%',那么,<replacement>中的这个'%'将是<pattern>中的那个%所代表的字串。
	返回:函数返回被替换过后的字符串
	示例:
		$(patsubst %.c, %.o, x.c bar.c)
		返回值格式:x.o bar.o

示例

三个文件 保存函数的声明(.h文件),函数的实现(.c文件),主函数文件

编写makefile

复制代码
processOn:main.c mytest.c
    gcc main.c mytest.c -o processOn
.PHONY:clean
clean:
    rm -f processOn

用上变量里的特殊符号的话就变成了

复制代码
processOn:main.c mytest.c
    gcc -o $@ $^
.PHONY:clean
clean:
    rm -f processOn

生成一个可执行文件processOn,它依赖于main.c和mytest.c,第二行是它的依赖方法。此时我们使用make命令,则目录下会自动生成一个可执行文件processOn.

而工程也是需要被清理的。像clean这种没有被第一个目标文件直接或者间接关联,那么它后面的命令就不会被执行,所以我们可以显式要make执行,即make clean,以此来一次性清除所有生成的目标文件,以便于重新编译。

.PHONY是一个关键字,被该关键字修饰的对象是一个伪目标,该目标总是被执行,不是拿时间来作为新旧文件的对比。所以一般将clean设置成伪目标。

GDB调试

GDB是由GNU软件系统社区提供的调试工具,同GCC配套组成一套完整的开发环境,

GDB功能

  1. 启动程序,可以按照自定义的要求随心所欲的运行程序

  2. 可让被调试的程序在所指定的调置的断点处停住(断点可以是条件表达式)

  3. 当程序被停住时,可以检查此时程序中所发生的事

  4. 可以改变程序,将一个BUG产生的影响修正从而测试其他BUG

准备工作

在为调试而编译时,我们会()关掉编译器的优化选项('-o'),并打开调试选项('-g')。另外,'-Wall'在尽量不影响程序行为的情况下选项打开所有warning,也可以发现许多问题,避免一些不必要的BUG

复制代码
gcc -g -Wall program.c -o program
'-g'选项的作用是在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件。

GBD命令

复制代码
启动和退出
	gdb 可执行程序
	quit
给程序设置参数/获取设置参数
	set args 10 20
	show args
GDB 使用帮助
	help
查看当前文件代码
	list/l  (从默认位置显示)
	list/l 行号   (从指定的行显示)
	list/l 函数名  (从指定的函数显示)
查看非当前文件代码
	list/l 文件名:行号
	list/l 文件名:函数名
设置显示的行数
	show list/listsize
	set list/listsize 行数

示例

复制代码
# test.c一个示例源文件
gcc test.c -o test -g
# 生成一个test
# 打开gdb
gdb test
# 进入到gdb里面
# 传入一些参数
set args 10 20
# 获取传入的参数
show args
# 退出gdb
quit
list  # 查看代码文件,注意只有前面加-g才可以

GDB断点操作

复制代码
设置断点
	b/break 行号
	b/break 函数名
	b/break 文件名:行号
	b/break 文件名:函数
查看断点
	i/info b/break
删除断点
	d/del/delete 断点编号
设置断点无效
	dis/disable 断点编号
设置断点生效
	ena/enable 断点编号
设置条件断点
	b/break 10 if i==5

示例

复制代码
# 第九行打断点
break 9
# 查看断点信息
info break

GDB调试命令

复制代码
运行GDB程序
	start(程序停在第一行)
	run(遇到断点才停)
继续运行,到下一个断点停
	c/continue
向下执行一行代码(不会进入函数体)
	n/next
变量操作
	p/print 变量名(打印变量值)
	ptype 变量名(打印变量类型)
向下单步调试(遇到函数进入函数体)
	s/step
	finish (跳出函数体)
自动变量操作
	display num (自动打印指定变量的值)
	i/info display
	undisplay 编号
其他操作
	set var 变量名=变量值
	until (跳出循环)
相关推荐
Hacker_Oldv3 分钟前
软件测试(功能、工具、接口、性能、自动化、测开)详解
运维·自动化
Java樱木5 分钟前
使用字节Trae + MCP,UI 到网页自动化。
运维·自动化
柳鲲鹏39 分钟前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
无敌暴龙兽z3 小时前
离线环境安装elk及设置密码认证
运维·elk
M4K03 小时前
Linux百度网盘优化三板斧
linux
好奇的菜鸟3 小时前
如何在 Ubuntu 24.04 (Noble) 上使用阿里源
linux·运维·ubuntu
bcbobo21cn4 小时前
初步了解Linux etc/profile文件
linux·运维·服务器·shell·profile
wayuncn4 小时前
月付物理服务器租用平台-青蛙云
运维·服务器·服务器租用·服务器托管·物理机租用
望获linux4 小时前
【实时Linux实战系列】CPU 隔离与屏蔽技术
java·linux·运维·服务器·操作系统·开源软件·嵌入式软件
0wioiw04 小时前
C#基础(项目结构和编译运行)
linux·运维·服务器