Linux:gcc工具

news2024/11/23 15:21:55

文章目录

  • 一.程序的翻译
  • 二.gcc工具的使用
    • 2.1gcc 文件名(直接编译)
    • 2.2gcc -o 自定义 原文件(自定义生成可执行程序名称)
    • 2.3./可执行文件
    • 2.4gcc -E(程序运行到预处理后结束)
    • 2.5gcc -S(程序运行到编译之后结束)
    • 2.6gcc -i(程序运行到汇编之后结束)
    • 2.7小结
  • 三.链接的过程
    • 3.1ldd命令
    • 3.2语言级别的头文件
    • 3.3语言对应的库
    • 3.4动态库
    • 3.5静态库
    • 3.6Linux下的库
    • 3.7库的总结
      • 1.库的分类
      • 2.库和链接
      • 3.链接成功之后
      • 4.空间问题

一.程序的翻译

gcc和g++都是一个编译器,gcc是用来编译C语言的,g++可以编译C语言也可以编译C++。
这个和之前学的vim工具一起可以实现在Linux上写C语言或者C++的代码。
g++和gcc类似,基本一样,接下来我主要围绕着gcc来讲。

在学gcc这个工具之前先来了解我们写的代码是如何变成一个可执行程序的,也就是程序的翻译过程。

  1. 预处理:在这一个过程,会将我们写的C代码进行头文件展开条件编译宏替换去注释等。虽然比较复杂,但是预处理完之后,这个代码仍然是C语言代码。
  2. 编译:将C语言变成汇编语言
  3. 汇编:将汇编语言变成可重定位目标二进制文件。这个文件是不可被执行的。一般这种文件都是后缀都是.obj。而且这一个步骤,只把我们自己写的代码进行翻译形成二进制文件。也可以说我们这个工程里有几个.c文件就会对应有几个.obj文件
  4. 链接:将我们上一步得到的这些.obj文件和库文件进行合并,形成可执行程序

二.gcc工具的使用

2.1gcc 文件名(直接编译)

gcc后面直接跟你要编译的.c文件就可以了:

gcc myfile.c

在这里插入图片描述

编译完之后,你所在的目录里就会自动生成一个a.out的可执行文件:
在这里插入图片描述

2.2gcc -o 自定义 原文件(自定义生成可执行程序名称)

gcc默认生成的可执行程序名称是a.out。但如果你希望自定义生成的文件名,可以用-o命令:

gcc -o myfile myfile.c

-o后面跟的就是你希望生成的文件名:
在这里插入图片描述

一定要注意-o后面要紧跟着自定义的文件名,所以-o myfile也可以放在其他位置:

gcc myfile.c -o myfile1

在这里插入图片描述

位置可以任意放,但是不要放在gcc前面。

2.3./可执行文件

gcc生成的可执行文件之后,可以在前面加上./来执行这个文件,这样的话,我们就可以得到我们代码执行的最终效果:
在这里插入图片描述

之前的三个可执行文件是都可以执行的。

2.4gcc -E(程序运行到预处理后结束)

gcc .c文件会帮你一次执行到链接然后结束。但是我们现在希望能一步一步的执行。所以gcc给我们提供了-E的指令:

-E:程序从现在开始进行程序的翻译,预处理做完就停下来

在这里插入图片描述

但是执行完这个指令后发现,它把预处理完之后的结果全部显示到显示器上,但是这样看的会很不舒服。所以我们在这个命令后面加点东西:
在这里插入图片描述

在指令后面加上-o 文件名这个命令可以上执行的结果放到这个文件里面。当然这个文件名你可以自己随便取,但是一般预处理执行后的文件后缀以.i结尾。

我们接下来看看这个.i文件和原来的.c文件有什么区别。
首先,大小就已经是天差地别了:
在这里插入图片描述

然后再看内部的代码:
在这里插入图片描述

发现一个10几行,而另一个有800多行。多出来的这么多行其实就是stdio.h文件展开的内容。接下来我们看主函数代码:
在这里插入图片描述

