380 likes | 512 Views
Linux 常用开发工具. 主要内容 gcc 编译系统的概念和使用 gdb 程序调试工具的概念和使用 程序维护工具 make 的概念和使用. 6.1 gcc 编译系统 6.1.1 文件名后缀. 6.1.2 C 语言编译过程. 1 .预处理阶段 预处理是常规编译 之前预先进行的工作, 故此得名。它读取 C 语言 源文件,对其中以 “ # ” 开头的指令(伪指令) 和特殊符号进行处理。 主要包括文件包含、宏 定义和条件编译指令。. 2 .编译阶段
E N D
主要内容 • gcc编译系统的概念和使用 • gdb程序调试工具的概念和使用 • 程序维护工具make 的概念和使用
6.1.2 C语言编译过程 1.预处理阶段 预处理是常规编译 之前预先进行的工作, 故此得名。它读取C语言 源文件,对其中以“#” 开头的指令(伪指令) 和特殊符号进行处理。 主要包括文件包含、宏 定义和条件编译指令。
2.编译阶段 • 编译程序(Compiler)对预处理之后的输出文件进行词法分析和语法分析,试图找出所有不符合语法规则的部分 3.汇编过程 • 汇编过程是汇编程序(Assembler)把汇编语言代码翻译成目标机器代码的过程 4.连接阶段 • 连接程序(Linker)要解决外部符号访问地址问题 • 连接模式分为静态连接和动态连接
6.1.3 gcc命令行选项 • 在Linux系统中,C/C++程序编译命令是gcc,例如: $ gcc f1.c f2.c (针对C语言源程序) 执行完成后,生成默认的可执行文件a.out。 1.预处理选项 C语言预处理程序通常称为cpp,它是宏处理程序,由C编译程序自动调用,在真正的编译过程之前对程序进行转换。 ●几个预处理常用选项: -C -D name -D name=definition -U name -I dir -o file-E
2.编译程序选项 gcc编译程序常用选项及其作用
3.优化程序选项 优化程序常用的选项及其作用
4.连接程序选项 连接程序常用的选项及其功能
Linux下库文件的命名有一个约定,所有的库名都以lib开头。形如:Linux下库文件的命名有一个约定,所有的库名都以lib开头。形如: libx.a 其中,x是指定的库名 • 以.a(归档,archive)结尾的库是静态库,以.so(共享目标,shared object)结尾的库是动态库 • 生成静态库的方法实际上可分为两步: ① 将各函数的源文件编译成目标文件 ② 使用ar工具将目标文件收集起来,放到一个归档文件中
6.2 gdb程序调试工具 • 程序中的错误可按性质分为三种: (1)编译错误,即语法错误。 (2)运行错误。 (3)逻辑错误。 查找程序中的错误,诊断其准确位置,并予以改正,这就是程序调试。 程序调试分为人工查错与机器调试。
6.2.1 启动gdb和查看内部命令 • 当程序执行过程中忽然中止,屏幕上显示××××-core dumped消息,然后显示提示符,其中,××××表示出错原因 • 为了发挥gdb的全部功能,需要在编译源程序时使用-g选项 。如: $ gcc -g prog.c -o prog (针对C语言源程序prog.c) $ gcc -g program.cpp -o program (针对C++源程序program.cpp) • 启动gdb的方法有以下几种: (1)直接使用shell命令gdb (2)以一个可执行程序作为gdb的参数 (3)同时以可执行程序和core文件作为gdb的参数 (4)指定一个进程号PID作为gdb的第二个参数 一旦启动gdb,就显示gdb提示符: (gdb) 并等待用户输入相应的内部命令
6.2.2 显示源程序和数据 1.显示和搜索源程序 (1)显示源文件 • 利用list命令可以显示源文件中指定的函数或代码行 list list - list [file:] num list start , endlist [file:]function (2)模式搜索 forward-search regexp search regexp reverse-search regexp
2.查看运行时数据 (1)print命令 一般使用格式是:print [/fmt]exp • 当被调试的程序停止时,可以用print命令(简写为p)或同义命令inspect来查看当前程序中运行的数据。 (2)gdb所支持的运算符 ① { type }adrexp表示一个数据类型为type、存放地址为adrexp的数据。 ② @ 是一个与数组有关的双目运算符,使用形式如: • print array@10print array[3]@5 ③ file :: var(或者 function :: var) 表示文件file(或者函数function)中变量var的值
(3)输出格式 • 在print /fmtexp命令中,“/”之后的fmt是表示输出格式的字母,它由表示格式的字母和表示数据长度的字母组成 。如: • 表示格式 的字母:o x d u t f a i c s • 表示长度的字母: b w h g (4)whatis命令显示出变量的数据类型 (5)x命令可以查看内存地址中数据的值。其使用格式是: x [/fmt]address (6)display命令可以预先设置一些要显示的表达式。其一般格式是: display [/fmt]exp • 要取消对先前设置的某些表达式的自动显示功能,可以使用以下命令: undisplay [disnum] delete display [disnum]
(7)显示函数调用栈信息 显示函数调用栈信息的命令
6.2.3 改变和显示目录或路径 • (1)directory命令一般格式是:directory [dir]或者 dir [dir] • (2)cd命令使用格式为: cd dir • (3)path命令使用格式是: path dirs • (4)pwd命令 • (5)show directories • (6)show paths
6.2.4 控制程序的执行 • 断点(breakpoint),观察点(watchpoint),捕捉点(catchpoint) 它们统称为停止点 1.设置和显示断点 (1)设置断点:用break命令(其缩写形式为b)设置断点: • break linenum break linenum if condition • break function break file:linenum • break file:function break *address break (2)显示断点 • info breakpoints [num] • info break [num]
2.设置和显示观察点 (1)设置观察点 watch expr rwatch expr awatch expr (2)显示观察点 • info breakpoints info watchpoints 3.设置捕捉点 • 命令catch的格式是: catch event • 另一个命令是tcatch event 4.维护停止点 • delete clear disable enable 5.运行程序 • run命令的格式:run [args]
6.程序的单步跟踪和连续执行 (1)单步跟踪 • 实行单步跟踪的命令是step和next,其格式是: step [N] next [N] (2)连续执行 continue,c或fg命令 7.函数调用 call exprreturn [expr]
6.2.5 其他常用命令 1.执行shell命令 • 其格式是: shell command-string 2.修改变量值 • (gdb) print x=10 • (gdb) set variable x=10 3.跳转执行 • jump linenum • jump *addr
6.2.6 应用示例 示例程序源代码
(1)使用带-g选项的gcc命令对该程序进行编译:(1)使用带-g选项的gcc命令对该程序进行编译: • $ gcc -g dbme.c -o dbme • 程序运行时出现错误——段错误 (2)用程序名dbme作为参数启动gdb。 (3)在gdb环境下运行该程序。
使用backtrace命令 • 使用list命令显示相关行的内容
6.3 程序维护工具make6.3.1 make的工作机制 • GNU的make的工作过程如下: ① 依次读入各makefile文件; ② 初始化文件中的变量; ③ 推导隐式规则,并分析所有规则; ④ 为所有的目标文件创建依赖关系链; ⑤ 根据依赖关系和时间数据,确定哪些目标文件要重新生成; ⑥ 执行相应的生成命令。
1.makefile文件 • make被调用后会依次查找名为GNUmakefile,makefile和Makefile的描述文件 • 一个示例 : prog: x.o y.o z.o assmb.o gcc x.o y.o z.o assmb.o -L/home/mqc/lib -lm -o prog x.o:x.c defs.h gcc -c x.c y.o: y.c defs.h gcc -c y.c z.o:z.c gcc -c z.c assmb.o:assmb.s as -o assmb.o assmb.s clean: rm prog *.o
Makefile规则有以下通用形式: 目标文件:[相依文件…] <tab>命令1[#注释] … <tab>命令n[#注释] • 在格式上应注意: • 依赖行从一行的开头开始书写 • 各命令行单独占一行,每个命令行的第一个字符必须是制表符<tab>,而不能使用8个空格 • #号后的内容为注释 • 在依赖行上,目标文件和相依文件之间要用一个或两个冒号分开
2.依赖关系图 • 使用make的一个核心问题是确定好各文件之间的依赖关系。一般来说,生成一个目标文件可能有多个不同的途径,根据这些途径能够指定不同的依赖关系。 • make是依据“关系图深度优先搜索”的算法来核查目标文件及相依文件的修改时间,深度相等时,可由左到右依次进行。 • 适当地引入中间结果,合理地构造依赖关系图,可以省去一部分编译工作量。但并非层次越多越好,要考虑目标文件的生成过程及其所起的作用。
6.3.2 使用变量 1.变量定义和引用 • make的变量(又称做宏定义)一般均由大写字母和数字组成。 • 定义变量的一般格式是: <变量名>=<字符串> 例如,下面都是合法的变量定义: OBJECT=x.o y.o z.o LIBES=-lm • 引用make变量的方式与引用shell变量类似,即:把变量用圆括号括起来,并在前面加上“$”符号。例如: $(OBJECT) $(LIBES)
2.自动变量 • 除了用户定义的变量外,make也可以使用环境变量、自动变量和预定义变量。 • make中定义了一些它们的值会因环境的不同而发生改变的变量,被称为自动变量。例如: • $@ 表示规则中的目标文件集合 • $? 所有比目标文件还新的那些相依文件的集合,以空格分开 • $< 规则中的第一个相依文件名 • $^ 规则中所有相依文件的集合,以空格分开 • $% 仅当目标文件是一个静态库成员时,表示规则中的目标成员 名,而此时$@表示相应库文件的名称 • $* 如果目标文件的后缀是make所识别的,则$*就是去掉后缀的目标文件名,但该引用只有用在隐含规则中才有意义
3.预定义变量 • 归档库: AR ARFLAGS • 汇编命令: AS ASFLAGS • C编译命令: CC CPP CFLAGS CPPFLAGS • C++编译命令: CXX CXXFLAGS
6.3.3 隐式规则 • 在makefile文件中显式地指定了一些规则,称为显式规则。 • 隐式规则就是一种惯例,即预先约定好了,不需要在makefile文件中写出来的规则。 • 几个常用的隐式规则: ① 编译C语言程序的隐式规则 ② 编译C++程序的隐式规则 ③ 汇编和汇编预处理的隐式规则
6.3.4 make命令常用选项 • make命令有丰富的命令行选项。例如: -C dir把目录改到dir -d 输出所有的调试信息 -e 指明环境变量优先于makefile文件中的变量 -f file使用file文件作为makefile文件 -I 忽略在执行重新生成文件的命令的过程中出现的所有错误 -I dir或 –Idir指定一个包含makefile文件的搜索目录