一、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 //跳出循环(前提是循环内没有断点了)