一、gdb调试
1.1gdb调试的作用
gdb调试检查的是逻辑错误,而非语法错误
1.2gdb流程
1、gcc -g 1.c ---->加-g参数的作用,生成可以调试的gdb文件
2、gdb 可执行文件名/a.out ---->进入gdb工具进行调试
3、输入l,带行号打印文件信息
4、打断点,b 行数
5、打完断电后,运行程序,输入r/run ----->停在断点的位置
6、n(next) ---->进入下一步,终端回显的代码是即将执行的代码而不是已经执行的代码
s(step) ---->s进行单步执行可以进入函数的内部
7、p 变量名 ----->打印变量的值
8、q 退出gdb调试
二、Makefile
2.1gcc的编译流程
预处理:gcc -E 1.c -o 1.i ----->gcc -E -o 1.i 1.c 删除注释, 替换宏定义,展开头文件,不检查语法错误,生成编译文件
编译:gcc -S -o 1.s 1.i 检查语法错误,生成汇编文件
汇编:gcc -c -o 1.o 1.s 生成二进制文件
链接:gcc -o 1 1.o 链接库
根据上面的编译流程,在生成可执行文件前,会生成一个中间二进制文件,对于源代码没有修改过的文件,不需要重新生成二进制文件。
2.2分文件编译存在的问题
在分文件编译时,常用的编译操作,gcc *.c ----->编译所有的.c文件
不论文件是否更新,都需要重新编译,浪费时间
2.3介绍Makefile
Makefile是一个工程管理文件,简化编译的流程,完成自动化编译的过程
在Makefile中,会把编译的过程分为两步,先生成.o文件,再对.o文件链接,生成可执行文件
2.4make工具
make是一个GNU的工具,make会读入文件并完成自动化编译的过程,
make默认读入文件是名为Makefile和makefile的文件,
如果makefile和Makefile同时存在,默认读入makefile
可以使用-f参数指定make工具的读入文件 ----->make -f Makefile clean
2.5Makefile的语法规则
Makefile由变量,函数和规则构成
2.6Makefile中规则的构成
目标:依赖
<tab>指令
注意事项:
1、一条规则必须有一个目标
2、一个目标可以有多个依赖
3、一条规则可以没有依赖,只完成相关的指令
4、一条规则可以没有指令,只描述依赖关系
2.7第一版Makefile
#是Makefile中的注释
all:fun #一般Mkefile会有一个all目标
#该目标通常写在Makefile中的第一个位置,用于保证Makefile文件一定会生成一个可执行性文件
main.o:main.c
gcc -c main.c -o main.o
fun:main.o fun.o
gcc main.o fun.o -o fun
fun.o:fun.c
gcc -c -o fun.o fun.c
clean:
rm *.o fun
2.8引入Makfile中的变量
= 递归赋值 ---->取变量最后一次的值
+= 追加赋值 ---->把值追加到原有值的后面,并带空格
:= 即赋值 ---->在哪赋值在哪展开
?= 件赋值 ---->如果前面出现过该变量,就不赋值否则赋值
递归赋值
立即赋值
追加赋值
条件赋值
Makefile中的自动变量
都是针对一条规则而言的
$@:所有目标
$^:所有依赖
$<:第一个依赖
2.9第二版Makefile
EXE=fun #定义EXE表示可执行文件名
OBJs+=main.o #定义中间代码文件(二进制文件)
OBJs+=fun.o
CC=gcc #定义编译器gcc为CC变量
CFLAGs=-c -g -o #定义CFLAGs保存gcc的编译参数
all:$(EXE) #一般Mkefile会有一个all目标
#该目标通常写在Makefile中的第一个位置,用于保证Makefile文件一定会生成一个可执行性文件
$(EXE):$(OBJs)
$(CC) $^ -o $@
main.o:main.c
$(CC) $(CFLAGs) $@ $^
fun.o:fun.c
$(CC) $(CFLAGs) $@ $^
clean:
rm $(OBJs) $(EXE)
2.10第三版的Makefile---->引入通配符
引入%通配符做模式匹配,能实现目标和依赖之间的唯一匹配关系
EXE=fun #定义EXE表示可执行文件名
OBJs+=main.o #定义中间代码文件(二进制文件)
OBJs+=fun.o
CC=gcc #定义编译器gcc为CC变量
CFLAGs=-c -g -o #定义CFLAGs保存gcc的编译参数
all:$(EXE) #一般Mkefile会有一个all目标
#该目标通常写在Makefile中的第一个位置,用于保证Makefile文件一定会生成一个可执行性文件
$(EXE):$(OBJs)
$(CC) $^ -o $@
%.o:%.c
$(CC) $(CFLAGs) $@ $^
clean:
rm *.o $(EXE)
%.o:%.c ----->会根据上面规则提供的依赖文件,找到OBJs里面的所有.o文件
main.o ---->%会自动获取到main,并且继续匹配%.c--->%.c会被展开为main.c
2.11引入内置函数
使用以下内置函数时,要求工作路径下,只存在可执行文件需要的.c文件
i)wildcard
获取当前工作路径下,所有满足格式的文件
$(wildcard 指定的文件格式)
$(wildcard *.c) ----->获取当前路径下的所有.c后缀的文件
ii)patsubst
模式匹配,把指定格式符字符串替换为另一个格式
$(patsubst 模式1,模式2,要转换的字符串)
$(patsubst %c,%o,1.c 2.c 3.c····· )
把用wildcard找到的所有.c文件文件名,转换成.o的字符串
EXE=fun #定义EXE表示可执行文件名
files=$(wildcard *.c) #使用内置函数wildcard获取当前路径下的所有.c文件
OBJs=$(patsubst %.c,%.o,$(files))
CC=gcc #定义编译器gcc为CC变量
CFLAGs=-c -g -o #定义CFLAGs保存gcc的编译参数
all:$(EXE) #一般Mkefile会有一个all目标
#该目标通常写在Makefile中的第一个位置,用于保证Makefile文件一定会生成一个可执行性文件
$(EXE):$(OBJs) #main.o fun.o
$(CC) $^ -o $@
%.o:%.c
$(CC) $(CFLAGs) $@ $^
.PHONY:clean #clean可以作为一个伪目标,这个目标不生成任何文件直接执行规则里的指令
clean:
rm *.o $(EXE)