Linux工具篇:gdb(调试工具)+ makefile(自动化构建工具)

目录

前言:

Linux调试器-gdb使用:

Linux项目自动化构建工具-make/Makefile:

问题:

为什么makefile对最新的可执行程序,默认不想不想重新形成呢?

make是如何知道到我的程序需要被编译的呢?

能不能简化一下makefile?

总结:


前言:

        在学习Linux之前,确切的说是在认识和使用vim之前,我们学习C语言甚至是C++都是在VS2022等Windows的IDE上进行编写代码的,我们之前也讲过,VS2022有两个版本,一个是Debug版本,还有一个是Release版本。Debug版本是给我们来进行调试编译的,那么在Linux下也存在我们的调试工具——gdb。makefile则是一个新的概念,它是Linux项目自动化构建工具。

Linux调试器-gdb使用:

        编译器在区别Debug和Release版本的方式,就是编译器在对Debug版本形成可执行程序时,会给Debug版本的可执行程序增添调试信息。 我们在平常输入指令gcc "XXX"的时候默认是形成Release的可执行程序,其实我们只需要在最后加上 -g选项就是Debug版本了。

  • list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
  • list/l 函数名:列出某个函数的源代码。
  • r或run:运行程序。
  • n 或 next:单条执行。
  • s或step:进入函数调用
  • break(b) 行号:在某一行设置断点
  • break 函数名:在某个函数开头设置断点
  • info break :查看断点信息。
  • finish:执行到当前函数返回,然后挺下来等待命令
  • print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
  • p 变量:打印变量值。
  • set var:修改变量的值
  • continue(或c):从当前位置开始连续而非单步执行程序
  • run(或r):从开始连续而非单步执行程序
  • delete breakpoints:删除所有断点
  • delete breakpoints n:删除序号为n的断点
  • disable breakpoints:禁用断点
  • enable breakpoints:启用断点
  • info(或i) breakpoints:参看当前设置了哪些断点
  • display 变量名:跟踪查看一个变量,每次停下来都显示它的值
  • undisplay:取消对先前设置的那些变量的跟踪
  • until X行号:跳至X行
  • breaktrace(或bt):查看各级函数调用及参数
  • info(i) locals:查看当前栈帧局部变量的值
  • quit:退出gdb
     

我们在调试的时候,一定要先设置断点再run起来,输入r。

Linux项目自动化构建工具-make/Makefile:

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构
mytest.exe:test.c
    gcc test.c -o test.exe
.PHONY:clean
clean:
    rm -f mytest

        以上就是最简单基础的makefile里的代码,这里要特别注意,gcc前面一定要加tab,剩下的也同理,一定一定要加tab,接下来就来创建test.c来实战编写一下。

 

 

         接下来输入make指令:

make就自动调用makefile里面的指令:gcc test.c -o test.exe

 

要想清理test.exe ,输入make clean即可。

make会根据makefile的内容,完成编译/清理工作。

一般会先默认形成第一个目标文件,先写可执行程序。

.PHONY : XXX

表示XXX总要被执行,如下图验证:

 

因为我已经存在了一个test.exe文件,而test.exe作为目标文件 且 没有.PHONY修饰,如果继续make则不会运行。再看看我们的 make clean:

不一样的地方就在于make clean可以一直运行,这是因为在make clean前面加了.PHONY进行修饰。

其实普通的make也可以用.PHONY进行修饰。

这次我把.PHONY提前了。 

 

 很明显,这次就没之前的英文:"test.exe is up to data"

问题:

为什么makefile对最新的可执行程序,默认不想不想重新形成呢?

        最主要的目的——为了提高编译效率,如果你对gcc或者g++之前添加了.PHONY,那么十几行的代码或者一个.c文件那还好,万一你又200000个.c文件需要被编译呢?这样效率就很低下了。

make是如何知道到我的程序需要被编译的呢?

        我先总结一句话:“代码编写完的时间和编译的时间绝对不一样!”

      

        如图,肯定是先编写完代码,才会对代码进行编译。所以不加.PHONY的make就是根据查找时间线之前是否存在编译好的代码,如果存在就不再进行编译了。.PHONY就是让系统别按照时间线来查找,一言不合就是“干”!

能不能简化一下makefile?

        当然是可以的,makefile/make会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有的相关的依赖方法。但必须保证你最终要到的目标文件放在最前面!

@:表示目标文件

^:表示后面的文件

        当然makefile中也支持定义变量:

 

当然如果你不想在执行make后,让屏幕出现执行语句,你可以在gcc前面加个@

总结:

1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“hello”这个文件,并把这个文件作为最终的目标文件。
3. 如果test.exe文件不存在,或是test.exe所依赖的后面的test.c文件的文件修改时间要比test.exe这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成test.exe这个文件。
4. 如果test.exe所依赖的test.c文件不存在,那么make会在当前文件中找目标为test.exe文件的依赖性,如果找到则再根据那一个规则生成test.c文件。(这有点像一个堆栈的过程)
5. 当然,你的C文件和H文件是存在的啦,于是make会生成 test.exe 文件,然后再用 test.c 文件声明make的终极任务,也就是执行文件test.exe了。
6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

相关推荐

  1. [ Linux ]调试工具gdb

    2024-07-18 15:26:01       37 阅读
  2. Linux】项目自动化构建工具 - make/Makefile

    2024-07-18 15:26:01       61 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 15:26:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 15:26:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 15:26:01       58 阅读
  4. Python语言-面向对象

    2024-07-18 15:26:01       69 阅读

热门阅读

  1. 网络安全学习流程

    2024-07-18 15:26:01       19 阅读
  2. 请解释vue的单页面应用是什么及其优缺点

    2024-07-18 15:26:01       20 阅读
  3. 7月17日学习打卡,数组

    2024-07-18 15:26:01       22 阅读
  4. 原生html点击按钮上传文件(隐藏file输入框)

    2024-07-18 15:26:01       22 阅读
  5. 在html中使用vue.js的component

    2024-07-18 15:26:01       22 阅读
  6. 邦芒支招:这三种方法帮你减轻工作负担

    2024-07-18 15:26:01       20 阅读
  7. 【18】Android 线程间通信(三) - Handler

    2024-07-18 15:26:01       18 阅读
  8. SpinalHDL之Flow

    2024-07-18 15:26:01       23 阅读
  9. 精通JVM监控与调优:工具使用与命令指南

    2024-07-18 15:26:01       22 阅读