【Linux】Linux编译器—gcc/g++的使用

news2024/11/18 4:20:38

目录

  • 一.背景
  • 二.gcc如何生成
    • 1.预处理(进行宏替换)
    • 2.编译(生成汇编)
    • 3.汇编(生成机器可识别代码)
    • 4.链接(生成可执行文件或库文件)
  • 三.函数库
    • 1.函数库的分类
      • (1)动态库
      • (2)静态库
    • 2.区别
    • 3.拓展
  • 四.记忆
    • 1.选项
    • 2.后缀
  • 五.gcc选项

该篇博客需要使用vim编译器,要是对其不熟悉,可以查看该篇博客vim的使用

一.背景

一个源文件生成可执行文件需要经过程序的翻译环境(将程序的文本文件翻译为机器可以识别的二进制文件),而翻译环境可以分为以下四个步骤:

  1. 预处理(头文件替换、条件编译、宏替换、去注释等)
  2. 编译(生成汇编语言)
  3. 汇编(生成机器可识别二进制文件,不可被执行,bin.obj)
  4. 链接(将我们自己形成的.obj文件和库文件进行某种合并,生成可执行文件)

具体可以看这篇博客程序环境。

gcc/g++可以帮我们在LInux下生成C/C++的可执行文件,并通过选项分别执行到翻译环境的四个不同的步骤。
gcc编译C语言代码,g++编译C++代码,两者的使用方法相同,以下以gcc为例。

二.gcc如何生成

格式:gcc [选项] 要编译的文件 [选项] [目标文件]
我们先创建一个hello.c的测试文件,并使用vim编辑器编写代码

[YX@VM-16-5-centos lesson7]$ touch hello.c    //创建hello.c文件
[YX@VM-16-5-centos lesson7]$ vim hello.c      //使用vim编译器编译代码

在这里插入图片描述
我们可以直接使用gcc生成该测试文件的可执行文件
在这里插入图片描述
接着使用./a.out执行该可执行文件,就可以得到我们编写代码的结果
在这里插入图片描述
但当我们想要的到它在翻译环境下四个不同阶段生成的文件时我们该如何执行?

1.预处理(进行宏替换)

  • 预处理功能主要包括宏替换,文件包含,条件编译,去注释等。
  • 预处理指令是以#开头的代码行。
  • 实例:gcc -E hello.c(该指令为直接得到预处理后的内容,将其打印在显示器上,不方便查看,不做演示)
  • 实例:gcc -E hello.c -o hello.i(将预处理后的内容,放入.i文件中)
  • 选项"-E",该选项的作用是让 gcc 在预处理结束后停止编译过程。
  • 选项"-o"是指将前面执行的结果放入后面的文件,”.i“文件为已经过预处理的C原始程序。
  • 注意:文件名可以随便起,这个不影响,但最好遵循规则,将其写为.i文件,下面的文件同理

按照上面的指令,我们执行并生成预处理后的文件
在这里插入图片描述
注意:.i文件不是可执行文件,我们不能使用./hello.i执行该文件,但可以通过vim编辑器查看

最终可以看到该文件的内容

在这里插入图片描述
我们已经知道了如何查看预处理生成的文件,但上面的案例并没有完全展示预处理作用,这里我们先将测试文件修改后,在生成.i文件查看其结果,就可以明显的感受到预处理的作用,如下:

在这里插入图片描述

  • 对于.i文件,我们可以看到,它有860行,而.c文件,只有24行,.i文件中多余的代码就是被包含头文件的代码

2.编译(生成汇编)

  • 在这个阶段中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码实际要的工作,在检查无误后,gcc把代码翻译成汇编语言。
  • 用户可以使用”-S“选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
  • 实例:gcc -S hello.c(直接将.c文件生成汇编后的内容,显示在显示器上,重新经历预处理,不建议这样使用)
  • 实例:gcc -S hello.i -o hello.s(该指令是将.i文件生成.s文件)
  • 实例:gcc -S hello.c -o hello.s(也可以直接将.c文件生成.s文件,重新经历预处理)
  • ”.s“文件为已经过编译的C原始程序

我们这里直接将.i文件生成.s文件

在这里插入图片描述

打开后可以清晰的看到它生成的汇编代码

在这里插入图片描述

