【Linux】Linux工具学习之gcc/g++

在这里插入图片描述
🔥博客主页 小羊失眠啦.
🎥系列专栏《C语言》 《数据结构》 《C++》 《Linux》 《Cpolar》
❤️感谢大家点赞👍收藏⭐评论✍️


在这里插入图片描述

接上文,我们已经学习了 Linux 中的编辑器 vim 的相关使用方法,现在已经能直接在 Linux 中编写C/C++代码,有了代码之后就要尝试去编译并运行它,此时就可以学习一下 Linux 中的编译器 gcc/g++ 了,我们一般使用 gcc 编译C语言,g++ 编译C++(当然 g++ 也可编译C语言),这两个编译器我们可以当作一个来学习,因为它们的命令选项都是通用的,只是编译对象不同。除了编译器相关介绍外,本文还会库、自动化构建工具、提权等知识,一起来看看吧

文章目录

  • 程序实现的两大环境
  • 一、gcc/g++使用
    • 1.1 gcc如何完成
      • 1.1.1 预处理
      • 1.1.2 编译
      • 1.1.3 汇编
      • 1.1.4 链接
  • 二、动态库与静态库
    • 2.1 动态库
    • 2.2 静态库
  • 三、自动化构建工具
    • 3.1 Makefile文件
    • 3.2 make指令
    • 3.3 任务刷新策略
    • 3.4 .PHONY伪目标
    • 3.5 补充
  • 四、sudo提权

程序实现的两大环境

任何一个C程序的实现都要经过翻译环境执行环境

在翻译环境中又分为4个部分,预编译、编译、汇编与链接。在各个阶段主要完成的任务有:

  1. 预编译(预处理):头文件的包含、注释的删除、#define符号的替换;

  2. 编译:将C语言代码转化为汇编代码;

  3. 汇编:把汇编指令转化为二进制指令;

  4. 链接:合并符号表和段表,生成可执行程序。

在这里插入图片描述

一、gcc/g++使用

1.1 gcc如何完成

通过gcc指令的不同选项可查看各阶段所形成的文件;

格式:gcc [选项] [目标文件名] -o [生成文件名]

首先在test.c文件中写好C代码:

#include<stdio.h>#define N 100//#define ...int main()
{int n = 0;printf("Hello World\n");printf("%d\n", n + N);return 0;
}

1.1.1 预处理

查看 test.c 预处理后的结果,-E选项的作用是让 gcc 在预处理结束后停止编译过程;-o 的作用是将预处理后的内容保存到test.i 文件中。

gcc -E test.c -o test.i

在这里插入图片描述

如图所示,预处理阶段进行了头文件包含、注释的删除、#define的替换。

1.1.2 编译

接下来将刚刚生成的 test.i 进行编译,并在编译之后停下来,将结果写入 test.s 中。gcc所用选项为 -S。

gcc -S test.i -o test.s

在这里插入图片描述

我们虽然可能没学习过汇编语言,但依旧隐约认识到这些就是汇编代码;可见编译阶段就是将C代码翻译为汇编指令。

1.1.3 汇编

gcc所用选项为 -c;-o 将结果写入到 test.o 中。

gcc -c test.s -o test.o

在这里插入图片描述

正如我们所见,汇编完成之后都这这样的乱码。其实汇编之后,生成的文件为二进制文件,是用来给计算机看的,咱们已经看不懂了。

1.1.4 链接

编译完成之后就进入了链接阶段,链接完成之后就会生成可执程序 mytest了。

gcc test.o -o mytest

在这里插入图片描述

但是关于链接,我们需要知道它在链接什么。

我们是否好奇过为什么我们明明没有定义过函数 printf 、return …等等的函数,但却可以使用它的功能?

其实,系统把这些函数的实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函 数 printf 了,而这也就是链接的作用。


二、动态库与静态库

函数库一般分为动、静态库两种。

2.1 动态库

