此系列还有两篇,大家想完整掌握可以阅读另外两篇
Linux文本编辑与shell程序设计-CSDN博客
Linux基础知识详解与命令大全(超详细)-CSDN博客
1.gcc编译系统
1.1 文件名后缀
文件名后缀 | 文 件 类 型 | 文件名后缀 | 文 件 类 型 |
.c | C源文件 | .s | 汇编程序文件 |
.i | 预处理后的C源文件 | .o | 目标文件 |
.ii | 预处理后的C++源文件 | .a | 静态链接库 |
.h | 头文件 | .so | 动态链接库 |
.C .cc .cp .cpp .c++ .cxx | C++源文件 | .out | 可执行程序文件 |
1.2 C语言编译过程
1.预处理阶段
预处理是常规编译之前预先进行的工作,故此得名。它读取C语言源文件,对其中以“#”开头的指令(伪指令)和特殊符号进行处理。主要包括文件包含、宏定义和条件编译指令。
2.编译阶段
3.汇编过程
4.连接阶段
连接程序(Linker)要解决外部符号访问地址问题
1.3 gcc命令行选项
$ gcc f1.c f2.c (针对C语言源程序)
执行完成后,生成默认的可执行文件a.out。
1.预处理选项
C语言预处理程序通常称为cpp,它是宏处理程序,由C编译程序自动调用,在真正的编译过程之前对程序进行转换。
-o file
2.编译程序选项
选项 | 功能 |
-c | 只生成目标文件,不进行连接。用于对源文件的分别编译 |
-E | 只生成预处理文件,不进行编译 |
-S | 只进行编译,不做汇编,生成汇编代码文件格式,其名与源文件相同,但扩展名为.s |
-o file | 将输出放在文件file中。如果未使用该选项,则可执行文件放在a.out中 |
-g | 指示编译程序在目标代码中加入供调试程序gdb使用的附加信息 |
-v | 在标准出错输出上显示编译阶段所执行的命令,即编译驱动程序及预处理程序的版本号 |
3 连接程序选项
选项格式 | 功能 |
-c -S -E | 如果使用其中任何一个选项,那么都不运行连接程序,而且目标文件名不应该用做参数 |
-llibrary | 连接时搜索由library命名的库。连接程序按照在命令行上给定的顺序搜索和处理库及目标文件。实际的库名是liblibrary,但按默认规则,开头的lib和后缀(.a或.so)可以被省略 |
-static | 在支持动态连接的系统中,它强制使用静态链接库,而阻止连接动态库;而在其他系统中不起作用 |
-Ldir | 把指定的目录dir加到连接程序搜索库文件的路径表中,即在搜索-l后面列举的库文件时,首先到dir下搜索,找不到再到标准位置下搜索 |
-o file | 指定连接程序最后生成的可执行文件名称为file,不是默认的a.out |
1.4 动态链接库与静态链接库
libx.a 其中,x是指定的库名
① 将各函数的源文件编译成目标文件
② 使用ar工具将目标文件收集起来,放到一个归档文件中
动态链接库的生成
gcc -c getdate.c -shared -o libgetdate.so
静态链接库的生成
gcc -c getdate.c -o getdate.o
ar -rcs libgetdate.a getdate.o
链接库的使用
动态:gcc main.c -L/root/testgcc -lgetdate -o main.out
静态:gcc main.c -static -L/root/testgcc -lgetdate -o main.out
2 gdb程序调试工具
(1)编译错误,即语法错误。
(2)运行错误。
(3)逻辑错误。
查找程序中的错误,诊断其准确位置,并予以改正,这就是程序调试,分为人工查错与机器调试。
2.1 启动gdb和查看内部命令
当程序执行过程中忽然中止,屏幕上显示××××-core dumped消息,然后显示提示符,其中,××××表示出错原因
$ gcc -g prog.c -o prog (针对C语言源程序prog.c)
$ gcc -g program.cpp -o program (针对C++源程序program.cpp)
启动gdb的方法有以下几种:
(1) 直接使用shell命令gdb
(2) 以一个可执行程序作为gdb的参数
一旦启动gdb,就显示gdb提示符:
(gdb)
并等待用户输入相应的内部命令
2.2 显示源程序和数据
1.显示和搜索源程序
(1)显示源文件
list list [file:] num
list start , end list [file:]function
(2)模式搜索
forward-search regexp
search regexp
reverse-search regexp
2.查看运行时数据
(1)print命令 一般使用格式是 :print [/fmt] exp
(2)gdb所支持的运算符
① 用&运算符取出变量在内存中的地址,如:print &i , print &array[i]
② { type }adrexp表示一个数据类型为type、存放地址为adrexp的数据。
③ file :: var (或者 function :: var ) 表示文件file(或者函数function)中变量var的值
(3)输出格式
(4)whatis命令显示出变量的数据类型,如:whatis i
(5)x命令可以查看内存地址中数据的值 。其使用格式是:
x [/fmt] address
(6)display命令可以预先设置一些要显示的表达式。其一般格式是:
display [/fmt] exp
undisplay [disnum]
delete display [disnum]
2.3 控制程序的执行
断点(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
4.维护停止点
delete clear disable enable
5.运行程序
run命令的格式: run [args]
6.程序的单步跟踪和连续执行
(1)单步跟踪
实行单步跟踪的命令是step和next,其格式是:
step [N]
next [N]
(2)连续执行
continue,c或fg命令
7.函数调用
call expr return [expr]
3 程序维护工具make
3.1 make工作机制
GNU的make的工作过程如下:
① 依次读入各makefile文件;
② 初始化文件中的变量;
③ 推导隐式规则,并分析所有规则;
④ 为所有的目标文件创建依赖关系链;
⑤ 根据依赖关系和时间数据,确定哪些目标文件要重新生成;
⑥ 执行相应的生成命令。
例6.1:某个正在开发的程序由以下内容组成:
(1) 三个C语言源文件:x.c,y.c和z.c。设x.c和y.c都使用了defs.h中的声明;
(2) 汇编语言源文件assmb.s被某个C语言源文件调用;
(3) 使用了在/home/mqc/lib/libm.so中的一组例程。
设最后生成的可执行文件名为prog。
3.2 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[#注释]
在格式上应注意:
依赖关系图
- 使用make的一个核心问题是确定好各文件之间的依赖关系。一般来说,生成一个目标文件可能有多个不同的途径,根据这些途径能够指定不同的依赖关系。
- make是依据“关系图深度优先搜索”的算法来核查目标文件及相依文件的修改时间,深度相等时,可由左到右依次进行。
- 适当地引入中间结果,合理地构造依赖关系图,可以省去一部分编译工作量。但并非层次越多越好,要考虑目标文件的生成过程及其所起的作用。
使用变量:
变量定义和引用
1 make的变量(又称做宏定义)一般均由大写字母和数字组成。
定义变量的一般格式是:
<变量名>=<字符串>
例如,下面都是合法的变量定义:
OBJECT=x.o y.o z.o
LIBES=-lm
引用make变量的方式与引用shell变量类似,即:把变量用圆括号括起来,并在前面加上“$”符号。例如: $(OBJECT) $(LIBES)
2 make命令有丰富的命令行选项。 例如:
-C dir 把目录改到dir
-d 输出所有的调试信息
-e 指明环境变量优先于makefile文件中的变量
-f file 使用file文件作为makefile文件
-I 忽略在执行重新生成文件的命令的过程中出现的所有错误
-I dir 或 –Idir 指定一个包含makefile文件的搜索目录
3.预定义变量
隐式规则:
在makefile文件中显式地指定了一些规则,称为显式规则。
隐式规则就是一种惯例,即预先约定好了,不需要在makefile文件中写出来的规则。
几个常用的隐式规则:
① 编译C语言程序的隐式规则
② 编译C++程序的隐式规则
③ 汇编和汇编预处理的隐式规则