冰冰学习笔记:gcc、gdb等工具的使用

发布于:2023-02-05 ⋅ 阅读:(1053) ⋅ 点赞:(0)

欢迎各位大佬光临本文章!!!

还请各位大佬提出宝贵的意见,如发现文章错误请联系冰冰,冰冰一定会虚心接受,及时改正。

本系列文章为冰冰学习编程的学习笔记,如果对您也有帮助,还请各位大佬、帅哥、美女点点支持,您的每一分关心都是我坚持的动力。

我的博客地址:bingbing~bang的博客_CSDN博客https://blog.csdn.net/bingbing_bang?type=blog

我的gitee:冰冰棒 (bingbingsupercool) - Gitee.comhttps://gitee.com/bingbingsurercool


系列文章推荐

冰冰学习笔记:《linux下权限的理解》

冰冰学习笔记:《vim工具的基本操作》


目录

系列文章推荐

前言

1.gcc与g++

1.1gcc与g++的概念

1.2代码编译的过程 

1.3链接函数库

1.4gcc的常用选项

2.Makefile/makefile

3.gdb

4.yum与git

4.1yum常用语句

4.2git三板斧


前言

        在前面的文章中,我们简单介绍了vim工具的使用,是我们能够在linux系统下简单的编辑代码,那么我们如何实现在Linux下对代码进行编译调试呢?显然vim并不具备这样的功能。与windows下的VS不同,VS是一个集成开发软件,它包含了编辑,编译,调试等工具,因此我们在windows下写完代码直接就可以对其进行编译和调试。Linux下每个软件都有不同的用处,因此vim工具只是一款代码编写的软件,gcc与g++才是编译的软件,其中gcc只能编译C语言,g++能编译C语言也能编译C++。而gdp是一款调试软件,它能够调试gcc生成的debug版本的代码。

1.gcc与g++

1.1gcc与g++的概念

        gcc与g++是linux下用于代码编译的软件,是一款编译器,他能将我们书写的程序通过预处理,编译,汇编,连接四个过程生成可执行程序,然后我们可以对其进行运行。

1.2代码编译的过程 

        在对代码编译时,gcc可以分阶段进行运行,搭配不同的命令生成不同信息的文件。

(1)预处理阶段

gcc -E test.c -o test.i

解释:将文件test.c只执行预编译阶段后停下来,并将生成的文件命名为test.i

        该阶段主要进行进行宏替换,条件编译,去注释,头文件的包含。

        我们发现在执行完预处理阶段后,原本20行左右的代码变成了800多行,原因就是我们将头文件中的内容全部放到了我们写的文件中;并且预编译之后的文件将宏全部替换,条件编译也进行处理,并且将注释全部去掉,只留下了最终代码该执行的部分。 

(2)编译阶段

gcc -S test.i -o test.s

解释:将文件test.i执行编译阶段后停下啦,并将生成的信息写入test.s中

        在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。

(3)汇编阶段

gcc -c test.s -o test.o

解释:将文件test.s只执行汇编阶段后停下来,生成文件test.o

        该阶段是将文件中的汇编语言变为了kechongdingwei目标二进制文件,并不能执行。

(4)链接阶段

gcc test.o -o mybin

解释:通过链接动静态库将文件变成可执行程序 

        该阶段啊的本质是引入我们在代码中使用的第三方库

1.3链接函数库

        这里有一个额外的概念:函数库

        我们在书写C语言时,仅仅包含了一些库函数的头文件,并没有包含该文件中库函数的实现文件,那么库函数是怎么进行工作的呢?答案是系统把这些函数的实现都被做成了名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。其中库提供了C语言的实现方法,头文件提供了C语言实现的方法列表。

        函数库一般分为静态库动态库。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是将地址填入,在程序执行时由运行时链接文件通过地址加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。

        gcc中默认生成的二进制文件是动态链接的,并且生成的是不可调试的release版本。

ldd  mybin        :查看可执行程序mybin的链接库

file  mybin        :查看可执行程序mybin的链接库类型,是静态还是动态链接

        当然我们可以使用static修饰将其变为静态链接。静态链接库生成的文件较大。

gcc test.c -o mytest -static

解释:将test.c文件生成静态链接的可执行文件mytest

1.4gcc的常用选项

        难道gcc只能一步一步的进行文件编译吗?当然不是,上面只是gcc中的一些常用选项,我们可以直接执行编译命令生成我们想要的执行文件。

gcc test.c -o mytest        :将文件test.c直接生成mytest的可执行文件

./mytest        :运行可执行文件mytest文件

        以上两个命令才是我们日常编译时最常用的两个命令。当然gcc还有其他的选项,其中 -o 后面接的是指定生成的可执行文件的名称,如果不指定,将生成名为a.out的可执行文件。

 其他选项

