linux-develop
Linux开发工具与环境
1. 包管理器
包管理器会自动为我们解决安装软件时所需要的依赖问题。
软件包和包管理器可以理解为APP和应用商店这样的关系。
1.1 centos
sudo yum list # 查看
sudo yum -y install package-name # 安装
sudo yum -y remove package-name # 卸载
1.2 ubuntu
apt/apt-get
sudo apt update # 更新软件包列表
sudo apt -y install package-name # 安装
sudo apt -y remove package-name # 卸载
2. Vim编辑器
vim是一款多模式的编辑器。
vim三种基础模式:
-
命令模式(vim刚进入默认是命令模式)
-
插入模式
-
底行模式
2.1 Vim模式之间的切换
按键 | 说明 |
---|---|
i/a/o | 命令模式 -> 插入模式 |
: | 命令模式-> 底行模式 |
shift + r | 命令模式 -> 替换模式 |
ctrl + v | 命令模式 -> 视图模式 |
ESC | 其他模式 -> 命令模式 |
a:光标向由移动并切换成插入模式;o:光标向下另起一行并切换成插入模式
2.2 命令模式
按键 | 说明 |
---|---|
gg | 光标定位到文件开始 |
shift + g(G)🔸 | 光标定位到文件结尾 |
shift + 4($) | 光标定位到该行结尾 |
shift+ 6(^) | 光标定位到该行开始 |
h🔸 | 光标左移 |
j🔸 | 光标下移 |
k🔸 | 光标上移 |
l🔸 | 光标右移 |
w🔸 | 光标以单词为单位向右移动 |
b🔸 | 光标以单词为单位向左移动 |
yy🔸 | 复制行 |
p🔸 | 粘贴行 |
u | 撤销 |
ctrl + r | 反撤销 |
dd🔸 | 剪切/删除行 |
x🔸 | 向右剪切/删除字符 |
shift + x(X)🔸 | 向左剪切/删除字符 |
r🔸 | 替换光标所在的字符(r + 新字符) |
shift + `(~)🔸 | 切换光标所在字符的大小写 |
shift + 3(#) | 光标所在的单词全部高亮(n 切换到下一个) |
拥有 🔸 的命令前面都可以加数字;eg:5 + yy 复制5行。
2.3 底行模式
按键 | 说明 |
---|---|
w w! wq! | 保存 强制保存 强制保存并退出 |
q q! wq! | 退出 强制退出 强制保存并退出 |
!command | 不退出Vim的情况执行命令 |
set nu | 设置行号 |
set nonu | 取消行号 |
%s/原始内容/替换内容/ | 批量化替换 |
vs filename | 分屏操作 |
ctrl + w + w | 分屏操作下切换到另一个文件 |
/搜索的内容 | 在文档中搜索内容 |
2.4 批量化注释
-
命令模式下输入
ctrl + v
进入视图模式 -
使用
hjkl
选中区域 (也可以使用n + shift + g
) -
按
shift + i
从视图模式切换到插入模式 -
输入
//
,按ESC
2.5 批量化去注释
-
命令模式下输入
ctrl + v
进入视图模式 -
使用
hjkl
选中区域 -
按
dd
删除注释
2.6 Vim的小技巧
# 命令行中操作
vim filename +20 # 打开文件时光标自动定位到20行
!v # 执行最近一次以v开头的命令
!l # 执行最近一次以l开头的命令
vim的配置文件路径:~/.vimrc
3. Linux编译器gcc/g++
g++和gcc同理
3.1 源文件到可执行程序的过程
选项 -> 后缀:ESc -> iso
- 预处理
gcc -E code.c -o code.i
预处理工作:1.头文件展开 2.去注释 3. 条件编译 4.宏替换
- 编译
gcc -S code.i -o code.s # code.i也可以是code.c
编译的工作:c语言编译成汇编语言
- 汇编
gcc -c code.s -o code.o # code.s也可以是code.c
汇编的工作:汇编语言生成二进制
- 连接
gcc code.o -o code # code.o也可以是code.c
连接的工作:源文件与库文件关联到一起,本质是将自己编写的.o文件与库中下的.o文件进行合并
3.2 将多个.c文件编译成一个可执行
# 1.
gcc -c code1.c # code1.o
gcc -c code2.c # code2.o
gcc -c code3.c # code3.o
gcc code1.o code2.o code3.o -o code # code# 2.
gcc code1.c code2.c code3.c -o code
3.3 gcc命令行级别的宏定义
gcc code.c -o code -DM(=10) # 相当于在code.c定一个宏M
3.4 动静态库
gcc/g++默认的行为是动态链接
动态库:Linux(.so)Windows(.dll)
静态库:Linux(.a)Windows(.lib)
静态库会把使用到的方法拷贝的源文件中,如果有多个源文件都使用到了该方法,在内存中就会拥有多个该方法实现的代码造成代码的冗余,从而造成内存资源的浪费;动态库则会在内存中开辟一段空间,将动态库的代码导入内存中,如果有多个源文件都使用到了该方法,则会以地址的形式去内存寻找该方法的实现,本质上动态库的代码只会出现一份,比较节省内存。
3.4.1 查看可执行程序的动态链接库
ldd 可执行程序
3.4.2 静态链接
sudo apt-get install -y glibc-static # 下载c静态库
gcc code.c -o code -static # 静态链接生成可执行程序
3.4.3 动态链接
给别人使用自己写的方法,但是不想暴露源代码,把.c文件都编译成.o文件,再将所有的.o文件打包(TODO)。打包之后将.o和.h文件暴露出去。
ls
code1.h code1.c code2.h code2.c main.c
gcc -c code1.c
gcc -c code2.c
gcc -c main.c
ls
code1.h code1.o code1.c code2.h code2.o code2.c main.c main.o
gcc main.o code1.o code2.o -o code
3.5 补充知识
3.5.1 条件编译的用途
-
使用条件编译,可以进行代码的动态裁剪。区分出专业版和免费软件
-
内核源代码使用条件编译进行代码裁剪,区分出桌面版和服务器版的Linux
-
语言跨平台是使用条件编译实现的
3.5.2 为什么C/C++编译要编程汇编?
因为语言的历史是二进制指令 -> 汇编语言 -> C语言,每一次语言的开发都是站在巨人的肩膀上开发,这样的效率更高,所以编译的过程是语言发展的逆过程。
3.5.3 编译器的自举
汇编语言产生的时候,需要把汇编语言编译成二进制指令,就需要一个汇编语言的编译器。首先先使用二进制指令编写一个汇编语言的编译器,再使用汇编语言编写一个汇编的编译器,使用二进制指令编写的汇编编译器编译汇编语言编写的编译器,这样之后的汇编代码都可以使用汇编语言所编写的编译器来进行编译。
3.5.4 g++使用c++11特性
g++ code.cpp -o code -std=c++11
4. 自动化构建工具make/makefile
make是一个命令,makefile是一个文件。
4.1 makefile的基本编写
make命令扫描makefile文件的时候,从上向下扫描,默认形成第一个目标文件。
.PHONY
称为伪目标,修饰后,命令总是被执行。make是通过源文件的Modify时间小于可执行程序的Modify时间,来确保源文件没有内容没有修改。
code:code.c # 依赖关系gcc code.c -o code # 依赖方法 且必须以Tab键开始.PHONY:clean
clean:rm -f code
4.2 变量版的makefile
# 定义变量
BIN=code.exe
CC=gcc
SRC=code.c
FLAGS=-o
RM=rm -f# $(变量) 使用变量
$(BIN):$(SRC)@$(CC) $(FLAGS) $@ $^ # $@代表依赖关系中:左侧的内容,$^代表依赖关系中:右侧的内容,@符号代表不会显示命令echo "linking $^ to $@" # 手动添加输出信息
.PHONY:clean
clean:@$(RM) $(BIN)
4.3 编译多文件的makefile
BIN=code.exe
CC=gcc
# 1.SRC=$(shell ls *.c) # 执行shell命令,SRC = 当前目录下的所有.c文件
SRC=$(wildcard *.c) # 和上面命令效果一样
OBJ=$(SRC:.c=.o) # 把SRC中所有的.c文件替换为.o文件
OUTFLAGS=-o
OBJFLAGS=-c
RM=rm -f$(BIN):$(OBJ)$(CC) $(OUTFLAGS) $@ $^
%.o:%.c # %代表通配符,把当前路径下的所有.o / .c依次展开$(CC) $(OBJFLAGS) $< -g # %<把依赖关系右侧的.c文件,⼀个⼀个的交给gcc生成同名的.o文件 / -g debug模式
.PHONY:clean
clean:$(RM) $(OBJ) $(BIN)
5. Linux调试工具gdb
-
debug:调试模式
-
release:发布模式(Linux默认模式)
程序要调试,必须是debug模式,编译时要添加-g选项。
5.1 gdb命令
命令 | 说明 |
---|---|
gdb binfile | 开启调试 |
quit | 退出 |
list/l | 显示源代码,从上次位置开始(按空格会依次继续向下显示) |
list/l 行号 | 指定行开始显示源代码 |
list/l 函数名 | 显示指定函数的源代码 |
break/b 行号 | 指定行号下添加断点 |
break/b 函数名 | 函数开头设置断点 |
run/r | 从程序开始连续执行(运行结束后按r可重新开始) |
info/i break/b | 查看断点信息(断点编号…) |
next/n | 逐过程 |
step/s | 逐语句 |
finish | 执行完当前函数,然后停止 |
print/p 表达式/变量 | 打印表达式或变量的值 |
set var 变量=值 | 修改变量的值 |
continue/c | 跳转到下一个断点处 |
delete/d n | 删除编号为n的断点 |
delete/d breakpoints | 删除所有的断点 |
display 变量 | 跟踪显示指定变量 |
undisplay 编号 | 取消跟踪指定变量 |
until 行号 | 执行到指定的行号 |
backtrace/bt | 查看当前执行栈的各级函数调用及参数 |
info/i locals | 查看当前栈帧的局部变量 |
disable breakpoints | 禁用所有断点 |
enable breakpoints | 启用所有断点 |
只有打断点时需要行号,其他操作断点都需要断点编号。
5.2 cgdb
cgdb会将调试信息和源代码分开显示,命令和gdb一样。
cgdb分屏操作ESC进入代码屏(可上下翻阅),i回到cgdb命令屏。
sudo apt-get install -y cgdb # Ubuntu
sudo yum install -y cgdb # Centos
5.3 watch命令
执行时监视一个表达式或变量的值。如果监视的变量在程序运行期间值发生变化,gdb会暂停到该,并且显示旧值和新值。i b
会查看到watch命令监视的断点。
如果有些变量不应该修改,但是你怀疑它修改导致了问题,可以使用watch。
5.4 条件断点
5.4.1 添加条件断点
b 行号 if 条件表达式 # 断点会在表达式为true的时候停下来
5.4.2 给已存在的断点添加条件
condition 断点编号 条件表达式