【Linux】gcc编译器的使用(程序的翻译过程)

news2024/10/6 8:37:36

目  录

  • 1 程序的翻译
    • 1.1预处理(进行宏替换)
    • 1.2 编译(生成汇编代码)
    • 1.3 汇编(生成机器可识别代码)
    • 1.4 链接(生成可执行文件或者库文件)
    • 1.5 gcc常用选项总结


程序的翻译过程包括:预处理、编译、汇编、链接四个部分,接下来文章中将讨论在Linux下如何使用gcc编译器完成程序的翻译。

1 程序的翻译

gcc使用命令格式:gcc [选项] 要编译的文件 [选项] 生成的目标文件

以下以 test.c 文件作为示例讨论程序翻译过程,其中源代码如下图所示:

test.c


1.1预处理(进行宏替换)

  • 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
  • 预处理指令是以 # 号开头的代码行。
  • 使用gcc完成预处理过程: gcc -E test.c -o test.i
    其中选项 -E 的作用是让gcc在预处理结束后停止编译过程;选项 -o 是指生成目标文件(注意:-o 选项后面必须紧跟目标文件);.i 文件是经过预处理后的C原始程序,如下图所示,源程序中的注释经过预处理后被删去了,main函数中的N也被替换为了100,还有条件编译也被处理了,此外,还可以看到,除了被处理后的原代码部分,前面还有八百多行代码是头文件等展开后的结果。

test.i


1.2 编译(生成汇编代码)

  • 编译过程包括词法分析、语法分析、语义分析等。在这个过程中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言程序。
  • 使用gcc完成编译过程:gcc -S test.i -o test.s
    其中 -S 的作用是让gcc在编译结束后停止翻译过程,.s 文件是编译后生成的汇编语言程序(如下图所示)。

test.s


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

  • 汇编阶段就是把编译阶段生成的 .s 文件转成目标文件。
  • 使用gcc完成汇编过程:gcc -c test.s -o test.o
    其中 -c 的作用是让gcc在汇编结束后停止翻译过程,.o 文件是汇编后生成的可重定位目标二进制代码(相当于windows下程序翻译后形成的 .obj 文件)。如下图所示,这里只是把我们自己编写的代码翻译成了二进制文件,即使将文件权限修改为可执行后,这个二进制文件仍是不可被执行的,还需经过链接过程形成完整的可执行程序。
    test.o

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

  • 使用gcc完成链接过程:gcc test.o -o test

链接过程具体做了什么呢?这里需要先了解一个概念:函数库

  • 我们在编写程序时,常常会用到 printf 等库函数,但事实上,在预编译中包含的头文件 stdio.h 中也只是有函数的声明,而没有函数的定义(实现),那 printf 又是在哪里实现的?我们的程序又是如何成功使用函数的呢?
    其实,系统把这些函数实现都写在名为 libc.so.6 的库文件中了,在没有特别指定时,gcc会到系统默认的搜索路径 /usr/lib 下查找,也就是链接到 libc.so.6 库函数中去,如此就能实现对应的库函数了,而这也是链接的作用。
  • 我们之所以能够在Linux下进行C、C++等代码的编写和编译是因为Linux系统默认已经携带了语言级别的头文件和语言对应库,而编译器能够自动帮我们识别解释这些语言,并根据相应的库完成程序的编译链接以形成可执行程序。

函数库一般分为静态库和动态库(共享库)两种,对应的链接也分为静态链接和动态链接

  • 库本质上也是一种文件,Linux下静态库通常以 libXXX.a 的形式命名,动态库通常以 libXXX.so 的形式命名;Windows下静态库通常以 .lib 为后缀,动态库通常以 .dll 为后缀。
  • 静态链接是指在编译链接时,把静态库中我们所需要的代码全部拷贝添加到最终的可执行文件中,因此生成的文件比较大(会比较占用空间),但同时静态链接完成后程序在运行时也就不需要再依赖任何库,自己就可以运行了。
  • 与静态链接不同,动态链接在程序编译链接时并没有把库文件中的代码拷贝添加到可执行文件中,而是将动态库文件中我们所需要的代码的地址拷贝添加到可执行文件中的相关位置,程序运行时则通过地址链接库文件找到相应的代码。如此,所有有需要的程序共享方法,而方法的真正实现永远只在库中,可有效节省系统的开销。但如果相关动态库缺失,对应的程序也将无法执行。

那我们要如何知道我们的可执行程序是静态链接形成的还是动态链接形成的呢?这里首先要了解一个命令:ldd 可执行文件 ,通过该命令可以查看对应可执行文件所依赖的动态库。
以下通过示例来进一步了解程序的链接:

