Linux学习之基础工具二

经过学习我们已经大致的学会了vim的使用,可以利用vim进行代码的编写了,在学习c语言的时候我们就知道,编译完成一个代码需要进行四个步骤:

1. 预处理(进行宏替换)
2. 编译(生成汇编)
3. 汇编(生成机器可识别代码)
4. 连接(生成可执行文件或库文件)

那么在Linux下是如何进行的呢?

通过vim进行代码的编写,通过gcc/g++进行代码的,预处理,编译,汇编链接。

目录

1.Linux编译器-gcc/g++使用

1.什么是gcc?

2. gcc如何实现

预处理(进行宏替换)

编译(生成汇编)

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

连接(生成可执行文件或库文件)

动静态库的理解与概念

3.Linux项目自动化构建代码

1.make/Makefile是什么?

2.伪目标

3.文件的三个时间属性

4.Makefile的自动推导

5.语法扩展


1.Linux编译器-gcc/g++使用

1.什么是gcc?

GCC(GNU Compiler Collection)是GNU工具链的关键组件,是与GNU、Linux相关项目的标准编译器。它最初仅用于处理C语言,紧接着扩展到C++、Objective-C/C++、Fortran、Java、Go等编程语言。GCC是一个可移植的编译器,支持多种硬件平台,例如ARM、X86等等。GCC不仅是个本地编译器,它还能跨平台交叉编译。

明白了gcc是一个最初 编译c语言的编译器,我们对于g++也就知道是对c++的编译器。

2. gcc如何实现

格式 : gcc [选项] 要编译的文件 [选项] [目标文件]

预处理(进行宏替换)

预处理功能主要包括宏定义 , 文件包含 , 条件编译 , 去注释等。
预处理指令是以 # 号开头的代码行。
实例 : gcc –E hello.c –o hello.i
选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
选项“-o”是指目标文件 ,“ .i”文件为已经过预处理的C原始程序

编译(生成汇编)

在这个阶段中 ,gcc 首先要检查代码的规范性、是否有语法错误等 , 以确定代码的实际要做的工作 , 在检查
无误后 ,gcc 把代码翻译成汇编语言。
用户可以使用 “-S” 选项来进行查看 , 该选项只进行编译而不进行汇编 , 生成汇编代码。
实例 : gcc –S hello.i –o hello.s

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

汇编阶段是把编译阶段生成的 “.s” 文件转成目标文件
读者在此可使用选项 “-c” 就可看到汇编代码已转化为 “.o” 的二进制目标代码了
实例 : gcc –c hello.s –o hello.o

连接(生成可执行文件或库文件)

在成功编译之后 , 就进入了链接阶段。
实例 : gcc hello.o –o hello
对于gcc对于文件的编译指令大致如下图

 -E指向到.i文件完成预处理,-S指向到.s文件实现编译,-c指向到.o文件实现汇编, gcc 加.o文件指向到一个文件 ,最后该文件就是可执行文件。利用./加载到内存中,就可以看到编译的最终结果。

动静态库的理解与概念

在了解之前我们先了解什么是函数库?

在最后链接的过程中:

1.我们现在所写的所有代码都是站在巨人的肩旁上,已经有人帮我们已经写好了对应的接口(函数),即各种函数库。

2.我们知道头文件在哪里,我们可以找到头文件的所在地,那么那些实现方法的函数库又在哪里呢?

我们可以利用ldd指令(可以查找可执行程序所依赖的第三方库)来查找相对应的函数库,.

可以看到它是会依赖一个lib64/libc.so.6的函数库:

可以总结出,在安装软件的时候,系统就已经帮我们安装的乐对应的各种函数库并将它放在特定的路径底下。

头文件提供方法的声明,库文件提供方法的实现