动态库 即通过 动态链接 的库,动态库 又称 共享库,因为 动态库 中的内容是被所有程序共享的,简言之 动态库 中的代码只需要存在一份,程序需要使用时,直接通过对应位置调用就行了

gcc 进行函数库的链接时可选择静态链接或者动态链接

Linux 中默认使用 动态链接 的方式,我们可以通过指令 ldd 最终生成的文件 来查看最终生成文件的链接情况

在这里插入图片描述

libXXX.so 是动态链接的标志

  • 其中 lib 是前缀
  • .so 是后缀
  • 去掉前缀与后缀,就是最终调用的库

举例:libc.so 去掉前缀与后缀,最终为 c ,可以看出文件最终调用的是C语言共享库,即 动态链接

动态链接 主要依赖不同函数在库中的位置信息进行调用,只有一份代码库,比较节省空间

我们还可以通过 file 命令查看文件详细信息

在这里插入图片描述

这也验证了 Linux 默认使用 动态链接 的现象

2.2 静态库

除了 动态库 外,还有静态库 ,采用静态链接的方式;静态链接不同与动态链接共享的方式,如果程序调用静态库,会将自己所需要的代码拷贝至程序中,完成拷贝后,后续不需要再调用 静态库

如果想采用 静态链接 链接的方式编译程序,需要在编译时加上 -static 选项,当然前提是得有 静态库,没有的可以通过 yum install -y glibc-static 下载 静态库

当然我们也可以通过 ldd 最终生成的文件 查看是否为 静态链接

#下载静态库
yum install -y glibc-static
#采取静态链接的方式编译程序
gcc -static test.c -o Test_static
#查看文件的链接方式
ldd Test_static

在这里插入图片描述

静态库 命名为 libXXX.a

  • lib 是前缀
  • .a 是后缀
  • 去掉前缀与后缀,就是最终调用的库

我们也可以采用 file 命令查看详细信息

file Test_static

在这里插入图片描述

静态链接 因为是直接将需要的代码拷贝到程序中,因此最终生成的文件会变大,比较占空间

对比二者生成的文件大小

#采用静态链接
gcc -static test.c -o Test_static
#默认采用动态链接
gcc  test.c -o Test

若在静态链接时出错,可能是因为你的 Linux 没有安装C语言的静态库,须手动安装。

在这里插入图片描述

两种连接方式生成的文件大小几乎相差百倍。

优劣对比

动态库静态库 各有优缺点,不然也不会同时存在两种库了

区别动态库静态库
调用方式通过函数位置进行调用直接将需要的函数拷贝至程序中
依赖性(运行时)需要依赖于动态库可以独立于静态库运行
空间占用共享动态库中的代码,空间占用少拷贝代码会占用大量空间
加载速度调用函数,加载速度慢直接运行,加载速度快

小结

动态库

  • 优点
    • 可以实现不同进程间的资源共享
    • 对于函数的升级只需要替换动态库文件,不需要重新编译程序
    • 可以控制是否加载动态库,不调用函数时就不加载
  • 缺点
    • 需要调用函数,加载速度较慢
    • 程序运行需要依赖动态库

静态库

  • 优点
    • 所需函数直接拷贝至程序中,运行速度快
    • 程序运行无需依赖库,便于移植
  • 缺点
    • 对于函数的升级,需要重新进行编译
    • 同一份代码可能出现重复拷贝的情况,浪费空间

三、自动化构建工具

自动化构建工具可以帮助我们完成设置好的指令,指令为 make ,我们可以通过提前设置,实现源文件的快速编译

3.1 Makefile文件

要想使用 make 指令,就得先有 Makefile 文件,Makefile 文件中主要编写任务,而任务由 依赖关系 + 依赖方法 构成

1.依赖关系

  • 比如源文件为 test.c ,编译后生成的文件为 mytest ,那么两者间的 依赖关系mytest:test.c 这组 依赖关系 我们可以写入 Makefile 文件中