3.汇编(生成机器可识别代码)

  • 汇编阶段是把编译阶段生成的”.s“文件转成目标文件。
  • 在此可以使用选项”-c“就可看到汇编代码已转化为”.o“的二进制目标代码了
  • 实例:gcc -c hello.c(同上,直接生成汇编后的数据,显示在显示器)
  • 实例:gcc -c hello.c -o hello.o(同上,从.c文件开始重新经过预处理、编译直到汇编)
  • 实例:gcc -c hello.s -o hello.o(由编译后的文件,生成汇编后的文件)

我们这里将.s文件生成汇编后的.o文件

在这里插入图片描述
打开后看到的是机器可以别的代码,我们看不懂的

在这里插入图片描述

4.链接(生成可执行文件或库文件)

  • 在成功编译之后,就进入了链接阶段。
  • 实例:gcc hello.c -o hello(从.c文件起经过翻译环境,直到链接)
  • 实例:gcc hello.o -o hello(由汇编生成的.o文件生成链接后的文件)
  • 链接后的文件是可执行文件,可以直接执行./hello,得到程序结果

我们使用.o文件生成链接后的文件

在这里插入图片描述

查看可执行文件中的内容

在这里插入图片描述
为机器识别的代码

问题

既然汇编和链接后生成的文件内容都是机器识别的代码,那么汇编后生成的文件是否可以执行?

我们先对其进行执行操作:
在这里插入图片描述
发现该文件没有可执行权限,给它加上,在执行:

在这里插入图片描述

结论: 即便一个文件具有可执行程序,它不是可执行文件就没有办法执行,同时证明.o文件无法执行

使用chmod -x hello.o取消它的可执行权限。

三.函数库

在链接阶段我们链接了库文件,那什么是库文件呢?这就要细细说来。

我们写的C/C++程序,在编译器上之所以可以运行,是因为我们的编译器将程序经过翻译环境变成可执行程序,最终输出结果。

我们写的程序中除了我们自己编写的代码,还要调用头文件中提供的函数,如我们经常使用的printf、scanf函数,就是在头文件stdio.h中声明的,这些头文件在Linux下存放在/usr/include目录及子目录下:

在这里插入图片描述
既然这些函数的声明是放在头文件中,那他们在哪里定义?

我们知道,翻译环境分为四个步骤,最后一个步骤链接的作用就是使汇编后生成的文件和库文件进行结合,而头文件声明的函数就存放在库文件中。

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

在这里插入图片描述
在比如我们看看上面写的测试文件hello.c的可执行文件a.out,看一下它链接的库文件,这里我们需要使用ldd指令查看。

在这里插入图片描述
实际上,在我们安装vs2019、vs2022这些编译器的时候,最重要的一个工作就是帮我们下载并安装语言的头文件和库文件。

所以我们可以得出结论,函数库本身就是文件,用来定义和存放函数。

1.函数库的分类

函数库分为两种,静态库和动态库,它们的区别如下:

(1)动态库

命名:libXXXXX.so

其中XXXXX可以使任意名字,如上面所使用的库文件libc.so.6,就是一个动态库。去掉前缀lib和后缀.so剩余c表面它是由c语言编写的库,而剩余的.6表示版本号。

动态库的作用:动态链接库文件,在链接阶段,拷贝动态库中我们需要的代码的地址到我们自己的可执行程序中的相关位置,在运行程序时通过地址调用动态库中函数,保证代码的正常运行。

我们编写的代码在链接时,如果没有指定,默认链接的都是动态库。

(2)静态库

命名:libXXXXX.a

如上,lib为前缀,.a为后缀,中间可以是任意名

静态库的作用:静态链接库文件,在编译链接时,把静态库中我们所需要的代码拷贝到可执行文件中,因此生成的文件比较大,但在运行时也就不在需要库文件了。

比如:我们写程序时,printf函数可能要出现不止一次,那么每个printf函数都会被替换为静态库中对应的代码,这样就使文件变大,多次替换的printf函数浪费了空间。

静态链接需要我们自己链接,链接方法如下:

  1. 我们可以通过file指令查看可执行文件链接的是动态库或静态库,或是使用ldd指令查看链接库的命名,根据命名判断
    在这里插入图片描述

  2. 通过指令gcc hello.c -o hello-static -static使生成的hello-static可执行文件静态链接在这里插入图片描述

    • 静态链接和动态链接后的文件相差10倍左右十分正常
  3. 我使用的是云服务器,默认只有动态库,我们需要自己手动安装静态库才可以使用,方法如下:

     sudo yum install -y glibc-static   //在普通用户下安装c语言静态库
    yum install -y glibc-static        //在root用户下安装c语言静态库
    
    sudo yum install -y glibc-static libstdc++-static    //在普通用户下安装c++静态库
    yum install -y glibc-static libstdc++-static    //在root用户下安装c++静态库
    

