Linux | gcc/g++的使用
目录
前言
一、程序的翻译过程
1、预编译
2、编译
3、汇编
4、链接
(1)链接做了什么
(2)动态链接
(3)静态链接
(4)如何使用gcc进行动态链接和静态链接
前言
本章主要带着大家一起学习Linux下编译C/C++的工具,以及关于动静态库的一些基础知识;
一、程序的翻译过程
我们的C语言和C++编写出的程序属于翻译型程序,此处以C语言为例,分析程序翻译过程;
1、预编译
当我们写完一个C语言程序时,首先,我们需要进行预编译操作;预编译主要将头文件展开、宏替换、条件编译与去注释;我们可使用下列指令生成我们的预编译完的文件(以.i为结尾的文件后缀);
gcc -o 生成文件名.i -E 被预编译的文件名.c

上图为我们编写的源程序,我们来验证我们的预编译阶段是否完成了上述工作;我们执行以下执行,生成预编译完成后的文件 test.i ;

预编译生成的文件从大小上,明显可以看出比我们的源文件要大很多,我们再使用vim查看我们的test.i文件,如下图;

我们发现我们的文件一下就变成了八百多行,前面增加的便是我们的stdio文件展开后的样子,故我们test.i文件变大了很多,因为把我们的库文件代码复制到预编译后的文件中了,而且我们不难发现我们之前些的注释被去掉了,我们的宏也完成了替换,也进行了条件编译的处理,与我们的预想完全一致;
2、编译
这一步主要实现的将我们的C语言代码编译成汇编代码,我们生成的汇编代码文件以s为后缀名,具体指令如下;
gcc -o 编译生成后文件名.s -S .c文件或.i文件都可


学过汇编语言的友友们,应该就很熟悉了,这就是我们的汇编代码,编译阶段也如我们所料完成了自己的工作;
3、汇编
这一步主要是将我们的汇编代码转换成机器指令,生成的文件叫 可重定向二进制目标文件(目标文件),这个文件在Linux下一般以o为后缀名,在window下一般以obj为后缀名,具体指令如下;
gcc -o 生成文件名 -c .c文件或.i文件或.s文件都可

我们可以使用od指令来阅读我们的可重定向目标文件,如下所示;

这里生成的已经是机器指令了,但是仍然不能直接执行,必须链接后才可以执行;
4、链接
(1)链接做了什么
实际上,我们上面的头文件,如 stdio.h 只有函数的声明,并没有函数的定义,因此我们在是使用我们库函数printf、scanf函数时,光有函数声明时远远不够的,我们必须还有具体的函数定义,这些函数定义都放在动态库或静态库,因此我们链接也有动态链接和静态链接;我们首先完成链接,具体指令如下;
gcc -o 生成可执行程序名 .c文件/.i文件/.s文件/.o文件都可

我们可以通过ldd指令或file指令查看文件使用的动态库/静态库的名字,以及采用何种链接方式;


补充:在Linux下,动态库文件的后缀为.so,静态库文件的后缀为.a,而在window下,动态库文件的后缀为.dll,静态库文件的后缀为.lib;
(2)动态链接
在动态链接中,我们的程序一旦发现有需要使用库函数的代码,则会保存该库函数在动态库中的地址,运行到此部分时,我们直接通过地址跳转到动态库的代码中,执行函数,执行完函数后继续返回程序执行程序后续代码;因此,一旦我们的动态库出现了问题,我们的程序就无法正确执行;
总结:
动态链接优点:可执行程序较小,因为只保存了库函数地址;
动态链接缺点:十分依赖动态库文件,若文件出现问题,程序则可能出现问题;
(3)静态链接
在静态链接中,我们的程序会将需要使用的库函数的定义直接拷贝一份到我们的可执行程序中,我们在运行可执行程序时,无需静态库,我们直接调自己拷贝的代码即可;
总结:
静态链接优点:对静态库文件的无依赖,一旦生成可执行程序,即使静态库被删除,也可以运行;
静态链接缺点:静态链接生成的可执行程序由于会拷贝静态库中的函数定义,因此会变得非常大;
(4)如何使用gcc进行动态链接和静态链接
在gcc中,我们默认使用动态链接的方式进行链接,因此直接使用正常的方式生成可执行程序即可,例如;
gcc -o test-d test.c
而我们若想使用静态链接的方式进行连接,我们加上一个static选项即可,如下所示;
gcc -o test-s test.c -static
补充:有些小伙伴可能没有安装静态库,可通过下面指令安装静态库
sudo yum install -y glibc-static (Centos)

显然,我们使用静态链接生成的可执行程序明显比动态生成的可执行程序要大十倍左右,也符合我们之前的推理,我们在通过ldd和file指令查看我们生成的可执行程序所依赖的库;

