【Linux】第八站:gcc和g++的使用

文章目录

  • 一、解决sudo命令的问题
  • 二、Linux编译器-gcc/g++
    • 1.gcc的使用
    • 2.g++的使用
  • 三、gcc编译链接过程
    • 1.预处理
    • 2.编译(生成汇编)
    • 3.汇编(生成机器可识别代码)
    • 4.链接(生成可执行文件或库文件)
    • 5.一些选项的意义
  • 四、库
    • 1.关于库的一些认识
    • 2.与库的链接
      • 1>动态链接
      • 2>静态链接
    • 3.验证
    • 4.一些问题
    • 5. file指令
    • 6.动静态链接的优缺点
  • 五、debug和release

一、解决sudo命令的问题

当我们使用一个新的普通用户想要对一条指令进行提权的时候,我们会遇到如下问题,显示不被信任

image-20231031150110891

所以我们现在需要做的就是将我们的该用户添加到系统的白名单中

这个白名单在下面这个路径下

/etc/sudoers

当然我们不可以用普通用户去访问,因为我们可以看到这个文件的权限是这样的

image-20231031150901193

所以我们需要用root账号去进行修改

image-20231031151131075

进入以后,我们在第100行可以看到这个

然后我们只需要修改添加一行即可

image-20231031151556550

然后我们在回到这个普通账号,我们就可以使用sudo进行提权了,以root的身份进行创建文件,我们也可以看到,我们创建的文件的拥有者就是root

image-20231031151743736

二、Linux编译器-gcc/g++

gcc智能用来编译c语言,g++即可用来编译c语言,又可用来编译c++

但我们一般用gcc编译c,g++编译c++

1.gcc的使用

当我们写好代码以后直接

gcc test.c

然后它会自动生成一个可执行程序a.out这个可执行程序的名字不重要,关键是它的属性具有可执行权限

然后我们直接使用如下命令,就可以进行运行了

./a.out

如下所示

image-20231031154440222

2.g++的使用

g++的使用与gcc是十分类似的

不过我们需要先安装一下g++

yum install gcc gcc-c++

安装以后,我们就可以使用g++编译c++代码了,它默认生成的就是a.out文件

image-20231031212008830

image-20231031211938673

三、gcc编译链接过程

我们知道执行一个c程序需要经过一下几个步骤

  • 预处理
  • 编译(生成汇编)
  • 汇编(生成机器可识别代码)
  • 链接(生成可执行文件或库文件)

1.预处理

在预处理过程中,会有如下操作

  1. 去掉注释
  2. 头文件展开
  3. 宏替换
  4. 条件编译

我们先来展示前三点

我们需要先输入如下指令

gcc -E test.c -o test.i

选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。

选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。

最后我们就可以观察到了前三点的现象

image-20231031170914851

这里,我们还需要了解的一点是,我们为什么可以在windows或者linux上进行C/C++或者其他形式的开发呢?

这是因为我们的系统中一定要提前或者后序安装上,C/C++开发相关的头文件,库文件

而这些文件就在下面的路径中

/usr/include

image-20231031171939096

然后我们可以打开一下比如stdio.h

vim /usr/include/stdio.h

我们可以看到大概有900多行的代码

image-20231031172144221

而我们前面的头文件展开,就是将这里面的内容全部拷贝到test.i中

其实我们在安装vs2022的时候,还在安装的时候,就要选择对应的开发包,同步也在下载C的头文件和库文件

也就是说,在windows也同步有着对应的文件

还有条件编译,也会在预处理阶段给解决掉

gcc -E test.c -o test.i

image-20231031173153384

不过对于宏,我们也可以在编译时候去定义的

gcc -E test.c -o test.i -DDEBUG

image-20231031173751456

image-20231031173811449

而条件编译的作用就是

比如vs2022有社区版和专业版,而公司不可能会专门维护两份代码,所以社区版只是专业版裁剪掉了某些功能得到的,而这个裁剪用的就是条件编译

