Linux常见开发工具
文章目录
- Linux常见开发工具
- 1. yum和apt
- yum、apt是什么
- 为什么要有包管理器
- 包管理器怎么用
- yum
- apt
- 认识rpm包
- 2. vim
- 安装vim
- 个性化vim界面
- vim常见操作
- 1. 命令模式下的操作
- 2. 编辑模式下的操作
- 3. 底行模式下的操作
- 4. vim中的注释操作
- # 输入注释符号
- 3. gcc
- 3.1 安装
- 3.2 基本命令格式
- 3.3 常用选项
- 3.4 编译过程
- 3.5 库文件详解
- 3.5.1 静态库(Static Library)
- 3.5.2 动态库(Dynamic Library)
- 3.6 文件查看工具
- 3.6.1 file命令
- 3.6.2 ldd命令
- 3.7 链接选项
- 4. gdb
- 4.1 简介
- 4.2 安装
- 4.3 可执行程序版本
- 4.4 常用命令
- 4.5 调试技巧
- 5. make和Makefile
- 5.1 重要性
- 5.2 安装
- 5.3 Makefile语法详解
- 5.3.1 基本格式
- 5.3.2 特殊变量
- 5.3.3 通配符和模式规则
- 5.3.4 伪目标
- 5.3.5 条件判断
- 5.3.6 函数
- 5.3.7 包含其他Makefile
- 5.3.8 常见用法示例
- 5.3.9 常见错误
- 5.4 常见写法
- 5.5 make命令用法
1. yum和apt
yum、apt是什么
- yum(yellowdog updater modified)是Red Hat、CentOS等RPM系Linux发行版的包管理器;
- apt(advanced package tool)是Ubuntu\Debian系统的包管理器。
为什么要有包管理器
下载软件的本质,就是要获得编程语言通过编译、汇编、链接所形成的可执行程序,所以为了获得可执行程序,一般有以下三种方法:
- 获取到软件的源代码,自行编译链接形成可执行程序;
- 通过rpm获取rpm安装包,但是不会处理软件依赖;
- 通过yum、apt软件包管理器自动获取软件包,并处理软件依赖。
这样看,第三种方式是用户体验最轻松的,同时也是大多数人的选择。
包管理器怎么用
包管理器虽然好用,但必须要联网才能安装,因为包管理器需要和远程的包服务器进行通信,才能下载相应的软件包,可以通过ping命令来测试自己的网络状况。
yum
基本指令:
安装相关:
# 安装软件包
yum install package_name
# 安装本地RPM包,自动解决依赖
yum localinstall package.rpm
# 重新安装
yum reinstall package_name
# 安装特定版本
yum install package_name-1.0.0
删除相关:
# 删除软件包
yum remove package_name
# 删除软件包及其依赖
yum autoremove package_name
# 清除缓存
yum clean all
yum clean packages
yum clean metadata
更新相关:
# 检查更新
yum check-update
# 更新所有包
yum update
# 更新指定包
yum update package_name
# 系统升级
yum upgrade
查询搜索相关:
# 搜索包
yum search keyword
# 显示包信息
yum info package_name
#列出所有包(已安装和可安装的)
yum list
# 列出所有可安装的包
yum list available
# 列出所有已安装的包
yum list installed
# 列出可更新的包
yum list updates
apt
基本指令:
更新和升级:
# 更新软件包列表
apt update
# 升级所有可更新的包
apt upgrade
# 升级整个系统(可能会删除一些包)
apt full-upgrade
# 智能升级(最小升级)
apt dist-upgrade
安装和删除:
# 安装软件包
apt install package_name
# 重新安装
apt reinstall package_name
# 删除软件包
apt remove package_name
# 删除软件包及其配置文件
apt purge package_name
# 自动删除不需要的依赖包
apt autoremove
搜索和查询:
# 搜索包
apt search keyword
# 显示包信息
apt show package_name
# 列出所有包
apt list
# 列出已安装的包
apt list --installed
# 列出可升级的包
apt list --upgradable
缓存管理:
# 清理本地缓存
apt clean
# 清理旧版本的缓存
apt autoclean
# 下载包但不安装
apt download package_name
依赖处理:
# 修复依赖关系
apt --fix-broken install
# 或
apt -f install
# 检查依赖关系
apt check
# 构建依赖关系
apt build-dep package_name
常见选项是-y,大多数时候安装yum会询问是否继续安装,如果不想被询问可以带上-y(yes)自动确定。
因为包管理器安装通常涉及到目录的读写,一般我们在命令前都会带sudo或者用root安装
认识rpm包
RPM包的命名格式通常为:name-version-release.architecture.rpm
例如:nginx-1.20.1-9.el7.x86_64.rpm
各部分含义:
- name: 软件包名称(如nginx)
- version: 软件版本号(如1.20.1)
- release: 发布版本号(如9.el7,其中el7表示RHEL/CentOS 7)
- architecture: 架构平台(如x86_64、i686、noarch等)
- .rpm: 文件扩展名
有���还可能在release前看到一些额外标识:
- devel: 开发包
- src: 源码包
- debug: 调试包
2. vim
Vim 是一个强大的文本编辑器,和我们使用的图形化编辑器不同,vim主要通过命令来进行操作。
安装vim
#Centos等操作系统
sudo yum install -y vim
#Ubuntu等操作系统
sudo apt install -y vim
个性化vim界面
通过修改vim在~/.vimrc的个人配置文件,可以让vim的操作界面更美观和实用:
# 常见配置
set number # 显示行号
set autoindent # 自动缩进
set syntax on # 语法高亮
set hlsearch # 搜索高亮
set incsearch # 增量搜索
vim常见操作
vim分为三种模式:
- 命令模式:默认模式,通过vim打开文件后默认进入命令模式,通过命令模式可以进入编辑模式和底行模式;
- 编辑模式:通过
i
、a
、o
进入编辑模式,在编辑模式下可以进行文本编辑; - 底行模式:通过
:
进入底行模式,在底行模式下可以执行一些vim的命令。
1. 命令模式下的操作
光标移动:
h # 左移一个字符
j # 下移一行
k # 上移一行
l # 右移一个字符
w # 移动到下一个单词开头
b # 移动到上一个单词开头
0 # 移动到行首
$ # 移动到行尾
gg # 移动到文件开头
G # 移动到文件末尾
nG # 移动到第n行
复制粘贴删除:
yy # 复制当前行
nyy # 复制从当前行开始的n行
p # 粘贴到光标后
P # 粘贴到光标前
dd # 删除当前行
ndd # 删除从当前行开始的n行
x # 删除当前字符
撤销和重做:
u # 撤销上一步操作
Ctrl + r # 重做上一步操作
2. 编辑模式下的操作
i # 在光标处插入
I # 在行首插入
a # 在光标后插入
A # 在行尾插入
o # 在当前行下方新建一行
O # 在当前行上方新建一行
ESC # 退出编辑模式,返回命令模式
3. 底行模式下的操作
保存和退出:
:w # 保存文件
:q # 退出vim
:wq # 保存并退出
:q! # 强制退出,不保存修改
:set nu # 显示行号
:n # 跳转到第n行
:/word # 搜索word
:s/old/new # 替换当前行第一个old为new
:s/old/new/g # 替换当前行所有old为new
:%s/old/new/g # 替换整个文件所有old为new
``
查找和替换:
```bash
/pattern # 向下搜索pattern
?pattern # 向上搜索pattern
n # 继续搜索下一个
N # 继续搜索上一个
4. vim中的注释操作
- 命令模式下批量注释:
- 命令模式下批量去注释:
- Ctrl + v # 进入可视块模式
- j/k # 选择要去注释的行
- x 或 d # 删除注释符号
- 底行模式下批量操作:
- :1,5s/^/#/ # 注释第1-5行
- :%s/^/#/ # 注释所有行
- :1,5s/^#// # 取消第1-5行的注释
- :%s/^#// # 取消所有行的注释
注:
^
表示行首#
可以替换成其他注释符号(如//
,--
等)1,5
可以替换成其他行号范围%
表示所有行
3. gcc
3.1 安装
# Ubuntu/Debian系统
sudo apt-get update
sudo apt-get install gcc
# CentOS/RHEL系统
sudo yum install gcc
# 验证安装
gcc --version
3.2 基本命令格式
gcc [选项] 文件名
3.3 常用选项
-E
:仅预处理,生成.i文件-S
:仅编译,生成汇编代码.s文件-c
:仅汇编,生成目标文件.o文件-o
:指定输出文件名-g
:包含调试信息,生成debug版本的可执行文件(如果不指定该选项���默认生成release版本的可执行文件)-O[0-3]
:优化级别(0-3)-Wall
:显示所有警告信息-w
:禁止所有警告信息-I
:指定头文件搜索目录-L
:指定库文件搜索目录-l
:指定链接的库名-std=
:指定C语言标准(如:c99、c11)-D
:定义宏-fPIC
:生成位置无关代码(用于共享库)
3.4 编译过程
-
预处理(Preprocessing)
gcc -E main.c -o main.i
- 展开宏定义
- 处理条件编译
- 删除注释
- 包含头文件
-
编译(Compilation)
gcc -S main.i -o main.s
- 将预处理后的文件翻译成汇编代码
-
汇编(Assembly)
gcc -c main.s -o main.o
- 将汇编代码转换为目标文件
-
链接(Linking)
gcc main.o -o main
- 将目标文件与库文件链接生成可执行文件
3.5 库文件详解
3.5.1 静态库(Static Library)
- 命名规则:
lib[name].a
- 创建步骤:
gcc -c file1.c file2.c # 生成.o文件 ar rcs libname.a file1.o file2.o # 打包成静态库
- 使用方法:
gcc main.c -L. -lname -o main # -L指定库路径,-l指定库名
- 优点:
- 执行速度快(直接包含在可执行文件中)
- 不依赖环境(独立性强)
- 移植方便
- 缺点:
- 占用磁盘空间大
- 更新维护不方便(需要重新编译)
- 内存利用率低(每个程序都要加载一份)
3.5.2 动态库(Dynamic Library)
- 命名规则:
- Linux:
lib[name].so
- Windows:
[name].dll
- Linux:
- 创建步骤:
gcc -fPIC -c file1.c file2.c # 生成位置无关的.o文件 gcc -shared -o libname.so file1.o file2.o # 生成动态库
- 使用方法:
gcc main.c -L. -lname -o main export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. # 添加库搜索路径
- 优点:
- 占用磁盘空间小
- 更新方便(只需替换库文件)
- 内存利用率高(多个程序共享)
- 缺点:
- 依赖环境(需要库文件存在)
- 运行速度较慢(需要动态加载)
- 移植相对复杂
注:
对于一个库的名字,实际上我们认为要掐头去尾,例如:libname.so,我们只认为name是库名,而lib是前缀,.so是后缀,因为有很多系统库既有动态库版本又有静态库版本,所以只取中间部分作为库名,我们进行链接选项的时候,也是只取库文件的中间部分。
3.6 文件查看工具
3.6.1 file命令
file [文件名] # 查看文件类型
- 可以识别可执行文件、库文件的类型
- 显示是否为动态链接
- 显示目标架构
3.6.2 ldd命令
ldd [文件名] # 查看程序依赖的共享库
- 显示程序依赖的所有动态库
- 显示动态库的完整路径
- 显示动态库的加载地址
3.7 链接选项
-l
:指定链接的库名-L
:指定库文件搜索目录-Wl,选项
:传递选项给链接器-static
:强制使用静态链接(如果一个库中同时存在静态库和动态库,默认使用动态库,如果指定-static,则强制使用静态库)-shared
:生成共享库-rpath
:指定运行时库文件搜索路径-Bstatic
:优先使用静态库-Bdynamic
:优先使用动态库\
4. gdb
4.1 简介
GDB (GNU Debugger) 是GNU软件系统中的标准调试器,用于调试C/C++程序。
4.2 安装
# Ubuntu/Debian
sudo apt-get install gdb
# CentOS/RHEL
sudo yum install gdb
# 验证安装
gdb --version
4.3 可执行程序版本
GDB调试需要带有调试信息的可执行程序,有两种版本:
- Release版本(默认)
gcc main.c -o main
- 去除调试信息
- 进行代码优化
- 文件体积小
- 运行速度快
- 不利于调试
- Debug版本
gcc -g main.c -o main_debug
- 包含调试信息
- 不进行优化
- 文件体积大
- 运行速度相对慢
- 便���调试
4.4 常用命令
启动和退出:
gdb [program] # 启动gdb
quit/q # 退出gdb
运行控制:
run/r # 运行程序
start # 启动程序,在main函数处停止
continue/c # 继续运行
next/n # 单步执行(不进入函数)
step/s # 单步执行(进入函数)
finish # 运行至函数结束
until/u # 运行至某行
kill # 终止当前程序
断点操作:
break/b [位置] # 设置断点
info break # 查看断点信息
delete [编号] # 删除断点
disable [编号] # 禁用断点
enable [编号] # 启用断点
clear [位置] # 清除断点
查看代码:
list/l # 显示源代码
display [变量] # 跟踪查看变量
print/p [变量] # 打印变量值
whatis [变量] # 显示变量类型
info locals # 显示局部变量
info args # 显示函数参数
查看调用栈:
backtrace/bt # 查看调用栈
frame [编号] # 切换栈帧
info frame # 查看栈帧信息
up # 上一层栈帧
down # 下一层栈帧
4.5 调试技巧
- 条件断点:
break [位置] if [条件]
- 观察点:
watch [变量] # 变量被修改时停止
rwatch [变量] # 变量被读取时停止
awatch [变量] # 变量被访问时停止
- 捕获信号:
catch signal [信号名]
5. make和Makefile
make/Makefile是自动化构建工具,make是命令,Makefile是文件,两者要一起搭配使用。
5.1 重要性
- 自动化构建:自动完成编译、链接等步骤
- 增量编译:只重新编译修改过的文件
- 管理依赖关系:处理文件之间的依赖
- 提高效率:节省编译时间
- 跨平台:支持不同平台的编译
5.2 安装
# Ubuntu/Debian
sudo apt-get install make
# CentOS/RHEL
sudo yum install make
# 验证安装
make --version
5.3 Makefile语法详解
5.3.1 基本格式
目标: 依赖
命令
注意:命令行前必须是Tab,不能是空格
5.3.2 特殊变量
- 自动变量:
$@
:表示目标文件$^
:表示所有依赖文件$<
:表示第一个依赖文件$?
:表示比目标更新的依赖文件列表$*
:表示匹配模式中的%部分
示例:
main.o: main.c
gcc -c $< -o $@ # 等价于 gcc -c main.c -o main.o
- 预定义变量:
CC
:C编译器,默认为ccCXX
:C++编译器,默认为g++CFLAGS
:C编译选项CXXFLAGS
:C++编译选项LDFLAGS
:链接选项
示例:
CC = gcc
CFLAGS = -Wall -g
main: main.c
$(CC) $(CFLAGS) $^ -o $@
5.3.3 通配符和模式规则
%
:通配符,用于模式匹配
%.o: %.c
$(CC) -c $< -o $@ # 将所有.c文件编译成.o文件
*
:shell通配符,用于文件名匹配
clean:
rm -f *.o # 删除所有.o文件
5.3.4 伪目标
.PHONY
:声明伪目标,不产生实际文件的目标
作用:
- 避免与同名文件冲突
- 强制执行命令
- 提高执行效率
示例:
.PHONY: clean all install
clean:
rm -f *.o main
all: main test # 构建多个目标
install:
cp main /usr/local/bin/
5.3.5 条件判断
- ifeq/ifneq - 字符串比较
语法:
ifeq (arg1, arg2)
# commands if equal
else
# commands if not equal
endif
ifneq (arg1, arg2)
# commands if not equal
else
# commands if equal
endif
示例:
ifeq ($(CC),gcc)
CFLAGS = -Wall
else
CFLAGS = -W
endif
# 也可以使用空格分隔
ifeq "$(CC)" "gcc"
CFLAGS = -Wall
endif
- ifdef/ifndef - 变量定义测试
语法:
ifdef VARIABLE
# commands if variable is defined
else
# commands if variable is not defined
endif
ifndef VARIABLE
# commands if variable is not defined
else
# commands if variable is defined
endif
示例:
# 检查是否定义了DEBUG
ifdef DEBUG
CFLAGS += -g -DDEBUG
endif
# 检查编译器是否定义
ifndef CC
CC = gcc
endif
5.3.6 函数
- 文本处理函数
a) subst - 字符串替换
语法:$(subst from,to,text)
# 将空格替换为逗号
COMMA_LIST = $(subst $(space),$(comma),$(LIST))
b) patsubst - 模式替换
语法:$(patsubst pattern,replacement,text)
# 将.c文件替换为.o文件
OBJS = $(patsubst %.c,%.o,$(SRCS))
c) strip - 去除空格
语法:$(strip string)
# 去除变量中的空格
CLEANED = $(strip $(VARIABLE))
- 文件名处理函数
a) dir - 取目录部分
语法:$(dir names...)
# 获取文件的目录部分
DIRS = $(dir src/foo.c src/bar.c) # 结果:src/ src/
b) notdir - 取文件名部分
语法:$(notdir names...)
# 获取文件的名称部分
FILES = $(notdir src/foo.c src/bar.c) # 结果:foo.c bar.c
c) suffix - 取后缀
语法:$(suffix names...)
# 获取文件后缀
SUFFIXES = $(suffix src/foo.c src/bar.h) # 结果:.c .h
- 文件查找函数
a) wildcard - 获取匹配的文件列表
语法:$(wildcard pattern)
# 获取所有.c文件
SRCS = $(wildcard *.c)
# 获取多个目录下的.c文件
SRCS = $(wildcard src/*.c lib/*.c)
- 循环函数
a) foreach - 循环处理
语法:$(foreach var,list,text)
# 为每个目录添加前缀
DIRS = src lib test
SRCS = $(foreach dir,$(DIRS),$(wildcard $(dir)/*.c))
- 条件函数
a) if - 条件判断
语法:$(if condition,then-part[,else-part])
# 根据DEBUG变量设置编译选项
CFLAGS += $(if $(DEBUG),-g -DDEBUG,-O2)
- 调用shell函数
a) shell - 执行shell命令
语法:$(shell command)
# 获取当前目录
CURRENT_DIR = $(shell pwd)
# 获取系统类型
OS = $(shell uname -s)
示例:综合使用多个函数
# 获取所有源文件
SRCS = $(wildcard src/*.c)
# 生成目标文件列表
OBJS = $(patsubst src/%.c,obj/%.o,$(SRCS))
# 确保目标目录存在
$(shell mkdir -p obj)
# 根据操作系统设置不同的选项
ifeq ($(shell uname),Linux)
LDFLAGS += -ldl
endif
# 为每个源文件目录添加include路径
DIRS = src lib
INCLUDES = $(foreach dir,$(DIRS),-I$(dir))
5.3.7 包含其他Makefile
include config.mk rules.mk
5.3.8 常见用法示例
- 多目录项目:
SRCDIRS = src lib test
SOURCES = $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c))
OBJECTS = $(SOURCES:.c=.o)
main: $(OBJECTS)
$(CC) $(OBJECTS) -o $@
%.o: %.c
$(CC) -c $< -o $@
- 自动依赖生成:
%.d: %.c
@set -e; rm -f $@; \
$(CC) -MM $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
include $(SOURCES:.c=.d)
- 调试和发布版本:
ifdef DEBUG
CFLAGS += -g -DDEBUG
else
CFLAGS += -O2 -DNDEBUG
endif
debug:
$(MAKE) DEBUG=1 all
5.3.9 常见错误
- 命令行前使用空格而不是Tab
- 循环依赖
- 文件名包含特殊字符
- 忘记声明伪目标
- 规则顺序不当
5.4 常见写法
- 简单版本:
main: main.c
gcc main.c -o main
- 多文件版本:
CC = gcc
CFLAGS = -Wall -g
main: main.o utils.o
$(CC) $(CFLAGS) main.o utils.o -o main
main.o: main.c
$(CC) $(CFLAGS) -c main.c
utils.o: utils.c
$(CC) $(CFLAGS) -c utils.c
clean:
rm -f *.o main
- 通用版本:
CC = gcc
CFLAGS = -Wall -g
OBJS = main.o utils.o
TARGET = main
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(TARGET)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET)
5.5 make命令用法
make # 执行默认目标
make [目标] # 执行指定目标
make -n # 显示命令但不执行
make -j4 # 并行执行(4个作业)
make clean # 清理编译产物
常用选项:
-f file
:指定makefile文件-C dir
:切换到指定目录-B
:强制重新构建-d
:调试模式-v
:显示版本信息