静态库 是指编译链接时, 把库文件的代码全部加入到可执行文件中 ,因此生成的文件比较大,但在运行时也 就不再需要库文件了。其后缀名一般为“.a”
且实际上我们有的静态库是非常少的,他们一般就做拷贝的作用。
动态库 与之相反,在 编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时 链接文件加载库,这样可以节省系统的开销 。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态 库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示:
gcc hello.o –o hello 。
gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。
我们可以同时利用静态库和动态库分别编译文件:
可以看到生成了两个可执行文件test-s与test-d,两个文件都可以运行。
利用ldd指令发现test-s并不是动态链接。

注意:默认情况下我们的云服务器并不会有静态库的,只有动态库,如有需要则可以安装

c的静态库:

sudo yum isntall glibc-static 

c++的静态库:

sudo yum install -y libstdc++ -static

3.Linux项目自动化构建代码

      在我们用vs写代码时,由于是集成开发工具,包含了对代码一条龙服务的功能,预处理+编译+汇编+链接,但在linux下我们对文件汇编后再接链接要去生成一个重定向的可执行程序,最后在./调用,如果是很多个文件呢,如此操作,太过麻烦,且生成太多的文件我们无从下手,那么如何去将这些文件规划整理呢?

1.make/Makefile是什么?

make:是一个命令符

makefile是一个在当前目录下存在的具有特定格式的文本文件。

对于Makefilede

那么如何去使用呢:

1.首先我们创建一个makefile(名字必须保证是这个,首字母可大写)文件,之后vim打开这个文件

,在此里面写我们要写对应可执行程序的名字,我们这里以一个code.c文件为例:

注意:这是makefile的语法格式,对于一个指令的编写:第一行我们称之为依赖关系,第二行我们称之为依赖方法。我们不能更改它的格式。

第一行写入生成可执行程序名,这里我写入为mybin,冒号和后面接.c文件

第二行先按以下TAB键,而不是四个空格,之后我们gcc编译文件并重定向我们所要给的名字。

这样前两行就完成了一个make的脚本指令。

编译后之后,因为代码在编译错之后改正后重新执行时,我们需要删掉之前生成的可执行程序来重新生成这里我们会引入一个新语法.PHONY。

2.伪目标

.PHONY叫做伪目标,.PHONY修饰clean后,clean就是一个伪目标文件,依赖关系可以为空,依赖方法为rm -f mybin  

目标文件与其他文件差不多,只不过被PHONY修饰后,增加了一个特点:它总是被执行。

       之后我们保存退出,同时使用make clean 指令,可以看到他会执行我们在其中写入的指令.

对于makefile,在调用时,自顶向下扫描,如果遇到第一个目标文件,他会直接执行相关指令。

3.文件的三个时间属性

为了提高编译效率,需要注意的是make是不会允许重复编译我们的文件,这是它特有的,如下:

那这是如何做到的呢,这应该取决于文件的属性--文件的修改时间,可是一个文件的时间怎么就确定了它是旧还是新文件,时间是在增长的,故还是需要去对比。那么和谁去对比呢?理所应当源文件应该和生成的可执行文件的时间来对比,我们可以知道源文件的修改时间时肯定小于生成可执行文件,若文件修改了,则新的时间大于可执行文件的时间,故通过对比两文件时间,确定是否还需要去编译。但有的文件,因为历史问题,修改时间也不会重新编译,需要删除可执行文件才能重新编译。

那么如何去查看一个文件的时间信息?

stat 文件名

我们可以看到文件的基本属性,尤其是这三个文件的时间:

Acess:访问文件的时间(包括打开文件,修改文件等)只要被访问,就会被重新记录。

Modify: 修改文件内容的时间(包括删除,增加),修改文件内容时所记录的时间。

Change:修改文件属性的时间(包括文件大小,权限,时间等),只要被修改,就会记录。

我们知道文件=内容+属性,但对于这里的Change,更改Modify与Acess也会更改Change,换言之,这里的内容修改与访问修改本质上是属性修改的一部分。

当然这里编译时看的就是modify,其次我们自己也可以手动更改时间:

