想用linux开发一些软件等必须要会的几种开发工具是必不可少的,在yum vim gcc gdb中指令繁杂的是vim和gdb这两个工具,至于yum和gcc的指令就比较简单了。
yum是linux的软件包管理器,那什么是软件包呢?
软件包:在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装. 软件包和软件包管理器, 就好比 "App" 和 "应用商店" 这样的关系. yum(Yellow dog Updater, Modifified)是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat, Centos等发行版上
注意事项:关于yum的所有操作必须保证主机(虚拟机)网络畅通!!
yum工具的常用选项有:
yum install : 表示安装软件包
在这里我以gdb为例,由于我的linux环境中已经有了gdb调试器,所以机器告诉我无需下载。
yum list : 列出所有可供安装的软件包
由于list显示出的包太多所以我们截取一部分。
yum list | grep xxx :由于list显示出的安装包太多所以我们用管道的方式只筛选出我们关注的包(xxx代表包的关键字,比如要查找ls,那么xxx就是ls)
上图是我们以ls为例
yum search : 搜索包含指定关键字的软件包
同样我们以ls为例:
yum remove : 卸载指定的软件
以gdb为例在删除的时候会询问是否删除,如果输入Y就删除了。
yum makecache : 将服务器的软件包信息缓存到本地
yum clean all : 清除缓存中老旧的头文件和软件包
yum -y update : 升级所有包的同时也升级软件和系统内核
yum -y upgrade : 只升级所有包,不升级软件和系统内核,软件和内核保持原样
以上就是yum的常用命令,命令并不多只要多练习很快就能掌握。
由于vim的模式很多在这里我们只讲解最常用的四个模式,分别是命令模式,插入模式,底行模式和替换模式
命令模式:
vim + 文件名进入vim
刚打开vim默认就在命令模式中,在命令模式中不可以直接修改代码需要输入相对应的指令才可以修改。
由于我的vim是已经配置过的所以会和大家的不一样。
插入模式:(进入插入模式需要在命令模式下按i或者a或者o还有其他进入插入模式的途径就不介绍了)
i : 光标不动进入插入模式
按i后进入插入模式光标不变
a:光标向后移动一个然后进入插入模式
按a进入插入模式发现光标向后移了一个位置
o:光标新起一行进入插入模式
按o后可以看到光标新起一行进入插入模式
底行模式:(在命令模式下按shift + ; 进入底行模式)
上面的界面就是底行模式,底行模式可以在底下的命令行输出指令来控制vim。
由于避免多开vim的情况,所以建议大家在进入底行模式前先退回到命令模式,不论在任何模式下要退回到命令模式下只需要按ESC键即可。
替换模式:(在命令模式下shift + r 进入替换模式)
替换模式顾名思义就是替换非常方便。
下面进入在vim中最实用的指令讲解:
底行模式下的命令:
w : 保存所修改的文件
q : 直接退出文件,如果已经修改了文件使用q会提示
wq : 保存并退出文件
! : 强制执行(与其他命令配合使用) 比如 :w ! :强制保存
set nu : 调出行号
set nonu : 取消行号
! + 指令 :跳出vim显示指令
比如上图的! ls 就是在vim中显示当前路径下的ls指令
vs + 文件名:分屏使用(如果没有这个文件则会创建一个文件)
如上图在此路径下并没有test.h文件,在我们使用vs命令后自动给我们创建了一个.h文件并且于刚刚的test.c文件分屏使用,理论上使用vs分屏没有次数,但是如果要分好几个文件的屏那么体验会非常不好。
在分屏模式下想要关闭或者修改哪个文件就要让光标在那个文件里,所以移动光标的指令必不可少
ctrl + ww:在分屏模式下切换光标
关闭哪个文件只需要让光标在哪个文件里然后在底行模式下用q或者wq关闭即可,这个操作与单个文件一样。
接下来的所有命令都在命令模式下使用:
注意:vim不支持右边的小数字键盘,所以输入数字在字母区的上面输入。
yy/nyy : 复制当前行或者复制当前行在内的指定若干行
此操作需要与粘贴指令配合所以先介绍粘贴指令在一起演示:
p/np : 粘贴一行或者多行相同的内容到当前光标所在行之下
当我的光标放在第9行时在键盘输入yy后然后直接输入p就将第九行的内容自动粘贴到下一行,如果想要复制第九行到第13行则输入5yy就是复制五行的内容然后p即可。如果想要10行一样的int i = 10那么只需要在第九行yy一下然后输入10p那么就自动粘贴了10行。
u : 撤销刚刚的操作(需要注意的是即使已经保存文件也可以撤销,但是一旦退出vim则不可以再撤销之前的命令)
ctrl + r : 对刚刚进行的撤销进行撤销
dd/ndd : 对当前行或者当前行在内的n行的内容进行剪切
比如我的光标在第9行然后键盘输入5dd则将第九行开始的后五行内容全删掉了
dd + p :dd是剪切内容p是复制内容所以dd+p可以实现内容的移动
如图所示是使用3dd + p指令后的代码
shift + g : 将光标定位到文档最结尾
gg :将光标快速定位到文档最开始
n + shift + g :将光标定位到第n行
shift + $(实际就是$键) :将光标定位到文档行的结尾
比如光标在第九行i的前面使用命令后光标到结尾
shift + ^(实际就是^):将光标定位到文档行的开始与$是一对
nw,nb : 按照单词为单位在行内进行前后移动n个单词,w向后,b向前
shift + ~ (也就是~):快速将光标指向的字符进行大小写转换
nr + 要替换的字符 : 替换n个光标(从左到右n个)所在的字符
nx : 行内向后删除n个字符
n shift x : 行内向前删除n个字符
h j k l :h:光标向左移动 j : 光标向下移动 k:光标向上移动 L :光标向右移动
以上就是vim中常用的命令及演示。
二、gcc/g++的使用
gcc/g++是一个编译器
gcc完成需要以下几个步骤:
1.预处理(头文件展开,条件编译,宏替换,去注释等)
使用: gcc –E hello.c –o hello.i
-E :从现在开始进行程序的翻译,预处理做完就停下来
gcc -E + 文件名 :直接生成.i文件
gcc -E + 原来的文件名 + 自己想取的文件名(最好后缀为.i,因为.i是预处理后的代码文件):将预处理后的代码文件写入自己命名的文件中
2. 编译(生成汇编语言)
实例: gcc –S hello.i –o hello.s
-S :从现在开始进行程序的翻译,当编译做完就停下来
gcc -S + 文件名:形成汇编代码(默认形成一个.s文件)在这里注意如果刚刚我们已经已经有了预处理后的.i文件那么直接用.i文件即可,如果用原来.c文件则会又进行一次预处理
gcc -S + 原来文件名 + -o + 自己命名的文件名 :形成一个自己指明的汇编文件
编译过程为:扫描程序->语法分析->语义分析->源代码优化->代码生成器->目标代码优化;
扫描程序进行语法分析,从左向右,从上往下扫描源程序字符,识别出各个单词,确定单词类型。
语法分析是根据语法规则,将输入的语句构建出分析树,或者语法树,也就是parse tree或者syntax tree
语义分析是根据上下文分析函数返回值类型是否对应这种语义检测,可以理解语法分析就是描述一个句子主谓宾是否符合规则,而语义用于检测句子的意思是否是正确的
目标代码生成指的是把中间代码变换成为特定机器上的低级语言代码
3. 汇编(可重定位目标二进制文件,不可以被执行的,bin.obj)
4.链接(将我们这自己形成的.obj文件和库文件等合并,形成可执行程序)
ldd + 链接好的文件 :可以显示都链接了哪些库
直接gcc + 文件名会形成一个a.out可执行文件,然后./a.out可以直接运行程序
如果想形成一个自己命名的文件:gcc + 文件名 -o + 自己命名的文件
gcc + 文件名 -o + 自己命名的文件-static -static :形成一个静态库
当出现当出现cannot find -lc时,需要先下载c的静态库 yum install -y libc-static
Linux系统默认已经携带了语言级别的头文件和语言对应的库
ls /usr/include/stdio.h :查看C语言头文件所在位置
静态库 libxxxxx.a 动态库 libxxxxx.so
1.库分为静态库(专门让编译器,对用户的程序进行静态链接的)和动态库(专门让编译器,对用户的程序进行动态链接的)
2.静态库和静态链接:链接的时候,如果是静态链接,找到静态库,拷贝静态库中的我所需要的代码到我自己的可执行程序中
3.动态库和动态链接:链接的时候,如果是动态链接,找到动态库,拷贝动态库中的我所需要的代码的地址到我自己的可执行程序中相关的位置
4.静态链接成功:我们的程序,不依赖任何库,自己就可以独立运行
5.动态链接成功:我们的程序,还是依赖动态库,一旦动态库缺失,我们的程序便无法运行
6.静态库,因为自身拷贝的问题,比较浪费空间
7.动态库,因为可以做到被大家共享,所以真正的实现永远在库中,程序内部只有地址,比较节省空间。
8.静态库VS动态库 :Linux默认使用的是动态链接和动态库
接下来讲解Linux项目自动化构建工具-make/Makefifile
规则:makefile是一个围绕依赖关系和依赖方法构建的一个自动化编译的工具
依赖关系中:
目标文件对应的依赖文件列表可以是空
.PHONY:总是被执行的
比如:
在上图的makefile里,test依赖test.c. 而clean后面为空说明目标文件对应的依赖文件列表可以是空
makefile文件中,保存了编译器和链接器的参数选项,并且描述了所有源文件之间的关系。make程序会读取makefile文件中的数据,然后根据规则调用编译器,汇编器,链接器产生最后的输出。
makefile里主要包含了五个东西:显式规则,隐晦规则,变量定义,文件指示和注释
显式规则说明了如何生成一个或多个目标文件
make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙的简略的书写makefile,比如源文件与目标文件之间的时间关系判断之类
在makefile中可以定义变量,当makefile被执行时,其中的变量都会被扩展到相应的引用位置上,通常使用$(var)表示引用变量
文件指示:包含在一个makefile中引用另一个makefile,类似C语言的include;
注释:makefile中可以使用#在行首表示行注释
默认情况下,make命令会在当前目录下按顺序找寻文件名为GNUmakefile,makefile,Makefile的文件,找到了解释这个文件
make的执行规则是,只生成所有目标对象的第一个,当然make会根据语法规则,递归生成第一个目标对象的所有依赖对象后再回头生成第一个目标对象,生成后退出
make在执行makefile规则中,根据语法规则,会分析目标对象与依赖对象的时间信息,判断是否在上一次生成后,源文件发生了修改,若发生了修改才需要重新生成
makefile中的伪对象表示对象名称并不代表真正的文件名,与实际存在的同名文件没有相互关系,因此伪对象不管同名目标文件是否存在都会执行对应的生成指令。伪对象的作用有两个。1.使目标对象无论如何都要重新生成。2.并不生成目标文件,而是为了执行一些指令。
makefile中使用.PHONY来声明伪对象
三、git的使用
如果没有Git就先安装git,命令为 yum install git
我这里使用的码云,首先在码云中新建一个仓库然后复制仓库的链接,然后再linux中输入命令
git clone + 仓库链接 : 就能将仓库克隆到本地了
上图是我的仓库的路径,该怎么提交呢?首先将你要提交的文件拷贝到这个路径中
然后 git add . : .的意思是将当前目录下所有没有被添加的文件添加到仓库
接下来 git commit -m "此处是提交日志 " : 提交日志必须好好写,这个可以查到
然后git push即可,在这里会有一些问题,如果你是第一次提交则会出现git config --global user.email "[email protected]"和git config --global user.name "Your Name"这样的报错,这时候可以将其保存粘贴下来输入你自己的名字和邮箱运行即可。
这个时候代码就已经提交到远端仓库了。
git log :可以查看以往提交和删除的日志
git rm + 文件名 :在git中删除一个文件,删除后远端仓库也没有这个文件了
如果要在linux中把仓库删了只需要:rm .git -rf 即可
四、gdb的使用
后面的-std=c99是什么意思呢?因为我们在.c文件中使用了新的C语言语法特性linux默认的C语言标准是不支持这个特性的,所以我将其改为c99就可以正常编译了。
只有在c99的标准下才默认支持for循环内定义变量。
接下来我们讲解gdb的常用指令:
首先 gdb + 可执行文件 开始对文件的调试(注意是可执行文件而不是普通文件)
当出现如上图的提示的时候即可调试。
list / L + 行号:显示文件的源代码,接着上次的位置往下列每次列10行
L + 1 就是从第一行开始显示
list / L + 函数名 :列出某个函数的源代码
run / r :直接运行完整个程序
break / b + 行数:在某行上打上断点
如图在第五行打上了断点
info b/break : 查看断点信息
此命令在上图中已有显示。
d + 断点编号 :删除某个断点
d + breakpoints :删除全部断点
disable + breakpoint + 断点编号 :禁用某个断点
enable + breakpoint + 断点编号 : 打开某个断点
quit 或者 ctrl + d : 退出gdb
n/next : 逐过程调试(遇见函数不进入函数)
在这里要说明一下gdb的每次run都会从距离main函数最近的那个断点开始,如果没有打断点run一下直接就程序运行完了也就无法调试,所以正确的步骤是先打断点,然后run,然后逐过程或者逐语句进行调试
s/step : 逐语句调试(遇见函数会进入函数)
p + 变量 :打印变量值
display + 变量 : 常显示变量
每一步调试都会自动把要常显示的变量打印一遍
undisplay + 常显示变量的编号 : 取消常显示
until + 行号 :在函数内,进行指定位置跳转,执行完区间代码
finish : 进入一个函数,只执行完一个函数就停下来
c : 从一个断点处直接运行到下一个断点处
set var : 修改变量的值
以上就是在gdb中最常用的调试命令了。
要掌握好linux这些环境基础开发工具是必须要会的,学会了这些再去写代码有着事半功倍的效果,在这些工具中,大多数指令是需要经常使用才能记住的,所以大家一定要多去练习这些指令,如果有能力的话还可以自己更深入的去研究,需要说明的是,虽然我们在文章中讲的git指令很少很简单,但实际只是让大家掌握了如何将代码提交到远程仓库,git还有很多功能是非常优秀的这就需要大家自己下去慢慢学习。