动态链接

  • 需要注意的是:Linux下默认使用的是动态链接和动态库。

那如何实现静态链接呢?

这里使用的是云服务器,一般云服务器默认只有动态库,如果要实现静态链接,还需安装静态库,否则会报错。我们可以通过命令:
yum install glibc-static libstdc++-static -y 来安装静态库。接着通过命令:gcc test.o -o test-static -static 实现静态链接(这里为了区分动态链接形成的可执行文件,将静态链接形成的可执行文件命名位 test-static。命令中选项 -static 表示使用静态链接和静态库)。如下图所示,可以看到静态链接形成的可执行文件的大小约有动态链接形成的可执行文件的大小的100倍,可见静态链接消耗的空间之大。

静态链接


总结: 以上为了更加详细的了解程序翻译的过程,所以分四步完成程序的翻译,在实际中,如果没有特殊需要,(以test.c文件的翻译为例)可直接使用命令 gcc test.c -o test 完成程序的编译及动态链接,使用命令 gcc test.c -o test -static 完成程序的编译及静态链接,其中如果不加选项 -o test 生成指定的目标文件,则会默认生成名为 a.out 的可执行文件。 如下图所示,无论是动态链接形成的可执行程序还是静态链接形成的可执行程序,又或是默认形成的可执行程序,最终的运行结果都是一样的。


链接


1.5 gcc常用选项总结

  • -E :只激活预处理,不生成文件,需要将执行结果重定向到一个输出文件中,否则默认将预处理结果输出到屏幕。
  • -S :编译到形成汇编语言代码就停止,不进行汇编和链接。
  • -c :编译到形成二进制目标代码。
  • -o :输出指定目标文件。
  • -static :对生成的二进制文件采用静态链接。
  • -g :生成调试信息(Debug版可执行程序)。GUN调试器可利用该信息。
  • -shared :尽量使用动态库,形成的可执行文件比较小,但前提需要系统有动态库。
  • -O0-O1-O2-O3 :编译器的优化选项的4个级别,-O0 表示没有优化,-O1 为缺省值,-O3 优化级别最高。
  • -w :不生成任何警告信息。
  • -Wall :生成所有警告信息。

以上是我对Linux中gcc编译器使用的一些学习记录总结,如有错误,希望大家帮忙指正,也欢迎大家给予建议和讨论,谢谢!

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

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

相关文章

Diffie-Hellman密钥协商算法探究

作者 | 魔王赵二狗 导读 隐私计算(Privacy-preserving computation)是指在保证数据提供方不泄露原始数据的前提下,对数据进行分析计算的一系列信息技术,保障数据在流通与融合过程中的可用不可见。而Diffie–Hellman密钥协商是一种…

2023-01-10 mysql列存储引擎-聚合多线程并行扫表-VCPackGuardian策略LOCK_ALL-概要设计

摘要: 当前的pack淘汰策略为LOCK_ONE, 在多线程切换时导致pack地址丢失。 新设计LOCK_ALL策略以保证多线程聚合正常工作。 设计思想: 多线程聚合运算期间, 对持有的pack不做淘汰业务中对pack的读取和释放保持原有逻辑架构设计: 静态结构: 动态结构: 上层业务通过VirtualCol…

【学习笔记之Linux】工具之vim基本介绍

vim基本认识 vim是一种多模式的编辑器,它是vi的升级版本,它兼容vi所有的指令并加入了一些新的特性在里面。vi是一个老式的文本编辑器,功能相当齐全,vim则是在vi之上更进了一步,拥有代码补全、编译及错误跳转等功能&…

pytorch OutOfMemoryError

torch.cuda.OutOfMemoryError before: self.memory deque(maxlen50000) after: self.memory deque(maxlen500) ok.... pytorch模型提示超出内存cuda runtime error(2): out of memory - pytorch中文网 看到这个提示,表示您的GPU内存不足。由于我们经常在PyTo…

做外贸有没有好的软件?

在外贸电商行业中,邮件营销是非常重要的一种营销方式之一。除了性价比高,他还能对目标客户进行精准营销。但是,对于刚开始做的公司来讲,不注意方法和细节也难收获到理想的营销效果。 一、问题 1)不管理邮箱联系人 只…

13.Isaac教程--模型制作

模型制作 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 该软件包演示了具有软件定义装配工作流程的工厂场景。 在模拟工厂环境中,多个 AMR 在装配站之间运输材料,而每个装配站的机械臂拾取所需材料并将其放置在对接的 …

自定义el-pagination分页

