Linux环境开发工具yum、makefile的使用 【Linux】

news2024/11/18 15:53:07

文章目录

  • Linux软件包管理器 - yum
    • Linux下安装软件的方式
    • yum
    • 查找软件包
    • 如何实现本地机器和云服务器之间的文件互传
    • 卸载软件
    • Linux编译器 - gcc/g++
  • 程序的翻译过程
    • 1.预编译(预处理)
    • 2.编译(生成汇编)
    • 3.汇编(生成机器可识别代码)
    • 4.链接(你写的代码 + C标准库的二进制代码 ==> 生成可执行的二进制程序)
  • 解决普通用户无法使用sudo提权
  • 静态库与动态库
    • 动态链接
    • 静态链接:
  • debug &&release
  • Linux项目自动化构建工具 - make/Makefile
    • 依赖关系和依赖方法
    • 初步理解makefile的语法
  • gcc是怎么知道源文件不需要再编译了呢?
    • 为什么执行的指令是make和make clean呢?
    • makefile的推导规则
    • Makefile的简写
  • 缓冲区
  • \r和\n
  • 倒计时

Linux软件包管理器 - yum

Linux下安装软件的方式

1)下载到程序的源代码,自行进行编译,得到可执行程序。
2)获取rpm安装包,通过rpm命令进行安装。——Linux安装包
3)通过yum进行安装软件。——解决安装源、安装版本、安装依赖

yum

yum是一个在Fedora、RedHat以及CentOS中的前端软件包管理器,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。
在这里插入图片描述
注意:一个服务器同一时刻只允许一个yum进行安装,不能在同一时刻同时安装多个软件。因为yum是从服务器上下载RPM包,所以在下载时必须联网,可以通过ping指令判断当前云服务器是否联网。
在这里插入图片描述

查找软件包

通过 yum list 命令可以罗列出当前一共有哪些软件包. 由于包的数目可能非常之多, 这里我们需要使用 grep 命令只筛选出我们关注的包. 例如:

[cxq@VM-4-10-centos ~]$ yum list |grep lrzsz

在这里插入图片描述
注意事项:

  • 软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构.
  • “x86_64” 后缀表示64位系统的安装包, “i686” 后缀表示32位系统安装包. 选择包时要和系统匹配.
  • “el7” 表示操作系统发行版的版本. “el7” 表示的是 centos7/redhat7. “el6” 表示centos6/redhat6.
  • 最后一列, os 表示的是 “软件源” 的名称, 类似于 “小米应用商店”, “华为应用商店” 这样的概念.

如何实现本地机器和云服务器之间的文件互传

指令: rz -E
通过该指令可选择需要从本地机器上传到云服务器的文件。
在这里插入图片描述
指令: sz 文件名
在这里插入图片描述

卸载软件

[root@VM-4-10-centos ~]# yum remove lrzsz.x86_64  

yum会自动卸载该软件,这时候输入“y”确认卸载,当出现“complete”字样时,说明卸载完成

Linux编译器 - gcc/g++

程序的翻译过程

1.预编译(预处理)

预处理包含头文件展开,去注释,条件编译,宏替换这四个步骤

指令 gcc -E

[cxq@VM-4-10-centos lesson7]$ gcc -E mycode.c -o  mycode.i

-E告诉gcc从现在开始进行程序的编译 ,将预处理工作做完就停下来,不要往后走了!
-o将处理结果输出到指定文件,该选项后需紧跟输出文件名。在这个例子中,-o mycode.i 表示将预处理后的代码输出到名为mycode.i的文件中。
在这里插入图片描述

预处理之后的文件中多出来的一大堆代码其实是从Linux中的/usr/include/stdio.h头文件路径下的头文件stdio.h中拷贝过来的,从头文件stdio.h中就可以找到printf函数的声明,具体的实现在C标准函数库里面

总结:

  • 预处理功能主要包括头文件展开、去注释、宏替换、条件编译等。
  • 预处理指令是以#开头的代码行。
  • -E选项的作用是让gcc/g++在预处理结束后停止编译过程。
  • -o选项是指目标文件,“xxx.i”文件为已经过预处理的原始程序。

我们为什么能够在windows或者Linux上进行C/C++或者其他形式的开发呢?
我们的系统中一定要提前或者后续安装上,C/C++开发相关的头文件,库文件