-g                 :生成调试信息,也就是生成debug版本的执行文件,可用gdb进行调试

-shared        :尽量使用动态库,生成文件较小,但是需要系统有动态库

-w                :不生产任何警告信息

-Wall            :生成所有警告信息

-O0              :

-O1              :

-O2              :

-O3              :编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级
                        别最高

2.Makefile/makefile

        如上面所讲,我们在将文件进行编译的时候并不能像VS那样直接Ctrl+F5运行,而是输入命令执行。那么问题来了,一个文件还好,如果我要是将多个文件协同编辑的工程进行运行呢?如果一个一个的输入,那岂不是相当麻烦。

为了解决这一情况,linux下还存在一个自动化构建工具,makefile。

        一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefifile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

        makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

        make是一个命令,makefile是一个文件。

我们在使用自动化工具makefile时需要完成下面几步

(1)创建makefile文件

        使用vim makefile命令创建一个makefile文件 

(2)编写makefile文件

        编写makefile文件需要两个要素,依赖关系依赖方法。

        举个例子,我们想把test.c文件生成一个可执行文件,test.c文件中使用了两个函数,game和show,这两个函数分别实现在了show.c的文件和game.c的文件中,并在show.h中进行了声明。那么我们的makefile文件就可如下编写。

  mybin:test.o game.o show.o
      gcc test.o game.o show.o -o mybin 
  test.o:test.c
      gcc -c test.c -o test.o
  game.o:game.c
      gcc -c game.c -o game.o
  show.o:show.c
       gcc -c show.c -o show.o
  .PHONY:clean
  clean:
      rm -f *.o mybin    

        具体什么意思呢?

        makefile文件将自上向下进行扫描,形成第一个遇到的命令后停止,在上述例子中,test.o game.o show.o等文件并不存在,于是makefile将该条指令入栈,然后接着向下扫描,将所需的文件test.o game.o show.o通过test.c game.c show.c进行构建后再将入栈的命令执行完毕。

        构建完毕后,我们只需要使用make命令就可生成对应的执行文件mybin

       makefile会根据文件的修改时间(Modify time)判断源文件是否修改,如果源文件test.c等文件没有更新,执行make将不会生成重复的执行程序 

        由于clean是被修饰的,是一条总被执行的命令。

         当然,当文件中的文件很多时我们就可以使用通配符。构建后的文件如下所示:

 $^        :依赖文件列表

$@       :目标文件

%.c       :当前目录下所有的.c文件

%.o       :对应的.c形成的.o

$<         :%.c所代表的源文件一个一个拿出来用gcc进行编译形成同名.o文件 gcc -c $<

(3)一次形成多个可执行文件

        如果我们想一次性形成两个以上的可执行文件呢?也很简单,我们需要再次使用.PHONY

3.gdb

        gdb就是Linux下代码的调试工具。gdb只能调试debug版本的代码,因此我们再用gcc生成可调试的执行程序时需要在后面添加-g选项,然后再用gdb进行调试。gdb会记录最近的一条命令,如果命令无变化,可直接回车。

使用:gdb+文件名,例如gdb mytest,对debug版本的文件mytest进行调试

退出:quit(q)、Ctrl+d

常用选项:

l                 :显示代码,后加行号可显示行号附近代码

r                 :开始调试,如果没有设置断点,就直接运行结束,类似于VS的F5选项

b+行号       :在给定的行号打断点

info b          :查看断点

d+断点编号:删除断点

n                :逐过程调试,VS中的F10

s                :逐语句调试,VS中的F11

p+变量名   :打印变量内容

bt               :进入调用堆栈,栈顶为当前函数

finish          :将当前函数跑完就停止

display       :常显示,类似于窗口

undisplay+编号   :取消常显示

until+行号:跳转到指定行号

c                :运行至下一个断点

disable/enable+断点编号:关闭/打开断点

condition bnum expresssion

                  :bnum:断点编号,expression断点条件表达式

condition bnum        :删除bunm处的条件

4.yum与git

4.1yum常用语句

(1)查找软件

sudo yum list | grep "name"

在yum中查询软件name的信息

(2)安装软件

sudo yum install -y name

将软件name安装

(3)卸载软件

sudo yum remove name

将软件name卸载

(4)更新软件

sudo yum update name

将软件name更新

4.2git三板斧

前提:在本地克隆仓库:git clone +仓库地址

添加代码:git add name   :将name文件条件到本地仓库

提交更改信息: git commit -m "xxxxx"

上传到仓库: git push

无法提交,出现冲突,无脑 git pull

git log 查看提交记录

git status 查看工作目录的暂存状态

本文含有隐藏内容,请 开通VIP 后查看