一、makefile
1、make && makefile
makefile带来的好处就是——自动化编译,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率
下面我们通过如下示例来进一步体会它们的作用:
①编写makefile文件
touch makefile
vim makefile
使用vim编辑器编辑makefile
文件:
#makefile文件中的内容
hello.exe:hello.c gcc hello.c -o hello.exe
.PHONY:clean
clean:rm -f hello.exe
此时我们只需一个make
命令即可完成自动编译:
make
make
命令的作用,即是执行makefile
中的命令,此处执行的命令是:
gcc hello.c -o hello.exe
当我们输入:
make clean
此处就执行了:
rm -f hello.exe
2、make执行步骤
当我们在Linux中输入并执行make
命令时,make
会干些什么呢?
step 1:
make
会在当前目录下寻找Makefile
文件,找到了就会用这个文件作为后续操作的依据;如果没找到Makefile
,就会寻找名为makefile
的文件;两个都没找到就报错;step 2:找到
Makefile
或者makefile
之后,默认文件中第一行作为第一个目标;make
命令会分析第一个目标的依赖关系,并且执行该目标的依赖方法**;
2.1 依赖关系
hello.exe:hello.c #依赖关系
makefile
文件中hello.exe
就是目标(期望生成的内容);我们编译文件hello.c
,期望生成它对应的可执行文件hello.exe
,而你要编译生成这个目标文件,需要依赖hello.c
这个文件,这就是依赖关系。
2.2 依赖方法
有了依赖关系,我们就知道了生成目标可执行文件hello.exe
需要依赖hello.c
这个文件,那么我们该怎么利用hello.c
文件生成hello.exe
文件呢?我们是不是还缺少一个方法,而这个使用目标的依赖关系文件生成期望的目标文件的方法就是依赖方法。
gcc hello.c -o hello.exe #依赖方法
需要注意的是,依赖文件列表可以为空
3、项目清理
# makefile文件中的清理部分
.PHONY:clean
clean:rm -f code
上述makefile
文件中,该部分即为项目清理部分;在上述介绍中,我们知道需要显式输入make clean
才能实现清除编译好的文件hello.exe
以便重新编译:
其中.PHONY
的使用,是将它设置为伪目标,伪目标的特性是:总是被执行的❓
4、伪目标 .PHONY
👉 怎样理解总是被执行的?我们试着多次输入make
指令,发现结果如下:
结果:当第一次使用make命令时,目标被执行生成了一个可执行文件,而当我们再使用make命令时发现make虽然不会报错但是会告诉我们生成的文件的已经是最新的了,目标并没有被执行
那么多次输入make clean
指令呢?结果如下:
可以一直执行rm -f hello.exe
这条指令!(即使已经重复执行了)
我们将生成可执行文件过程更改为伪目标(使用vim编辑器):
# 修改makefile文件
.PHONY:hello.exe
hello.exe:hello.cgcc hello.c -o hello.exe
再测试一下:
二、GDB
GDB是命令行模式的调试工具,能够让用户在程序运行时观察程序的内部结构和内存的使用情况。
1、准备工作
gdb_test.c:
#include<time.h>void Print(int sum)
{long long timestamp=time(NULL);printf("result=%d,timestamp:%lld\n",sum,timestamp);
}int AddtoVal(int from,int to)
{int sum=0;for (int i = from; i <= to; i++){sum+=i;}return sum;
}int main()
{int sum=AddtoVal(0,100);Print(sum);return 0;
}
生成可执行文件:
1、debug版本:程序本身会被加入更多的调试信息,以便于进行调试。
2、release版本:不会添加任何调试信息,是不可调试的。
在Linux当中gcc/g++默认生成的可执行程序是release版本的,是不可被调试的。如果想生成debug版本,就需要在使用gcc/g++生成可执行程序时加上-g
选项。
gdb_test_g.exe:gdb_test.cgcc gdb_test.c -o gdb_test_g.exe -g
.PHONY:clean
clean:rm -rf gdb_test_g.exe
可使用工具读取可执行程序符号表debug部分:
[Kevin@VM-8-13-centos code1]$ readelf -S gdb_test_g.exe | grep debug[26] .debug_aranges PROGBITS 0000000000000000 00001095[27] .debug_info PROGBITS 0000000000000000 000010c5[28] .debug_abbrev PROGBITS 0000000000000000 00001536[29] .debug_line PROGBITS 0000000000000000 000016af[30] .debug_str PROGBITS 0000000000000000 000017d5
总结:要用gdb调试,首先要进行给编译器添加-g
2、正式调试
调试命令:
进入gdb:gdb 文件名
显示代码:l n 显示从第n行开始的源代码,每次显示10行,若n未给出则默认从上次的位置往下显示。
打一个断点:b n在第n行设置断点。
查看已打断点:info b
去掉打的断点:d 断点编号 删除指定编号(不是行号)的断点。
开始调试运行:r(run)
逐过程:n(next)
逐语句:s(step)会进入函数体中
运行到下一个断点处:c(continue)
查看函数调用堆栈:bt
直接运行完当前函数:finish 个性化跑完自定义的一个个函数,方便定位代码错误的位置
打印变量的值/地址:p(print)变量/&变量
将变量的值/地址加入常显示:display 变量/&变量
取消指定编号变量的常显示:undisplay 编号
跳出循环/跳转至指定行:until 行号
修改变量值:set var 变量=x 将变量的值修改为x
退出gdb:quit/ql
continue)
查看函数调用堆栈:bt
直接运行完当前函数:finish 个性化跑完自定义的一个个函数,方便定位代码错误的位置
打印变量的值/地址:p(print)变量/&变量
将变量的值/地址加入常显示:display 变量/&变量
取消指定编号变量的常显示:undisplay 编号
跳出循环/跳转至指定行:until 行号
修改变量值:set var 变量=x 将变量的值修改为x
退出gdb:quit/ql