C/C++开发环境不仅仅指的是vs,gcc、g++,更重要的是,语言本身的头文件和库文件!
其实我们安装vs2019、vs2022等,我们其实还在安装的时候,选择对应的开发包,同步也在下载c的头文件和库文件
在对编译型语言,安装对应的开发包,必定是下载安装对应的头文件+库文件

2.编译(生成汇编)

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

[cxq@VM-4-10-centos lesson7]$ gcc -S mycode.c -o mycode.s

在这里插入图片描述

  • 在这个阶段中,gcc/g++首先检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,将代码翻译成汇编语言。
  • 用户可以使用-S选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
  • -o选项是指目标文件,“xxx.s”文件为已经过翻译的原始程序。

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

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

[cxq@VM-4-10-centos lesson7]$ gcc -c mycode.s -o mycode.o
[cxq@VM-4-10-centos lesson7]$ od mycode.o//将二进制文件以二进制形式打印到显示器上

在这里插入图片描述
形成的mycode.o文件是可重定位目标二进制文件,简称目标文件,Windows下也有这样的文件 ,在Windows中叫做obj文件
mycode.o这个可重定位目标二进制文件不可以独立执行,虽然已经是二进制了,但是还需要经过链接才能执行

4.链接(你写的代码 + C标准库的二进制代码 ==> 生成可执行的二进制程序)

[cxq@VM-4-10-centos lesson7]$ gcc mycode.o -o  mytest//将可重定位目标二进制文件,和库进行链接形成可执行程序
  • 在成功完成以上步骤之后,就进入了链接阶段。
  • 链接的主要任务就是将生成的各个“xxx.o”文件进行链接,生成可执行文件。
  • gcc/g++不带-E、-S、-c选项时,就默认生成预处理、编译、汇编、链接全过程后的文件。
  • 若不用-o选项指定生成文件的文件名,则默认生成的可执行文件名为a.out。

在这里插入图片描述

注意: 链接后生成的也是二进制文件。

解决普通用户无法使用sudo提权

[root@VM-4-10-centos ~]# vim /etc/sudoers

将用户切换为root,在root中找到/etc/sudoers文件并用vim打开,然后在下面列表中仿照root的格式添加普通用户,最后在底行模式下输入wq!保存并退出
在这里插入图片描述
上面步骤完成之后,普通用户也可以使用sudo指令了,因为我们已经将普通用户添加至信任列表了。

在这里插入图片描述

静态库与动态库

函数库一般分为静态库和动态库两种:

  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件当中,因此生成的文件比较大,但在运行时也就不再需要库文件了,静态库一般以.a为后缀。
  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件当中,而是在程序运行时由链接文件加载库,这样可以节省系统的开销,动态库一般以.so为后缀。

总结:

在Linux下库的命名:
动态库:lib作为前缀,.so作为后缀,
静态库:lib作为前缀,.a作为后缀,
去掉前缀和后缀,剩下的就是库名称!
stdio的std就是standard标准的意思

动态链接

优点:省空间(磁盘的空间,内存的空间),体积小,加载速度快。
 缺点:依赖动态库,动态库一旦缺失,导致各个程序都无法运行

静态链接:

优点:不依赖第三方库,程序的可移植性较高。
 缺点:比较消耗磁盘空间,内存空间,网络空间等资源。

在Linux中,编译形成可执行程序,默认采用的就是动态链接(提供动态库),我们可以使用file指令进行查看。
在这里插入图片描述
我们还可以使用ldd指令查看动态链接的可执行文件所依赖的库。
在这里插入图片描述
gcc和g++默认采用的是动态链接,在Linux中,如果要按照静态链接的方式,进行形成可执行程序,需要添加-static选项–提供静态库

[cxq@VM-4-10-centos lesson7]$ gcc mycode.c  -o mytest-static -static

在这里插入图片描述

总结:

1如果我们没有静态库,但是我们就要-static,行不行呢? 不行
2如果我们没有动态库,只有静态库,而且gcc能找到? 能的,gcc默认优先动态链接
3-static的本质:改变优先级,如果加了-static选项,所有的链接要求变成全部变成静态链接
4不一定是纯的全部动态链接或者静态链接,可能是混合的!

扩展:可执行程序形成的时候,不是没有顺序的二进制构成,有自己的格式的,可执行程序有自己的二进制格式,ELF格式

debug &&release

debug可以被追踪调试,在形成可执行程序的时候,添加了debug信息

[cxq@VM-4-10-centos lesson7]$ gcc mycode.c -o mytest-debug -g 

在这里插入图片描述

[cxq@VM-4-10-centos lesson7]$ readelf -S mytest-debug

