在 Linux 环境下进行开发,熟练掌握基础工具链是提升效率的关键。无论是软件安装、代码编辑,还是编译调试、版本控制,一套高效的工具组合能让开发流程事半功倍。本文将系统讲解 Linux 开发的核心工具 —— 从软件包管理器 yum/apt、编辑器 vim,到编译器 gcc/g++、自动化构建工具 make/Makefile,再到版本控制 git 和调试器 gdb,最后通过一个实战案例(进度条程序)将所有工具串联,帮助开发者快速上手 Linux 开发环境。
一、软件包管理器:快速搭建开发环境
Linux 开发的第一步是配置环境,软件包管理器能帮我们一键安装所需工具,避免手动编译源码的繁琐。主流的包管理器有 yum(CentOS/RHEL)和 apt(Ubuntu/Debian),两者核心功能一致,仅命令略有差异。
1.1 包管理器核心概念
软件包:预编译好的可执行程序 + 依赖库,类似 Windows 的 “安装包”;
依赖解决:自动处理软件间的依赖关系(如安装 gcc 时自动安装 libc);
软件源:存储软件包的服务器,国内源(如阿里云、清华源)比国外源速度更快。
1.2 国内常用软件源
为提升下载速度,建议将系统默认源替换为国内源:
| 源名称 | 适用发行版 | 官方链接 |
|---|---|---|
| 阿里云镜像站 | 全平台 | https://developer.aliyun.com/mirror/ |
| 清华大学开源镜像站 | 全平台 | https://mirrors.tuna.tsinghua.edu.cn/ |
| 中国科学技术大学镜像站 | 全平台 | http://mirrors.ustc.edu.cn/ |
| 网易开源镜像站 | 全平台 | http://mirrors.163.com/ |
1.3 常用操作(以 yum 为例,apt 类似)
1.3.1 查看软件包
# 查看是否安装 lrzsz(文件传输工具)
yum list | grep lrzsz
# Ubuntu 用 apt search lrzsz
1.3.2 安装软件
# 安装 gcc(C 编译器)和 g++(C++ 编译器)
sudo yum install -y gcc g++
# Ubuntu 用 sudo apt install -y gcc g++
# 安装扩展源(包含更多软件)
sudo yum install -y epel-release
1.3.3 卸载软件
# 卸载 lrzsz
sudo yum remove -y lrzsz
# Ubuntu 用 sudo apt remove -y lrzsz
1.3.4 注意事项
安装 / 卸载需 sudo 权限(修改系统目录);
确保网络通畅,可用 ping www.baidu.com 验证;
同一时间只能有一个包管理器进程运行(避免冲突)。
二、编辑器 Vim:高效代码编写神器
Vim 是 Linux 下最强大的文本编辑器,支持多模式编辑,熟练使用后效率远超记事本类工具。核心是掌握 “模式切换” 和常用命令。
2.1 Vim 三种核心模式
Vim 有 12 种模式,日常开发只需掌握 3 种:
| 模式名称 | 功能说明 | 切换方式 |
|---|---|---|
| 命令模式(Normal) | 控制光标移动、删除 / 复制文本、切换模式 | 启动 Vim 默认进入,插入 / 底行模式按 ESC 返回 |
| 插入模式(Insert) | 输入文本 | 命令模式按 i(光标前插入)/a(光标后插入)/o(新行插入) |
| 底行模式(Last Line) | 保存文件、退出、查找替换、配置 Vim | 命令模式按 Shift + ;(即 :)进入 |
2.2 常用命令速查
2.2.1 命令模式常用命令
光标移动:
h/j/k/l:左 / 下 / 上 / 右移(替代方向键);
gg:跳至文件开头,G:跳至文件结尾;
$:跳至行尾,^:跳至行首;
w:跳至下一个单词开头,e:跳至下一个单词结尾。
文本操作:
x:删除光标所在字符,dd:删除当前行,#dd:删除 # 行;
yy:复制当前行,#yy:复制 # 行,p:粘贴到光标后;
u:撤销上一步操作,Ctrl + r:恢复撤销;
r:替换光标所在字符,R:持续替换直到按 ESC。
2.2.2 底行模式常用命令
文件操作:
w:保存文件,wq:保存并退出,q!:强制退出(不保存);
set nu:显示行号,set nonu:隐藏行号;
查找替换:
/关键字:向下查找,?关键字:向上查找,n:继续查找下一个;
2.3 Vim 简单配置
为提升编辑体验,可在用户主目录(~)下创建 .vimrc 文件,添加常用配置:
# 编辑配置文件
vim ~/.vimrc
配置内容:
syntax on " 开启语法高亮
set nu " 显示行号
set shiftwidth=4 " 缩进空格数为 4
set tabstop=4 " Tab 键对应空格数为 4
set autoindent " 自动缩进
set cursorline " 高亮当前行
保存后重启 Vim,配置即可生效。
三、编译器 GCC/G++:从源码到可执行文件
GCC(GNU Compiler Collection)是 Linux 下默认的 C/C++ 编译器,支持从源码到可执行文件的全流程编译。理解其编译过程和选项,能帮我们排查编译错误、优化程序性能。
3.1 编译四步流程
C/C++ 源码编译需经过 4 个阶段,GCC 可通过选项控制每个阶段的输出:
- 预处理(Preprocessing):展开头文件、替换宏、去注释、条件编译;
# 生成预处理文件(.i),停止编译 gcc -E test.c -o test.i - 编译(Compilation):将预处理后的代码转为汇编语言;
# 生成汇编文件(.s),停止编译 gcc -S test.i -o test.s - 汇编(Assembly):将汇编代码转为机器码(目标文件 .o);
# 生成目标文件(.o),停止编译 gcc -c test.s -o test.o - 链接(Linking):将目标文件与依赖库链接,生成可执行文件;
# 生成可执行文件 a.out(默认名),或指定名 test gcc test.o -o test
3.2 常用编译选项
| 选项 | 功能说明 |
|---|---|
-o 文件名 | 指定输出文件名称(默认输出 a.out); |
-g | 生成调试信息(供 GDB 调试使用); |
-Wall | 开启所有警告信息(如未使用变量、类型不匹配); |
-O0/-O1/-O2/-O3 | 优化级别(O0 无优化,O3 优化最强,默认 O0); |
-static | 静态链接(将依赖库打包到可执行文件,体积大但不依赖系统库); |
-l 库名 | 链接指定库(如 -lm 链接数学库,-lpthread 链接线程库); |
示例:编译带调试信息、开启警告的 C++ 程序:
g++ -g -Wall test.cpp -o test
3.3 静态链接 vs 动态链接
动态链接(默认):可执行文件仅包含调用库的接口,运行时依赖系统中的动态库(.so 文件),体积小但需确保系统有对应库;
静态链接(-static):将依赖库的代码全部打包到可执行文件,体积大但可独立运行,不依赖系统库。
查看可执行文件依赖的动态库:
ldd test # 输出 test 依赖的所有动态库
四、自动化构建 Make/Makefile:管理复杂项目
当项目包含多个源文件时,手动执行 gcc 命令会非常繁琐。Makefile 定义了编译规则,make 工具按规则自动编译,实现 “一键构建”。
4.1 Makefile 基本语法
Makefile 的核心是 “目标 - 依赖 - 命令” 规则,格式如下:
# 目标(要生成的文件): 依赖(生成目标需要的文件)
# <tab> 命令(生成目标的指令,必须以 tab 开头)
目标: 依赖1 依赖2 ...
命令1
命令2
...
4.2 简单 Makefile 示例
假设项目有 main.c、sum.c、sum.h 三个文件,Makefile 如下:
# 最终目标:生成可执行文件 test
test: main.o sum.o
gcc -o test main.o sum.o # 链接目标文件
# 生成 main.o(依赖 main.c 和 sum.h)
main.o: main.c sum.h
gcc -c main.c -o main.o
# 生成 sum.o(依赖 sum.c 和 sum.h)
sum.o: sum.c sum.h
gcc -c sum.c -o sum.o
# 伪目标:清理编译产物(.o 和 test)
.PHONY: clean
clean:
rm -f test *.o
4.3 Makefile 进阶:变量与函数
为简化 Makefile 维护,可使用变量和函数:
# 定义变量(类似宏)
BIN = test # 可执行文件名
CC = gcc # 编译器
SRC = $(wildcard *.c)# 函数:获取所有 .c 文件
OBJ = $(SRC:.c=.o) # 替换:将 .c 转为 .o
CFLAGS = -g -Wall # 编译选项(调试+警告)
# 最终目标
$(BIN): $(OBJ)
$(CC) -o $@ $^ # $@: 目标名,$^: 所有依赖名
# 生成 .o 文件(模式匹配:所有 .o 依赖对应的 .c 和 .h)
%.o: %.c sum.h
$(CC) $(CFLAGS) -c $< -o $@ # $<: 第一个依赖名
# 伪目标
.PHONY: clean test
clean:
rm -f $(BIN) $(OBJ)
test: $(BIN)
./$(BIN) # 运行程序
4.4 Make 命令使用
make # 执行 Makefile,生成最终目标(默认第一个目标)
make clean # 执行 clean 伪目标,清理编译产物
make test # 执行 test 伪目标,编译并运行程序
五、版本控制 Git:代码管理与协作
Git 是目前最流行的分布式版本控制系统,能跟踪代码修改历史、支持多分支开发、方便团队协作。结合 GitHub/GitLab 等平台,可实现代码的远程托管。
5.1 Git 核心概念
工作区:本地编辑代码的目录;
暂存区(Index):临时存储待提交的修改;
本地仓库:本地存储代码历史的数据库;
远程仓库:GitHub/GitLab 上的远程代码库。
5.2 Git 常用命令(GitHub 为例)
5.2.1 初始化与配置
# 安装 Git
sudo yum install -y git
# 配置用户名和邮箱(GitHub 账号)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
5.2.2 本地仓库操作
# 初始化本地仓库(在项目目录执行)
git init
# 添加文件到暂存区(. 表示所有文件)
git add main.c Makefile
# 提交暂存区文件到本地仓库(-m 后跟提交说明)
git commit -m "init project: add main.c and Makefile"
# 查看提交历史
git log
# 查看工作区状态(是否有未提交的修改)
git status
5.2.3 远程仓库操作
- 关联远程仓库:在 GitHub 新建仓库,复制仓库 URL(如
https://github.com/yourname/test.git),执行:# 关联远程仓库(命名为 origin) git remote add origin https://github.com/yourname/test.git - 推送代码到远程:
# 首次推送,设置 upstream(后续可直接 git push) git push -u origin main # 后续推送 git push - 拉取远程代码:
# 拉取远程最新代码(合并到当前分支) git pull origin main
5.2.4 忽略文件 .gitignore
创建 .gitignore 文件,指定无需跟踪的文件(如编译产物、日志):
# .gitignore 内容
test # 忽略可执行文件 test
*.o # 忽略所有 .o 文件
*.log # 忽略所有 .log 文件
六、调试器 GDB:定位代码 bug
GDB 是 Linux 下的命令行调试工具,支持断点设置、单步执行、变量查看等功能,是排查代码逻辑错误的核心工具。
6.1 编译时生成调试信息
GDB 调试需在编译时添加 -g 选项,生成调试信息:
gcc -g test.c -o test
6.2 GDB 常用命令
| 命令 | 功能说明 |
|---|---|
gdb test | 启动 GDB,加载可执行文件 test; |
r/run | 运行程序(可加参数,如 r 10 20); |
n/next | 单步执行(不进入函数); |
s/step | 单步执行(进入函数); |
b/break 行号 | 在指定行设置断点(如 b 10,b sum.c:20 指定文件); |
b/break 函数名 | 在函数开头设置断点(如 b main); |
info b | 查看所有断点信息; |
delete 断点号 | 删除指定断点(如 delete 1); |
c/continue | 从当前位置继续执行到下一个断点; |
p/print 变量 | 打印变量值(如 p result,p a+b); |
set var 变量=值 | 修改变量值(如 set var i=10); |
bt/backtrace | 查看函数调用栈(定位崩溃位置); |
finish | 执行到当前函数返回; |
watch 变量 | 监视变量值变化(值改变时暂停程序); |
quit | 退出 GDB; |
6.3 GDB 调试示例
以 sum.c(计算 1~100 的和)为例:
#include <stdio.h>
int Sum(int s, int e) {
int result = 0;
for (int i = s; i <= e; i++) {
result += i;
}
return result;
}
int main() {
int start = 1, end = 100;
int n = Sum(start, end);
printf("Sum(1-100) = %d\n", n);
return 0;
}
调试流程:
# 1. 编译带调试信息的程序
gcc -g sum.c -o sum
# 2. 启动 GDB
gdb sum
# 3. 在 Sum 函数设置断点
(gdb) b Sum
# 4. 运行程序
(gdb) r
# 5. 单步执行,查看变量
(gdb) s # 进入 Sum 函数
(gdb) n # 单步执行
(gdb) p result # 查看 result 值
(gdb) watch result # 监视 result 变化
(gdb) c # 继续执行,直到 result 变化
# 6. 退出 GDB
(gdb) quit
七、实战:开发一个 Linux 进度条程序
结合上述工具,我们开发一个动态进度条程序,体验从编码到运行的全流程。
7.1 需求分析
进度条从 0% 到 100% 动态更新;
显示进度百分比和动态旋转图标(|/-\);
进度条不换行,实时覆盖更新。
7.2 核心技术点
回车与换行:\r 回车(回到行首),\n 换行,用 \r 实现覆盖更新;
行缓冲区:printf 默认行缓冲,需用 fflush(stdout) 强制刷新缓冲区;
微秒延迟:用 usleep(50000) 控制进度条更新速度(50ms 一次)。
7.3 代码实现
7.3.1 进度条代码(process.c)
#include "process.h"
#include <string.h>
#include <unistd.h>
#define BAR_LEN 101 // 进度条长度(100 个字符 + 结束符)
#define STYLE '=' // 进度条填充字符
// 版本 1:固定速度进度条
void process_v1() {
char bar[BAR_LEN] = {0}; // 进度条缓冲区
const char *spin = "|/-\\"; // 旋转图标
int spin_len = strlen(spin);
for (int i = 0; i <= 100; i++) {
// 格式化输出:进度条(左对齐 100 字符)、百分比、旋转图标
printf("[%-100s][%d%%][%c]\r", bar, i, spin[i % spin_len]);
fflush(stdout); // 强制刷新缓冲区
bar[i] = STYLE; // 更新进度条
usleep(50000); // 延迟 50ms
}
printf("\n"); // 进度条结束后换行
}
// 版本 2:根据当前进度更新(如下载进度)
void flush_process(double total, double current) {
static char bar[BAR_LEN] = {0};
static const char *spin = "|/-\\";
static int spin_cnt = 0;
// 计算当前进度百分比
int progress = (int)(current * 100 / total);
// 填充进度条
for (int i = 0; i < progress; i++) {
bar[i] = STYLE;
}
// 输出并刷新
printf("[%-100s][%.1f%%][%c]\r", bar, (double)progress, spin[spin_cnt % 4]);
fflush(stdout);
spin_cnt++;
}
7.3.2 头文件(process.h)
#pragma once
#include <stdio.h>
// 固定速度进度条
void process_v1();
// 动态进度条(total:总进度,current:当前进度)
void flush_process(double total, double current);
7.3.3 测试主函数(main.c)
#include "process.h"
#include <unistd.h>
// 模拟下载过程
void simulate_download(double total_size) {
double current = 0;
while (current <= total_size) {
flush_process(total_size, current);
current += 1.0; // 模拟下载 1MB
usleep(30000); // 延迟 30ms
}
printf("\nDownload done! Total: %.2fMB\n", total_size);
}
int main() {
printf("Test process_v1:\n");
process_v1(); // 测试固定速度进度条
printf("\nTest simulate_download:\n");
simulate_download(1024.0); // 模拟下载 1024MB
return 0;
}
7.3.4 Makefile
BIN = progress
CC = gcc
SRC = $(wildcard *.c)
OBJ = $(SRC:.c=.o)
CFLAGS = -Wall
$(BIN): $(OBJ)
$(CC) -o $@ $^
%.o: %.c process.h
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean run
clean:
rm -f $(BIN) $(OBJ)
run: $(BIN)
./$(BIN)
7.4 编译与运行
# 编译程序
make
# 运行程序
make run
运行效果:
Test process_v1:
[====================================================================================================][100%][\]
Test simulate_download:
[====================================================================================================][100.0%][|]
Download done! Total: 1024.00MB
八、总结
Linux 基础开发工具是高效开发的基石,本文涵盖的 yum/apt(环境搭建)、vim(代码编辑)、gcc/g++(编译)、make/Makefile(自动化构建)、git(版本控制)、gdb(调试),构成了完整的开发工具链。通过进度条实战案例,我们将这些工具串联,体验了从编码到运行的全流程。
1228

被折叠的 条评论
为什么被折叠?