touch  -a 文件名  //更改access time
touch -m  文件名  //更改modify time   修改为当前时间

 通过时间对比,我们可以让代码可以一直被或者不被执行,而PHONY总会被执行,就是不被时间影响,我们可以在makefile中给我们的指令做.PHONY修饰是的可以被一直操作,不受影响

4.Makefile的自动推导

对于make/Makefile是具有依赖性的自动推导能力的,比如:

可以看到,我们直接写的编译.o文件,运行时可以执行,而我们最初是没有.o文件的,我们也没让它生成.o文件,由此判断make是具有自动推导能力的,根据我们的需要自动补充改文件。

完整的应该是这样:

5.语法扩展

1.通过添加@符号,使得执行命令时不打印依赖方法

 make时不再打印gcc test.c -o code.c。

利用这点可以编写一些信息,例如echo不会打印这条指令,执行时打印其中内容,编写信息时更加简洁。

2.利用#注释

3.可编写变量

我们可以理解通过编写变量实现和宏一样的替换效果。

 这段代码的效果和上面的效果一样

4.依赖关系与依赖方法的简写

因为在依赖关系中已经指明了目标文件与源文件,故此可以利用$^代替源文件,使用$@表示目标文件。

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

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

相关文章

Java实现计算两个日期之间的工作日天数