发现预处理之后,宏定义的被直接替换,注释全部被删掉,条件编译也被替换掉了。

2.5gcc -S(程序运行到编译之后结束)

-S:从现在开始进行程序的翻译,当编译做完,就停下来

在这里插入图片描述

这个命令的意思就是说,从myfile.c这个地方开始,运行到编译之后结束。编译完之后,会自动帮我们生成一个.s的文件。

当然我们直接从.i这个文件开始执行也是可以的:
在这里插入图片描述

2.6gcc -i(程序运行到汇编之后结束)

-i:程序从现在开始翻译,当汇编做完之后就停下来

在这里插入图片描述

这个命令的意思是从现在这里也就是myfile.s这个文件开始,汇编执行完之后结束,同样默认帮我们形成一个.o文件。这个二进制文件在Windows下是.obj文件,在Linux文件下是.o文件。

2.7小结

上面三个步骤已经把整个程序的前三步做完了,最后一步,也就是链接的部分,不用其他什么命令,可以直接gcc运行,也可以gcc执行.o文件:
在这里插入图片描述

gcc myfile.o -o myfile
gcc myfile.c -o myfile

这些类似的写法都是可以的。最终就得到了一个可执行文件。

通过上面那些步骤,对初学者来讲可能就有点昏头了,一个gcc工具,一下子多出来了这么多的指令。

巧记命令
其实看目录2.4-2.6这三步,需要用到的指令连起来就是:ESc,这不就是键盘左上角那东西吗?只不过这里的S是大写的。以后要是忘了就到你键盘上瞄一眼。
三个步骤生成的文件类型连起来就是-iso。这是镜像文件的后缀名。记不住也没问题,多读两遍就熟悉了。

g++用到的命令和gcc差不多,这里就不在赘述了。

三.链接的过程

3.1ldd命令

在学习之前先学一个指令:ldd

ldd:显示出该文件都依赖哪些库。

在这里插入图片描述

接下来我们再来了解一个点:
我们为什么能在Linux上写c/c++的代码呢?因为Linux系统默认已经携带了语言级别的头文件语言对应的库

像我们写一个hello word。要用到printf这个函数,而printf函数,我们需要对应的头文件。

然后C语言本身也是一个库,像我们用到的while循环,for循环,int…这些都是在一个语言库里。

所以说要运行一个C语言代码首先要各种各样的头文件,语言所需要的库,还有一个能将代码转换成二进制的编译器。Linux中这些东西都有,所以我们能在Linux上写c/c++的代码。

3.2语言级别的头文件

