【Linux开发工具】gcc/g++的使用


📙 作者简介 :RO-BERRY
📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持


在这里插入图片描述


目录

  • 1.前言
  • 2.gcc/g++使用方法:以gcc为例
  • 3.程序翻译的四个阶段
    • 3.1 预处理(进行宏替换)
      • 创建预处理文件
      • 查看预处理文件
    • 3.2 编译(生成汇编)
      • 创建编译文件:
      • 查看编译文件:
    • 3.3 汇编(生成机器可识别代码)
      • 创建汇编文件
      • 查看汇编文件
    • 3.4 链接(生成可执行文件或库文件)
  • 4.函数库
    • 4.1 函数库的分类
    • 4.2 动静态库的区别与优缺点
    • 4.3 动静态库链接方式


1.前言

Linux下皆文件,在Linux下文件不分文件的后缀,文件的类型是看文件前面的字符
今天要学习的gcc和g++就是Linux下的程序
它们是要看文件后缀的!

  • gcc: C语言编译器,只能编译C语言
  • g++: C++编译器,C/C++都可以编译

2.gcc/g++使用方法:以gcc为例

编译文件:

  1. 编译文件并形成a.out的执行文件
  • gcc test.c
  1. 编译文件并形成test的执行文件,这里的test可以自取名字
  • * gcc test.c -o test

执行可执行程序
当我们编译好程序后,会在当前目录生成一个
可执行程序
在这里插入图片描述

  1. 执行形成的a.out的执行文件
  • ./a.out
  1. 执行形成的test的执行文件
  • ./test

注:.代表要在当前目录下找可执行文件.必须加上

gcc/g++选项

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

3.程序翻译的四个阶段

3.1 预处理(进行宏替换)

预处理功能主要包括

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

创建预处理文件

我们使用指令看一看

gcc –E test.c –o test.i

选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。
在这里插入图片描述

查看预处理文件

vim test.i

在这里插入图片描述

可以看到上面全部都是宏定义,文件包含,条件编译,去注释等操作,一共有八百多行,最后才是我们写的文件操作

3.2 编译(生成汇编)

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

创建编译文件:

gcc –S hello.i –o hello.s

在这里插入图片描述

查看编译文件:

vim test.s

在这里插入图片描述

这里的汇编代码没学过真不好懂

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

汇编阶段是把编译阶段生成的“.s”文件转成目标文件
在此使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了

创建汇编文件

gcc –c hello.s –o hello.o

在这里插入图片描述

查看汇编文件

vim test.o

在这里插入图片描述

此时使用vim打开文件是乱码
可以使用指令od查看二进制文件:

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

在成功编译之后,就进入了链接阶段。
链接阶段是将编译成功的文件变成可执行文件

gcc -o test test.o
这里我们将test.o文件进行编译并生成test可执行文件

在这里插入图片描述

链接阶段比较复杂,它大致的流程是这样的:

.o文件 + 系统库 = 可执行程序

在本篇文章的后半段讲完动静态库后再解释!


4.函数库

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

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

这里我们引入一个新指令:

ldd 可执行程序名
查看一个可执行程序依赖的第三方库

在这里插入图片描述
可以发现,在路径lib64里有一个文件叫libc.so.6
这个就是刚刚的C语言程序所要依赖的库
在这里插入图片描述
可见,libc.so.6实际上就是C的标准库


其中Linux环境下,动态库的后缀是.so,静态库的后缀是.a。在Windows环境下,动态库的后缀是.dll,静态库的后缀是.lib。所有的库文件,都遵守相同的命名规则,即:libname.后缀.xxx。
小Tips:gcc编译器会默认找到C的标准库,它会把我们写的源代码经过编译得到的目标文件与库文件进行链接。这也是为什么gcc不能去编译C++的源文件,因为gcc默认找的是C的标准库,它找不到C++的库。

现在我们就可以理解链接过程了
链接过程就是将.o文件和动/静态库结合的过程