2.编译(生成汇编)

在我们与预处理完以后,我们的代码其实还是C语言

所以我们下一步就是生成汇编

gcc -S test.i -o test.s

不过我们也可以从test.c直接生成汇编

gcc -S test.c -o test.s

生成以后,里面就是这个东西

image-20231031174647128

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言

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

  • 汇编阶段是把编译阶段生成的“.s”文件转成目标文件

  • 在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了

gcc -c test.s -o test.o

不过我们可以看到里面全是乱码

image-20231031175230737

这是因为这个.o文件是二进制文件,而vim是文本编辑器。

所以我们可以使用二进制查看工具比如od

image-20231031175330178

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

我们直接将所有的目标文件进行链接起来即可

gcc test.o -o mytest

最终这个mytest就是我们的可执行文件

image-20231031175534732

对于生成可执行程序这里,还有很多种方式

首先就是直接生成

gcc test.c

这种方式最终生成的可执行程序是a.out

第二种方式是这样的

gcc test.c -o test

这种方式就和前面比较相似,直接将.c文件变成一个可执行程序test

这种方式我们也是最为推荐的

不过也可以这样写,无论如何-o后面跟的永远都是最终的可执行程序

gcc -o test test.c

5.一些选项的意义

gcc -E test.c -o test.i

这个-E的意思是告诉gcc,从现在开始进行程序的翻译,将预处理工作做完就停下来,不要往后走了!

gcc -S test.i -o test.s

从现在开始进行程序的翻译,将编译工作做完,就停下来

gcc -c test.s -o test.o

从现在开始进行程序的翻译,将汇编工作做完,就停下来

我们最终形成的这个test.o文件就是可重定位目标二进制文件,简称目标文件,在windows下他就是.obj文件;还需要注意的是这个文件不可以独立执行,虽然已经是二进制文件了,但是还需要经过链接才能执行

gcc test.o -o test

上面就是链接的过程,可将重定位目标二进制文件,和库进行链接形成可执行程序

四、库

1.关于库的一些认识

我们知道,我们写完程序后最终要有链接过程,链接要与我们的头文件进行链接,而头文件的一些方法是由库给提供的

比如我们C语言的标准库在这里路径下

/usr/lib64/libc.so

image-20231031184033858

所以这个C语言标准存在的本质就是一个文件,它有自己的路径

在linux种这个库有以.so结尾的,也有以.a结尾的

LInux:.so(动态库) .a(静态库)

windows : .dll(动态库) .lib(静态库)

所以我们上面的就是Linux系统默认的动态库

一般我们这个库是有自己的命名规则的:libname.so.XXX

这个命名中只有最开头的name这四个是不同的,所以我们只需要它就可以了

注意:我们现在的机器上,默认只会安装动态库,静态库是默认没有安装的

所以现在回过头来

  • 方法的实现就是在库当中的!

  • 库其实就是把源文件(.c),经过一定的翻译,然后打包,只给你提供一个文件即可,不用给你提供给太多的源文件,也可以达到隐藏源文件的目的

  • 头文件提供方法的声明, 库文件提供方法的实现+ 我们自己的代码== 我们的软件

有了库就可以不用做很多重复的工作,可以站在巨人的肩膀上了

而我们在使用gcc的时候,是不用手动的去链接它的库的,gcc天生就是链接c语言的,里面早已经处理好了

对于gcc,它默认找的是c语言的库,所以它无法编译c++代码

2.与库的链接

我们的.o文件和库是如何链接的呢?

我们的链接方式有两种

  1. 动态链接
  2. 静态链接

1>动态链接

假如小明今年刚刚考上了高中,它比较喜欢玩游戏。

所以他问他的学长,哪里有网吧。

小明在某一天个自己列了一个清单:完成物理作业、数学作业、语文作业、玩游戏…

