目录
一.软件包管理器
一).软件包
- 在Linux下安装软件, ⼀个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序.
- 但是这样太麻烦了, 于是有些人把⼀些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在⼀个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.
- 软件包和软件包管理器, 就好比 "App" 和 "应用商店" 这样的关系.
- yum(Yellow dog Updater, Modified)是Linux下非常常用的⼀种包管理器. 主要应用在Fedora,RedHat, Centos等发行版上.
- Ubuntu:主要使用apt(Advanced Package Tool)作为其包管理器。apt同样提供了⾃动解决依赖关系、下载和安装软件包的功能
二).安装软件
# Centos
$ sudo yum install sl
# Ubuntu
$ sudo apt install sl
虚拟机安装拓展软件源: yum install -y epel-realse
注意事项:
- 安装软件时由于需要向系统目录中写入内容, ⼀般需要 sudo 或者切到 root 账户下才能完成.
- yum/apt安装软件只能⼀个装完了再装另⼀个. 正在yum/apt安装⼀个软件的过程中, 如果再尝试用yum/apt安装另外⼀个软件, yum/apt会报错.
- yum/apt 会⾃动找到都有哪些软件包需要下载, 这时候敲 "y" 确认安装.
- 出现 "complete" 字样或者中间未出现报错, 说明安装完成.
三).删除软件
# Centos
sudo yum remove sl
# Ubuntu
sudo apt remove sl
二.编辑器vim
一).vim的基本介绍
讲解vim的三种模式(其实有好多模式,目前掌握这3种即可),分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下。
1.正常/普通/命令模式(Normal mode)
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到last line mode
2.插入模式(Insert mode)
只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。
3.底行模式(last line mode)
文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。在命令模式下,*shift+:* 即可进入该模式。要查看你的所有模式:打开 vim,底行模式直接输入 :help vim-modes
二).vim的基本操作
1.进入文本
进⼊vim,在系统提⽰符号输⼊vim及⽂件名称后,就进⼊vim全屏幕编辑画⾯
2.切换模式
进⼊vim之后,是处于[正常模式],你要切换到[插⼊模式]才能够输文字
[正常模式]切换⾄[插⼊模式] 按下「i」
[插⼊模式]切换⾄[正常模式] 处于[插⼊模式],就只能⼀直输⼊文字,如果发现输错了字,想用光标键往回移动,将该字删除,可以先按⼀下「ESC」键转到[正常模式]再删除文字。当然,也可以直接删除。
[正常模式]切换⾄[末⾏模式] 「shift + :」, 其实就是输⼊「:」
3.退出文本
退出vim及保存文件,在[正常模式]下,按⼀下「:」冒号键进⼊「Last line mode」:
w (保存当前⽂件)
wq (输⼊「wq」,存盘并退出vim)
q! (输⼊q!,不存盘强制退出vim)
shift + z + z(保存退出vim)
三). vim--正常模式--命令集
1.移动光标
1.按「i」
按「i」切换进入插入模式「insert mode」,按“i”进⼊插⼊模式后是从光标当前位置开始输入⽂件;
2.按「a」
按「a」进⼊插入模式后,是从目前光标所在位置的下⼀个位置开始输入文字;
3.按「o」
按「o」进⼊插入模式后,是插⼊新的⼀行,从行首开始输入文字
4.按「shift + g」
移动到文章的最后
5.按「 shift + $(4) 」
移动到光标所在行的“行尾“
6.按「shift + ^(6)」
移动到光标所在行的“行首"
7.按[g + g]
进入到本文开始
8. 按[shift+g]
进入文本末端
9.其他的命令
按「w」:以单词为单位,光标跳到下个字的开头
按「e」:以单词为单位,光标跳到下个字的字尾
按「b」:以单词为单位,光标回到上个字的开头
按「#l」:光标移到该行的第#个位置,如:5l,56l
按「ctrl」+「b」:屏幕往“后”移动一页
按「ctrl」+「f」:屏幕往“前”移动一页
按「ctrl」+「u」:屏幕往“后”移动半页
按「ctrl」+「d」:屏幕往“前”移动半页
2.删除文字
1.按「x」
每按⼀次,删除光标所在位置的⼀个字符
2.按「d + d」
剪切或删除光标所在行
3.其他
「#x」:例如,「6x」表示删除光标所在位置的“后面(包含自己在内)”6个字符
「X」:大写的X,每按⼀次,删除光标所在位置的“前面”⼀个字符
「#X」:例如,「20 + shift + x」表示删除光标所在位置的“前面”20个字符
「#dd」:从光标所在行开始删除#行
3.复制-粘贴
1.按「yy」
复制光标所在行到缓冲区。
2.其他
「yw」:将光标所在之处到字尾的字符复制到缓冲区中。
「#yw」:复制#个字到缓冲区
「#yy」:例如,「6yy」表示拷贝从光标所在的该⾏“往下数”6行⽂字。
「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能。
4.替换
1.按「r」
替换光标所在处的字符。
2.按「R」
替换光标所到之处的字符,直到按下「ESC」键为⽌
3「shift + ~ 」
大小写切换
5. 撤销上⼀次操作
一旦退出wq文件编辑,就无法再进行文件撤销了。但只是保存w,没有进行退出q,可以撤销。
1.「u」
如果您误执行⼀个命令可以马上按下「u」,回到上⼀个操作。按多次“u”可以执行多次复。
2.「ctrl + r」
撤销的恢复
6.更改
1.「cw」
更改光标所在处的字到字尾处
2.「c#w」
例如,「c3w」表示更改3个字
7.跳至指定的行
1.「ctrl」+「g」
列出光标所在行的行号。
2.「# + shift + g」
「15 + shift + g」,表示移动光标至文章的第15行行⾸。
四).vim--底行模式--命令集
在使用末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进⼊末行模式。
1.列出行号
「set nu」: 输⼊「set nu」后,会在文件中的每⼀行前面列出行号。
2.跳到文件中的某⼀行
「#」:「#」号表示⼀个数字,在冒号后输入⼀个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。
3.查找字符
- 「/关键字」: 先按「/」键,再输入您想寻找的字符,如果第⼀次找的关键字不是您想要的,可以⼀直按「n」会往后寻找到您要的关键字为⽌。
- 「?关键字」:先按「?」键,再输入您想寻找的字符,如果第⼀次找的关键字不是您想要的,可以⼀直按「n」会往前寻找到您要的关键字为⽌。
4.补充
1).「: + ! + 命令」
直接在vim中执行命令
2).「: + %s+ / 当前文本内容 / 新内容 /」
批量化替换
3).「: + vs+ 文件名」
分屏操作 (切换文件:Ctrl + w + w)
五).简单vim的配置
1.配置文件的位置
在目录 /etc/ 下面,有个名为vimrc的文件,这是系统中公共的vim配置文件,对所有用户都有效。
而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为:“.vimrc”。例如,/root目录下,通常已经存在⼀个.vimrc文件,如果不存在,则创建之。
切换用户成为自己执行 su ,进入自己的主工作目录,执行 cd ~
打开自己命令下的.vimrc文件,执行 vim .vimrc
2.常用配置选项
" 开启语法高亮
syntax on
" 显示行号
set number
" 高亮当前行
set cursorline
" 自动缩进
set autoindent
" 设置 Tab 为 4 个空格
set tabstop=4
set shiftwidth=4
set expandtab
" 搜索时忽略大小写
set ignorecase
" 智能大小写(如果搜索内容有大写则区分大小写)
set smartcase
" 启用鼠标支持
set mouse=a
3.插件配置
可以看下面这位大佬的连接,非常详细
三.编译器gcc/g++
一).背景知识
- 预处理(进行宏替换/去注释/条件编译/头文件展开等)
- 编译(生成汇编)
- 汇编(生成机器可识别代码)
- 连接(生成可执行文件或库文件)
二).gcc编译选项
1.预处理(进行初步操作)
- 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
- 预处理指令是以#号开头的代码行。
实例: gcc –E hello.c –o hello.i
选项“-E”,该选项的作⽤是让 gcc 在预处理结束后停止编译过程。
选项“-o”是指目标⽂件,“.i”⽂件为已经过预处理的C原始程序。
2.编译(生成汇编)
- 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
- 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
实例: gcc –S hello.i –o hello.s
3.汇编(生成机器可识别代码)
- 汇编阶段是把编译阶段⽣成的“.s”文件转成目标文件
- 读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
实例: gcc –c hello.s –o hello.o
4.连接(生成可执行文件或库文件)
- 在成功编译之后,就进入了链接阶段。
实例: gcc hello.o –o hello
5.补充
- E -S -c 形成 .i .s .o文件
我们一般先将源文件编译成 .o文件,再将所有的.o文件连接成可执行程序
三).动态链接和静态链接
1.动态链接
动态链接的基本思想是把程序按照模块拆分成各个相对独立部分,在程序运⾏时才将它们链接在⼀起形成⼀个完整的程序,而不是像静态链接⼀样把所有程序模块都链接成⼀个单独的可执行文件
举个简单的例子吧
2.静态链接
在我们的实际开发中,不可能将所有代码放在⼀个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立的,而会存在多种依赖关系,如⼀个源文件可能要调用另⼀个源文件中定义的函数,但是每个源⽂件都是独立编译的,即每个*.c文件会形成⼀个*.o文件,为了满足前面说的依赖关系,则需要将这些源文件产生的目标文件进行链接,从而形成⼀个可以执行的程序。这个链接的过程就是静态链接
四).静态库和动态库
- 静态库(只在链接时有用)是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名⼀般为“.a”
- 动态库与之相反,在编译链接时并没有把库文件的代码加⼊到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库⼀般后缀名为“.so”,如前面所述的libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc hello.o –o hello
- gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证
强制使用静态库生成:
Linux下,动态库XXX.so, 静态库XXX.a
Windows下,动态库XXX.dll, 静态库XXX.lib
库的名称:
1.动静态库对比:
- 动态库形成的可执行程序体积一定很小
- 可执行程序对静态库的依赖度小,动态库不能缺失
- 程序运行,需要加载到内存,静态链接的,会在内存中出现大量的重复代码,
- 动态链接,比较节省内存和磁盘资源
2.补充:
使用C++
初步认识库
四.自动化构建-make/Makefile
一).背景
- 会不会写makefile,从⼀个侧面说明了⼀个人是否具备完成大型工程的能力。
- ⼀个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了⼀系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
- makefile带来的好处就是⸺“自动化编译”,⼀旦写好,只需要⼀个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
- make是⼀个命令工具,是⼀个解释makefile中指令的命令工具,⼀般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了⼀种在工程方面的编译方法。
- make是⼀条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建
二).理解
makefile的基本概念---------依赖关系,依赖方法
依赖关系
上面的文件code,它依赖code.c
依赖方法
gcc -o code code.c ,就是与之对应的依赖关系
1.默认老代码不做重新编译
2.那么make怎么知道可执行程序和源文件的新旧问题?
操作:stat - 文件名
Modify:内容变更,时间更新
Chang:属性变更,时间更新
Access:常指的是文件
最近⼀次被访问的时间。在Linux的早期版本中,每当文件被访问时,其atime都会更新。但这种机制会导致大量的IO操作(多次查看才会改变)
通过对比源文件和可执行文件的Modify时间
项目清理
- 工程是需要被清理的
- 像clean这种,没有被第⼀个目标文件直接或间接关联,那么它后⾯所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令⸺“make clean”,以此来清除所有的目标文件,以便重编译
- 但是⼀般我们这种clean的目标文件,我们将它设置为伪目标,⽤ .PHONY 修饰,伪⽬标的特性是,总是被执行的
PHONY:让make忽略源文件和可执行目标文件的M时间对比
三).推导过程
code:code.o gcc code.o -o code code.o:code.s gcc -c code.s -o code.o code.s:code.i gcc -S code.i -o code.s code.i:code.c gcc -E code.c -o code.i .PHONY:clean clean: rm -f *.i *.s *.o code
当然一般没有人会像上面这么写
make是如何工作的,在默认的方式下,也就是我们只输入make命令。
1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2. 如果找到,它会找文件中的第⼀个目标文件(target),在上面的例子中,他会找到 code这个文件,并把这个文件作为最终的目标文件。
3. 如果 code文件不存在,或是 myproc 所依赖的后面的 myproc.o 文件的文件修改时间要比code这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成code这个文件。
4. 如果 code所依赖的 code.o 文件不存在,那么 make 会在当前文件中找目标为code.o 文件的依赖性,如果找到则再根据那⼀个规则生成 code.o 文件。(这有点像⼀个堆栈的过程)
5.当然,你的C文件和H文件是存在的啦,于是 make 会生成 code.o ⽂件,然后再用 code.o文件声明 make 的终极任务,也就是执行文件 hello 了。
6. 这就是整个make的依赖性,make会⼀层⼜⼀层地去找文件的依赖关系,直到最终编译出第⼀个⽬标⽂件。
7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理
8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
面对多个文件,我们习惯把源文件先编译.o文件,再进行链接
BIN=proc.exe #定义变量 CC=gcc #SRC=$(shell ls *.c) #采用shell命令⾏方式,获取当前所有.c⽂件名 SRC=$(wildcard *.c) #或者使⽤ wildcard 函数,获取当前所有.c⽂件名 OBJ=$(SRC:.c=.o) #将SRC的所有同名.c 替换 成为.o 形成⽬标⽂件列表 LFLAGS=-o #链接选项 FLAGS=-c #编译选项 RM=rm -f #引⼊命令 $(BIN):$(OBJ) @$(CC) $(LFLAGS) $@ $^ #$@:代表⽬标⽂件名。 $^: 代表依赖⽂件列表 @echo "linking ... $^ to $@" %.o:%.c #%.c 展开当前⽬录下所有的.c。 %.o: 同时展开同名.o @$(CC) $(FLAGS) $< #%<: 对展开的依赖.c⽂件,⼀个⼀个的交给gcc。 @echo "compling ... $< to $@" #@:不回显命令 .PHONY:clean clean: $(RM) $(OBJ) $(BIN) # $(RM) .PHONY:test test: @echo $(SRC) @echo $(OBJ)