【Linux】认识Linux下的编译器gcc/g++ | 认识动静态库

news2024/11/28 1:32:04

本文思维导图:
在这里插入图片描述

文章目录

  • 前言
    • tips: 关于前两篇文章所提到的sudo指令
  • 一、gcc/g++编译器的认识和使用
      • tips
    • 1.预处理
    • 2. 编译
    • 3.汇编
    • 4.链接
      • 关于预编译,编译,汇编阶段的指令记忆方法
  • 二、gcc/g++指令汇总
  • 三、认识动静态库
    • 1.库的认知
      • 库的命名规则
      • 静态库安装方法
    • 2.什么是动静态库
    • 3.动静态库优缺点
    • 4.链接方式
  • 总结


在这里插入图片描述

🍉博主主页:@在肯德基吃麻辣烫

前言


tips: 关于前两篇文章所提到的sudo指令

我们知道,sudo指令后面紧跟的一条指令,该条指令是以root身份执行的对于有一些我们普通用户无法执行的指令,就需要用到该指令进行提权。

sudo + 指令
功能:以管理员身份执行该条指令

比如:

sudo touch mycode.c

然而我们执行该条指令时,却发现这样的问题:
在这里插入图片描述
意思是说张三这个用户不在sudoers这个文件当中。

举个例子:学校门口保安对认识的人他可以不问这个人是干什么的,直接就给放行了, 对不认识的人会询问,问完之后还是不给放行。
对一些做过坏事并且被保安记住的人,问都不问,一定不给放行。

上面三种情况分别就是生活中的白名单,普通人,黑名单

所以我们需要将zhangsan这个用户添加到Linux系统信任的白名单里面,才可以使用sudo指令提权。(必须是root用户才可以添加名单)

步骤:

1.在root用户下输入:
vim /etc/sudoers --使用vim编辑器打开etc目录下的sudoers文件,
按shift+;进入底行模式,输入set nu,配置一下,相当于给该文件标记了行号:
在这里插入图片描述
按Esc退出底行模式,进入命令模式输入100+shift+g,将光标移动到大概100行的位置
在这里插入图片描述
快速按两次yy指令复制root行的指令,再按p粘贴,随后进入插入模式,将张三的用户名字添加进去即可。
在这里插入图片描述
shift+;进入命令模式,wq!保存并强制退出即可。
此时zhangsan用户成功被添加到系统所信任的白名单中。

再次以zhangsan的身份执行

sudo touch code1.c

即可提权到root下执行touch code1.c指令

在这里插入图片描述

一、gcc/g++编译器的认识和使用

tips

为什么我们可以在Windows或者Linux上编译C/C++代码呢?

实际上,我们有Visual Studio 编译器还不行,还需要有各种头文件和库文件来共同支撑配合才能够实现编译C/C++的代码。

所以我们在安装编译器的时候,顺带已经安装了各种头文件和库文件。

一个.c文件会经过预编译(预处理),编译,汇编,链接等主要步骤最终才会生成可执行程序。
下面来逐一讲解:
在这里插入图片描述

1.预处理

预处理阶段会做一下几个工作:

去掉注释
头文件展开
条件编译
宏替换

指令:

gcc -E code.c -o code.i

将code.c文件经过预编译器进行预处理后,得到一个干净的文件。

  • -E:预编译指令,后面紧跟的是待预编译文件
  • -o:生成的目标文件指令前缀,后面紧跟的是生成的目标文件的名字

比如:
样例代码:

  1 #include<stdio.h>                                           
  2 #define M 100                                                  
  3 int main()                                                     
  4 {                                                         
  5 #ifdef DEBUG                                                                            
  6                                                                
  7     printf("Hello Linux:aaa,%d\n",M);                          
  8 #else                                                     
  9     printf("Hello Linux\n");                                                           
 10 #endif                                                                                         
 11     //printf("Hello Linux\n");                                 
 12     //printf("Hello Linux\n");                                               
 13     //printf("Hello Linux\n");                                 
 14     //printf("Hello Linux\n");                                           
 15     //printf("Hello Linux\n");                                  
 16     //printf("Hello Linux\n");                                 
 17     //printf("Hello Linux\n");                            
 18     //printf("Hello Linux\n");                                 
 19     printf("Hello Linux:bbb\n");                               
 20     printf("Hello Linux:ccc\n");                                                           
 21     return 0;                                                               
 22 }                                                                                                                        
                                    

在经过预编译阶段后,形成的code.i文件如下:
在这里插入图片描述

对比发现,code.i文件有800多行代码,这是因为头文件的内容被拷贝到code.c文件去了。

在code.c文件所注释的内容也同样被去掉了,定义的宏最终被替换掉。
经过条件编译后,只留下一条语句。

