
文章目录
- 引言
- 1.软件包管理器:yum和apt
- 2.编辑器Vim
- 3.编译器:gcc/g++
-
- 3.1.编译流程
- 3.2.编译完整流程演示
- [3.3.静态链接 vs 动态链接](#3.3.静态链接 vs 动态链接)
- 4.自动化构建:-make/Makefile
- 5.编写第一个Linux程序:进度条
- 结语
引言
作为 Linux 开发的入门者,掌握 "软件安装→代码编辑→编译构建" 的基础流程是打通开发链路的关键。日常开发中,我们常面临 "如何快速安装工具","用什么编辑代码","怎样将代码转为可执行程序" 等问题,这些都离不开
yum/apt、vim、gcc/g++、Makefile等核心工具的支撑。
1.软件包管理器:yum和apt
1.1.为什么需要包管理器?
在Linux中手动编译源代码安装软件不仅繁琐,还会面临依赖问题 。包管理器就像"应用商店",能自动解决依赖、下载编译好软件包。

在Linux系统下,不同发行版对应不同的工具:
- CentOs/RHEL :使用
yum(Yellow dog Updater,Modified); - Ubuntu/Debian :使用
apt(Advanced Package Tool)。
国内镜像源能解决官方源下载慢的问题,常用镜像源如下:
阿里云镜像站
清华大学开源镜像站
中科大镜像站
1.2.从查询到卸载的完整流程
1.2.1.查看安装包
想知道系统中是否有lrzsz(串口传输工具),可以用一下命令筛选:
bash
# CentOS(yum)
yum list | grep lrzsz
# 输出示例:lrzsz.x86_64 0.12.20-36.el7 @base
# Ubuntu(apt)
apt search lrzsz
# 输出示例:lrzsz/focal,now 0.12.21-10 amd64 [installed]
1.2.2.安装文件
安装gcc编译器,-y参数表示自动确认:
bash
# CentOS
sudo yum install -y gcc
# Ubuntu
sudo apt install -y gcc
1.2.3.卸载软件
卸载不需要的lrzsz:
bash
# CentOS
sudo yum remove -y lrzsz
# Ubuntu
sudo apt remove -y lrzsz
1.2.4.源配置:更换国内镜像源
以 CentOS 7 更换阿里云镜像源为例:
bash
# 1. 备份原有源
sudo mkdir /etc/yum.repos.d/backup
sudo mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/
# 2. 下载阿里云源配置文件
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# 3. 清理缓存并生成新缓存
sudo yum clean all
sudo yum makecache
2.编辑器Vim
vim是Linux默认的全功能编辑器,能够实现多模式间切换。
2.1.核心模式
- 命令模式(Normal mode):控制光标、删除复制文本;
- 插入模式(Insert mode):输入文字(左下角显式
--INSERT--); - 底行模式(last line mode):执行保存、退出、列行号等操作。

2.2.常用命令
2.2.1.光标移动(命令模式)
bash
h/j/k/l # 左/下/上/右移动(替代方向键)
gg # 跳至文件开头
G # 跳至文件结尾
$ # 跳至当前行末尾
^ # 跳至当前行开头
w # 跳至下一个单词开头
e # 跳至下一个单词结尾
5l # 向右移动5个字符(数字+操作)
2.2.2.编辑操作(命令模式)
bash
# 删除
x # 删除光标所在字符
dd # 删除当前行
3dd # 删除从当前行开始的3行
X # 删除光标前一个字符
# 复制粘贴
yy # 复制当前行
2yy # 复制从当前行开始的2行
p # 粘贴到光标后
P # 粘贴到光标前
# 替换与撤销
r # 替换光标所在字符(只换一个)
R # 连续替换(直到按ESC)
u # 撤销上一步操作
Ctrl+r # 恢复撤销(反撤销)
2.2.3.底行模式常用命令
bash
:set nu # 显示行号(nu=number)
:set nonu # 隐藏行号
:/keyword # 向下查找关键字(按n下一个,N上一个)
:?keyword # 向上查找关键字
:w # 保存文件(write)
:wq # 保存并退出(write+quit)
:q! # 强制退出(不保存,!表示强制)
:15 # 跳至第15行
2.3.简单vim配置
- 如果想个性化配置vim,可以在当前要配置的用户主目录下创建
.vimrc文件,添加以下配置:
bash
# ~/.vimrc 配置示例
syntax on " 开启语法高亮(代码颜色区分)
set nu " 默认显示行号
set shiftwidth=4 " 缩进时的空格数(默认4个)
set tabstop=4 " Tab键对应4个空格
set autoindent " 自动缩进(新行继承上一行缩进)
set cursorline " 高亮当前行(方便定位)
- 想要一键化配置更好看的vim,可以访问以下链接:VimForCpp
2.4.vim高频指令速查表
| 功能分类 | 命令 | 说明 |
|---|---|---|
| 模式切换 | i |
命令模式 -> 插入模式(光标前) |
a |
命令模式 -> 插入模式(光标后) | |
Shift + ; |
命令模式 -> 底行模式 | |
| 保存退出 | :wq |
退出并保存 |
q! |
强制退出 | |
| 查找替换 | :%s/old/new/g |
全文替换old为new(%=全文,g=全局) |
| 行操作 | dd + p |
剪切并粘贴 |
yy + np |
复制当前行并粘贴n(数字)次 |
3.编译器:gcc/g++
3.1.编译流程
- 预处理:主要包括展开头文件、宏替换、去注释等;
- 编译:检查代码的规范性、是否有语法错误等,并将代码转成汇编语言;
- 汇编:将汇编代码翻译成二进制可重定向目标文件(机器码);
- 链接:将目标文件与系统库结合,生成可执行文件。
3.2.编译完整流程演示
以hello.c(打印Hello Linux)程序为例:
- 预处理阶段(生成
.i文件)
bash
gcc -E hello.c -o hello.i
# -E:只执行预处理,不进行后续步骤
# -o:指定输出文件(hello.i)
- 编译阶段(生成
.s文件)
bash
gcc -S hello.i -o hello.s
# -S:只执行预处理和编译,生成汇编代码
此时,hello.s文件中是汇编指令,如:
bash
main:
pushq %rbp
movq %rsp, %rbp
movl $.LC0, %edi
call puts
movl $0, %eax
popq %rbp
ret
.LC0:
.string "Hello Linux"
- 汇编阶段(生成
.o文件)
bash
gcc -c hello.s -o hello.o
# -c:只执行预处理、编译、汇编,生成目标文件
.o是二进制文件,无法直接查看,需用objdump工具分析:
bash
objdump -d hello.o # 查看目标文件的汇编指令
- 链接阶段
bash
gcc hello.o -o hello
# 无特殊参数,默认链接动态库
运行可执行文件:
bash
./hello # 输出:Hello Linux
- 一键编译(跳过中间文件)
bash
gcc hello.c -o hello # C语言
g++ hello.cpp -o hello # C++语言
3.3.静态链接 vs 动态链接
| 特性 | 静态链接(.a库) |
动态链接(.so库) |
|---|---|---|
| 编译参数 | gcc -static hello.c -o hello |
gcc hello.c -o hello(默认) |
| 文件大小 | 较大(包含库代码) | 较小(运行时加载库) |
| 运行依赖 | 不依赖系统库(可移植性强) | 依赖系统库安装对应动态库 |
| 更新维护 | 库更新需重新编译程序 | 库更新无需重新编译程序 |
| 适用场景 | 需移植到无对应库的环境 | 日常开发(节省内存和磁盘) |
查看可执行文件的依赖库:
bash
ldd hello # 查看动态链接的库
# 输出示例:libc.so.6 => /lib64/libc.so.6(依赖C标准库)
4.自动化构建:-make/Makefile
当工程中有多个源文件(如:main.c、func1.c、func2.c)时,手动输入gcc命令编译会非常繁琐。Makefile能定义"依赖关系"和"编译命令",只需执行make就能自动完成所有源文件的编译,还能清理中间文件。
4.1.核心概念
- 目标(Target):要生成的目标文件(如可执行文件、目标文件等);
- 依赖(Prerequisites):生成目标需要的文件(如
.c文件、.0文件); - 依赖方法(Recipe):生成目标的命令(如
gcc -c main.c -o main.o)。
格式如下:
bash
Target: Prerequisite1, Prerequisite2 ...
Recipe(命令前必须是Tab,不能是空格)
4.2.简单Makefile(单文件)
以myproc.c(计算1-100的和)为例,编写Makefile文件:
bash
# Makefile示例(单文件)
myproc: myproc.c # 目标:myproc;依赖:myproc.c
gcc -o myproc myproc.c # 编译命令(Tab开头)
.PHONY: clean # 声明clean为伪目标(避免与同名文件冲突)
clean: # 清理目标(无依赖,执行make clean时触发)
rm -f myproc # 删除可执行文件
使用方法:
bash
make # 编译生成myproc
make clean # 清理myproc(删除可执行文件)
4.3.进阶Makefile(多文件)
假设有三个文件:main.c(主函数)、add.c(加法函数)、add.h(头文件),工程结构如下:
bash
project/
├── main.c
├── add.c
├── add.h
└── Makefile
编写支持多文件的Makefile,使用变量简化维护:
bash
# 定义变量(方便修改,类似代码中的宏)
BIN = calc # 可执行文件名
SRC = $(wildcard *.c) # 所有.c文件(main.c、add.c)
OBJ = $(SRC:.c=.o) # 将.c替换为.o(main.o、add.o)
CC = gcc # 编译器
CFLAGS = -Wall -g # 编译选项(显示警告+生成调试信息)
# 目标:可执行文件calc,依赖所有.o文件
$(BIN): $(OBJ)
$(CC) $(CFLAGS) -o $@ $^ # $@=目标名,$^=所有依赖
@echo "编译完成!可执行文件:$(BIN)" # @:不显示命令本身
# 目标:.o文件,依赖对应的.c和.h文件(自动推导)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ # $<=第一个依赖(.c文件)
# 伪目标:清理中间文件和可执行文件
.PHONY: clean
clean:
rm -f $(OBJ) $(BIN)
@echo "清理完成!"
使用方法:
bash
make # 编译生成calc(自动生成main.o、add.o)
./calc # 运行程序
make clean # 清理main.o、add.o、calc
4.4.伪目标.PHONY
-
我们一般把clean设置成伪目标,伪目标的特性是,总是被执行的
-
.PHONY让make忽略源文件和可执行文件的M时间(文件内容修改时间)对比
如果工程中恰好有一个名为clean的文件,执行make clean时,make 会认为 "目标文件已存在且无依赖更新",不会执行清理命令。声明为伪目标后,make 会忽略同名文件,强制执行clean对应的命令。
5.编写第一个Linux程序:进度条
5.1.核心知识点
- 回车(
\r):光标回到当前行开头; - 换行:光标跳到下一行,现代计算机语言中的
\n实际上包含了回车和换行两部分; - 行缓冲区:printf默认会输出到缓冲区,遇到
\n或手动刷新(fflush(stdout))才会显示。
5.2.完整代码实现
5.2.1.头文件:process.h
c
// process.h
#pragma once
#include <stdio.h>
// 版本1:固定进度(0-100%)
void process_v1();
// 版本2:动态进度(根据当前进度更新)
// total:总任务量,current:当前完成量
void FlushProcess(double total, double current);
5.2.2.源文件:process.c(实现进度条逻辑)
c
// process.c
#include "process.h"
#include <string.h>
#include <unistd.h> // 包含usleep函数(微秒级休眠)
#define NUM 101 // 进度条缓冲区大小(100个字符+1个结束符)
#define STYLE '=' // 进度条填充字符
// 版本1:固定进度
void process_v1() {
char buffer[NUM] = {0}; // 初始化缓冲区(全0)
// 旋转光标(|/-\),实现动态效果
const char *lable = "|/-\\";
int len = strlen(lable); // 长度4
for (int cnt = 0; cnt <= 100; cnt++) {
// 格式化输出:进度条(左对齐100字符)、百分比、旋转光标
printf("[%-100s][%d%%][%c]\r", buffer, cnt, lable[cnt % len]);
fflush(stdout); // 手动刷新缓冲区(否则不显示)
buffer[cnt] = STYLE; // 填充进度条
usleep(50000); // 休眠50ms(控制进度条速度)
}
printf("\n"); // 进度条结束后换行
}
// 版本2:动态进度
void FlushProcess(double total, double current) {
char buffer[NUM] = {0};
const char *lable = "|/-\\";
int len = strlen(lable);
static int cnt = 0; // 静态变量(记录旋转光标位置,不重置)
// 计算当前进度百分比(转为整数)
int progress = (int)(current * 100 / total);
// 填充进度条缓冲区
for (int i = 0; i < progress; i++) {
buffer[i] = STYLE;
}
// 计算进度率(保留1位小数)
double rate = current / total;
cnt %= len; // 循环使用旋转光标
printf("[%-100s][%.1f%%][%c]\r", buffer, rate * 100, lable[cnt]);
fflush(stdout);
cnt++;
}
5.2.3.主函数:main.c(模拟下载场景)
c
// main.c
#include "process.h"
#include <unistd.h>
#define TOTAL_SIZE 1024.0 // 模拟总文件大小(1024MB)
#define SPEED 10.0 // 模拟下载速度(10MB/次)
// 模拟下载过程
void DownLoad() {
double current = 0.0; // 当前已下载大小
while (current <= TOTAL_SIZE) {
FlushProcess(TOTAL_SIZE, current); // 更新进度条
usleep(100000); // 休眠100ms(模拟下载耗时)
current += SPEED; // 累加已下载大小
}
printf("\n下载完成!总大小:%.2lfMB\n", current);
}
int main() {
printf("开始模拟下载...\n");
DownLoad(); // 执行下载(显示进度条)
return 0;
}
5.2.4.Makefile:自动化编译
bash
# Makefile
SRC = $(wildcard *.c) # main.c、process.c
OBJ = $(SRC:.c=.o) # main.o、process.o
BIN = processbar # 可执行文件名
CC = gcc
CFLAGS = -Wall -g # 显示警告+调试信息
$(BIN): $(OBJ)
$(CC) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(OBJ) $(BIN)
5.3.运行效果:
生成可执行文件,并运行:
bash
make # 编译生成processbar
./processbar # 运行程序
输出如下:
bash
开始模拟下载...
[================================================== ][50.0%][/]
最终显示:
bash
开始模拟下载...
[====================================================================================================][100.0%][|]
下载完成!总大小:1030.00MB
结语
本文从软件包管理器的 "依赖解决",到 vim 的 "多模式编辑",再到 gcc 的 "四阶段编译" 与 Makefile 的 "自动化构建",最后通过"进度条"项目完成了以上工具的实战使用,今后LInux系统中复杂的开发项目,都离不开这些基础工具的使用。