2.区别

动态库通过程序中动态库代码对应的地址调用动态库中对应的函数完成代码的执行,如果动态库突然消失,可执行程序将无法执行。

静态库通过函数名生成的地址,在库中找到对应的函数,将其拷贝到可执行文件中,在文件中调用,这使得可执行文件即使没有静态库也可以执行代码,但随着拷贝,可执行文件也会变大。

3.拓展

我们在Linux中使用的指令,都是使用c语言编写的,我们可以查看不同指令的链接库,看是否使用c语言编写,如下:

查看ls指令的库文件:

在这里插入图片描述
查看which指令的库文件:

在这里插入图片描述

所以指令就是程序。

  • 关于函数库的知识该篇博客就只有这些了,更多的内容会在基础I/O中讲解。

四.记忆

1.选项

我们在进行翻译环境的四个步骤中,都使用了-o选项,而链接只使用了-o,剩余三个步骤我们可以通过键盘左上角的Esc按钮来记忆。

预处理——-E,编译——-S,汇编——c

我们要是忘记了只需要看键盘左上角的Esc按钮,但注意,ES是大写的。

2.后缀

链接生成的文件没有后缀不需要记忆,其余三个按顺序刚好对应镜像文件的后缀.iso

五.gcc选项

gcc的选项中最常用的就是上面翻译环境四个步骤的各个选项,将其汇总并和其他的一些选项一起放在这里,方便大家查看。

  • -E 只激活预处理,这个不生产文件,需要把它重定向到一个输出文件里面。
  • -S 编译到汇编语言不进行汇编和链接。
  • -c 编译到目标代码。
  • -o 文件输出到文件。
  • -static 此选项对生成的文件采用静态链接。
  • -g 生成调试信息。GNU 调试器可利用该消息。
  • -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库。
  • -O 0
  • -O 1
  • -O 2
  • -O 3 编译器的优化选项的4各级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高。
  • -w 不生成如何警告信息。
  • -Wall 生成所有警告信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/149512.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

excel排序技巧:这些不同方式的排序方法你都会了么

都说这Excel里暗藏玄机,求最大值的MAX函数可以用于查找,用于查找的LOOKUP函数可以对数据进行四舍五入…就连看似人人都会的Excel自动排序,也藏着许多我们不知道的“小秘密”。今天我们就来探索一下这些藏在自动排序中的“小秘密”。一、扩展选…

Numpy数据分析csv文件的应用

1.数据存取与函数 1.1.数据的CSV文件存取 CSV(Comma-Separated Value,逗号分隔值) CSV是一种常见的文件格式,用来存储批量数据 np.savetxt(frame, array, fmt‘%.18e’, delimiterNone) 复制代码 frame : 文件、字符串或产生器,可以是.gz或.bz2的压缩…

SpringCloud从入门到精通(七)

Gateway Gateway-概述 网关旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。 在微服务架构中,不同的微服务可以有不同的网络地址,各个微服务之间通过互相调用完成用户请求,客户端可能通过调用N个微服务的接口完成一个用户请求…

【C++】优先级队列、仿函数和反向迭代器

​🌠 作者:阿亮joy. 🎆专栏:《吃透西嘎嘎》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉priority…

工具及方法 - 字幕下载网站

1,射手网(伪) 首页 - 射手网(伪) - assrt.net - 字幕下载,字幕组,中文字幕,美剧字幕,英剧字幕,双语字幕,新番字幕 2,国外网站。 Subscene - Passionate abo…

sentinel-热点参数限流

Pages 60 Sentinel 官方网站 OpenSergo 微服务治理 文档 Read Me新手指南Sentinel 介绍FAQRoadmap如何使用工作原理流量控制集群流控(分布式流控)网关流控熔断降级热点参数限流系统自适应限流黑白名单控制实时监控数据动态规则控制台生产环境使用 Sent…

【自学Python】Python IDLE使用

Python IDLE使用 Python IDLE使用教程 在 Windows 上安装好 Python 之后,Python 都会提供一个 Python 命令行工具,就叫 IDLE。IDLE 是一个 Python Shell,Python Shell 可以用于与 Python 进行交互。 Python IDLE使用 打开Python IDLE 首…