项目场景: 提示:这里简述项目相关背景: vue项目使用el-ui库,由于原本的el-pagination显示字段和样式无法满足其他项目的设计要求,需要进行改动 el-ui官网: 改动后: 解决方案: 1…

golang字符串常见功能

文章目录1. 获取字符串长度2. 是否一xx开头3. 是否以xx结尾4. 是否包含5. 变大写6. 变小写7. 去两边8. 替换9. 分割10. 拼接11. string转换为int12. int转换为string13. 字符串和字节切片14. 字符串和rune切片15. string和字符1. 获取字符串长度 2. 是否一xx开头 3. 是否以xx结…

抖音seo优化排名

武汉微驱动科技有限公司 你有没有想过,同样是运营抖音,为什么别人的视频总是排在你的前面?你死磕创意,拍摄、剪辑,甚至比同行更投入,为什么他的收益总是高于你? 当下抖音搜索引擎的用户数量已经…

Nginx与LUA(1)

您好,我是湘王,这是我的CSDN博客,欢迎您来,欢迎您再来~HTTP服务器是相对于HTTP客户端来说的——HTTP客户端就是各种常用的「浏览器」,如IE、chrome、微信浏览器。当浏览器通过URL地址栏访问一个Web页面时&a…

【C++】STL六大组件之一——适配器(adapters)

目录1. 前言2. 初始适配器2.1 适配器的概念2.2 适配器的分类3. 容器适配器(container adapters)3.1 认识deque3.1.1 逻辑结构3.1.2 物理结构3.1.3 deque的迭代器3.1.4 选择deque做stack/queue底层容器的原因3.2 stack3.3 queue3.4 另一种容器适配器 ——…

阿里云计算巢 x GBase GCDW:自动化部署云原生数据仓库

近日,阿里云计算巢与天津南大通用数据技术股份有限公司(以下简称:GBASE)合作,双方融合各自技术优势,助力企业用户实现云上数据仓库的自动化部署,让用户在云端获取数据仓库服务“更简单”&#x…

【ESP32+freeRTOS学习笔记-(六)软件定时器】

目录1、软件定时器概念2、软件定时器的运行机制2.1 组成2.2 创建2.3 运行3、软件定时器的属性和状态3.1 定时器的周期3.2 定时器的类型3.3 定时器的状态4、软件定时器的回调函数原型5、定时器的使用5.1 创建定时器xTimeCreate()5.2 启动定时器xTimerStart()5.3 终止定时器xTime…

IPC进程间通信-system V 共享内存

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸 文章目录一、共享内存原理二、共享内存的建立原理三、共享内存的创建四、共享内存的删除五、共享内存挂接到自己的地址空间六、从进程地址空间去掉与…

快过年了用Python抢红包

快过年了,刚刚收到了两个消息,一个好消息,一个坏消息。 先说好消息,好消息就是微信群里即将有人要发红包, 坏消息是我抢不上! 难道就这么放弃了吗?那就只能试试能不能通过编程的方式实现自动化…

基于轻量级YOLOV5+BIFPN的苹果瑕疵检测识别分析系统

BIFPN是一种比较经典有效的特征融合手段,在很多检测模型中都有集成应用,实际表现也验证了BIFPN的有效性,这里并不是要探讨BIFPN的原理内容,而是想集成这项技术,提升原有模型的性能表现,在我之前的一些文章中…

排序算法之冒泡排序

一般学习过编程的人都知道,排序算法有很多种,包括直接选择排序、直接插入排序、计数排序、快速排序、归并排序、冒泡排序等,在我看来,以上六种排序算法是必须要掌握的,今天,我们先来讲解一下冒泡排序算法&a…

Java高手速成 | 新增类Record的工作实例

01、什么是Record? Record 是Java新增的库类,在Java 14和Java 15中以预览(preview)形式公布。Record类用来自动生成对定义数据进行创建、设置、访问以及比较等代码,所以又被称作数据类(data class)。在一…

初级开发者福音:手把手教你实现数字滚动效果~

文章目录一、前言二、背景知识三、实现方案Step 1:分析需求Step 2:实现单个数字的滚动效果Step 3:组件接口设计Step 4:完善组件一、前言 前端数字滚动显示的场景很多,比如抽奖的时候,营造一种马上公布中奖…

[MySQL从入门到实战环境部署](超详细版)

MySQL从入门到实战环境部署1.部署CentOS1.1部署CenOS虚拟机步骤(1)基于VirtualBox(2)下载CentOS1.2环境部署过程2.部署MySQL1.部署CentOS 1.1部署CenOS虚拟机步骤 (1)基于VirtualBox 下载网址&#xff1…