Linux项目自动化构建工具 - make/Makefile

make是一条命令,Makefile是一个当前目录下的文件,两个搭配使用,完成项目自动化构建,makefile文件既可以写成makefile,也可以写成Makefile
在这里插入图片描述

依赖关系和依赖方法

makefile文件中,要写的是依赖关系和依赖方法,例如生成的可执行程序mycode依赖的就是mycode.c源文件,没有这个源文件,就没有mycode这个可执行程序,生成可执行程序的过程中又依赖方法gcc mycode.c -o mycode也就是需要gcc来编译链接生成可执行程序。

在这里插入图片描述

依赖关系: 文件A的变更会影响到文件B,那么就称文件B依赖于文件A

  • 例如,mycode文件是由mycode.c文件通过预处理、编译以及汇编之后生成的文件,所以mycode.c文件的改变会影响mycode,所以说mycode文件依赖于mycode.c文件。

依赖方法: 如果文件B依赖于文件A,那么通过文件A得到文件B的方法,就是文件B依赖于文件A的依赖方法

  • 例如:mycode依赖于mycode.c,mycode.c 通过 gcc mycode.c -o mycode指令 得到mycode这个可执行程序,那么mycode依赖于mycode.c的依赖方法就是gcc -c -o mycode mycode.c

初步理解makefile的语法

在这里插入图片描述
make一次后继续make为什么就不行了? make会根据源文件和源文件生成的可执行程序的新旧,判定是否需要重新执行依赖关系进行编译,从而提供编译效率
如何做到的?
首先我们得清楚一定是源文件形成可执行程序,换句话说先有源文件,才有源文件生成的可执行程序, 所以一般来说,源文件的最近修改时间比源文件生成的可执行程序要新

当我们发现源文件还有bug,我们就会更改源文件,但是历史上曾经还有源文件生成的可执行程序,那么源文件的最近修改时间,一定要比可执行程序要新!

make只需要**比较可执行程序的最近修改时间 和源文件的最近修改时间(Modify)**来判断是否需要重新编译
可执行程序 新于 源文件 ,不需要重新编译
可执行程序 老于 源文件 ,需要重新编译

如果我们想要对应的依赖关系总是被执行? .PHONY (伪目标)
被.PHONY关键字修饰的对象是一个伪目标,该目标总是被执行的。
由于第一条依赖关系和依赖方法没有被.PHONY:修饰,所以如果命令执行过,且源文件没有被改动过的话,make是不允许连续多次执行的,但clean的依赖关系和依赖方法被.PHONY:修饰了,所以它是可以多次执行的

换言之,有了关键字.PHONY:修饰过后,就不要通过对比源文件和可执行程序Modify时间来判断是否能够执行指令了,不走这套规则

gcc是怎么知道源文件不需要再编译了呢?

Modify代表文件内容被修改的时间,Change代表文件属性被修改的时间,Access代表最后一次访问文件的时间

在这里插入图片描述
当已经使用make指令过后,无法继续使用时,我们可以用touch,touch后面跟上已存在的文件,可以更新此文件的三个时间,这个时候就又可以用make指令了
在这里插入图片描述

为什么执行的指令是make和make clean呢?

make也可以跟上mycode使用,make默认从上到下扫描文本makefile的时候,第一个扫描到的目标文件可以省略名称使用,例如直接使用make,执行的就是makefile里面的第一个目标文件,并且默认情况下makefile只形成一个目标文件,也就是总目标文件只能有一个。

makefile的推导规则

  1 mycode:mycode.o 
  2     gcc mycode.o -o mycode                                                                                                                                            
  3 mycode.o:mycode.s                  
  4     gcc -c mycode.s -o mycode.o       
  5 mycode.s:mycode.i                     
  6     gcc -S mycode.i -o mycode.s
  7 mycode.i:mycode.c              
  8     gcc -E mycode.c -o mycode.i
  9                  
 10 .PHONY:clean     
 11 clean:           
 12      rm -f mycode

根据依赖关系列表,make先找mycode,发现没有,那就去找mycode依赖的mycode.o,结果发现也没有,那就去找mycode.o依赖的mycode.s,结果发现还是没有,那就去找mycode.s依赖的mycode.i,结果没找到,那就去找mycode.i依赖的mycode.c结果找到了,那就执行他们之间的依赖方法gcc -E mycode.c -o mycode.i ,然后mycode.i 就有了,然后再一点一点向上执行每条依赖方法

