Linux基础7 编译与调试

一.编译与调试

1.gcc,g++, gdb的安装

1.1 gcc的安装

请添加图片描述

1.2 g++的安装

请添加图片描述

1.3 gdb的安装

和上述操作一致。

2.gcc分步进行编译

之前讲到的C语言“.c”文件如果可以想直接去运行,首先需要将源文件变成可执行文件,那么这个过程可以细分为四个过程: 处理(预编译),编译,汇编,链接

可以分为四个步骤:

1. 预编译(-E(大写):预处理指定的源文件,但是不进行编译)
gcc -c main.s -o main.o

2. 编译(-S(大写):编译执行的源文件,但是不进行汇编)
gcc -S main.i -o main.s

3. 汇编(-c(小写):编译,汇编指定的源文件,但是不进行链接)
gcc -c main.s -o main.o

4. 链接(-o:指定生成文件的文件名)
gcc main.o -o main请添加图片描述

3.一步编译

3.1 上述四个步骤,怎么通过一行代码,直接将源文件变成可执行文件呢?

命令如下:gcc main.c

请添加图片描述
如果不给-o,系统会默认生成可执行文件a.out,如果想自定义最终生成的可执行文件的文件名,
可以通过-o:gcc main.c -o main

3.2 前三个步骤,怎么通过一行代码,直接将源文件变成目标文件“.o”呢?

gcc -c main.c

4.编译后执行

通过路径+文件名的方式可以启动一个程序,这里主要目的就是让系统可以准确的找到指定的文件 。
例如刚才我们通过"./main"和"./a.out"的方式启动了刚才生成的这两个可执行文件,那么这的"./"可不可以省略,像pwd,ls这些命令一样,不需要路径就可以执行呢?
请添加图片描述
测试是不可以的,系统反馈信息,告诉我们,不加路径的话,系统将其看做一个命令,而且并不是在我当前相对目录下找main或者a.out,而是默认直接去标准路径下找main和a.out,当然找不到的话,就会报错,说在/usr/bin里面找不到对应的命令。

既然知道系统报错的原因,那么现在就可以将刚才生成的main和a.out放到/usr/bin里面请添加图片描述
,则这时系统就可以找到了,就不会报错了,就可以像pwd,ls这些命令一样, 不需要路径也可以执行了。

5.编译链接过程

请添加图片描述
这里不详细说明了 将会在后面对编译链接过程写一篇博客。

6.g++

gcc主要处理C语言的“.c”文件

g++主要处理C++的“.cpp”文件

例如:现在有一个main.cpp文件,如果通过g++去编译:
请添加图片描述
这里有两种方法可以对main.cpp进行编译:

第一种:通过g++去进行编译
请添加图片描述
第二种:通过gcc去进行编译

之前我们认为gcc主要处理C语言的".c"文件,但是其实也可以用来编译“.cpp”文件,只不过gcc默认链接的是C语言的标准库,并没有链接C++的标准库,所以只要手动给其添加上C++的标准库,则可以通过gcc去编译了(g++默认链接C++的标准库)

请添加图片描述
请添加图片描述
-l(-library):其中library表示库文件的名称,该选项用于手动指定链接环节中程序可以调用的库文件,-l和库文件名之间不使用空格,例如-lstdc++

二.makefile和make

1.make的安装

安装如下:
请添加图片描述

2.makefile和make命令的介绍

makefile文件:Linux上的项目工程管理工具,可以实现自动化编译。

后期一个项目工程里面的源文件可能不计其数,它还根据类型,功能,模块,将这些源文件分到好些目录里,makefile文件里面就可以定义一系列的规则来指定哪一些文件先需要进行编译,哪一些后编译,哪些文件需要重新编译,甚至更复杂的操作,makefile文件就像一个shell脚本一样,可以自动执行自定义好的一系列命令。

make:是一个命令,可以解释makefile文件中的指令。

从另一个角度来说,一个人会不会写makefile,就说明他是否具备完成大型工程的能力。

3.makefile文件的规则和make的使用

例如:现在有三个文件 main.c max.c add.c
请添加图片描述
通过gcc执行一下:
请添加图片描述
但是如果有很多的源文件,或者说突然想修改其中几个源文件的数据,其他大部分的源文件是没有被修改的,这时如果按照上面的说法,没有修改过的文件还需要再编译一下,太费时费力。

这时我们就可以使用makefile文件,提高编译效率,通过make命令执行makefile文件,这时只会将修改过的文件或者依赖修改过的文件的文件,不受影响的文件不会重新编译。

makefile文件示例如下:
请添加图片描述
使用make命令根据makefile文件的规则生成对应的可执行文件:
请添加图片描述
现在修改main.c中的数据,则未收影响的源文件不会重新编译,示例如下:
请添加图片描述
如果make完想保持整洁,可以通过make clean:
请添加图片描述

三.gdb调试

1.Debug版本和Release版本介绍

Debug版本叫做开发版本或者可调试版本,生成的可执行文件里面包含调试需要用到的信息。我们作为开发人员,最常用的就是debug版本产生的可执行文件。

Release版本是发行版本,面向用户的,里面没有调试信息,所以体积会相较于debug版本非常的小。

注意:gcc默认生成的是Release版本。

2.gcc生成Debug版本的可执行文件

Debug版本的生成:因为调试信息是在编译阶段加入到可重定向的目标文件(.o)中的,所以必须在编译阶段就让它添加调试信息进来。

命令如下:
第一种方式

  • 首先 gcc -c main.c -g (生成的中间文件main.o这时包含调试信息)
  • 然后再通过gcc -o main main.o(生成了debug版本的可执行文件)

第二种方式:
一步生成,gcc -o main main.c -g

3.通过gdb进入调试

首先需要将源文件编译,链接生成debug版本的可执行文件,然后通过gdb debug版本的可执行文件名,就可以进入到gdb调试模式.

演示示例1如下:
请添加图片描述
执行起来
请添加图片描述
执行起来后,发现输入end,不能正常结束循环,这时则可以进入到gdb模式去查看问题所在。

示例如下:(先生成debug版本的可执行文件)
请添加图片描述

  • l //显示当前文件的源代码
  • list filename:num //显示filename文件中第num行附近的的源代码-
  • b 行号 //给指定行添加断点
  • info break //显示所有断点信息
  • delete 断点编号 //删除对应断点
  • r (run)//启动程序
  • q //退出调试
  • p buff //临时打印数组所有元素的值
  • p val //临时打印变量val的值
  • p &val //临时打印变量val 的地址
  • p a+b //临时打印表达式的值
  • p *parr@num //通过指向数组的指针打印数组的元素值
  • display buff //自动显示监视对象,操作格式和p一致
  • info display //显示所有自动显示监视对象的信息
  • undisplay 编号 //删除对应的自动显示监视对象
  • n (next) //单步执行 逐过程(vs里面F10)
  • s //进入到将被调用的函数中(逐语句 vs里面F11)
  • finish //跳出函数(跳出 vs里面shift+ F11)
  • c (continue) //继续执行,直到执行到下一个断点出
  • ptype val //显示变量的数据类型

猜你喜欢

转载自blog.csdn.net/weixin_56935264/article/details/124332870