4.1 函数库的分类

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

  • 静态库(static library, Statically-linked library, LIB)或称静态链接库,是一个外部函数与变量的集合体。静态库的文件内容,通常包含一堆程序员自定的变量与函数,在编译期间由编译器与连接器将它集成至应用程序内,并制作成目标文件以及可以独立运作的可执行文件。而这个可执行文件与编译可执行文件的程序,都是一种程序的静态创建(static build)。其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令全部被直接包含在最终生成的可执行文件中。静态库的后缀是.a

  • 动态库(Dynamic library, Dynamic-link library, DLL)或称动态链接库,是微软公司在微软视窗操作系统中实现共享函数库概念的一种实现方式。动态链接库可被多个程序同时使用。所谓动态链接,就是把一些经常会共用的代码(静态链接的OBJ程序库)制作成DLL档,当程序有需求时函数才进行链接。透过动态链接方式,存储器浪费的情形将可大幅降低。静态链接库则是直接链接到可执行文件。动态库的后缀是.so

gcc hello.o –o hello
gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。

4.2 动静态库的区别与优缺点

  • 动态库是共享库,通过函数地址来关联程序
  • 静态库是私有库,可以独立运行

动态库: 是C/C++或其他第三方提供的所有方法的集合,被所有程序以动态链接的方式关联起来
静态库: 是C/C++或其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码拷贝至自己的可执行程序当中!

优点缺点
静态库有效的节省资源(磁盘空间、内存空间、网络空间等)一旦缺失,所有程序都无法运行
静态库不依赖库,编译成功的可执行程序,可以独立执行,不需要再向外部要求读取库函数中的内容体积大,比较消耗资源

4.3 动静态库链接方式

链接分为两类:动态链接静态链接

  • 静态链接:由链接器在链接时将库的内容加入到可执行程序中。在编译器使用静态库进行静态链接的时候,会将自己的方法拷贝到目标程序中,该程序以后不再依赖静态库。
  • 动态链接:连接器在链接时仅仅建立与所需库函数的之间的链接关系,在程序运行时才将所需资源调入可执行程序。动态库是被所有程序所共享的,一般也被叫做共享库。这意味着,动态库只需要一个就够了,它可以满足所有程序的需求。

Linux中,编译形成可执行程序,优先采用动态链接。
如果想使用静态库编译程序

使用指令: gcc test.c -static

总的来说,静态库可以产出独立程序,动态库实现了模块化和代码共享,以空间换时间。
链接器会根据是静态链接还是动态链接,调用不同的处理逻辑,最终产出可执行程序。
所以同样的代码,静态链接和动态链接链接后的结果并不相同。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA新建文件夹后右击不能创建class类排错方法

目录 1 查看自身文件名是否为关键词 2 查看是否被“蓝色文件夹”给包含了 3 检查设置那边的class模板 4 报错解决 1 查看自身文件名是否为关键词 如下使用了 Java中的关键词"class"所以才无法创建包 ---------------------------------------------------------…

Vue3.4+element-plus2.5 + Vite 搭建教程整理

一、 Vue3Vite 项目搭建 说明: Vue3 最新版本已经基于Vite构建,关于Vite简介:Vite 下一代的前端工具链,前端开发与构建工具-CSDN博客 1.安装 并 创建Vue3 应用 npm create vuelatest 创建过程可以一路 NO 目前推荐使用 Vue R…

Elasticsearch-内存结构

ElasticSearch的内存从大的结构可以分堆内存(On Heap)和堆外内存(Off Heap)。Off Heap部分由Lucene进行管理。On Heap部分存在可GC部分和不可GC部分,可GC部分通过GC回收垃圾对象,从而释放内存。不可GC部分不…

LabVIEW高精度微小电容测量

LabVIEW高精度微小电容测量 在电子工程和科研领域,精确测量微小电容值是一项有一定要求的任务,尤其在涉及到高精度和低成本时。设计了一种基于LabVIEW高精度微小电容测量系统,旨在提供一个既经济又高效的解决方案。 该系统的核心在于使用FD…

【代码随想录24】93.复原 IP 地址 78.子集 90.子集II

目录 93.复原IP地址题目描述参考代码 78.子集题目描述参考代码 90.子集II题目描述参考代码 93.复原IP地址 题目描述 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 . 分隔。 例如…

爬虫工作量由小到大的思维转变---<第四十五章 Scrapyd 关于gerapy遇到问题>