然后小明就像一个可执行程序一样,一条一条的完成,当遇到玩游戏的时候,由于之前学长(编译器)告诉过他网吧在哪里,所以他就可以去网吧玩游戏。然后打完以后再返回原来的程序中继续执行

在这个过程中,学长就像一个编译器,存储着地址,告诉小明去哪里找,小明就像一个可执行程序,网吧就像一个库,当去执行游戏的操作时候,就会跳转到对应的库执行,执行完毕以后返回到代码调用出,这个过程就是动态链接的过程。

网吧这个库也就是一个动态库,也称作共享库(因为可以有很多人去像小明一样),所以网吧只要一个就可以了

假如有一天网吧被查封了,那么就糟糕了,所有人都玩不了游戏了

所以说动态库不能缺失,一旦对应的动态库缺失,影响的不止一个程序,可能导致很多程序都无法正常运行!

我么可以用ldd指令去查看某一个可执行程序它所依赖的动态库

image-20231031194105387

如果一旦我们将这个库给删掉了,那么我们这个程序就无法跑了

其实我们系统中的很多指令就是用C/C++写的,因为他们本身就是可执行程序(大部分的指令都是用c语言写的)

image-20231031194421328

2>静态链接

继续前面的故事,网吧被查封了以后

大家都没法上网了,于是这个老板开始了卖电脑

于是很多人都去自己买了电脑。

这时候当我们想要去上网的时候,直接用自己的电脑就可以了,再也不用去网吧了

上面的这种方式其实就是静态链接

这个电脑店就是静态库

并不像之前的动态一样给一个地址,然后去找动态库;而是直接将静态库里面的方法给拷贝过来。

当未来这个电脑店再次被查封的时候,也不会影响到我们了。我们也不关心它

在编译器使用静态库链接的时候,会使自己的方法拷贝到目标程序中,该程序以后不用再依赖静态库了!

3.验证

如下所示,是关于动态链接的验证

image-20231031201712053

在linux中,编译形成可执行程序,默认采用的就是动态链接–需要提供动态库

如下是关于静态链接的验证

静态链接时需要加上-static选项

gcc test.c -o test_static -static

在linux中,如果要按照静态链接的方式,进行形成可执行程序,需要给添加static选项 — 也要提供静态库

不过在我们的系统中一般是默认没有安装静态库的

我们可以用如下命令去安装

sudo yum install -y glibc-static

我们可以明显的感觉到,静态链接以后,体积变大了。

image-20231031202940798

如果使用ldd,会显示不是动态的可执行程序

image-20231031203025128

前面是关于c语言的静态库,我们也可以装一下c++的静态库

sudo yum install -y libstdc++-static

4.一些问题

  1. 如果我们没有静态库,但是我们就要-static,行不行呢?

其实是不行的

  1. 如果我们没有动态库,只有静态库,而且gcc能找到静态库,能成功编译吗?

是可以的,因为gcc默认优先动态链接。-static的本质其实是改变优先级

注意:我们的程序不一定是纯的全部动态链接或者静态链接的,有可能是混合的

-static可以使得所有的链接要求全部变为静态链接,即只适配一次

5. file指令

我们可以直接使用file指令去查看是动态链接还是静态链接

image-20231031204217228

6.动静态链接的优缺点

动态库的优点

动态库因为是共享库,有效的节省资源(节省磁盘空间,内存空间,网络空间等)

动态库的缺点

动态库一旦缺失,导致各个程序都无法运行

静态库的优点

静态库,不依赖库,程序可以独立运行

静态库的缺点

体积大,比较消耗资源

五、debug和release

我们已经很清楚,debug可以被追踪调试

这是因为在形成可执行程序的时候,添加了debug信息

而release就无法进行调试

这就注定了debug的体积比较大

我们的gcc默认是release版本的,如果我们要生成debug版本的,要加上-g选项

image-20231031205934531

我们可以看到,无论是静态的还是动态的,在debug下都是要大一点的

我们可以去验证一下

我们可以用如下指令去将我们的可执行程序给以一种格式呈现出来

