【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用

这篇具有很好参考价值的文章主要介绍了【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Linux编译器-gcc/g++

1.1 gcc/g++ 使用方法

格式: gcc [选项] 要编译的文件 [选项] [目标文件]gcc / g++安装: sudo yum install -y gcc-c++。安装后的编译器默认的版本是较低的,我们可以使用选项-std=c99(即使用c99标准),-std=c++11(即使用c++11的标准)来进行版本提升。使用-o选项,可以将编译生成的可执行重命名。最后使用./可执行,来运行程序。如下:

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器

Linux中一个文件要真正的执行:1. 有x权限;2. 就是一个可执行文件。 很明显文件test.exe满足上述条件!

1.2 程序的翻译过程

程序的翻译过程,可以说是生成二进制方案的过程,具体可以细分为以下几步:

  • 预处理:

预处理功能主要包括宏定义,文件包含,条件编译,去注释等。 预处理指令是以#号开头的代码行。

实例: gcc -E test.c -o test.i。选项"-E",该选项的作用是让gcc从现在开始进行程序的翻译,预处理完成就停下! 选项"-o"是指目标文件,".i"文件为已经过预处理的C原始程序。

  • 编译(生成汇编):

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

实例: gcc -S test.i -o test.s。用户可以使用"-S"选项来进行查看,该选项的作用是让gcc从现在开始进行程序的翻译,编译完成就停下! 可以从test.c开始编译,也可以从test.i开始。

  • 汇编(生成机器可识别代码):

