目录
3.1 yum的软件包都是从哪里来的?是从哪里能下载到这些软件包?
二、vim -- Linux的开发工具也是一款多模式的编辑器
3.3 ldd指令 -- 可以查看一个可执行程序所依赖库的情况
四、Linux项目自动化构建工具 -- make/Makefile
一、yum -- Linux软件包管理器
1、什么是yum
yum(Yellow dog Updater, Modified):
是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat, Centos等发行版上。
在Linux上安装软件的方式:
- 源代码直接安装:在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序.
- RPM包直接安装:但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.
- yum/apt-get:yum是Linux系统预装的一个指令,用于搜索,下载,安装对应的软件。所以yum就相当于Linux的应用商店。它的功能相当于手机上的应用商店!!但是需要注意的是,当我们使用yum来搜索,下载,安装对应软件的过程中必须要联网才能访问软件源!!
2、yum的使用
当我们使用yum命令来进程下载安装软件或删除软件的操作时,需要用超级管理员root的权限才能完成操作。
这里就介绍一个yum命令的选项:
-y :当下载软件时,自动用“yes”来回答系统的提示(这就类似于rm指令的-f选项)
2.1 yum一些经常见的操作
1.查看软件包
yum list | grep package's name
通过yum list 命令可以罗列出当前一共由哪些软件包。由于软件包的数量很多,所以我们需要用grep指令来筛选出我们需要的软件包。例如:
注意事项:
- 软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构.
- "x86_64" 后缀表示64位系统的安装包, "i686" 后缀表示32位系统安装包. 选择包时要和系统匹配.
- "el7" 表示操作系统发行版的版本. "el7" 表示的是 centos7/redhat7. "el6" 表示 centos6/redhat6.
- 最后一列, base 表示的是 "软件源" 的名称, 类似于 "小米应用商店", "华为应用商店" 这样的概念.
2. 安装软件包
sudo yum install [y] package's name
注意事项:
- 安装软件时由于需要向系统目录中写入内容, 一般需要 sudo 或者切到 root 账户下才能完成.
- yum安装软件只能一个装完了再装另一个. 正在yum安装一个软件的过程中, 如果再尝试用yum安装另外一个软件, yum会报错.
- yum会自动找到都有哪些软件包需要下载,这时候在键盘上输入‘y’确认安装即可。如果输入yum指令时带有 -y选项,这就意味着当由提示时自动输入‘y’。
- 当出现‘complete’字样,说明下载成功。
3. 删除软件包
sudo yum remove package's name
输入想要删除的软件包的名字来进行删除,同样也需要sudo 或者切到 root用户才能完成。
3、yum的周边知识
3.1 yum的软件包都是从哪里来的?是从哪里能下载到这些软件包?
当yum需要下载软件时,需要从yum的远端仓库(远端服务器)中来搜寻想要下载的软件包。
yum的远端仓库的相关配置文件也存放在Linux系统的 /etc/yum.repos.d/ 这个目录中
3.2 yum的拓展软件源
yum的拓展软件源中有着官方软件源中都没有的资源包,以满足用户更多的需求。
拓展软件源的安装
sudo yum install -y epel-release
二、vim -- Linux的开发工具也是一款多模式的编辑器
1、介绍
vim 是从 vi 发展出来的一个文本编辑器。代码补全、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。
简单的来说,vi 是老式的字处理器,不过功能已经很齐全了,但是还是有可以进步的地方。 vim 则可以说是程序开发者的一项很好用的工具。
vim编辑器中有着12种编辑模式,但是我们目前只需要掌握好这三种编辑模式(命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode))
2、基本的三种模式
- 2.1 正常/普通/命令模式(Normal mode)
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode
- 2.2 插入模式(Insert mode)
只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。
- 2.3 末行模式(last line mode)
文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下,shift+: 即可进入该模式。要查看你的所有模式:打开vim,底行模式直接输入
:help vim-modes
我这里一共有12种模式:six BASIC modes和six ADDITIONAL modes.
当我们在命令行输入 vim + 文件名进入编辑器时,默认的模式是NORMAL MODE(命令模式)。
后续编辑器模式的转换都会在各位vim编辑器左下角标红的地方显示。
三种模式之间的切换
3、三种模式的使用
在正式介绍三个模式前先说明,每当我们进入vim时,默认的模式是命令模式(Normal mdoe)。我们也可以使用键盘上不同的按键来进行不同的操作。
3.1 命令模式(Normal mode)的命令集
3.1.1 移动光标
- vim可以使用键盘的方向键来控制光标,但是在vim中最初的操作是使用键盘上的[h]、[j]、[k]、[l]这四个字母来分别控制光标左、下、上、右的移动
- 按下 G(shift + g) 跳到文件的末尾,按下 gg 跳到文件的开头
- 按下 $(shift + 4) 定位到当前行最右侧结尾处,按下 ^(shift + 6) 定位到当前行最左侧结尾处
- 按下 w 跳到下个字的开头,按下 e 跳到下个字的结尾,按下 b 回到上个字的开头
3.1.2 删除文字
- 按下 x ,每按一次,删除光标所在位置的一个字符;按下 nx,删除光标所在位置的“后面”(包括自己在内)的n个字符
- 按下 X(shift + x),每按一次,删除光标所在位置的“前面”的一个字符;按下 nX(shift + x),删除光标所在位置的“前面”的n个字符
- 按下 dd 删除光标所在行;按下 ndd 从光标所在行开始删除n行
3.1.3 复制
- 按下 yy 复制光标所在行到缓冲区;按下 nyy 拷贝从光标所在行往下数n行文字
- 按下 p 将缓冲区的字符贴到光标所在行的下一行;按下 np 在下一行进行多次粘贴
- tip:所有与‘y’有关的复制指令都必须与‘p’配合才能完成复制与粘贴的功能。
3.1.4 替换
- 按下 r 替换光标所在处字符
- 按下 R(shift + r) 替换光标所在处字符,直到按下 [Esc]键 为止
3.1.5 撤销上一次操作
- 按下 u 回到上一次操作,多次按下 u 可以执行多次回复
- 按下 Ctrl + r 对撤销进行撤销
3.1.6 更改
- 按下 cw 更改光标所在处的字到字尾处
- 按下 cnw 更改n个字
3.1.7 跳转至指定行
- 按下 Ctrl + g 列出光标所在行号
- 按下 nG(shift + g) 表示移动光标至文章的第n行行首
3.2 插入模式(Insert mode)
- 在vim编辑器中,只有在插入模式下才能进行文字输入。
- 在插入模式中,直到按下 [Esc]键 才能退出插入模式回到命令模式。
3.3 底行模式(Last line mode) 的命令集
在使用底行模式前,先记住按[Esc]键 确定已经处于命令模式,再按 [:] 冒号进入底行模式
3.3.1 列出行号
- 输入 set nu 后,会在文件中的每一行前面列出行号
3.3.2 跳到文件的某一行
- 在冒号后输入一个数字,再按回车键就会跳到该行
3.3.3 保存文件
- 在冒号后输入 w 就可以保存文件
3.3.4 查找字符
- 先按 [/]键 ,再输入想要寻找的字符。如果第一次找到的字符不是想要的,可以按 [n]键 往后寻找,直到找到想要的字符
- 先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 [n]键 会往前寻找到您要的关键字为止
3.3.5 离开vim
- 按 [q]键 就是退出,如果无法离开vim,可以在 [q]后面加一个 [!] 强制离开vim
- 一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。
4、不小心没保存vim编辑的文件就直接退出
当我们在vim中输入完代码后,因为某些原因没有保存就直接退出vim或者是直接关闭了xshell。所以当我们再次用vim打开文件时就会出现这种情况:
由于我们强制退出了vim,系统直接帮我们保存并生成了一个 名字为.test.c.swp的隐藏文件
所以我们有两种方法可以解决这个问题
- 当我们进去vim后,输入r,也就是恢复的意思。随后我们进入底行模式并保存退出文件,当我们再次进入文件时还是会出现我们第一次进入文件的框子,原因是系统建立的隐藏文件还未删除,所以我们输入d,也就是删除这个隐藏文件就能正常vim这个文件了。
- 不用进入vim,直接删除把这个.test.c.swp隐藏文件给删除。但是这样就没有保存之前文件的数据。
5、批量注释以及删除空格
批量注释:
- Ctrl + v
- 通过 h,j,k,l 进行区域选择
- shift + i
- 按下 //
- 按下 Esc键
批量删除注释、删除空格
- Ctrl + v
- 通过 h,j,k,l 进行区域选择
- 按下 d
三、Linux的编译器 -- gcc/g++
1、介绍
- gcc(GUN C Compiler)是GCC中的c编译器,而g++(GUN C++ Compiler)是GCC中的c++编译器。
- gcc和g++两者都可以编译c和cpp文件,但存在差异。gcc在编译cpp时语法按照c来编译但默认不能链接到c++的库(gcc默认链接c库,g++默认链接c++库)。g++编译.c和.cpp文件都统一按cpp的语法规则来编译。所以一般编译c用gcc,编译c++用g++。
这里我用gcc来举例,因为gcc和g++的使用方法都差不多
使用格式:gcc [选项] 要编译的文件 [选项] [目标文件]
选项:
- -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
- -S 编译到汇编语言不进行汇编和链接
- -c 编译到目标代码
- -o 文件输出到 文件
- -static 此选项对生成的文件采用静态链接
- -g 生成调试信息。GNU 调试器可利用该信息。
- -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库. -O0
- -O1
- -O2
- -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高-w 不生成任何警告信息。
- -Wall 生成所有警告信息。
当我们用gcc编译.c文件后,默认生成一个a.out的可执行文件 。当然我们也可以带 -o 选项生成自己想要的名字的可执行文件。
运行可执行文件
2、编译过程
四个阶段:
预编译 --> 编译 --> 汇编 --> 链接
2.1 预编译(进行宏替换)
预编译的功能:头文件展开,去注释,宏替换,条件编译
gcc –E hello.c –o hello.i
选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程.选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。
- 头文件展开:本质就是把头文件的内容拷贝到源文件中。
- 条件编译:运用条件编译的指令通过给编译器传递不同宏的值对代码进行有利的动态裁剪
-D选项:定义宏及其值。在条件编译中,通过给编译器传递不同的宏值,来进行对代码的动态裁剪。
为什么头文件开头会这样写
原因就是防止头文件被重复包含。
如果在源文件中重复包含多个头文件,在预编译过程中系统就会把多个头文件展开,而一个stdio.h文件大概有800多行,多个头文件一起展开会对操作系统造成极大的负担。
2.2 编译(生成汇编)
- 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
- 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
gcc -S hello.i -o hello.s
-S 编译到汇编语言不进行汇编和链接
2.3 汇编(生成机器可识别代码)
- 汇编阶段是把编译阶段生成的“.s”文件转成目标文件
- 读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
gcc -c hello.s -o hello.o
-c 编译到目标代码
2.4 链接(生成可执行文件或者库文件)
- 在成功编译之后,就进入了链接阶段。
gcc hello.o –o hello
3、 函数库
在连接过程中,我们需要将汇编后的文件与函数库进行连接,这样才能形成一个可执行文件。
这里就涉及到一个重要概念:函数库
函数库一般分为两种:静态库和动态库(本质都是文件)
3.1 静态库(允许复制的库)
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
优点:
- 不依赖库
- 同类型平台中都可以直接运行使用
缺点:
- 可执行程序体积较大,比较浪费资源 -- 磁盘、内存、网络等资源
连接方式:gcc test.c -o test test-static -static
3.2 动态库(允许关联的库)
动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc hello.o –o hello
优点:
- 比较节省资源,不会出现太多重复代码
缺点:
- 对库的依赖性比较强,一旦库丢失,所有使用这个库的程序都无法正常运行
连接方式:gcc test.c -o test
使用动态库连接文件和使用静态库连接文件大小的区别:
3.3 ldd指令 -- 可以查看一个可执行程序所依赖库的情况
格式:ldd + 文件名
四、Linux项目自动化构建工具 -- make/Makefile
- make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
- make是一条命令,makefile是一个文件(里面存放可执行程序的依赖关系和依赖方法),两个搭配使用,完成项目自动化构建。
makefile/Makefile 文件的结构:
示例:
1 test:test.c
2 gcc -o test test.c
3 clean:
4 rm -f test
那在makefile文件中什么是依赖关系,什么是依赖关系?
依赖关系:
- 依赖关系由目标文件和依赖文件列表组成,告诉make工具是哪个文件需要被构建。
- 目标文件是我们想要生成的文件,目标文件要通过依赖文件和依赖关系才能生成可执行程序。(相当于我为什么要帮?)
依赖方法:
- 包含了一系列的指令,这些指令被执行后生成相对应的目标文件
在上面的示例中,makefile文件中存在两个目标文件test 和 clean。那我们就以依赖关系和依赖方法来对这两个目标文件进行解释。
1.依赖关系
- 目标文件test在依赖关系中的依赖文件是test.c,所以在生成目标文件test之前,我们首先得生成依赖文件test.c
- 目标文件clean由于在依赖关系中并没有依赖文件,所以就不能生成目标文件clean
2.依赖方法
- 对于目标文件test来说,依赖方法就是使用gcc编译器将依赖文件test.c进行编译并将生成的可执行文件重命名为test
- 对于目标文件clean,由于没有实际的依赖关系,所以它后面所定义的命令将不会被自动执行。不过,我们可以要求make执行,既命令 -- make clean,以此来清除test这个目标文件
3.补充(伪目标)
- 对于clean这种没有实际的依赖关系的目标文件,我们并不是要生成clean这个文件,所以make无法生成它的依赖关系和决定它是否要执行。我们只有通过显示地指明这个“目标”才能让其生效。对于这种文件我们称作伪文件。当然,“伪目标”的取名不能和文件名重名,不然其就失去了“伪目标”的意义了。
- 当然,为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”。
只要有这个声明,不管是否有“clean”文件,要运行“clean”这个目标,只有“make clean”这样
- make和makefile形成目标文件的时候,默认是自上而下扫描makefile文件。所以默认形成的是第一个目标文件。
当make指令执行后,扫描makefile文件。发现有两条待执行指令,但make默认先执行第一个目标文件,也就是mybin文件。其依赖的方法就是gcc编译test.c。
- 为什么make指令执行后创建的可执行文件,再输入一次make就创建不了了呢?
原因是由于可执行文件的最近修改时间比源文件test.c的最近修改时间还新,所以如果源文件test.c不更新代码,那可执行文件就是最新的文件。那make就不用重新创建新的可执行文件。
- 有什么方法能在不修改文件内容的情况下,还能执行make指令呢?
可以修改Modify,用touch命令可以对源文件的A、C、M时间进行刷新,这样就可以让make指令再执行一次。
扩展
- 在makefile中,$@代表目标文件,$^代表源文件(依赖文件).这两个符号,makefile可以自动识别。
- 当然,也可以在makefile一开始就定义变量,不用定义类型。使用$(变量)来替换变量所对应的值可以将这种定义的变量看作宏。