Linux中C语言用到的头文件所在的位置一般在**/usr/include/**这个目录下
在这里插入图片描述
语言级别的头文件我们已经清楚了。那语言对应的库是什么呢?

3.3语言对应的库

在学习库之前要明白一件事:
在这些编译型语言,库一般分两种(库也是一个文件)。

1.Linux的静态库:libxxxx.a(一般以.a结尾)
2.Linux的动态库:libxxxx.so(一般以.so结尾)可能有的动态库后面还会跟一些各种各样的版本。

1.Windows的静态库:libxxxx.lib
2.Windows的动态库:libxxxx.dll

中间这些xxxx就是库对应的名字。

接下来我么在看一下刚才用ldd找到的那个可执行程序文件所需的库:
在这里插入图片描述

这里我们主要观察一下中间这个。myfile文件用到的一个库的位置就是在/lib64/libc.so.6这个地方:
在这里插入图片描述

而libc-2.17.so就是myfile这个文件所依赖的库。如果我们把前缀后缀去掉,剩下的就是c-2.17,说明myfile是用C语言来写的。

3.4动态库

库你目前就简单认为是一个装有很多函数的大箱子就行,这些函数都是某些人帮你写好的。

那什么是动态库呢?在解释之前,我把动态库变成你生活中的例子来解释:
假如你是一名准高一的学生,你希望在暑假的时候好好熟悉一下即将要上的高中附件有什么新奇的东西,比如说-- 网吧。你很想知道你们学校边上的网吧在哪里,但是你又有点懒,不想自己动身去看,于是你就去找了一个曾经在这个学校上过学的远方表哥,然后他就把网吧的地址告诉你,你也认认真真的记下来了。
紧接着,你觉得要上高中了,总不能一直去网吧。所以你就自己制定了高一每天的任务清单

  1. 早上6点起床背单词
  2. 上课
  3. 吃饭,午睡
  4. 上课
  5. 下课写作业
  6. 吃饭
  7. 上网!
  8. 睡觉
    好,任务清单做好了,初三的暑假也结束了。所以你高高兴兴去高中上学,并且认认真真的执行暑假中指定的任务。清单中除了上网,其它的事情都可以在学校中完成。所以你要上网,只能跑到你远方表哥跟你说的地址去上网,进入网吧后兴冲冲的开了一台电脑并玩了起来,然后玩完之后回学校睡觉。一天就这么愉快的过去了。

在上面的小故事之中:

  1. 你就代表程序
  2. 你的任务清单就是你写的代码
  3. 你的远房表哥告诉你地址并且记住的过程就叫做动态链接
  4. 你上的高中就是所谓的内存
  5. 你的远房表哥就相当于你的编译器
  6. 而网吧就代表今天所要理解的动态库
  7. 你去高中上学的过程就是程序导入到内存的过程
  8. 你跑去上网玩游戏的过程就是调用库函数

在这里插入图片描述

接下来我们在谈谈我们的大表哥,就是你这个表哥呀,他曾经是这个学校的学生会主席,很多人都认得他,所以和你同级的学生也认得这个表哥,所以这个网吧里不止有你这一个人去,这个学校里的很多人都在去,所以这个网吧不是私有网吧,而是共享网吧。同理动态库也等价于共享库

想必上高一的孩子基本上都是未成年吧,我记得未成年好像不让去网吧,我为了让祖国的花朵健康成长,于是我把这个网吧举报了,警察过来罚款,贴封条。好了,现在就都没人玩了。所以说,如果你不小心把你电脑中库给删掉了,你写的绝大部分指令和代码就都运行不了了。

3.5静态库

刚才的网吧被警察封了,你很难受,哭着找到了你的爸爸,当然,你的爸爸也很爽快,当场就同意了。后来你父亲找到了当初那家网吧的老板,觉得他家的电脑配置很不错,所以你父亲就按着这个配置给你买了一个

而这个按网吧电脑配置给你买电脑的过程就叫做静态链接:将动态库中的代码拷贝一份到你的程序中。

3.6Linux下的库

在Linux下默认使用的是动态库和动态链接,我们可以用指令来查看最开始生成的可执行文件的具体信息:
在这里插入图片描述

会发现这里写的就是动态链接(使用分享库)。

但是我希望我现在写的程序是动态链接,该怎么做呢?
方法很简单在用gcc指令后加上一个-static就行:
在这里插入图片描述

接下来我们在直观上观察一下这两种方式得到的可执行程序:
在这里插入图片描述

可以看到静态链接得到的可执行程序内存要大得多,这里好像有100倍的样子。

一般你的服务器或者系统,都是默认只有动态库,如果这时候你进行静态链接,会出错的
但是你可以用指令下载一个:

C语言静态库

sudo yum install -y glibc-static

C++的静态库也可以下

sudo yum install -y libstdc++-static

3.7库的总结

1.库的分类

动态库:专门让编译器对用户的程序进行动态链接的。
静态库:专门让编译器对用户的程序进行静态链接的。

2.库和链接

动态库和动态链接:链接的时候如果是动态链接,找到动态库,拷贝动态库中我所需要的代码的地址到我自己可执行程序中的相关位置。

静态库和静态链接:链接的时候如果是静态链接,找到静态库,拷贝静态库中我所需要的代码到我自己可执行程序中。

3.链接成功之后

静态库:链接成功后,我们的程序不需要依赖任何库,自己可以独立运行。
动态库:连接成功后,还是要依赖动态库,一旦动态库缺失,我们的程序将无法成功运行。

4.空间问题

静态库:虽然在链接成功后直接可以脱离库,独立运行,但是这样做你的程序必然会因为静态库的到来变的很大,如果内存里不止有一个程序呢?那必然会造成空间的极大浪费。

动态库:虽然在链接成功后还要依赖库,但是程序内部只有地址,非常的节省空间。

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

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

相关文章

2023年最新谷歌Google帐号Gmail邮箱账号怎么注册成功的方法与教程?

因为工作、游戏或其他需求,有时需要使用谷歌Google帐号或Gmail邮箱账号。首先明确:谷歌google帐号不一定是Gmail邮箱帐号,但是Gmail邮箱账号一定是谷歌帐号。所以,大家注册Google谷歌帐号时默认为谷歌Gmail邮箱帐号就可以满足谷歌…

Linux基础命令,常用操作

Linux基础命令Linux的目录结构ls命令(list)隐藏文件、文件夹pwd命令(print work directory)cd命令(change directory)HOME目录相对路径、绝对路径特殊路径符mkdir命令(make directory)touch命令(touch)cat命令more命令cp命令mv命令rm命令(remove)which命令find命令grep命令wc命…

私有云建设,ALLINONE还是分层自主建设优化?

新钛云服已累计为您分享720篇技术干货私有云建设有两种思路,一种是使用整合解决方案,即ALLINONE的思路。一种是将私有云分层每层自主建设,使用不同的产品和解决方案分层优化组合使用。两种思路各有优缺点,适合不同的场景。一、ALL…

Mybatis-plus(上)

1.什么是mybatis-plus升级版的mybatis,目的是让mybatis更易于使用, 用官方的话说“为简化而生”官网:https://baomidou.com/初体验按照官网中的快速开始即可1.准备数据库脚本数据库 Schema 脚本如下: DROP TABLE IF EXISTS user; …

javaWeb RequestResponse

Request Request 继承体系 Tomcat解析请求数据,封装为request对象,并且创建request对象传递到service方法中 。Java提供了接口,tomcat的RequestFacade提供了实现。 Request 获取请求数据 请求数据分为3部分: 请求行&#xff…

一台手机即可完成 3D 建模,功能有多强大? #Luma AI

AIGC 的出现拓展了内容生产的诸多可能,借助 AI 技术来进行 3D 建模,可以节省不少的时间,市面上也出现了许多功能强大的 3D 建模工具。1 月 9 日,AppStore 上架了一款名为“Luma AI”的软件,能够将现实中的 2D 照片快速…

通过Terraform创建GCP Pubsub

1 简介 Terraform是管理许多平台的基础设施的工具,如AWS、GCP和Azure。这篇文章将讲解如何通过Terraform来管理GCP Pub/Sub。 创建GCP项目请参考:初始化一个GCP项目并用gcloud访问操作 2 Terraform创建Pub/Sub 2.1 下载Terraform插件 我们需要安装G…

【Blende UV映射01】创建UV 使用UV贴图处理纹理

写在前面 这是进行云渲染的最后一步,实践!! 会跟着这个Blender 2.8 UV Mapping教程快速学习一边UV映射的东西,已经是最最最最基础的了。 本文是教程的P1-P7的过程记录。 1 UV映射 拿一个3D物体,怎么去切割它&…

1301. C 循环(扩展欧几里得算法)

题目如下&#xff1a; 思路 or 题解: 抽象出数学公式&#xff1a; ak∗c≡b(mod1<<k)a k * c \equiv b (mod\ 1 << k)ak∗c≡b(mod 1<<k) 等价&#xff1a; x∗c−y∗(1<<k)b−ax * c - y * (1 << k) b - ax∗c−y∗(1<<k)b−a 用扩展欧…

[Python逆向] 逆向Pyinstaller打包的exe文件源码及保护

Python逆向Pyinstaller打包的exe文件源码及保护 写在前面 我们都知道可以使用Pyinstaller库可将.py文件编译成.exe文件运行&#xff0c;这篇文章我们就从将脚本编译成.exe并将.exe的源码内容反编译出源文件&#xff0c;再顺便谈谈如何防止被逆向。 环境工具 Python 3.6&#x…

(一)MicroPython——WIFI点灯

目录 学习目标 成果展示 硬件知识 代码 总结 学习目标 成果展示 预备知识 代码 总结 学习目标 我们今天来学习有关MicroPython的知识点&#xff0c;相比于用C语言来开发&#xff0c;MicroPython有许多的优点&#xff0c;比如可以交互&#xff0c;有大量的库可以调…

Allegro如何把快速BUS组高亮成不同颜色操作指导

Allegro如何把快速BUS组高亮成不同颜色操作指导 在做PCB设计的时候,会需要把BUS组高亮成不同颜色,方便评估与布线,Allegro支持快速把BUS高亮成不同的颜色,如下图 具体操作如下 打开颜色管理器出现颜色管理器

1576_AURIX_TC275_MTU控制与状态寄存器

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 在这一页之前&#xff0c;连续有好几个寄存器都是预留的&#xff0c;因此可以直接跳过。访问使能寄存器的功能&#xff0c;从描述看其实是非常熟悉的&#xff0c;因为这个描述的模板可以从…

Java多线程:线程通信:生产者 和 消费者 || 顺序打印

Java多线程&#xff1a;线程通信&#xff1a;生产者 和 消费者 || 顺序打印 每博一文案 靠谱&#xff0c;是最高级的聪明&#xff1a;师父说&#xff1a;人生一回&#xff0c;道义一场。你对人对事的态度&#xff0c;藏着你一生的福报。 千金难买好人缘&#xff0c;人活的就是…

Android编译Skia库

Android编译Skia库 本文档提供两种方法编译Skia库 使用aosp源码进行编译使用skia源码进行编译 两种编译方法都可以编译,并且都可以使用在多个平台中,且可以使用在不同Android版本中 使用aosp源码编译 第一步是拿到aosp的源码.因为写这篇教程,使用的是msm8996的源码,因此,我…

Armitage图形化前端

开源免费图形前端 ● 作者自称是众多不会使用metasploit的安全专家之一&#xff08;命令行&#xff09; ● MSF基于命令行&#xff0c;缺少直观的GUI图形用户接口 Armitage只是调用MSF的漏洞利用能力 ● Armitage的每一个GUI操作都可以对应MSF中的一条命令 红队团队合作模拟…

OSCP vulhub LORD OF THE ROOT: 1.0.1

vulhub LORD OF THE ROOT: 1.0.1靶场信息&安装Description一、信息收集第一种ssh爆破第二种猜二、漏洞探测三、漏洞利用四、提权第二种方法&#xff1a;udf提权第三种缓冲区溢出提权靶场信息&安装 地址&#xff1a;https://www.vulnhub.com/entry/lord-of-the-root-10…

APSIM练习:向管理组件添加额外规则

“标准”作物管理组件没有提供很多选项来决定何时播种作物——很可能应该考虑一系列额外的种植规则&#xff08;例如&#xff0c;土壤是否足够干燥以驱动拖拉机过去&#xff1f;&#xff09;&#xff0c;并且在播种时应采取额外措施&#xff08;例如添加一些肥料&#xff09;。…

Tofu目标识别跟踪模块介绍

1.简介Tofu3 是多波段视频物体识别跟踪模块&#xff0c;支持可见光视频与红外视频的输入&#xff0c;支持激光补光变焦自适应控制&#xff0c;支持视频下的多类型物体检测、识别、跟踪等功能。产品支持视频编码、设备管理、目标检测、深度学习识别、跟踪等功能&#xff0c;提供…

服务器防勒索病毒场景分析经验分享

服务器防勒索病毒 l 场景描述 互联网飞速发展&#xff0c;各企业均搭建了自己的服务器。包括文件服务器、代码服务器、业务系统服务器、数据库服务器等。目前大多数企业使用的服务器系统以Windows Server和Linux&#xff08;Centos&#xff09;居多&#xff0c;但随着国产操作…