linux开发工具
目录
一、软件包管理器
在不同平台上,会有不同的软件下载安装渠道
手机上的应用商店相当于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屏