前言
作者:小蜗牛向前冲
名言:我可以接受失败,但我不能接受放弃
如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。
本期学习目标:学习yum的基础操作,用gcc编写在vim中写好的代码,学会如何编写makefile文件,用make指令编程。
一、yum的基本操作
1、什么是yum
在回答什么是yum这个问题的时候,我想请大家思考一个小问题,平常我们在window下是怎么安装软件(app)的,一般我们是在应用商城上下载的。那么Linux和window同为操作系统,都应该是可以安装软件的,但是由于window是可视化平台,而Linux不是就不会出现我们要那个app直接点一下屏幕就可以了,Linux都是通过命令行来控制的。而其中的yum就相当于window下的应用商城,。
所以说(Linux下的各种工具)软件包和(yum)软件包管理器, 就好比 "App" 和 "应用商店" 这样的关系
2、yum的三板斧
查看软件包
通过 yum list 命令可以罗列出当前一共有哪些软件包. 由于包的数目可能非常之多, 这里我们需要使用 grep 命令只 筛选出我们关注的包.
例如:
yum list | grep lrzsz
这里补充一个小知识:rzsz 这工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件. 安装完毕之后可以通过拖拽个的方式将文件上传过去。
注意事项:
- 软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构.
- "x86_64" 后缀表示64位系统的安装包, "i686" 后缀表示32位系统安装包.
- 选择包时要和系统匹配. "el7" 表示操作系统发行版的版本.
- "el7" 表示的是 centos7/redhat7. "el6" 表示 centos6/redhat6.
- 最后一列, base 表示的是 "软件源" 的名称, 类似于 "小米应用商店", "华为应用商店" 这样的概念
安装软件
通过 yum, 我们可以通过很简单的一条命令完成 gcc 的安装.
sudo yum install lrzsz
卸载软件
这里我们去卸载gcc
sudo yum remove lrzsz
3、yum的深度思考
上面我们知道yum怎么去查找软件包,安装和卸载软件,但是软件包又是从何处来的呢?
我们都知道在下载软件的时候都是联网的,也就说软件包并不是在本地,其实软件包是通过联网访问服务器。
那些服务器又是谁在维护,软件包又是怎么来的呢?
这就不得不说Liunx是个开源的操作系统,那么在一个操作系统中肯定要下载软件的,所以那么Liunx社区的大佬就会去维护服务器(当然不同的版本的操作系统,服务器可能不同),然后因为服务器是免费为大家提高的,所以自然会有些大佬乐于奉献去些软件包并上传到。
二、gcc的学习使用
前面我们在自己的服务器是安装的gcc,我们都知道vim仅仅只是个高级点的编辑器,他是不能完成对代码的编译链接的,这将要靠我们的gcc编译器去完成。
1、在Liunx下理解编译链接
下面我们简单回忆一下翻译的过程:
- 预处理:这过程中我们完成对头文件的展开,去注释,对代码中的宏进行替换,进行条件编译。
- 编译:把c语言代码转为汇编语言。
- 汇编:这里将汇编语言在转换为二进制(这里虽然生成了计算机可识别的二进制,但是由于没有进行链接,所以仍然是不可执行的)。
- 链接:将写好的代码和C标准库中的代码合起来。
下面我们在Linux操作系统下体会一下编译的过程
预处理
gcc -E test.c -o mytest.i
这句代码的意思是从现在开始翻译,当到预处理阶段的做完就停下来,其中的 -o是指明生成的临时文件名称。(如果我们不指向生成的文件名称为auto.c)
编译
gcc -S test.c -o mytest.s
这句代码表示,从现在开始程序的翻译 ,做完编译工作后就停下来。
汇编
gcc -c test.c -o mytest.o
这句代码表示,从现在开始程序的翻译 ,做完汇编工作,讲汇编语言转化为二进制语言后就停下来。
链接
gcc mytest.o -o mytest.c
这里就对二进制文件进行链接过程,生成可执行文件。
2、函数库
虽然我们了解从上面了解到对程序翻译过程,但是在链接过程中我们要讲C标准的库函数和我们写的代码合并到一起。为了更好的理解,我们还需要知道库函数是分为动态库和静态库这二类的。
静态库和动态库
- 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也 就不再需要库文件了。其后缀名一般为“.a”。
- 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时 链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,
那么我们在Linux下进行的链接是动态库还是静态库呢?
下面我们可以通过file命令来查找一下文件信息:
而在此系统的动态库的名称为libc.so.6。
如果我们要让文件链接静态库怎么做呢?
这里我们只要在链接阶段加上 -static就可以了,但是发现报错了是不能执行这个命令,这是因为我们可能没有安装静态库只要我们安装一下就可以了(sudo yum -install -y glibc-static)。
3、makefile和make
首先我们要明白makefile是一个文件,make是一个配合makefile使用的命令。
背景知识
- 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
- 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能操作。
- makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
- make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命 令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一 种在工程方面的编译方法。
- make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
为了更好的理解makfile和make,我们在Linux写个小项目:进度条。
process.h
#pragma once
#include<stdio.h>
#include<unistd.h>
#include<string.h>
//定义进度条的多种展示形式
const char style[] = {'#','$','>','-','*'};
#define N 2
process.c
#include"process.h"
int main()
{
int i = 0;
//给一个字符数组存放进度条
char bar[101];
//这里给一个进度条在直观跑的形态
const char* label = "|\\-/";
memset(bar, 0, sizeof(bar));
//展示进度条
while (i <= 100)
{
printf("[%-100s][%d%%][%c]\r", bar, i, *(label + (i % 4)));
//这里的是为刷新缓冲区
fflush(stdout);
bar[i++] = style[N];
usleep(100000);
}
printf("\n");
return 0;
}
这里我们写好了代码,正常情况下,我们只要用gcc编译器编译就好了,但为了实现项目的自动化构建,所以我们就要使用makefile和make。
那么我们要在makefile文件定义什么呢?
我们主要在文件中定义清楚,依赖关系和依赖方法。
下面我将以进度条小项目进行分析:
上面我们可以看到由于我们要生成的process是依赖于proccess.c生成的,所以我们在第1行定义了文件之间的依赖关系。而依赖的方式我们是通过gcc编译器生成的。
那么下面的clean又是上面呢?
这其实是和make是相反的,调用make命令,会编译文件,而调用make clean会清理文件。
进度条