这就是整个make的依赖性,类似于堆栈结构,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件

Makefile的简写

Makefile文件的简写方式:

$@:表示依赖关系中的目标文件(冒号左侧)。
$^:表示依赖关系中的依赖文件列表(冒号右侧全部)。
$<:表示依赖关系中的第一个依赖文件(冒号右侧第一个)。

在这里插入图片描述
例如 : $@是冒号左侧的目标文件mycode , $^是mycode.c

缓冲区

缓冲区 :就是由c语言维护的一段内存

代码一:
在这里插入图片描述
先输出字符串hello world 然后休眠3秒之后结束运行
代码二:
在这里插入图片描述
代码中删除了字符串后面的’\n’,结果就截然不同,结果是:先休眠3秒,然后打印字符串hello world之后结束运行。该现象就证明了行缓冲区的存在。

显示器对应的是行刷新,即当缓冲区当中遇到’\n’或是缓冲区被写满才会被打印,代码二中并没有’\n’,所以字符串hello world先被写到缓冲区中,然后休眠3秒后,直到程序运行结束时才将hello world打印到显示器当中。

\r和\n

\r: 回车,使光标回到本行行首。
\n: 换行,使光标下移一格。

倒计时

 1: main.c  ⮀                                                                              ⮂⮂ buffers 
  1 #include"processBar.h"
  2 #include<unistd.h>
  3 int main()
  4 {
  5   //倒计时
  6   int count =10 ;
  7   while(count>=0  )
  8   {
  9    printf("%-2d\r",count);                                                                          
 10    fflush (stdout); //刷新数据
 11    count --;
 12    sleep(1);
 13 
 14    }
 15   printf("\n");
 16   return 0 ;
 17 }

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

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

相关文章

MySQL数据库 #3

文章目录 一、创建表的完整语法二、约束条件1.unsigned &#xff08;无符号&#xff09;2. zerofill &#xff08;0填充&#xff09;3. default &#xff08;默认值&#xff09;4. not null&#xff08;非空&#xff09;5. unique&#xff08;唯一&#xff09;6. primary key &…

1024程序员节背后的秘密:1024程序员节的前世今生

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

中国艺术孙溟㠭篆刻《绕绕》

孙溟展先生现在的这方篆刻作品&#xff0c;没有使用大篆和小篆文字来篆刻&#xff0c;彰显篆刻的金石魅力。一改以往的不同&#xff0c;以圆形组合设计&#xff0c;用篆刻的刀法刻出&#xff0c;即体现篆刻的美&#xff0c;又达到了作者想表达的感情。这方篆刻作品溟展先生起名…

SD NAND

文章目录 前言SD NAND vs SD 卡SD NAND vs SPI NANDCS SD NAND 优势芯片介绍结构框图引脚介绍参考设计 焊接测速单片机读写测试作为 ARM Linux 系统盘使用 前言 提到 SD&#xff0c;最先想到的就是 SD 卡&#xff0c;由于体积关系&#xff0c;TF 卡使用得更为普遍&#xff0c;…

[Ubuntu 18.04] 搭建文件夹共享之Samba服务器

Samba是一个开源项目,允许Windows用户在Linux和Unix系统上进行文件共享。 Samba服务器是一个可以让Linux或Unix系统在网络上充当Windows NT/2000/XP/2003等网络操作系统的共享资源的软件。它允许用户通过SMB/CIFS协议在Linux或Unix系统与Windows共享资源。 Samba服务器的主要…

VRPTW(MATLAB):淘金优化算法GRO求解带时间窗的车辆路径问题VRPTW(提供参考文献及MATLAB代码)

一、VRPTW简介 带时间窗的车辆路径问题(Vehicle Routing Problem with Time Windows, VRPTW)是车辆路径问题(VRP)的一种拓展类型。VRPTW一般指具有容量约束的车辆在客户指定的时间内提供配送或取货服务&#xff0c;在物流领域应用广泛&#xff0c;具有重要的实际意义。VRPTW常…

ARM | 传感器必要总线IIC

IIC总线介绍 1.谈谈你对IIC总线理解&#xff1f; 1&#xff09;IIC总线是串行半双工同步总线,主要用于连接整体电路 2&#xff09;SCL/SDA作用:IIC是两线制,一根是时钟线SCK,用于控制什么时候进行进行数据传输,时钟信号由主机发出; 另一根是数据线SDA,用于进行数据传输,可以从…

垃圾收集器与内存分配策略