前言: 本章主要是解决一些gerapy遇到的问题,会持续更新这篇! 正文: 问题1: 1400 - build.py - gerapy.server.core.build - 78 - build - error occurred (1, [E:\\项目文件名\\venv\\Scripts\\python.exe, setup.py, clean, -a, bdist_uberegg, -d, C:\\Users\\Administrat…

vue3:24—组件通信方式

目录 1、props 2、自定义事件 (emit) 3、mitt(任意组件的通讯) 4、v-model【封装ui组件库用的多,平时用的少。和vue2有点不同】 5、$attrs 6、$refs和$parent 7、provide和inject 8、pinia(即vue2中…

OpenGL 入门(九)—Material(材质)和 光照贴图

文章目录 材质设置材质光的属性脚本实现 光照贴图漫反射贴图高光反射贴图 材质 材质本质是一个数据集,主要功能就是给渲染器提供数据和光照算法。 如果我们想要在OpenGL中模拟多种类型的物体,我们必须针对每种表面定义不同的材质(Material)属性。 我们…

04、全文检索 -- Solr -- 管理 Solr 的 core(使用命令和图形界面创建、删除 core,以及对core 目录下的各文件进行详细介绍)

目录 管理 Solr 的 core创建 Core方式1:solr 命令创建演示:使用 solr 命令创建 Core:演示:命令删除 Core(彻底删除) 方式2:图形界面创建Web控制台创建CoreWeb控制台删除 Core(未彻底…

代驾应用系统(ssm)

登录首页 管理员界面 代驾司机界面 普通用户界面 前台页面 1、系统说明 (1) 框架:spring、springmvc、mybatis、mysql、jsp (2) 系统分为前台系统、后端管理系统 2、欢迎留言联系交流学习讨论:qq 97820625…

高灵敏比色法IgG2a (mouse) ELISA kit

用于检测IgG2a(小鼠)的高灵敏度ELISA试剂盒,仅需90分钟即可得到实验结果 免疫球蛋白G(IgG)是一种免疫球蛋白单体,由两条(γ)重链和两条轻链组成。每个IgG分子包含两个抗原结合域和一…

前端基础复习(后端人员看前端知识)

企业级前端项目开发中,需要将前端开发所需要的工具、技术、流程、经验进行规范化和标准化,而不是零散的html、js、css文件堆叠在一起。 首先我们需配置前端的开发基础环境NodeJS,相当于后端人员java开发的JDK。然后搭建前端工程脚手架Vue-cl…

回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)

回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制) 目录 回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注…

Open3D 深度图像转点云

目录 一、算法原理1、算法过程2、主要函数3、算法源码二、代码实现三、结果展示1、深度图像2、点云四、测试数据

20240202在WIN10下使用whisper.cpp

20240202在WIN10下使用whisper.cpp 2024/2/2 14:15 【结论:在Windows10下,确认large模式识别7分钟中文视频,需要83.7284 seconds,需要大概1.5分钟!效率太差!】 83.7284/4200.1993533333333333333333333333…

Android Studio从零基础到APP上线(3)

第3章 简单控件 本章介绍App开发常见的几类简单控件的用法,主要包括:显示文字的文本视图,容纳视图的常用布局,响应点击的按钮控件,显示图片的图像视图等。然后结合本章所学的知识,演示一个实战项目“简单计算器”的设计与实现。 3.1 文本显示 本节介绍如何在文本视图Tex…

【优先级队列(大顶堆 小顶堆)】【遍历哈希表键值对】Leetcode 347 前K个高频元素

【优先级队列(大顶堆 小顶堆)】【排序】Leetcode 347 前K个高频元素 1.不同排序法归纳2.大顶堆和小顶堆3.PriorityQueue操作4.PriorityQueue的升序(默认)与降序5.问题解决:找前K个最大的元素 :踢走最小的&…

Java多态原理

参考 虚方法 JVM杂记:对多态实现原理、虚方法表、虚方法、静态解析、动态链接的一些思考_多态和方法表的关系-CSDN博客 静态分派与动态分派 (JVM)Java虚拟机:静态分派 & 动态分派 原理解析 - 掘金 虚方法表 JVM 栈帧&am…

【C++】类和对象(3)

继续学习类和对象的最后一部分知识,主要有初始化列表、static成员、友元、内部类、匿名对象等。 目录 再谈构造函数 构造函数体赋值 初始化列表 explicit关键字 static成员 概念 特性 友元 友元函数 友元类 内部类 匿名对象 拷贝对象时的一些编译器优化…

跨境电商新风潮:充分发挥海外云手机的威力

在互联网行业迅速发展的大环境下,跨境电商、海外社交媒体营销以及游戏产业等重要领域都越来越需要借助海外云手机的协助。 特别是在蓬勃发展的跨境电商领域,像亚马逊、速卖通、eBay等平台,结合社交电商营销和短视频内容成为最有效的流量来源。…