这个过程就是code.c文件经过预编译所发生的动作。

2. 编译

编译阶段是将预编译生成的code.i文件经过编译器生成code.s文件
指令:

gcc -S code.i -o code.s

  • -S:编译指令,后面紧跟的是待编译文件
  • -o:生成的目标文件指令前缀,后面紧跟的是生成的目标文件的名字
  • .s后缀:编译完成后生成的汇编语言

打开code.s文件,内容是这样的:
在这里插入图片描述

这个过程是编译器将code.i文件编译后生成的汇编文件code.s

3.汇编

汇编过程是将汇编文件code.s翻译成二进制机器码给机器进行识别。

指令:

gcc -c code.s -o code.o

  • -c:汇编指令,后面紧跟的是待汇编操作文件
  • -o:生成的目标文件指令前缀,后面紧跟的是生成的目标文件的名字
  • .o后缀:编译完成后生成的二进制机器码,叫做可重定位二进制目标文件

打开二进制机器码,我们是看不懂的,因为vim是文本编辑器,只认识文本,不认识二进制。
在这里插入图片描述
不过我们还可以用一条指令以二进制的方式打开:

od code.o

  • od:以二进制的方式打开code.o文件
    在这里插入图片描述

注意:.o文件是不能独立执行的。
需要经过链接才能执行。

4.链接

链接过程是将汇编生成的.o文件经过和动态库/静态库的连接后,生成的可执行程序,这个过程就是链接。

指令:

gcc code.o -o code

  • -o:生成的目标文件指令前缀,后面紧跟的是生成的目标文件的名字,这里是将可执行程序命名为code,如果不命名,默认生成 a.out可执行程序
  • .o后缀:编译完成后生成的二进制机器码,叫做可重定位二进制目标文件

关于预编译,编译,汇编阶段的指令记忆方法

指令记忆方法:可以看键盘左上角的Esc按键,对应的Linux指令是:ESc

文件后缀记忆方法:参考国际标准化组织(iso)或者镜像文件后缀(.iso),与指令一一对应来记忆。

总结:
上面的内容讲述了一个.c文件经过gcc编译器分别进行预编译,编译,汇编,链接等主要步骤后,生成可执行程序/文件的过程。

注意:上述过程可以一步一步往下走,也可以从头开始直接走到对应的过程。

比如:汇编阶段,可以用编译阶段生成的.s文件来作为待汇编文件,也可以直接使用最原始的.c文件直接经过预编译,编译,汇编的过程

二、gcc/g++指令汇总

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

三、认识动静态库

1.库的认知

库其实是由许许多多源文件经过一定的编译,打包后形成的。
只需要提供一个.c库文件,不需要再提供许多其他的源文件,库的存在提高了代码使用的便利性,使用别人打包好的库,可以帮助我们事半功倍地提高工作效率。同样c++的库也是由许多.cpp源文件经过一定的编译打包后形成库,只对外开放一个库文件即可。

这样也解释了gcc编译器会自动去寻找.c的库,g++编译器会去寻找.cpp的库,gcc编译器默认并不认识.cpp的库,所以让gcc编译c++的代码是行不通的。

库的命名规则

在Linux中,动态库的命名规则一般是:

  • libname.so.XXX/libname.so——动态库
  • libname.a——静态库

其中:

lib是前缀,.so.XXX/.so是后缀
真正的动态库名字只有name那一部分
对于静态也是如此

比如:
在这里插入图片描述

这个就是c的动态库。

在这里插入图片描述
静态库如上。

静态库安装方法

sudo yun install -y glibc-static

2.什么是动静态库

对于动态库(也叫共享库):动态库就像是一个网吧,可执行程序就像是网民,网名想要上网必须去到网吧,可执行程序想要运行,就必须去到动态库中将动态库的地址拷贝到本地,通过地址获取内容,达到链接的目的。

对于静态库:静态哭就像是一台电脑,可执行程序就像是网民,网名直接将电脑买回家中,就相当于可执行程序直接将静态库的内容直接拷贝到本地,达到链接的目的。

3.动静态库优缺点

动态库优缺点:
优点:可执行程序只是拷贝动态库的地址,通过地址获取内容,大大减少了内存消耗,节省资源(磁盘空间,内存空间,网络空间)
缺点:一旦动态库缺失,所有使用动态库的可执行程序将无法运行。

静态库优缺点:
优点:静态库是否缺失与可执行程序无关,即使静态库缺失,可执行程序仍然可以运行。
缺点:可执行程序将静态库的内容直接拷贝到本地,大大增加了资源消耗(磁盘空间,内存空间,网络空间)。

系统默认优先使用动态库。

4.链接方式

  • 动态链接
  • 静态连接

动态库只能使用动态链接,静态库只能使用静态链接。