readelf -S test_debug

image-20231031210211308

然后我们结合管道,就可以看到,原来的是没有debug信息,而用debug的是有debug信息的

image-20231031210302172

扩展

可执行程序形成的时候,不是无序的二进制构成,是有自己的格式的,—可执行程序有自己的二进制格式—ELF格式

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQLITE3 函数接口

简述 sqlite3 接口的核心元素: 两大对象,八大函数; 其中两个对象指的是: sqlite3 数据库连接对象 数据库的连接句柄(数据库的文件描述符) 代表你打开的那个 sqlite3 的数据库文件,后序对数据库的操作都需要用到这个对象 sqlite3_stmt SQL 语句对象…

从「码农」到管理者,E人程序员的十年蜕变

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 场地支持 / 声湃轩北京录音间 当我们谈论程序员创业时,常常会首先想到一些传统观念认为的挑战:沟通技巧不佳、逻…

各种爱心特效代码免费分享

「链接:https://pan.xunlei.com/s/VNi9l3Mqp9oEflga1T6M-ZUOA1?pwdsam3# 提取码:sam3”复制这段内容后打开手机迅雷App,查看更方便」 「链接:https://pan.xunlei.com/s/VNi9lWqdFIwdtD5sdCDZFamoA1?pwdka8b# 提取码:…

集简云x slack(自建)无需API开发轻松连接OA、电商、营销、CRM、用户运营、推广、客服等近千款系统

slack是一个工作效率管理平台,让每个人都能够使用无代码自动化和 AI 功能,还可以无缝连接搜索和知识共享,并确保团队保持联系和参与。在世界各地,Slack 不仅受到公司的信任,同时也是人们偏好使用的平台。 官网&#x…

基于SSM的理发店管理系统