2.依赖方法

  • 有了关系后,就要描述具体实现方法,比如上面那组 依赖关系依赖方法gcc test.c -o mytest依赖方法 也写入 Makefile 文件中

在这里插入图片描述

完成上面两个内容的编写后,我们就得到了一个基本的自动化任务,输入 make mytest 即可编译 test.c 文件,生成 mytest

#执行自动化指令,编译test.c文件
make mytest

在这里插入图片描述

注意: 同一个自动化任务,执行成功后,如果相关文件最近没有发生改变,那么无法再次执行自动化任务

3.2 make指令

上面展示了如何编写 Makefile 文件并执行相关任务,使用了 make file 指令,并没有直接使用 make指令,因为这个指令还是有些说法的

单纯输入 make 指令时,默认执行 Makefile 中的第一个任务,当任务成功执行后,不再继续执行后续任务(一个 Makefile 文件中,可以有多个任务),由此可见,单纯的 make 指令只会执行第一个自动化任务

在这里插入图片描述

在这里插入图片描述

当我们编写好 Makefile 文件后,可以通过 make 任务名 调用任务,任务名就是 依赖关系 中的左侧名;也可以直接通过 make 调用第一个任务

3.3 任务刷新策略

前面说过,同一个方法如果成功执行过,在原文件最近修改时间没有发生变化时,无法再执行任务,这背后的原因是方法是否执行会先判断生成的目标文件是否为最新,如果为最新,就不再执任务

举例:重复执行 make myfile 任务

make myfile    //第一次执行任务,成功
make myfile    //第二次执行任务,失败,因为源文件最近没有被修改

在这里插入图片描述

想要再次执行任务也很简单,对源文件做出修改,或者直接 touch 一下源文件就行了,两种行为都会修改文件的最近修改时间,使源目标文件不是最新时间

3.4 .PHONY伪目标

.PHONYMakefile 文件中的一个关键字,意为对某某对象生成伪目标,这样就能在不对源文件进行修改的情况下,重复执行任务了

//Makefile文件中
.PHONY:mytest

在这里插入图片描述

在这里插入图片描述

在使用关键字 .PHONY 对目标进行修饰后,可以无视任务刷新策略,重复执行任务了

不过这有什么意义呢?
答:对于这种源文件来说,没有任何意义

.PHONY 这个关键字,一般是用来修饰 clean 任务,即清理解决方案,Makefile 实现为

//Makefile 文件中
.PHONY:clean
clean:rm -r mytest

在这里插入图片描述

在这里插入图片描述

换个角度想想,当我们把生成的原目标文件清理后,再执行任务,生成目标文件是一件很合理的事,也完全符合任务刷新策略

由此来看,.PHONY 也是很有用的

注意: clean:这种半缺失 依赖方法 是合理的,毕竟清理这个任务也不需要任何对象,只需要单纯的执行删除(清理)指令就行了

3.5 补充

make 指令的工作原理是去 Makefile 文件中寻找任务执行,它的设计者为了确保普适性,创建 makefile 文件也是合法可用的

也就是说,我们创建 make 指令的任务源文件时,可以创建为 Makefile ,也可以创建为 makeile

四、sudo提权

权限,是一个让人又爱又恨的东西,它的安全性固然很重要,但有时候又太麻烦了,当我们普通用户想执行操作时,需要请 root 出马,比如最基本的下载软件指令,感觉有些小题大做了

为了解决这种不合理的现象,Linux 中就有 sudo 提权 这个概念,简单来说,就是暂时借助 root 的身份去完成某条指令

在这里插入图片描述

不过普通用户默认是没有赋予提权权限的,还是需要请 root 帮忙配置
步骤如下

  • 切换为 root 用户
  • 打开 /etc/sudoers 这个文件
  • 找到如下图所示区域,将需要提权的普通用户添加进去就行了

在这里插入图片描述