动态链接:

gcc code.c -o code

静态链接:

gcc code.c -o code_static -static

1.链接成功后,使用下面的指令查看是否使用动态库:

ldd code

在这里插入图片描述

2.还可以使用下面指令查看:

file code
file code_static

在这里插入图片描述

从第二点所讲到,静态链接的可执行程序是要比动态链接的可执行程序要大的。
在这里插入图片描述

总结:

  • 1.如果没有静态库,但是仍然要-stataic,行不通。
  • 2.如果有动态库和静态库,默认优先动态库,但是如果加了-staitc,那就先使用静态库,-static的本质是改变优先级,并且只能使用静态链接方案。
  • 3.动态链接和静态链接不一定是纯的,可能是动态链接静态链接混合。

总结

1.实际上,我们可以直接使用gcc code.c一步到位生成可执行程序,不过多了解具体做什么还是更有优势的。
2.对于动静态库,现在只需要掌握认识动静态库和动态链接静态链接以及它们的优缺点即可。
3.对于g++编译器,其指令和过程与gcc是几乎一样的。

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

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

相关文章

C++ ---- 继承

目录 继承概念及定义 继承概念 继承定义 语法 继承关系和访问限定符 继承基类成员访问方式的变化 规律总结 以公有继承为例测试 基类和派生类对象赋值转换 继承中的作用域 派生类的默认成员函数 构造函数 析构函数 拷贝构造 赋值重载 继承与友元 继承与静态成员…

ESP8266调用NTP服务器进行时间校准

一、背景知识 【1】什么是NTP服务器&#xff1f; NTP是网络时间协议&#xff08;Network Time Protocol&#xff0c;简称NTP&#xff09;&#xff0c;是一种用于同步计算机时间的协议。NTP服务器指的是提供NTP服务的计算机或设备。NTP服务器的主要功能是保证网络上的所有设备…

Linux下信号量使用总结

目录 1.Linux下信号量简介 2.POSIX信号量 2.1 无名信号量 2.2 有名信号量 3.System V信号量 1.Linux下信号量简介 信号量是解决进程之间的同步与互斥的IPC机制&#xff0c;互斥与同步关系存在的症结在于临界资源。 临界资源是在同一个时刻只容许有限个&#xff08;一般只有…

ble系统知识介绍(较为完整,持续更新中)

BLE学习 现在网上关于BLE系统的学习资料实在是太少了&#xff0c;因此本文希望能够聚集一些资料能够系统的入门BLE,本文翻译自Bluetooth_LE_Primer_Paper,还有一些网上的一些资料,如果侵害到了某些作者的权益请及时联系我 参考资料和链接 Bluetooth_LE_Primer_Paper_3MtXws-zP…

GitOps 实践之渐进式发布

本文作者&#xff1a;陈钧桐 腾讯云 CODING DevOps 高级解决方案架构师&#xff0c;从事多年技术布道工作&#xff0c;对于云原生时代下企业数字化转型、IT 与 DevOps 建设、价值流体系搭建等有丰富的经验&#xff0c;曾为多家大型企业提供咨询、解决方案以及内训服务。既关注工…

【Python小技巧】加密又提速,把.py文件编译为.pyd文件(类似dll函数库),你值得拥有!

文章目录 前言一、常见的Python文件格式有哪些&#xff1f;二、准备编译环境1. 安装cython2. 安装Microsoft C 生成工具 三、编译.py文件为.pyd文件1. 编辑原始.py文件2. 准备setup.py文件3. 进行编译 四、测试总结 前言 Python的脚本文件是开源的&#xff0c;若直接发布&#…

i.MX RT1010跨界MCU上手体验(上)

由于项目需要性价比高一些的高性能MCU&#xff0c;了解到NXP的RT1010主频高达500MHZ的MCU&#xff0c;半个月以前已经拿到官方Demo板了&#xff0c;今天抽空上电体验下&#xff0c;在此记录。这颗芯片的优势是主频高&#xff0c;功能全&#xff0c;价格合理&#xff0c;但是需要…

第六章 方法区

文章目录 前言一、&#x1f6fa; 栈、堆、方法区的交互关系二、&#x1f68e; 方法区的理解1、方法区在哪里2、方法区的演变过程 三、&#x1f697; 设置方法区的大小与 OOM1、设置方法区内存的大小2、使用CGLib 让方法区OOM3、如何解决 OOM4、方法区的内部结构5、non-final 的…

利用提示工程优化软件架构:ChatGPT的应用

ChatGPT时代的软件架构全生命周期 简介 在如今日新月异的技术环境中&#xff0c;软件架构师必须不断地寻找和采纳新的工具和方法&#xff0c;以优化开发过程&#xff0c;提高效率&#xff0c;并保证最终产出的质量。其中&#xff0c;人工智能&#xff08;AI&#xff09;已经成…

