linux开发工具
目录
linux开发工具
一、软件包管理器
二、Linux安装软件的方式
三、Linux软件生态
四、镜像源
4.1.镜像的概念
4.2.切换镜像源
五、软件包管理器的操作
5.1.查看软件包
5.2.安装软件
5.3.卸载软件
5.4.查看安装源
5.5.软件的分类
六、编辑器vim
6.1.vim的三种主模式
6.2.命令模式的操作
6.3.底行模式的操作
6.4.vim配置
七、编译器gcc/g++
7.1.编译与链接
7.2.ldd指令
7.3.条件编译
7.4.预处理的本质
7.5.汇编的本质
7.6.链接的本质
7.7.动静态库
7.8.静态链接
7.9.动态链接
7.10.补充知识
八、自动化构建工具
8.1.,Makefile的基本概念
8.2.依赖关系与依赖方法
8.3.项目清理与伪目标
8.3.Makefile的基本使用
8.4.文件时间详解
8.5.make的工作原理
8.6.Makefile的扩展语法
九、进度条
9.1.行缓冲区
9.2.倒计时
9.3.进度条
十、版本控制器Git
10.1.版本控制
10.2.数据安全与协作开发
10.3.Git的历史
10.4.Git的操作
十一、调试器gdb/cgdb
11.1.软件发布方式
11.2.cgdb命令
11.3.调试技巧
一、软件包管理器
在不同平台上,会有不同的软件下载安装渠道
手机上的应用商店相当于Linux中的软件包管理器
- 手机中的应用商店:华为应用商店、小米应用商店、苹果应用商店
- Linux中的软件包管理器:yum(centos)、apt(ubuntu)
手机上的App相当于Linux中的软件包
二、Linux安装软件的方式
方式一:下载程序源码并编译生成可执行程序
操作繁琐,需要自行解决依赖问题
优化:将常用软件预编译成软件包放在服务器
方式二:RPM软件包安装
直接安装预编译的RPM软件包
- 版本兼容性问题
- 依赖库文件缺失
方式三:软件包管理器安装
- Centos:yum(Yellow dog Updater,Modified)
- Ubuntu:apt(Advanced Package Tool)
从网络仓库直接下载安装,自动解决软件包的依赖问题
需要root权限安装拷贝到系统,安装后任何用户都能使用
三、Linux软件生态
生态问题是评估操作系统好坏的标准
Linux的配套软件是由它的生态提供
目的是让这款操作系统被更多的人接受
四、镜像源
4.1.镜像的概念
镜像:将国外服务器上的软件包同步拷贝到国内服务器
操作系统内部内置的是国外的下载链接
在国内需要切换镜像源,更改下载链接
4.2.切换镜像源
示例:ubuntu更新apt源
- 备份现有的apt源
- 下载选择的镜像源,替换配置文件
- 更新apt缓存
五、软件包管理器的操作
5.1.查看软件包
示例:查看lrzsz软件包的详细信息
5.2.安装软件
示例:安装lrzsz软件包
5.3.卸载软件
示例:卸载lrzsz软件包
5.4.查看安装源
示例:查看ubuntu安装源路径
- 标准源
- 扩展源
5.5.软件的分类
Epel:企业版Linux扩展软件源
Base:基础稳定软件源
六、编辑器vim
一款多模式编辑器
6.1.vim的三种主模式
命令模式(Normal mode)
功能:控制光标的移动,字符、字或行的删除
- 按i进入插入模式
- 按:进入底行模式
插入模式(Insert mode)
功能:只有在插入模式下才能输入文字
- 按ESC进入命令模式
底行模式(Last line mode)
功能:文件保存或退出、文本替换、找字符串、列出行号
- 按ESC进入命令模式
6.2.命令模式的操作
切换插入
i:从光标当前位置开始输入文字
a:从目前光标所在位置的下一个位置开始输入文字
o:在光标下一行另起一行在行首输入文字
移动光标
- nh:左移任意一位
- nj:下移任意一位
- nk:上移任意一位
- nl:右移任意一位
- nw:后移任意单词
- nb:前移任意单词
- gg:移动到文本开始
- G:移动到文本最后
- nG:移动到任意行号
- $:移动到当前行尾
- ^:移动到当前行首
删除文字
- x:删除或剪切光标所在位置的字符
- nx:删除或剪切光标所在位置与后面位置的任意字符
- X:删除或剪切光标所在位置前面的一个字符
- nX:删除或剪切光标所在位置前面的任意字符
- dd:删除或剪切光标所在行
- ndd:从光标所在行开始删除或剪切
复制粘贴
- yw:复制光标所在位置到字尾
- nyw:复制任意个字
- yy:复制光标所在行
- nyy:复制光标所在行与当前行往下的任意行
- np:光标下一行粘贴任意次
撤销操作
- u:撤销操作
- ctrl+r:撤销u操作
替换操作
- r:替换光标所在处的字符
- R:进入替换模式,替换光标所到之处的字符,按ESC键返回命令模式
- ~:切换大小写
批量操作
- ctrl+v:进入视图模式,选定区域
- I:从视图模式跳转到插入模式
- d:删除操作
- ESC:回到命令模式
查找操作
- #:选中单词
- n:逆向查找选中的单词
6.3.底行模式的操作
- w:保存
- q:退出
- wq:保存并退出
- w!:强制保存
- q!:强制退出
- wq!:强制保存并退出
- ZZ:退出
- set nu:设置行号
- set nonu:去掉行号
- !:在不退出vim情况下执行命令
- %s/dst/src:批量化替换
- vs new_src:分屏操作
- ctrl+ww:切换分屏
使用技巧
- vim src n:打开时光标跳转到指定行号
- !v:跳转到上一次用v开头的命令
6.4.vim配置
在目录etc中有一个.vimrc文件,是系统公共的vim配置文件,所有用户有效
在当前用户的家目录下,用户可以自己建立私有的配置文件,命名为.vimrc
常用配置
- 语法高亮:syntax on
- 显示行号:set nu
- 设置缩进:set shiftwidth = 4
- 注释信息:"
七、编译器gcc/g++
7.1.编译与链接
- 预处理
功能:宏替换、头文件展开、条件编译、去注释
-E:预处理结束后停止编译
-o:生成目标文件
.i:经过预处理后的文件(C/C++语言)
- 编译
功能:把代码翻译生成汇编语言
-S:只进行编译但不进行汇编,生成汇编代码后停止编译
.s:经过编译后的文件(汇编语言)
- 汇编
功能:把代码翻译成二进制语言
-c:将汇编语言翻译为二进制语言后停止
.o:经过汇编后的文件(二进制语言)
- 链接
功能:生成可执行文件或库文件
7.2.ldd指令
功能:查看可执行程序依赖哪些库
示例:查看a1依赖的C++标准库
注:a1中的C++标准库函数(比如:cout)需要从库中执行再返回(动态链接)
7.3.条件编译
-D:动态添加宏定义
条件编译的用途
- 业务功能区分
根据软件专业等级和收费模式裁剪代码
- 系统内核优化
内核源代码通过条件编译实现按需定制
- 实现跨平台适配
开发工具和应用软件通过条件编译实现多平台兼容
7.4.预处理的本质
修改编辑文本代码
7.5.汇编的本质
将程序转化为计算机可执行的二进制指令
计算机编译的历程
从最初的开关控制,到打孔编程,再到编译器技术
编译器的作用是将汇编语言翻译为二进制机器码
那么编译器又是用什么语言编写的呢?
编译器的自举过程
- 汇编语言的编译器
最初使用二进制版本的汇编编译器来编译汇编语言程序
随后就可以用汇编语言来编写更高级的编译器
此后就可以用汇编语言版本的编译器编译汇编语言程序
- C语言的编译器
最初使用汇编编译器来编译C语言程序
随后就可以用C语言来编写更高级的编译器
此后就可以用C语言版本的编译器来编译C语言程序
7.6.链接的本质
链接的本质:将目标文件进行合并
一些基础功能函数被打包成库,将自己写的代码编译成目标文件,与库进行链接,形成可执行程序
7.7.动静态库
库:一套方法或者数据集
作用:为开发提供最基本的接口与功能,加速二次开发
(注:Linux中的命令都依赖于C标准库)
动态库
- Linux:XXX.so
- windows:XXX.dll
静态库
- Linux:XXX.a
- windows:XXX.lib
库的命名规则:去掉lib前缀,去掉后缀,剩下的就是库的名字
- Linux下C语言的静态库:libc.a
- Linux下C语言的动态库:llbc.so
动静态库的对比
静态库只有在链接的时候有用,一旦形成可执行程序,静态库可以不需要
动态库形成的可执行程序体积一定很小
可执行程序对静态库的依赖度小,动态库不能缺失
7.8.静态链接
将静态库中的方法实现直接拷贝到使用该方法的地方
7.9.动态链接
在动态库中查询方法的地址,加载到内存后调用动态库中的方法
动静态链接对比
静态链接会在内存中出现大量重复代码
动态链接节省内存和磁盘资源
7.10.补充知识
gcc/g++默认使用的是动态链接
- gcc
- g++
使用静态链接时如果缺失静态库就会无法链接,此时需要添加静态库
- C语言的静态链接
- C++语言的静态链接
动态库的本质:将语言中的公共代码,未来在内存中只出现一份
Linux系统中的指令都依赖于动态库,如果把动态库删去,那么指令就无法执行
编辑sudo指令的白名单
编写多文件项目,需要先在当前目录下新建主函数源文件
再在当前目录新建lib文件存放自定义库的源文件与头文件
将它们的源文件编译成目标文件,再将所有目标文件链接成可执行程序
在提交程序时,只需要将头文件和目标文件提供给别人,不用给源文件
库:库文件 + 头文件
库文件(.so/.a):多个目标文件(.o)的集合
动静态库的本质:被打包起来的目标文件集合
(注:动静态库本身是库文件,而非广义的库)
Linux系统的头文件:
注:
- < >:仅从Linux系统的头文件路径下查找头文件
- " ":先从当前源码所在的项目本地目录中查找,再从Linux系统的头文件中查找
八、自动化构建工具
8.1.,Makefile的基本概念
Makefile:自动化构建脚本文件
Make:解释并执行Makefile指令的命令行工具
在大型项目中,源文件数量庞大,按照类型、功能、模块放在不同目录
Makefile通过定义构建规则明确
- 各个文件的编译顺序
- 文件之间的依赖关系
完成Makefile编写后,仅需执行make命令,整个工程自动编译,提高开发效率
8.2.依赖关系与依赖方法
依赖关系:文件myproc依赖myproc.c
依赖方法:通过gcc编译器将myproc.c编译成myproc
8.3.项目清理与伪目标
项目清理:工程是需要被清理的
伪目标:目标总是需要被执行对应的依赖关系和依赖方法
本质:让make忽略文件和可执行目标文件的M时间对比
(注:可执行程序没有修改一般不需要伪目标,默认旧代码不需要重新编译)
8.3.Makefile的基本使用
- 文件不总被执行
- 文件总被执行
8.4.文件时间详解
- Access Time:查看文件内容或属性的时间
- Modify Time:修改文件内容的时间
- Change Time:修改文件属性的时间
修改文件内容
更新Change time和Modify time
修改文件权限属性
更新Change time
查阅文件的内容
更新Access time
频繁更新访问时间会产生大量IO操作
只有在连续访问多次后,才会更新Access time
touch命令
touch后加不存在的文件名是创建新的文件
touch后加存在的文件是更新文件所有时间
更新时间后就可以再对文件进行make操作
因为源文件与可执行程序是无法同时产生的
Make通过修改文件内容的时间判断文件新旧
modify time:只更新查看内容时间,与内容有关
change time:只更新修改属性时间,与内容无关
access time:只更新查看文件时间,与内容无关
8.5.make的工作原理
make在当前目录下寻找makefile或Makefile文件
找文件中的第一个目标文件作为最终的目标文件
如果该目标文件的依赖文件不存在,会找依赖文件对应的依赖关系
再查找该依赖文件的依赖文件是否存在,直到查找最后的依赖文件
如果该依赖文件存在,最终编译出第一个目标文件
如果该依赖文件不存在,或者中途出错,直接退出
8.6.Makefile的扩展语法
=:定义变量
@:不回显命令
$():替换变量内容
$@:代表目标文件名
$^:代表依赖文件列表
$<:对展开的依赖.c文件一个一个交给gcc
%.c:展开当前目录下所有的.c
%.o:展开当前目录下所有的.o
#:注释
多文件编译
九、进度条
9.1.行缓冲区
回车(\r):回到当前行最开始
换行(\n):换到下一行
缓冲区:一段内存块
打印执行完成,显示器没有立即显示
休眠3s期间字符串存在行缓冲区中
刷新行缓冲区:换行或者程序退出
fflush刷新缓冲区可以直接打印出来
- 换行
- fflush刷新
9.2.倒计时
通过回车让光标回到最开始,输出倒计时
回车不支持数据刷新,需手动刷新缓冲区
最后换行刷新命令行,防止被命令行覆盖
优化:
显示器是字符设备,只认识字符
12345:'1''2''3''4''5'
%d:将内存中的数据转化为字符
打印时第二位的0不会消失(10 90 80 ... 00)
可以在d前面加2,设置位宽
可以在2前面加-,让最后的0输出在左边
9.3.进度条
- Makefile
- process.h
- process.c
- main.c
实验现象
解耦设计
十、版本控制器Git
10.1.版本控制
在企业级开发场景中,团队协作是关键,多个开发者参与一个项目时
必须借助集中式管理工具整合各方代码,来管理这些不同版本的文件
场景举例
同学A向老师提交实验报告,每次修改的版本都比前面差
多次修改后,老师要最初的版本,但学生A无法找回原件
同学B吸取A的教训,每次修改都将前一个版本进行备份
同学B的做法就叫作版本控制
同学B切换到先前版本叫回退
同学B回退备份的过程用工具自动化完成,这个工具叫版本控制器
老师:项目经理
同学:程序员
同学B在自己的D盘中建了一个data目录
将其他同学的文件添加进目录进行管理
那么所有同学的文件夹集合就叫做仓库
同学B的电脑只能自己访问,其他同学无法访问,所以他
买了一个配置高的云服务器,并且开发了一款客户端软件
在客户端中查看当前用户任意版本的实验报告,但同学们上传文件到云服务器需要网络
如果没有网络,就需要写一个应用程序,让每个同学都能在本地自动管理实验报告列表
每个同学的文件夹集合叫就做本地仓库
10.2.数据安全与协作开发
数据安全
本地仓库推送远端云服务器
每个用户要建立不同的仓库
本地允许用户新建多个仓库
支持多个仓库同时推送到自己的账户
登录注册给每一个用户提供一个目录
git && gitee && github
git:版本控制器软件,图中的xxx.exe,在客户端操作
gitee/github:基于git的网站或者平台,在服务端操作
可以云服务器端实现推送操作,实现数据同步
git既是一个客户端client也是一个服务器server
去中心化分布式的版本控制原则
协作开发
10.3.Git的历史
开源分布式版本控制器
Linus需要一款多人管理Linux操作系统各种版本的软件,支持代码提交后的版本发布与管理
Bitkeeper免费给Linux社区使用它的版本控制器,社区中有工程师尝试破解,所以Bitkeeper
停止与Linux社区合作,于是Linus自己编写了一款版本控制器软件,并且开源,命名为Git
10.4.Git的操作
新建仓库
复制项目链接
git clone 项目链接:将远端仓库拉取到本地仓库
.git:隐藏的本地仓库
README:软件说明书(en:英文版本)
git在提交的时候,只会提交数据变化的部分
将变化的信息存放在.git目录的objects文件中
当前工作区:.git所在的目录
git add:把文件添加到.git的暂存区
git commit:将暂存区的文件提交到本地git仓库,提交日志信息
git log:查看git仓库信息
git push:远端仓库的提交,同步本地与远端的仓库
.gitignore文件:避免特定类型的文件提交到仓库
git版本管理只管理源文件和头文件
被忽略的文件完全不受git版本控制
即使修改也不会被记录
Windows端操作
克隆:clone
将gitee远端仓库代码拉到windows平台的本地仓库
在windows端更改文件数据
提交:add+commit
推送:push
当前直接在Linux端更改数据,推送时会被拒绝
需要pull,将Linux本地的数据与远端的数据同步
(注:如果没有pull就修改文件内容,Linux端需要打开冲突文件,手动删去冲突符号)
再在windows端修改文件,推送时也会发生冲突,需要pull,将本地数据与远端数据同步
(注:windows系统会自动删除冲突符号)
远端仓库相比较任何人,都是最新的,冲突是提醒本地用户要和远端仓库进行同步
十一、调试器gdb/cgdb
11.1.软件发布方式
debug模式:开发
release模式:测试、上线
Linux编译好的代码无法进行调试
gcc/g++默认为release工作模式
-g:在最终的可执行程序添加调试信息
因为多了debug内容,所以文件变大
- Makefile
11.2.cgdb命令
cgbd 文件名:开始调试
list/l:显示源代码,从上次位置开始,每次列出10行
list/l 函数名:列出指定函数的源码
list/l 文件名:行号:从第一行显示,回车显示所有行
run/r:从程序开始连续执行到断点位置
continue/c:从当前位置连续执行程序
break/b [文件名:]行号:在指定行号设置断点
b 函数名:在函数开头设置断点
info b:查看当前所有断点信息
delete/d:删除所有断点
d 断点编号:删除序号为n的断点
next/n:逐过程执行程序
step/s:逐语句执行程序,可以进入函数内部
finish:执行到当前函数返回,然后停止
bt:查看当前执行栈的各级函数调用以及参数
每调用一次函数,会在main函数上面创建一个函数栈帧
objdump:查看反汇编
函数体中会将返回值写入寄存器,每次调用都会mov函数内部栈上的一个临时变量
p 变量:打印指定变量的值
disable 断点编号:禁用断点
enable 断点编号:使能断点
until 行号:执行到指定行号
display 变量名:查看上下文数据
undisplay 编号:关闭常显示
quit:退出调试
调试的本质:找到问题,找到问题的命令
断点的本质:把代码进行块级别的划分,以块为单位进行快速定位区域
11.3.调试技巧
watch
执行监视一个表达式的值
一些变量不应该修改,怀疑是它的修改导致了问题
通过watch观察,如果该值发生变化,会主动通知
set var
更改变量值
设置条件断点
- b 行号 条件
给不存在的断点设置条件
- condition 行号 条件
给已经存在的断点设置条件
ESC:从gdb屏切换代码屏
i:从代码屏切换gdb屏