需求: 需要在后端实现 计算当前日期与数据库内保存的日期数据之间相隔的工作日数目 实现 import java.time.DayOfWeek; import java.time.LocalDateTime;public class WorkdaysCalculator {public static void main(String[] args) {String givenDateTimeStr &q…

HTTPS Tomcat Servlet 博客系统 软件测试的概念 Linux

第 1 题(多选题) 题目名称: 以下关于http和https说法正确的是 题目内容: A .http是超文本传输协议 B .https是超文本传输安全协议 C .http是明文传输 D .https是加密传输 第 2 题(单选题) 题目名称…

【计算机视觉】Image Feature Extractors方法介绍合集(一)

文章目录 一、Convolution二、1x1 Convolution三、Depthwise Convolution四、Pointwise Convolution五、Depthwise Separable Convolution六、Grouped Convolution七、Dilated Convolution八、3D Convolution九、Non-Local Operation十、Deformable Convolution十一、Switchabl…

UI自动化测试神器Playwright(Java版)(保存登录cookie,解决免登录)

🎭 Playwright在称为浏览器上下文的隔离环境中执行测试。该隔离模型提高了可重复性并防止相关联的测试脚本执行失败。测试可以加载现有的已验证状态,比如获取已登录的状态(Cookie),在后续脚本中复用。这消除了在每个测…

【论文笔记】Perception, Planning, Control, and Coordination for Autonomous Vehicles

单纯作为阅读笔记,文章内容可能有些混乱。 文章目录 1. Introduction2. Perception3. Planning3.1. Autonomous Vehicle Planning Systems3.2. Mission Planning3.3. Behavioral Planning3.4. Motion Planning3.4.1. Combinatorial Planning3.4.2. Sampling-Based P…

web安全漏洞-SQL注入攻击实验

实验目的 学习sql显注的漏洞判断原理掌握sqlmap工具的使用分析SQL注入漏洞的成因 实验工具 sqlmap是用python写的开源的测试框架,支持MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,I…

解决mybatis-plus不能俩表联查分页之手动写分页

public class MyPageHelper {// 调用pageInfo插件内的方法 开启分页 需要传入一个起始页的值和每页显示的条数public static void startPage(PageRequest pageRequest) {PageHelper.startPage(pageRequest.getPageNum(),pageRequest.getPageSize());}// 封装结果集public stati…

【CMU15-445 Part-11】Join Algorithms

Part11-Join Algorithms Why Do We Need to Join? Join其实是关系数据库和范式化表时候所产生的副产物。 也就是说我们范式化表是为了减少冗余信息,而我们使用join就是为了去重建reconstruct 这些原本的tuple Join Algorithms 主要关注两表的inner equijoin a…

01_网络编程_传统IO

网络编程 1.什么是网络编程 在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 如果想把一个计算的结果,或者是电脑上的文件通过网络传递给你的朋友,就需要用到网络编程。 在实际生活中,网络通信无处不在…

Windows 10 Enterprise LTSC 2021 (x86) - DVD (Chinese-Simplified)文件分享

Windows 10 Enterprise LTSC 2021 (x64) - DVD (Chinese-Simplified) SW_DVD9_WIN_ENT_LTSC_2021_64BIT_ChnSimp_MLF_X22-84402.ISO 镜像文件: 链接:https://pan.quark.cn/s/2f8f61ec4a98 Windows 10 Enterprise LTSC 2021 (x86) - DVD (Chinese-Simpli…

python selenium 爬虫教程

Python和Selenium是很强大的爬虫工具,可以用于自动化地模拟浏览器行为,从网页中提取数据。下面是一个简单的使用Python和Selenium进行爬虫的案例。 入门: 1. 安装和配置: 首先,你需要安装Python和Selenium。可以使用…

Postman的高级用法一:重新认识postman核心模块

本请求示例来自于免费天气API: 实况天气接口API开发指南 未来一天天气预报api - 天气API 关于Postman的核心模块 全局变量请求接口请求体预处理脚本 类似beforeTest,在发起请求前的预执行逻辑,通常是生成一些动态变量值 测试用例模块 测试者…

开源社区赋能,Walrus 用户体验再升级

基于平台工程理念的应用管理平台 Walrus 已于上月正式开源,目前在 GitHub 已收获 177 颗星🌟 Walrus 希望打造简洁清爽的应用部署与管理体验,帮助研发与运维团队减少“内耗”工作,提升开发体验。 我们十分重视 Walrus 用户的…

Ubuntu安装深度学习环境相关(yolov8-python部署)

Ubuntu安装深度学习环境相关(yolov8-python部署) 本文将从如下几个方面总结相关的工作过程: Ubuntu系统安装(联想小新pro16) 2.显卡驱动安装3.测试深度学习模型 1. Ubunut 系统安装 之前在台式机上安装过Ubuntu,以为再在笔记本上安装会是小菜一碟&…

查询IP地址可得到哪些信息

通过IP地址定位,可以获取一些基本的信息,包括以下内容: 1. 地理位置:你可以确定IP地址所在的地理位置,包括国家、州或省、城市和地理坐标。这通常是通过将IP地址与地理位置数据库进行匹配来实现的。 2. ISP&#xff…

JDK13特性

文章目录 JAVA13概述语法层面特性switch表达式(预览)文本块(预览) API层次特性重新实现旧版套接字API 其他变化ZGC取消未使用的内存增加废弃和移除增加项移除项废弃项 JAVA13概述 2019年9月17日,国际知名的OpenJDK开源社区发布了Java编程语言环境的最新版本OpenJDK…

【资源监视器】设备占用,强制弹出移动硬盘

设备占用,强制弹出移动硬盘 任务管理器中找到资源监视器 资源监视器:找到CPU 输入磁盘:如H: , 点击旁边的刷新 结束句柄 右键

简单工厂模式 和 工厂方法 和 抽象工厂的区别

简单工厂模式、工厂方法模式和抽象工厂模式是三种不同的创建型设计模式,它们在对象的创建和封装方面有不同的用途和实现方式。以下是它们之间的主要区别: 1. **简单工厂模式(Simple Factory Pattern)**: - **目的**&a…

二十一、MySQL(多表)内连接、外连接、自连接实现

1、多表查询 (1)基础概念: (2)多表查询的分类: 2、内连接 (1)基础概念: (2)隐式内连接: 基础语法: select 表1.name,…

私域流量的优势

私域流量是指由自身品牌或个人拥有并具备完全掌控权的流量资源。它相比于传统的广告推广,拥有独特的优势。 首先,私域流量能够更加精准地定位目标用户,实现精准传播。不再盲目投放广告,而是通过建立自身社群、粉丝群,获…