《淘宝技术这十年》读书笔记

一. 分布式时代 在系统发展的过程中&#xff0c;架构师的眼光至关重要&#xff0c;作为程序员&#xff0c;只要把功能实现即可&#xff0c;但作为架构师&#xff0c;要考虑系统的扩展性、重用性&#xff0c;对于这种敏锐的感觉&#xff0c;有人说是一种“代码洁癖”。淘宝早期…

使用双屏时两个屏幕的色调、亮度不一样如何设置?

当使用双屏时&#xff0c;即使两个屏幕的型号一致也可能存在色差的问题&#xff08;色调不一致&#xff0c;亮度不一致&#xff09;&#xff0c;以下是解决此问题的方法。 Step1.同时按下两个屏幕下方的ok按钮 Step2.此时会进入显示器的OSD界面 Step3.通过按键切换菜单 Step4.…

节省35% MCU开发成本的红外智能洗手器运用方案,N9300-S16音乐芯片

随着全国人民生活水平的逐步提升以及近期疫情影响&#xff0c;公民的健康保护意识也越来越强&#xff0c;洗手液越来越被人们重视以及提倡&#xff0c;即时在受疫情影响是2022年洗手液市场规模也是上升至恐怖34亿元产值&#xff1b;而近年来自动感应洗手液器凭借实用性、便携性…

APP测试面试题快问快答(三)

11. App安装测试的主要内容有哪些&#xff1f; App是客户端程序&#xff0c;客户端程序就需要进行安装才能使用&#xff0c;因此需要测试安装、卸载、升级测试 关注点&#xff1a;正常场景、异常场景。 正常场景&#xff1a; 1. 在不同的操作系统上安装 2. 从不同的安装渠…

windows10安装ElasticSearch

一 安装 Java环境 ElasticSearch使用Java开发的&#xff0c;依赖Java环境&#xff0c;安装 ElasticSearch 之前&#xff0c;需要先安装一个较新版本的 Java&#xff0c;jdk 1.8版本太低了&#xff0c;需要安装jdk 11或更高版本。 Java安装方法请参考 Java 15环境安装 。 二 …

详解字典树原理,代码分析leetcode208. 实现 Trie (前缀树)

0、引言 本文介绍一种能够偶快速查找字符串的树形数据结构-----字典树。介绍其原理&#xff0c;以及通过leetcode208题目这个实例&#xff0c;用数组动手实现一棵字典树&#xff0c;并完成其增、查字符串、查字符串前缀的功能。 1、字典树的应用场景 询问一个单词b&#xff0c…

Mujoco 加载机器人模型(三)

目录 .1 简介 1.1 urdf概述 ​编辑 1.2 导出urdf为可用的xml​编辑 1.3 导出测试​编辑 .2 修改 2.1 添加平面和物体 2.2 关节修改 2.2.1 group 2.2.2 关节修改 2.2.3 关节 解压提供的ur5后 修改compiler的 meshdir路径 <mujoco model"ur5"><compi…

一条耗时100ms的SQL把系统搞崩了

一个项目上线了两个月&#xff0c;除了一些反馈的优化和小Bug之外&#xff0c;项目一切顺利。前期是属于推广阶段&#xff0c;可能使用人员没那么多&#xff0c;当然对于项目部署肯定提前想到并发量了&#xff0c;所以早就把集群安排上&#xff0c;而且还在测试环境搞了一下压测…

2023年的深度学习入门指南(15) - 大模型的幻觉

2023年的深度学习入门指南(15) - 大模型的幻觉 大模型的能力最另人惊讶的&#xff0c;一个是强大的能力&#xff0c;另一个就是时不时一本正经地胡说八道。如果你用的是小一点的模型&#xff0c;可能还见过输出循环内容之类的情况。我们将这种生成不良内容的现象称为幻觉-hall…

3d动画用云渲染靠谱吗?

3d动画是一种利用计算机技术制作的动画形式&#xff0c;它可以模拟真实世界的物体和场景&#xff0c;创造出各种惊人的效果和视觉体验。3d动画广泛应用于影视、游戏、广告、教育等领域&#xff0c;成为当今最流行的艺术表现形式之一。据统计&#xff0c;2019年全球3d动画市场规…

吴恩达老师《机器学习》课后习题1之线性回归

在学习这些内容之前&#xff0c;需要学习python数据分析相关内容&#xff1a; numpy&#xff1a;科学计算库&#xff0c;处理多维数组&#xff0c;进行数据分析 pandas&#xff1a;基于numpy的一种工具&#xff0c;该工具是为了解决数据分析任务而创建的 matplotlib&#xff1a…