//root 身份下
vim /etc/sudoers    //打开这个配置文件,找到上图区域进行修改就行了

提权 配置完成后,普通用户遇到权限拒绝的场景时,只需要 sudo 指令 ,然后输入当前普通用户的密码,就可以暂时借助 root 的身份无视权限完成指令了

注意: sudo 后,输入的是当前普通用户的密码,不需要输入 root 密码,这样就能做到保护 root 的情况下,执行指令了

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WordPress Plugin NotificationX插件 SQL注入漏洞复现(CVE-2024-1698)

0x01 产品简介 WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。 0x02 漏洞概述 WordPress plugin NotificationX是一个应用插件。2.8.2版本及之前 存在安全漏洞,该…

【RAG实践】基于 LlamaIndex 和Qwen1.5搭建基于本地知识库的问答机器人

什么是RAG LLM会产生误导性的 “幻觉”&#xff0c;依赖的信息可能过时&#xff0c;处理特定知识时效率不高&#xff0c;缺乏专业领域的深度洞察&#xff0c;同时在推理能力上也有所欠缺。 正是在这样的背景下&#xff0c;检索增强生成技术&#xff08;Retrieval-Augmented G…

第八篇【传奇开心果系列】Python自动化办公库技术点案例示例:深度解读使用Python库清洗处理从PDF文件提取的文本

传奇开心果博文系列 系列博文目录Python自动化办公库技术点案例示例系列 博文目录前言一、Python清洗处理文本的常见步骤二、使用Python库去除非文本元素示例代码三、使用Python库去除格式化元素的示例代码四、使用Python库去除空白字符示例代码五、使用Python库合并段落和行示…

Oracle P6 Professional 配置连接数据库总结

前言 P6 Professional作为Oracle P6计划管理系统的重要套件之一&#xff0c;其操作出色&#xff0c;体检佳&#xff0c;是非常多的计划工程师跟踪项目进度计划的辅助工具。自20年前&#xff0c;Professional一直在不断的演变更新&#xff0c;以适应当前的新技术&#xff0c;从…

什么是可回收箱?可回收箱能回收哪些物品?具有哪些功能?

可回收箱是指专门用于收集居民或单位产生的、适宜回收和资源化利用的废弃物的容器。这些箱子通常会按照垃圾分类的标准进行设计&#xff0c;贴有明确标识&#xff0c;不同类型的可回收箱可能在开口大小、形状等方面有所不同&#xff0c;以适应不同类型可回收物的投放需求&#…

电源配小了,是不是容易烧?是的!

电源小的话会不会容易烧毁&#xff1f; 是的。 功率电压*电流。 随着功率增大&#xff0c;电压不变&#xff0c;电流增大&#xff0c;发热量增大&#xff0c;可能会烧毁。 今天给大家推荐一款650w的电脑电源&#xff0c;不过在推荐之前&#xff0c;首先要确认自己的电脑功耗…

制造业工厂为什么需要生产管理MES系统

一、制造业的生产管理需求与痛点 日趋激烈的市场竞争、客户对产品多样化要求越来越高&#xff0c;导致产品的生命周期缩短&#xff0c;企业需要通过智能制造实现降本、增效、提质&#xff0c;以提高企业的快速响应能力和核心竞争力。 二、生产管理的过程的痛点具体表现如下&am…

ES的集群节点发现故障排除指南(1)

本文是ES官方文档关于集群节点发现与互联互通的问题排查指南内容。 英文原文&#xff08;官网&#xff09; 集群节点发现是首要任务 集群互连&#xff0c;重中之重&#xff01; 在大多数情况下&#xff0c;发现和选举过程会迅速完成&#xff0c;并且主节点会长时间保持当选状…

Jmeter-基础元件使用(二)-属性及对数据库简单操作