概述 垃圾收集需要完成的三件事情&#xff1a; 哪些内存需要回收&#xff1f;什么时候回收&#xff1f;如何回收&#xff1f; 判断对象是都存活的算法&#xff1a; 引用计数法&#xff1a;在对象中添加一个引用计数器&#xff0c;每当有一个地方引用时&#xff0c;计数器值就…

python基础教程:异常处理

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 有时候我们在写程序的时候会出现错误或者异常&#xff0c;导致程序终止&#xff0c;如下这个例子&#xff1a; #!/usr/bin/env python a 2/0 print(a)结果提示如…

Visual Studio Professional 2019 软件安装教程(附安装包下载)

Microsoft Visual Studio 是一个非常强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;适用于 Windows 上的 .NET 和 C 开发人员。它提供了一系列丰富的工具和功能&#xff0c;可以提升和增强软件开发的每个阶段。 Visual Studio IDE 是一个创意启动板&#xff0c;可…

C++ 多线程编程和同步机制:详解和实例演示

C中的多线程编程和同步机制使得程序员可以利用计算机的多核心来提高程序的运行效率和性能。本文将介绍多线程编程和同步机制的基本概念和使用方法。 多线程编程基础 在C中&#xff0c;使用<thread>库来创建和管理线程。线程可以通过函数、成员函数或者Lambda表达式来实现…

基于C#使用winform技术的游戏平台的实现【C#课程设计】

基于C#使用winform技术的游戏平台的实现【C#课程设计】 说明项目结构项目运行截图及实现的功能 部分代码一些说明(个人觉得一些难点的说明)一、ListView &#xff0c;ImageList 的综合使用二、图片上传以及picturebox 图片的动态替换三、图表插件的使用四、SQL工具类封装五、高…

最新哔哩哔哩邮箱绑定接口签名JS逆向分析

本章教程主要逆向分析 哔哩哔哩邮箱绑定接口biliCSRF 和mid 参数。 教程仅供学习参考,请勿滥用,由此带来的法律责任需由自己承担。 目录 一、接口参数分析 二、签名加密代码 三、滑块验证码 一

LabVIEW应用开发——控件的使用(四)

接上文&#xff0c;这篇介绍时间控件。 LabVIEW应用开发——控件的使用&#xff08;三&#xff09; 1、时间控件Time Stamp control 在日常软件开发场景中&#xff0c;时间也是一种常用的控件&#xff0c;用于表达当前时间的显示、对下设置时间、时间同步等等场景。LabVIEW专门…

Redis主从模式(一)----搭建主从结构并演示

目录 一, 主从模式 1.1 单个Redis服务器可能存在的问题 1.2 单点问题 1.3 什么是主从模式 概念 图示 二, 演示Redis的主从复制 2.1 Redis-server进程 2.2 建立复制 1. 首先将redis.conf配置文件复制一份并修改daemonize 为 yes 2.修改配置文件中的端口号 3. 分别在…

力扣每日一题63:不同路径||

题目描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物…

RK3568平台开发系列讲解(应用篇)串口应用编程之串口介绍

🚀返回专栏总目录 文章目录 一、串口介绍1.1、数据传输方式1.2、数据格式1.3、波特率1.4、硬件流控制和软件流控制1.5、错误检测1.6、串口编程二、串口设备节点介绍沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 串口设备是嵌入式开发中最常用的外设之一,通过串口…

2023年信息科学与工程学院学生科协第一次前端培训

目录 一、前端是什么&#xff1f;前端能做什么&#xff1f;前端需要做什么&#xff1f;现阶段如何理解前端 二、前端学习路线html是什么&#xff1f;css是什么&#xff1f;什么是jshtml、css以及js关系掌握三种语言之后的学习路线 三、HTML基础语法标题段落文本换行文本标签图像…

协程和 C++ Boost库的Coroutine2

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 协程和 C Boost库的Coroutine2 摘要为什么不是boost.coroutine&#xff1f; 线程与协程为什么不介绍C20标准的协程C协程与golang的goroutine 二、使用步骤1.引入库2.核心类单…

作为程序员,很多时候容易急眼,如何缓解?

程序员在工作中面临着高压和快节奏的环境&#xff0c;容易因为紧张的工作节奏、复杂的技术问题或与团队的沟通问题而感到焦虑和急躁。下面提供一些策略来帮助缓解这种情况&#xff1a; 1. 定时休息 遵循“番茄工作法”或其他时间管理技术&#xff0c;每工作25分钟后休息5分钟&…