基于SSM的理发店管理系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringSpringMVCMyBatis工具:IDEA/Ecilpse、Navicat、Maven 系统展示 主页 公告信息 管理员界面 用户界面 摘要 基于SSM(Spring、Spring MVC、…

1. PPT高效初始化设置

1. PPT高效初始化设置 软件安装:Office 2019 主题和颜色 颜色可以在白天与黑夜切换,护眼 切换成了黑色 撤回次数 撤回次数太少,只有20次怎么办 自动保存 有时忘记保存就突然关闭,很需要一个自动保存功能 图片压缩 图…

TypeScript之装饰器

一、是什么 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上 是一种在不改变原类和使用继承的情况下,动态地扩展对象功能 同样的,本质也不是什么高大上的结构,就…

网络质量探测

目录 一.BFD监测网络状态 二. NQA检测网络状态 一.BFD监测网络状态 BFD(BidrectionaL Forwarding Detection 双向转发检测)用于快速检测系统设备之间的发送和接受两个方向的通信故障,并在出现故障时通知生成应用。BFD 广泛用于链路故障检测,并能实现与…

Python画图之皮卡丘

Python-turtle画出皮卡丘(有趣小游戏) 一、效果图二、Python代码 一、效果图 二、Python代码 import turtledef getPosition(x, y):turtle.setx(x)turtle.sety(y)print(x, y)class Pikachu:def __init__(self):self.t turtle.Turtle()t self.tt.pensi…

在虚拟机centos7中部署docker+jenkins最新稳定版

在虚拟机centos7中部署dockerjenkins最新稳定版 查看端口是否被占用 lsof -i:80 查看运行中容器 docker ps 查看所有容器 docker ps -a 删除容器 docker rm 镜像/容器名称 强制删除 docker rmi -f 镜像名 查看当前目录 pwd 查看当前目录下所有文件名称 ls 赋予权限 chown 777 …

回归预测 | Matlab实现WOA-CNN-SVM鲸鱼算法优化卷积神经网络-支持向量机的多输入单输出回归预测

回归预测 | Matlab实现WOA-CNN-SVM鲸鱼算法优化卷积神经网络-支持向量机的多输入单输出回归预测 目录 回归预测 | Matlab实现WOA-CNN-SVM鲸鱼算法优化卷积神经网络-支持向量机的多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.WOA-CNN-SVM鲸鱼算法…

STM32-RTC实时时钟

目录 RTC实时时钟 功能框图 UNIX时间戳 初始化结构体 RTC时间结构体 RTC日期结构体 RTC闹钟结构体 进入和退出配置函数 实验环节1:显示日历 常规配置 RTC配置 测试环节 实验现象 实验环节2:闹钟 常规配置 RTC配置 测试环节 实验现象 R…

【C/C++】仿函数

函数调用运算符 () 也可以重载由于重载后使用的方式非常像函数的调用&#xff0c;因此称为仿函数仿函数没有固定写法&#xff0c;非常灵活 示例&#xff1a; #include <iostream> #include <string> using namespace std;class MyPrint { public://重载的运算符是…

Antlr4学习笔记

背景 在阅读shardingjdbc-4.1.1代码时&#xff0c;发现一段sql解析的逻辑&#xff0c;好奇它的实现&#xff0c;查阅相关资料发现解析引擎基于Antlr4实现&#xff0c;便有了此文 官方文档中也描述了解析引擎的迭代过程 SQL解析作为分库分表类产品的核心&#xff0c;其性能和兼…

VSCode 如何设置背景图片

VSCode 设置背景图片 1.打开应用商店&#xff0c;搜索 background &#xff0c;选择第一个&#xff0c;点击安装。 2. 安装完成后点击设置&#xff0c;点击扩展设置。 3.点击在 settings.json 中编辑。 4.将原代码注释后&#xff0c;加入以下代码。 // { // "workben…

第4章_运算符

文章目录 1. 算术运算符1.1 加法与减法运算符1.2 乘法与除法运算符1.3 求模运算符 2. 比较运算符2.1 等号运算符2.2 安全等于运算符2.3 不等于运算符2.4 空运算符2.5 非空运算符2.6 最小值运算符2.7 最大值运算符2.8 BETWEEN AND运算符2.9 IN运算符2.10 NOT IN运算符2.11 LIKE运…

Mysql用sql查询数字四舍五入小数点后两位并且第二位如果没有数用0填补

表中数据小数点后几位好长&#xff0c;直接上图 核心sql REPLACE(FORMAT(ROUND(d2.jiner, 2), 2), ,, ) ROUND函数处理数字四舍五入 FORMAT处理小数点后面必须跟进两位&#xff0c;也就是第二位没数字的话用0填补 REPLACE处理将逗号全部去除&#xff0c;因为FORMAT会导致数字…

苹果相机怎么磨皮 苹果手机怎么磨皮

相信使用苹果相机的小伙伴都有这样的疑惑&#xff0c;苹果相机怎么磨皮&#xff1f;其实可以通过相机的参数进行设置从而达到磨皮的效果&#xff0c;如果觉得相机自带的设置磨皮效果不够好&#xff0c;可以下载磨皮软件来对照片磨皮。今天的文章就来给大家介绍苹果相机怎么磨皮…

【嵌入式项目应用】__cJSON基础介绍与代码测试

目录 前言 一、JSON是什么&#xff1f; 1. JSON 基本语法 2. JSON值(value)的类型 3. 逻辑值&#xff08;true 或 false&#xff09; 4. null 5. NUMBER 数字&#xff08;整数或浮点数&#xff09; 6. STRING 字符串&#xff08;在双引号""中&#xff09; 7…

在NestJS应用程序中使用 Unleash 实现功能切换的指南

前言 近年来&#xff0c;软件开发行业迅速发展&#xff0c;功能开关&#xff08;Feature Toggle&#xff09;成为了一种常见的开发实践。通过功能开关&#xff0c;可以在运行时动态地启用或禁用应用程序的特定功能&#xff0c;以提供更灵活的软件交付和配置管理。对于使用 Nes…