一、Jmeter属性 当我们想要在不同线程组中使用某变量&#xff0c;就需要使用属&#xff0c;此时Jmeter属性的设置需要函数来进行set和get操作 1.创建set函数 2.然后采用Beanshell取样器进行函数执行 3.调用全局变量pro_id 4.将上面生成的函数字符串粘贴到另一个线程组即可…

Python数学建模-2.9Matplotlib库

Matplotlib库是Python中一个非常流行的绘图库&#xff0c;它提供了大量的绘图工具&#xff0c;可以生成各种类型的静态、动态、交互式的图表。Matplotlib的设计初衷是为了与NumPy配合使用&#xff0c;从而提供一个强大的数学绘图工具。 1.Matplotlib的主要特点 丰富的图表类型…

java 抽象

在进入抽象的学习之前&#xff0c;先看下面的代码&#xff0c;有一个Animal类&#xff0c;并且有一个eat方法&#xff0c;我们可以通过 Animal animal new Animal(); 来创建一个动物类对象。 public class Animal {public void eat(){System.out.println("动物吃东西&qu…

Github: Github actions自动化工作原理与多workflow创建和部署

Github actions 1 &#xff09;概述 Github Actions 是Github官方推出的 CI/CD 解决方案 https://docs.githu.com/en/actions 优点 自动发布流程可减少发布过程中手动操作成本&#xff0c;大幅提升ci/cd效率&#xff0c;快速实现项目发布上线 缺点 存在较高的技术门槛需要利用…

ARM_基础之RAS

Reliability, Availability, and Serviceability (RAS), for A-profile architecture 源自 https://developer.arm.com/documentation/102105/latest/ 1 Introduction to RAS 1.1 Faults,Errors,and failures 三个概念的区分&#xff1a; • A failure is the event of devia…

UE4 Json事件设置Asset值

通过Json事件来设置&#xff0c;比如骨骼网格体&#xff08;换皮&#xff09;等等

webpack5零基础入门-10babel的使用

Babel JavaScript 编译器。 主要用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 语法&#xff0c;以便能够运行在当前和旧版本的浏览器或其他环境中 1.安装相关包 npm install -D babel-loader babel/core babel/preset-env 2.进行相关配置 2.1第一种写法是在webp…

基于yolov5的单目测距实现与总结+相机模型+标定

写这篇文章的目的是为了总结我之前看的标定&#xff0c;相机模型以及单目测距的内容&#xff0c;如果有错误&#xff0c;还请不吝赐教。 参考链接&#xff1a; 相机模型、相机标定及基于yolov5的单目测距实现 深度学习目标检测目标追踪单目测距 单目测距代码部署&#xff08;目…

操作系统:malloc与堆区内存管理

malloc是函数而不是系统调用&#xff0c;他的底层是同调调用brk和mmap这两个系统调用实现功能的&#xff0c;具体选择brk还是mmap要看申请的空间大小以及malloc中的阈值&#xff08;一般是128kb&#xff09; 注意申请的空间只有使用才会触发缺页中断映射到物理内存 不理解的话先…

流畅的 Python 第二版(GPT 重译)(十二)

第五部分&#xff1a;元编程 第二十二章&#xff1a;动态属性和属性 属性的关键重要性在于&#xff0c;它们的存在使得将公共数据属性作为类的公共接口的一部分完全安全且确实可取。 Martelli、Ravenscroft 和 Holden&#xff0c;“为什么属性很重要” 在 Python 中&#xff0…

鸿蒙开发实战:【Faultloggerd部件】

theme: z-blue 简介 Faultloggerd部件是OpenHarmony中C/C运行时崩溃临时日志的生成及管理模块。面向基于 Rust 开发的部件&#xff0c;Faultloggerd 提供了Rust Panic故障日志生成能力。系统开发者可以在预设的路径下找到故障日志&#xff0c;定位相关问题。 架构 Native In…

成为高效Java工程师的干货笔记

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流&#xff0c;摸鱼划水的小伙伴&#xff0c;请点击【全栈技术交流群】 作为一名Java工程师&…