分布式基础篇4 —— 基础篇完结(谷粒商城)

分类维护一、三级分类后端实现准备工作跨域问题关闭 ESLint 检查前端实现二、分类删除前端完善分类列表后端实现——删除配置发送请求代码片段前端实现——删除三、分类增加前端实现四、分类修改五、拖拽菜单拖拽效果实现拖拽数据收集拖拽功能完成拖拽功能完善六、批量删除品牌…

粒子系统-常用子模块

目录 Emission (发射) Shape (形状) Cone (锥形) Velocity over Lifetime (运动) Limit Velocity over Lifetime (速度限制) Force over lifetime (受力) Color over Lifetim…

【C语言航路】第十站:指针进阶(二)

目录 六、函数指针数组 七、指向函数指针数组的指针 八、回调函数 1.回调函数的概念 2.回调函数实现计算器 3.回调函数实现冒泡排序 总结 六、函数指针数组 我们已经知道了函数指针,它的类型是int(*)(int,int)。那么我们能否进行推广呢?将其推广成…

基于AD Event日志实时检测DSRM后门

01、简介每个域控制器都有一个目录还原模式(DSRM)帐户,它的密码是在安装域控时设置的,实际上它对应的就是sam文件里的本地管理员“administrator”,基本很少会被重置,因此有着极强的隐蔽性。攻击者通过获取…

面试篇之NoSQL

面试篇之NoSQL一、redis持久化1.1、字节1.2、微软1.3、题解1.3.1、RDB快照1.3.2、AOF日志1.3.3、最佳实践二、redis删除策略2.1、字节2.2、阿里云2.3、题解2.3.1、过期删除2.3.2、内存淘汰2.3.3、LRU2.3.4、LFU三、redis高可用3.1、字节3.2、美团3.3、微软3.4、题解3.4.1、主从…

前端性能优化(六):传输加载优化

目录 一:启用压缩 Gzip 二:启用 Keep Alive 三:HTTP 资源缓存 3.1.HTTP 缓存方案 3.2.各大网站缓存策略参考 四:Service Worker 五:HTTP2 的性能提升 5.1.HTTP2 优势 5.2.开启 HTTP2 5.3.Server Push&#x…

【Spring(五)】带你深入了解bean的生命周期

1.5 bean的生命周期 bean的实例化已经说完了,我们最后再来讲讲bean的生命周期。 我们主要来围绕着bean生命周期控制来学习,那么什么是生命周期呢?其实就是一个东西从创建到消亡的完整过程,比如人从出生到死亡的整个过程&#xff…

【MySQL进阶】深入理解redoLog日志

【MySQL进阶】深入理解redoLog日志 文章目录【MySQL进阶】深入理解redoLog日志一:redo日志概述二:redo日志格式三:Mini-Transaction1:以组的形式写入redo日志2:Mini-Transaction的概念四:redo日志的写入过程…

富淼转债,优彩转债上市价格预测

富淼转债基本信息转债名称:富淼转债,评级:A,发行规模:4.5亿元。正股名称:富淼科技,今日收盘价:18.25,转股价格:20.26。当前转股价值 转债面值 / 转股价格 * …

(3分钟速览)SLAM中的三大金刚-H E F Matrix

编辑切换为居中添加图片注释,不超过 140 字(可选)三个矩阵的自由度:单应矩阵H 自由度8基础矩阵F 自由度7本质矩阵E 自由度5或者8,这个是根据使用旋转矩阵还是旋转向量编辑切换为居中添加图片注释,不超过 14…

每日一题之Vue的异步更新实现原理是怎样的?

最近面试总是会被问到这么一个问题:在使用vue的时候,将for循环中声明的变量i从1增加到100,然后将i展示到页面上,页面上的i是从1跳到100,还是会怎样?答案当然是只会显示100,并不会有跳转的过程。…

计算机基础——计算机应用领域以及未来发展趋势

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 目录 前言 一.计算机应用领域 1.信息管理 2.过程控制 3.计算机辅助技术 1&#xff09…

一天天过去,每天该如何过?

刚跨了年,又快到春节,日子就这样一天天过去。如何过好这一生是个大命题,不如简化点考虑下如何过好一天?人的时间大体分为两类:主动的,可以自由支配;被动的,等着被安排。过去我在互联…