汇编阶段是把编译阶段生成的".s"文件转成目标文件(即将汇编语言编译成为,二进制目标文件

实例: gcc -c test.s -o test.o。读者在此可使用选项"-c",该选项的作用是让gcc从现在开始进行程序的翻译,汇编完成就停下!。就可看到汇编代码已转化为".o"的二进制目标代码了。

  • 链接(生成可执行文件或库文件):

实例: gcc hello.o –o hello。在成功编译之后,就进入了链接阶段,最后形成可执行程序


那么为什么会有这些过程呢?

这就要说到编程语言的历史了。最初的计算机只能处理二进制,二进制是处理器的“母语”。这叫“机器语言”或者“机器码”。在计算机早期阶段,必须用机器码写程序(即二进制编程)(前段时间很火的《三体1》中,早期叶文洁当时就是使用的二进制编程,还用到了打孔带,上面记录的就是二进制信息)。

在1940-1950年代,程序员开发一种新语言(汇编语言),它为每个操作码分配一个简单名字,叫“助记符”,助记符后面紧跟数据,形成完整指令。当然,计算机并不认识助记符,它只认得二进制码,然后就有了汇编的编译器,它可以读懂文字指令,自动转换成二进制指令,这种程序叫“汇编器”

汇编语言直接对应机器码,虽然已经很方便了。但是,汇编器仍然强迫程序员思考,用什么寄存器和内存地址,如果我们突然要用额外一个数,可能要改很多代码。这时候就出现了一些高级语言和与之对应的编译器(如:C,C++,Java…)。

因为计算机只认识二进制。以c语言为例,所以我们要先将c语言代码转化为汇编代码,然后再转为二进制目标文件。 那为什么不直接将c语言转为二进制目标文件呢?因为前人已经写好了汇编的编译器,我们只需站在巨人的肩膀上,再将高级语言转为较简单的汇编代码即可。

那么如何形成第一个汇编写的汇编编译器呢?

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器
先用二进制写一个汇编编译器(此时汇编代码便可通过此编译器形成软件)。汇编编译器本质上就是软件,那么便可先用汇编语言写一个新的编译器,再将这个新的编译器放在二进制写的汇编编译器上执行,最后形成新的汇编编译器(软件)。日后只需维护汇编代码即可! 这个过程也可叫做编译器的自举(bootstrap),c语言的第一个编译器也是如此形成的!

1.3 链接 – 动静态链接特点及区别

我们的C程序中,并没有定义"printf"的函数实现,且在预编译中包含的"stdio.h"中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实"printf"函数的呢?

最后的答案是:系统把这些函数实现都被做到名为 libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径 /usr/lib下进行查找,也就是链接到 libc.so.6库函数中去,这样就能实现函数"printf"了,而这也就是链接的作用。

函数库一般分为静态库和动态库两种。

  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为".a"
  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为".so",如前面所述的 libc.so.6就是动态库。gcc在编译时默认使用动态库。完成了链接之后,gcc就可以生成可执行文件,如下所示。 gcc test.o –o test
  • gcc默认生成的二进制程序,是动态链接的,这点可以通过 file命令验证。

验证:

  1. -static指令,作用是链接时使用静态链接:

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器
2. ldd 可执行指令,作用是查看链接的库:

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器

  1. file filename指令,查看链接属性:

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器


动态库 && 动态链接的优缺点:1. 不能丢失。共享动态库,但是一旦动态库缺失,所有的动态链接这个库的程序,都无法执行! 2. 节省资源。

静态库 && 静态链接的优缺点:1. 一旦形成,与库无关。在编译的时候,把库中的方法,拷贝到我自己的可执行程序中,此时程序将不再关心任何的库; 2. 浪费资源,占用空间大。

二、Linux调试器-gdb

2.1 背景

程序的发布方式有两种,debug模式和release模式。Linux gcc/g++出来的二进制程序,默认是release模式。 要使用gdb调试,必须在源代码生成二进制程序的时候,加上 -g选项,此时编译器形成可执行程序的时候,会给可执行程序添加调试信息。 我们也可以发现可调式的可执行程序比普通的程序占用内存大。

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器

调试信息大致如下:

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器

2.2 使用方法

gdb binFile退出: ctrl + dquit调试命令:

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

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

3.1 背景

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

3.2 原理

make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么,

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

makefile / make会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有的相关的依赖方法。

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器


  • makefile文件中,保存了编译器和链接器的参数选项,并且描述了所有源文件之间的关系。make程序会读取makefile文件中的数据,然后根据规则调用编译器,汇编器,链接器产生最后的输出。
  • Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。1. 显式规则说明了,如何生成一个或多个目标文件。2. make有自动推导的功能,所以 隐晦规则可以让我们比较粗糙地简略地书写makefile ,比如源文件与目标文件之间的时间关系判断之类。3. 在makefile中可以定义变量makefile被执行时,其中的变量都会被扩展到相应的引用位置上。4. 通常使用 $(var) 表示引用变量文件指示。包含在一个makefile中引用另一个makefile,类似C语言中的include。5. 注释makefile中可以 使用 # 在行首表示行注释
  • 默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件

3.3 项目清理

  • 工程是需要被清理的
  • clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。 即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
  • 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用.PHONY 修饰,伪目标的特性是,总是被执行的。 makefile中的伪对象表示对象名称并不代表真正的文件名,与实际存在的同名文件没有相互关系,因此伪对象不管同名目标文件是否存在都会执行对应的生成指令。伪对象的作用有两个,1. 使目标对象无论如何都要重新生成。2. 并不生成目标文件,而是为了执行一些指令.

【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用,Linux学习,linux,自动化,服务器,编辑器
于是我们便可使用vim编写如上内容。里面$相当于取值操作,@最终会被替换目标文件,而^会被替换为依赖方法。文章来源地址https://www.toymoban.com/news/detail-838179.html

到了这里,关于【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【UNIX 环境编程】GCC 编译器 | Makefile 基础入门 | GDB 调试教学

    💭 写在前面: 本文将介绍如何使用 GCC 编译器编译,并详细介绍了 Makefile 的基本构造、创建Makefile 文件以及 Makefile 变量,以提高编译效率。此外,本文还将探讨GDB调试器的使用,包括调试前的准备、readelf 读取 ELF 文件信息、显示代码、断点、调试、监视、跳转等内容。 

    2024年02月03日
    浏览(71)
  • 为 Microsoft C++ 配置 VS Code在本教程中,您将配置 Visual Studio Code 以在 Windows 上使用 Microsoft Visual C++ 编译器和调试器

    在本教程中,您将配置 Visual Studio Code 以在 Windows 上使用 Microsoft Visual C++ 编译器和调试器。 配置完 VS Code 后,你将在 VS Code 中编译和调试一个简单的 Hello World 程序。本教程不教您有关 Microsoft C++ 工具集或 C++ 语言的详细信息。对于这些主题,网上有很多很好的资源。 如果您

    2024年02月10日
    浏览(75)
  • Linux开发工具大全 - 软件包管理器yum | vim编辑器 | gcc/g++编译器 | 自动化构建工具Make/Makefile | gdb调试工具

    目录 Ⅰ.  Linux 软件包管理器 yum 一、yum 背景知识 二、yum 的基本使用 1、查看软件包 2、软件包名称构成 3、安装软件 4、卸载软件 Ⅱ.vim编辑器  一、认识vim 1、vim概念  2、模式及其切换  二、vim使用 1、vim的指令(重要)  命令模式 插入模式 底行模式 2、vim配置 Ⅲ.gcc/g++编

    2024年02月05日
    浏览(55)
  • [linux初阶][vim-gcc-gdb] TwoCharter: gcc编译器

    目录 一.Linux中gcc编译器的下载与安装 二.使用gcc编译器来翻译 C语言程序  ①.编写C语言代码 ②翻译C语言代码 a.预处理 b.编译  c.汇编  d.链接 ③.执行Main 二进制可执行程序(.exe文件)  三.总结  使用yum命令(相当于手机上的应用市场)来进行安装.  下载完毕之后,使用 which gc

    2024年04月10日
    浏览(59)
  • Linux——gdb调试器

    目录    前言: 二.gdb定义及指令: 如何查看该exe文件是否为Debug版本?两种方法: 三.gdb调试:         调试指令1:l指令(小写L) run指令:运行程序,相当于VS中的直接运行不调试——可简化输入r  break指令:设置断点——指令可简化输入为b ​编辑  info b指令:查看整个代码

    2024年02月07日
    浏览(37)
  • Linux--调试器:gdb

    gcc与g++默认动态链接形成的可执行程序(比如a.out)是 release 版本,不可调试!!! 如何搞成debug可调试版本? 查看可执行程序存储了哪些内存空间:   调试语法:

    2024年02月13日
    浏览(51)
  • Linux调试器gdb

    本文已收录至《 Linux知识与编程 》专栏! 作者: ARMCSKGT 演示环境: CentOS 7     ​ 目录 前言 正文 下载gdb 生成可调式文件 进入gdb gdb常用指令 查看代码 l  运行程序 r  断点设置 b  显示信息 info  查看断点 info b  删除断点 d  禁用断点 disable breakpoints  启用断点 enable brea

    2024年02月14日
    浏览(53)
  • Linux - 还不懂 gdb 调试器?(调试软件)

    当前,我们可以使用 make/makefile 来程序化执行代码文件;可以使用 gcc/g++ 等编译器来编译代码;可以使用 vim 编辑器来编写代码;其实在 Linux 当中还有一个工具,可以实现调试工作,这个工具就是 -- gdb。 在了解调试器之前,你应该对代码的发布版本做一些了解: 我们在 VS

    2024年02月07日
    浏览(54)
  • Linux调试器之gdb

    我们前面介绍了几个基本的环境开发工具。例如通过yum我们可以安装和卸载软件、通过vim我们可以写代码、通过gcc和g++我们可以编译代码成可执行程序。但是如何在Linux下调试代码呢?我们并未介绍,本期我们将来介绍最后一个工具 --- 调试器gdb。 程序的发布方式 gdb基本的调

    2024年04月16日
    浏览(67)
  • [Linux] Linux代码调试器 -- gdb

    1、程序的发布方式有两种,debug模式和release模式 2、Linux gcc/g++出来的二进制程序,默认是release模式 3、要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项 我们先来写一段C语言代码: 这里我们正常再编写一个Makefile文件,用于自动化构建,我们要还是正常的编

    2024年02月05日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包