一、Makefile
1. 什么是Makefile
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,Makefile 文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 Makefile文件就像一个Shell 脚本一样,也可以行操作系统的命令。Makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make 是一个命令工具,是一个解释Makefile 文件中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如Delphi 的 make,Visual C++的nmake,Linux 下GNU的 make。
2.Makefile的命名规则
2.1文件命名
Makefile 或者makefile,在输入make命令后,操作系统会在当前路径下查找上述两个文件进行编译
2.2 Makefile规则
1.Makefile中其他规则一般为第一条规则服务
2.一个Makefile中可以有多个规则,规则形式如下:
目标 ....... : 依赖文件 ........
命令 (Shell命令)
.........
3.命令在执行前,需要检查规则中的依赖是否存在
-存在则执行
-不存在则向下查找,是否有一条规则是用来生成这个依赖的
4.检测更新,在执行规则中的命令时,会比较目标和依赖文件的时间
-若依赖更新时间晚,则需要重新生成目标
-若目标更新时间晚,则不需要执行命令
2.3 Makefile中的变量
变量:
//自定义变量 //变量名=变量值 var=hello //$获取变量值 $(var) // 预定义变量 AR //归档维护程序名 CC //C编译器名称,默认为cc CXX //C++编译器名称,默认为g++ $@ //目标的完整名称 $< //第一个依赖文件的名称 $^ //所有依赖文件 //举例 app : main.c a.c b.c gcc -c main.c a.c b.c -o app //可又变量替换为 app : main.c a.c b.c $(CC) -c &^ -o $@
模式匹配:
%.o : %.c
- %:通配符,匹配同一个字符串
2.4 Makefile中的函数
$(wildcard PATTERN...)
-功能:获取制定目录下指定类型的文件列表
-参数:PATTERN指多个目录对应下的某种类型的文件,多个目录空格隔开
-返回值:得到若干个文件列表,空格隔开
-例:
$(wildcard *.c ./sub/*.c)
返回: a.c b.c c.c d.c ........
$(patsubst <pattern>,<replacement>,<text>)
-功能:查找<text>中的单词(单词以“空格”、“Tab"或“回车""换行"分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。
-<pattern>可以包括通配符`8`,表示任意长度的字串。如果<replacement>中也包含`8`,那么,<replacement>中的这个`%`将是<pattern>中的那个%所代表的字串。(可以用`\`来转义,以`\%`来表示真实含义的`%`字符)
-返回值:函数返回被替换过后的字符串
-例:
$(patsubst %.c, %.o, x.c bar.c)
返回: x.o bar.o
二、GDB调试
1.什么是GDB
GDB 是由 GNU 软件系统社区提供的调试工具,同GCC配套组成了一套完整的开发环境,GDB 是Linux和许多类Unix系统中的标准开发环境。—般来说,GDB 主要帮助你完成下面四个方面的功能:
1.启动程序,可以按照自定义的要求随心所欲的运行程序
2.可让被调试的程序在所指定的调置的断点处停住(断点可以是条件表达式)
3.当程序被停住时,可以检查此时程序中所发生的事
4.可以改变程序,将一个 BUG产生的影响修正从而测试其他BUG
2.启动GDB调试的准备工作
通常,在为调试而编译时,我们会()关掉编译器的优化选项(`-o`) ,并打开调试选项(` -g `)。另外, `-wall`在尽量不影响程序行为的情况下选项打开所有warning,也可以发现许多问题,避免一些不必要的 BUG。
gcc -g -wall program.c -o program
'-g`选项的作用是在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件。
3.GDB常用命令和操作
1 gdb [file] //对具有调试信息的文件启动gdb调试 2 quit //退出调试 3 set args .. .. .. //对调试程序设置参数 4 show args //获取参数 5 show list/listsize //获取当前显示行数 6 set list/listsize 行数 //设置每次显示行数 7 set inferior-tty 进程id//设置不同进程的调试 8 info inferiors //显示当前存在的所有进程和id 9 show nferior-tty //显示当前调试进程 10 11 l/list //从默认位置显示 12 l/list 行号 //将指定行放到中间显示 13 l/list 函数名 //将指定函数放到中间显示 14 15 //查看非当前文件的代码 16 list/l 文件名:行号 17 list/ l文件名:函数名 18 19 20 //设置断点 21 b/break 行号 22 b/break 函数名 23 b/break 文件:行号 24 b/break 文件:函数名 25 26 i/info b/break //查看断点信息 27 d/del/delete 断点编号//删除断点 28 dis/disable 断点编号 //设置断点无效 29 ena/enable 断点编号 //设置断点生效 30 b/break 断点编号 if 条件 //设置条件断点 31 32 //调试指令 33 //运行 34 start //程序停在第一行 35 run //遇到断点才停 36 37 //继续运行,遇到下一个断点停止 38 c/continue 39 40 //向下执行一行代码,不会进入函数 41 n/next 42 43 //向下单步调试 44 s/step 45 46 //跳出函数体 47 finish 48 49 //变量操作 50 p/print 变量名 //打印变量值 51 ptype 变量名 //打印变量类型 52 display 变量名 //自动打印指定变量 53 i/info display //查看自动变量信息 54 undisplay 编号 //删除自动变量 55 56 //循环相关 57 set var 变量名=变量值 58 until //跳出循环(前提是循环内没有断点了)