test-s是静态链接生成的可执行程序,因此没有依赖的动态库,而test-d是动态链接生成的可执行程序,因此有依赖的动态库,我们可以通过file看出这两个可执行程序是动态链接还是静态链接;
相关文章:
Linux | gcc/g++的使用
目录 前言 一、程序的翻译过程 1、预编译 2、编译 3、汇编 4、链接 (1)链接做了什么 (2)动态链接 (3)静态链接 (4)如何使用gcc进行动态链接和静态链接 前言 本章主要带着大…...
了解容器运行时安全:保护你的容器应用
前言 容器是一种虚拟化技术,用于封装和运行应用程序及其依赖项,以便在不同的计算环境中保持一致性和可移植性。自2013年容器诞生至今,容器Docker镜像的下载量超20亿,虽然容器行业发展如火如荼,但是其安全风险却不容乐…...
大规模语言LLaVA:多模态GPT-4智能助手,融合语言与视觉,满足用户复杂需求
大规模语言LLaVA:多模态GPT-4智能助手,融合语言与视觉,满足用户复杂需求 一个面向多模式GPT-4级别能力构建的助手。它结合了自然语言处理和计算机视觉,为用户提供了强大的多模式交互和理解。LLaVA旨在更深入地理解和处理语言和视…...
Element UI定义方法校验邮箱格式
1. .vue中定义了3个邮箱输入框,前面两个是输入多个邮件地址,最后一个是使用element自带的校验来校验单个邮件地址 <el-row><el-col :span"24"><el-form-item label"收件人" prop"to"><el-input v-mo…...
DigiCert代码签名证书
在当今的数字化时代,确保软件的完整性和来源的可靠性至关重要。DigiCert代码签名证书是一种专业而受信任的数字签名解决方案,帮助开发者保护其软件免受篡改和恶意行为的侵害。本文将介绍DigiCert代码签名证书的特点和优势,并讨论为何选择Digi…...
HTML5+CSS3小实例:网页底部间隔波浪动画特效
实例:网页底部间隔波浪动画特效 技术栈:HTML+CSS 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content…...
前端 js 之 代码执行的一个过程 02
嘿,欢迎你来 !💕 文章目录 前言一、运行一个 js 文件二、运行环境三、js执行代码的过程(普通变量)四、打印 window五、js执行代码的过程(函数变量)六、函数调用函数的过程注意!&…...
【经验分享】如何构建openGauss开发编译提交一体化环境
前文 本文适合对openGauss源代码有好奇心的爱好者,那么一个友好的openGauss源代码环境应该是怎么样的。openGauss的开发环境是如何设置的?openGauss的编译环境是如何构建的?如何向openGauss提交代码,笔者集合官方和几位博主实践提…...
儿童疫苗接种:安全与注意事项
引言: 儿童的疫苗接种是维护其健康和预防传染病的重要措施。疫苗可以有效地保护儿童免受各种疾病的威胁,但在接种过程中需要家长和监护人特别关注一些注意事项,以确保接种的安全性和有效性。本文将深入探讨儿童疫苗接种的重要性,…...
Go 代码块与作用域,变量遮蔽问题详解
Go 代码块与作用域详解 文章目录 Go 代码块与作用域详解一、引入二、代码块 (Block)2.1 代码块介绍2.2 显式代码块2.3 隐式代码块2.4 空代码块2.5 支持嵌套代码块 三、作用域 (Scope)3.1 作用域介绍3.2 作用域划定原则3.3 标识符的作用域范围3.3.1 预定义标识符作用域3.3.2 包代…...
可观测性-Metrics-WebClient异步Http远程Call
代码示例 1.依赖导入 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><ar…...
Android之播放本地视频和Url视频方法
一、播放本地视频文件 根据文件路径在浏览器中播放,可用于视频预览等场景 效果: 用浏览器播放本地视频 文件路径例子: /storage/emulated/0/Android/data/com.custom.jfrb/files/Movies/1697687179497.mp4 File file new File("文件…...
设计模式:工厂方法模式(C#、JAVA、JavaScript、C++、Python、Go、PHP):
本节主要介绍设计模式中的工厂方法模式。 简介: 工厂方法模式,它是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。 它定义了一个用于创建对象的工厂接口,让…...
C++基础——指针
1 概述 指针的作用:可以通过指针间接访问内存 内存编号从0开始,一般使用十六进制数字表示,指针可以保存地址 2 指针变量定义和作用 int main() {//1、指针的定义int a 10; //定义整型变量a//指针定义语法: 数据类型 * 变量名 …...
PLC 学习day02 硬件输入/输入的知识
1.资料来源 1.链接:三菱PLC视频教程全集之FX3U基本单元输入接线_哔哩哔哩_bilibili 2. 链接: 三菱plc视频教程全集之FX3U基本单元输出接线_哔哩哔哩_bilibili 2. PLC 的输入部分器件连接。 2.1 PLC输入部分的硬件知识 1. 一般输入部分是PLC获取信息的地…...
rabbitMq (2)
RabbitMQ 消息应答与发布 文章目录 1. 消息应答1.2 自动应答1.2 手动应答1.3 代码案例 2. RabbitMQ 持久化2.1 队列持久化2.2 消息持久化 3. 不公平分发4. 预取值分发5. 发布确认5.1 发布确认逻辑5.2 开启发布确认的方法5.3 单个确认发布5.4 批量确认发布5.5 异步确认5.5.1 处理…...
通讯协议学习之路:RS422协议理论
通讯协议之路主要分为两部分,第一部分从理论上面讲解各类协议的通讯原理以及通讯格式,第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN;视频会发布在bilibili(UID:399951374) 一、…...
剪映failed to initialize,cuda.is_available()为false解决
debug记录帖 错误1:打开剪映发现弹窗提示failed to initialize graphics backed for D3D11 错误2:torch版本、cuda版本(之前的正常环境)都对但是torch.cuda.is_available()为false 怀疑是显卡驱动的问题 打开Nvidia Geforce Exp…...
基于Spring Boot的LDAP开发全教程
写在前面 协议概述 LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是一种用于访问和维护分布式目录服务的开放标准协议,是一种基于TCP/IP协议的客户端-服务器协议,用于访问和管理分布式目录服务,如企业内部的…...
在 Linux 上保护 SSH 服务器连接的 8 种方法
SSH 是一种广泛使用的协议,用于安全地访问 Linux 服务器。大多数用户使用默认设置的 SSH 连接来连接到远程服务器。但是,不安全的默认配置也会带来各种安全风险。 具有开放 SSH 访问权限的服务器的 root 帐户可能存在风险。尤其是如果使用的是公共 IP 地…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
