《Linux系统编程》Linux基础开发工具 (一):软件包管理器yum/apt,编辑器Vim,编译器GCC/G++

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》《C++入门到进阶&自我学习过程记录》
《Linux操作系统从入门到实践》
《算法题讲解指南》--优选算法
《算法题讲解指南》--递归、搜索与回溯算法
《算法题讲解指南》--动态规划算法

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

前言

一、认识软件包管理器

[1.1 什么是软件包](#1.1 什么是软件包)

[1.2 了解Linux软件生态](#1.2 了解Linux软件生态)

[1.3 为什么需要国内镜像源?](#1.3 为什么需要国内镜像源?)

[1.3.1 国内主流开源镜像站汇总](#1.3.1 国内主流开源镜像站汇总)

[二、yum 与 apt 实操](#二、yum 与 apt 实操)

[2.1 查看软件包](#2.1 查看软件包)

[2.2 安装软件](#2.2 安装软件)

[2.3 卸载软件](#2.3 卸载软件)

[2.4 安装源](#2.4 安装源)

三、编辑器vim

[3.1 Vim 三大核心模式](#3.1 Vim 三大核心模式)

[3.2 vim的基本使用:常用命令速查](#3.2 vim的基本使用:常用命令速查)

[3.2.1 启动与退出 vim + 模式切换(基础)](#3.2.1 启动与退出 vim + 模式切换(基础))

[3.2.2 移动光标(普通模式):](#3.2.2 移动光标(普通模式):)

3.2.3文本编辑(普通模式:复制、删除、撤销、切换):

[3.2.4 视图模式的一些操作(批量处理)](#3.2.4 视图模式的一些操作(批量处理))

[3.2.5 末行模式的一些操作](#3.2.5 末行模式的一些操作)

[3.3 vim的配置](#3.3 vim的配置)

[四、编译器gcc /g++](#四、编译器gcc /g++)

[4.1 核心认知:编译的四个阶段(ESc-iso速记)](#4.1 核心认知:编译的四个阶段(ESc-iso速记))

[4.1.1 阶段 1:预处理](#4.1.1 阶段 1:预处理)

[4.1.2 阶段 2:编译](#4.1.2 阶段 2:编译)

[4.1.3 阶段 3:汇编(Assembly)](#4.1.3 阶段 3:汇编(Assembly))

[4.1.4 阶段 4:链接(Linking)](#4.1.4 阶段 4:链接(Linking))

[4.1.5 一键编译(合并四阶段)](#4.1.5 一键编译(合并四阶段))

[4.2 GCC核心功能选项](#4.2 GCC核心功能选项)

[4.2.1 核心功能速查表:](#4.2.1 核心功能速查表:)

[4.3 条件编译](#4.3 条件编译)

[4.3.1 条件编译的逻辑和应用场景](#4.3.1 条件编译的逻辑和应用场景)

[4.3.2 编译的过程:编译器和语言的历史](#4.3.2 编译的过程:编译器和语言的历史)

[4.4 关键原理:静态链接和动态链接](#4.4 关键原理:静态链接和动态链接)

[4.4.1 静态链接(Static Linking)](#4.4.1 静态链接(Static Linking))

[4.4.2 动态链接(Dynamic Linking)](#4.4.2 动态链接(Dynamic Linking))

[4.4.3 查看依赖的库文件](#4.4.3 查看依赖的库文件)

[4.4.4 核心概念对比 && 整体总结](#4.4.4 核心概念对比 && 整体总结)

结束语


前言

在Linux C/C++开发中,高效运用核心工具是提升效率的关键。本文聚焦三款核心工具------包管理器(yum与apt)、文本编辑器Vim、编译器GCC/G++。

yum与 apt 是环境搭建的基石,负责安装工具、配置环境、解决依赖;Vim助力高效编辑,摆脱鼠标依赖;GCC/G++实现源代码到可执行程序的转换,三者协同支撑Linux C/C++开发全流程。串联"环境搭建→代码编辑→程序编译"的完整链路,拆解核心用法与实操技巧,帮你快速掌握关键技能,为项目开发筑牢基础。

一、认识软件包管理器

在 Windows 或 macOS 中,我们是通过 "应用商店" 或 .exe安装包 获取软件;而在Linux中,软件包管理器承担了类似的角色,而且能解决"软件依赖"的问题。

1.1 什么是软件包

  • 软件包 :在Linux下安装软件,一个直接的办法是先下载到程序的源代码,再进行编译,才会得到可执行程序,但是这样太麻烦了,于是有些人把一些常用的软件提前进行编译好 ,做成软件包(可以理解成windows上的安装程序)放在一个服务器上,通过包管理器可以很方便的获取到这个编译好的软件包,直接进行安装;

  • 包管理器:负责软件包 "查找 - 下载 - 安装 - 卸载 - 依赖处理" 的工具,主流分为两类:

    • **yum:**适用于 CentOS、RedHat、Fedora 等基于 RPM 包的发行版;
    • **apt:**适用于 Ubuntu、Debian 等基于 DEB 包的发行版。

1.2 了解Linux软件生态

  • Linux下载软件的过程(Ubuntu,Centos,other):

  • 我们评估一款操作系统的好坏,最重要的是什么呢?不就是这款操作系统的生态是否完善嘛。
  • 为什么会有人免费特定社区提供软件,还发布?还提供云服务器让你下载?

这里我们是不是有点熟悉了,这些好处不正是开源带来的嘛,我们在刚开始学Linux的时候就讲过,开源的本质是一种商业模式

  • 依赖问题: 多数软件需要依赖其他库文件(如libc.sossl.so)才能运行。但是包管理器会自动识别下载这些依赖避免 "缺少某某文件" 的报错

1.3 为什么需要国内镜像源?

Linux 默认的软件源多位于国外服务器,国内用户下载时会面临速度慢、频繁中断的问题。国内镜像源是官方源的 "副本",由国内高校或企业维护,能大幅提升下载速度。

1.3.1 国内主流开源镜像站汇总

镜像站名称 官方链接 主要支持场景
阿里云镜像站 https://developer.aliyun.com/mirror/ CentOS、Ubuntu、Debian 等系统及常见软件包
清华大学镜像站 https://mirrors.tuna.tsinghua.edu.cn/ 全系列 Linux、Python/Perl/Ruby 等编程语言扩展包
中国科学技术大学镜像站 http://mirrors.ustc.edu.cn/ 全系列 Linux、常用编程语言及开发工具
北京交通大学镜像站 https://mirror.bjtu.edu.cn/ 多种 Linux 发行版及相关软件仓库
中国科学院软件研究所镜像站 http://mirror.iscas.ac.cn/ 多种 Linux 发行版、编程语言和开发工具
上海交通大学镜像站 https://ftp.sjtu.edu.cn/ 多种 Linux 发行版镜像及软件仓库
网易镜像站 http://mirrors.163.com/ CentOS、Ubuntu 等基础发行版及相关软件

补充说明:

  • 以上镜像站均提供丰富的 Linux 软件资源,可根据地理位置和网络情况选择使用。
  • 清华大学、中科大和阿里云镜像站是目前国内最活跃、资源最全面的镜像源之一。
  • 部分镜像站还提供 Docker 镜像、开源文档等额外资源。

二、yum 与 apt 实操

我们可通过包管理器高效管理软件。以下是 yum(CentOS)和 apt(Ubuntu)的核心命令,对应场景包括 "查看软件""安装软件""卸载软件" 等。

操作场景 CentOS/RHEL (yum/dnf) 命令 Ubuntu/Debian (apt) 命令
更新软件包列表 yum check-update dnf check-update sudo apt update
搜索指定软件 yum search 软件名 dnf search 软件名 apt search 软件名
查看软件详细信息 yum info 软件名 dnf info 软件名 apt show 软件名
列出所有可安装软件 yum list available dnf list available apt list
安装软件 sudo yum install 软件名 sudo dnf install 软件名 sudo apt install 软件名
卸载软件 sudo yum remove 软件名 sudo dnf remove 软件名 sudo apt remove 软件名
升级所有软件包 sudo yum update``sudo dnf upgrade sudo apt upgrade

2.1 查看软件包

在安装软件前,可先查看该软件是否在镜像源中,以及当前可用版本。

通过 yumlist 命令可以罗列出当前一共有哪些软件包,由于包的数目可能非常之多,这里我们需要使用 grep 命令只筛选出我们关注的包。

示例:查看 "lrzsz"(Linux 与 Windows 文件传输工具)

  • CentOS:
bash 复制代码
$ yum list | grep lrzsz 
lrzsz.x86_64        0.12.20-36.el7        @base

# 输出示例:lrzsz.x86_64  0.12.20-36.el7  base
# 解读:x86_64=64位包;el7=适配CentOS 7;base=源名称
  • Ubuntu:
bash 复制代码
$ apt search lrzsz
Sorting... Done
Full Text Search... Done
cutecom/focal 0.30.3-1build1 amd64
Graphical serial terminal, like minicom
 
lrzsz/focal,now 0.12.21-10 amd64 [installed]
    Tools for zmodem/xmodem/ymodem file transfer
 
$ apt show lrzsz
Package: lrzsz
Version: 0.12.21-10
Priority: optional
Section: universe/comm
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Martin A. Godisch <godisch@debian.org>
...

注意事项

  • 软件包名称:主版本号,次版本号,源程序发行号-软件包的发行号,主机平台,cpu架构
  • x86_64" 后缀表示64位系统的安装包, "i686" 后缀表示32位系统安装包. 选择包时要和系统匹配
  • "el7" 表示操作系统发行版的版本,"el7" 表示的是 centos7/redhat7. "el6" 表示 centos6/redhat6
  • 最后一列, base 表示的是 "软件源" 的名称, 类似于 "小米应用商店", "华为应用商店" 这样的概念
  • Ubuntu 上述有详细介绍

2.2 安装软件

安装软件需 root 权限(通过 sudo 临时获取,或直接切换 root 用户),-y 选项可自动确认安装(无需手动输入 "y" 确认)

操作场景 CentOS (yum/dnf) 命令 Ubuntu (apt) 命令
更新软件包列表 sudo yum check-update sudo apt update
安装指定软件 sudo yum install -y 软件名 sudo apt install -y 软件名
安装扩展源 sudo yum install -y epel-release sudo add-apt-repository ppa:xxx
列出已安装软件 yum list installed apt list --installed

实际示例

bash 复制代码
# CentOS
sudo yum install -y lrzsz

# Ubuntu
sudo apt install -y lrzsz

注意事项

  • 安装软件时由于需要向系统目录中写入内容,一般需要 sudo 或者切换到 root 账户下才能完成。
  • Linux系统下,如果有多个用户,也只需要安装一次就行
  • yum/apt 安装软件只能一个装完了再装另一个,正在 yum/apt 安装下一个软件的过程中,如果再尝试用 yum/apt 安装另外一个软件,yum/apt 会报错。
  • 如果 yum/apt 报错,请自行在网上查找原因。

2.3 卸载软件

若软件不再使用,可通过包管理器彻底卸载,避免占用磁盘空间。

实际示例

bash 复制代码
# CentOS
sudo yum remove -y lrzsz

# Ubuntu(仅卸载软件,保留配置)
sudo apt remove -y lrzsz

注意

  • 网络验证:包管理器依赖网络,若命令执行失败,先通过 ping www.baidu.com 验证网络是否通畅

2.4 安装源

  • Centos 安装源路径:
bash 复制代码
[root@iZbp12ear9ufvimc78fddkZ ~]# ll /etc/yum.repos.d/
total 8
-rw-r--r-- 1 root root 641 Sep 10 22:45 CentOS-Base.repo
-rw-r--r-- 1 root root 230 Sep 10 22:45 CentOS-Epel.repo

# 安装扩展源
[root@iZbp12ear9ufvimc78fddkZ ~]# sudo yum install -y epel-release
..................
[root@iZbp12ear9ufvimc78fddkZ ~]# ll /etc/yum.repos.d/
total 16
-rw-r--r-- 1 root root  641 Sep 10 22:45 CentOS-Base.repo
-rw-r--r-- 1 root root  230 Sep 10 22:45 CentOS-Epel.repo
-rw-r--r-- 1 root root 1358 Sep  5  2021 epel.repo
-rw-r--r-- 1 root root 1457 Sep  5  2021 epel-testing.repo
  • Ubuntu 安装源路径:
bash 复制代码
$ cat /etc/apt/sources.list # 标准源
$ ll /etc/apt/sources.list.d/ # 扩展源
# ubuntu 安装扩展源,就结合未来具体场景

软件源更新的本质:这个新的配置文件会替换系统的,如果你想保留,可以对老的备份一下------sudo mv;否则就直接覆盖老的------sudo cp。

三、编辑器vim

vim是一款基于Linux的文本编辑器,只能用于写代码或者更改配置文件。

3.1 Vim 三大核心模式

Vim 有三种主要模式,你必须清楚当前处于哪种模式:

模式 说明 如何进入
普通模式(Normal) 默认模式,用于移动光标、删除、复制等操作,光标为块状。 启动 Vim 后默认进入。从其他模式按 Esc 键返回。
插入模式(Insert) 用于输入和编辑文本,光标为竖线,状态栏显示-- INSERT --。 在普通模式下按 i(光标前插入)、a(光标后插入)、o(下一行插入新行)等。
命令行模式(Command‑line) 用于保存文件、退出 Vim、查找替换等。 在普通模式下按 : 进入。

提示:如果不确定自己处于什么模式,可以多按几次 Esc 键,确保回到普通模式。

其实一共是有12种模式的。这里先讲三种比较核心的,后面还会补充几种。

下面的图是本篇文章会讲解的模式,其余模式的使用场合较少就不进行讲解了:

3.2 vim的基本使用:常用命令速查

3.2.1 启动与退出 vim + 模式切换(基础)

  1. 进入vim,在系统提示符号输入vim及文件名称后,就进入vim全屏编辑页面:

    vim: 直接打开 Vim,进入空白文件。
    vim 文件名: 打开或新建指定文件(例如 vim test.txt)。

    如果文件已存在,Vim 会显示其内容;如果文件不存在,Vim 会在保存时创建新文件。

    不过有一点需要特别注意,就是你进入vim之后,是默认处于[命令模式],你要切换至[插入模式]才能够输入文字。

  2. [正常模式] 切换至 [插入模式]

    输入 i: 光标不动
    输入 a: 光标向后移一个
    **输入 o:**光标向下移一个

  3. [插入模式] 切换至 [正常模式]

    目前处于[插入模式],就只能⼀直输入文字,如果发现输错了字,想用光标键往回移动,将该字删除,可以先按⼀下「ESC」键转到[正常模式]再删除文字。当然,也可以直接删除。

  4. **[正常模式] 切换至 [末行模式]

    shift + ;\]:** 其实就是输入 **\[:\]** 末行模式想要切换回去直接「ESC」就完了

    w(保存文件)

    q(退出文件)

    wq(输入[wq],存盘并退出vim

    q!(输入 q!,不存盘强制退出vim) --还有wq!,w!等

    在正常模式下也可以直接 shift+zz(不用切换至末行模式,但是不建议用)

3.2.2 移动光标(普通模式):

普通模式中,默认只能移动光标,无法输入字符

使用小键盘上的上下左右移动,也可以使用HJKL 键移动。虽然这里肯定会有人说都可以用键盘上的上下左右箭头来控制光标移动,用HJKL键移动不是多此一举吗?

其实并不是,主要原因是以前的键盘是没有上下左右四个箭头按键的:

为了实现光标的移动,就把HJKL这几个按键设计成光标移动功能,而上下左右箭头按键是后来加进去的,这也就说明vim的部分功能操作只能用HJKL这四个按键来控制光标的移动(后面会进行讲解)

基本移动(可以用n)

  • h 左移一格(记忆法:hjkl中h在最左边 -> 左移)

  • j 下移一行(记忆法:j -> jump -> 往下跳 -> 下移)

  • k 上移一行(记忆法:k -> king -> 国王(高高在上) -> 上移)

  • l 右移一格(记忆法:hjkl中l在最右边 -> 右移)

单词移动(可以用n)

  • w(下一个单词开头)

  • e(单词结尾)

  • b(上一个单词开头)

行内移动

  • [shift+6] (^)(行首第一个非空字符)

  • [shift+4] ($)(行尾)

文件内移动:

  • gg(文件开头)

  • [shift+g] (G)(文件结尾)

  • nG(跳转到第 n 行,如 5G 跳第 5 行)

3.2.3文本编辑(普通模式:复制、删除、撤销、切换):

普通模式下执行,配合数字前缀可批量操作:

删除

  • x(删除光标处字符)
  • dd(删除当前行)
  • dw(删除当前单词)
  • ndd(删除 n 行,比如3dd,删除3行)

复制粘贴

  • yy(复制当前行)
  • yw(复制当前单词)
  • p(光标后粘贴)
  • [shift+p] (P)(光标前粘贴)
  • nyy(复制n行,比如5yy ,复制5行)

撤销与重做

  • u(撤销上一步)
  • Ctrl+r(重做撤销操作)
  • .(重复上一次编辑命令)

替换

  • r(替换光标处单个字符)
  • [shift+r] (R)(进入替换模式,连续替换)

切换

  • ~**(**对特定的字符进行大小写切换)

3.2.4 视图模式的一些操作(批量处理)

批量化注释和去注释

3.2.5 末行模式的一些操作

查找字符:

  • /关键字:先按 / 键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 n 会往后寻找到您要的关键字为止。
  • ?关键字:先按 ? 键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 n 会往前寻找到您要的关键字为止。

列出/去掉行号:

  • set nu:输入 set nu 后,会在文件中的每一行前面列出行号。
  • set nonu:输入 set nu 后,文件中的行号进行删除。

跳到文件中的某一行:

  • #:# 号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字 15,再回车,就会跳到文章的第 15 行。

分屏操作

  • vs 文件名 (分屏,用来写文件,光标在哪写到哪), ctrl+ww(移到其它文件)

3.3 vim的配置

配置文件的位置

  • 在目录 /etc/下面,有个名为 .vimrc的隐藏文件(没有就手动创建一个) ,这是系统中公共的vim配置文件,对所有用户都有效。
  • 而在每个用户的主目录 下,都可以自己建立私有的配置文件 ,命名为:".vimrc"。例如:/root目录下,通常已经存在一个.vimrc文件,如果不存在,则创建之。
  • 切换用户成为自己执行 su,进入自己的主工作目录,执行 cd ~
  • 打开自己目录下的 .vimrc文件 ,执行 vim .vimrc

常用配置选项,大家可以自己写进去配置一下

  • 设置语法高亮:syntax on
  • 显示行号:set nu
  • 设置缩进的空格数为4:set shiftwidth=4

其实还有非常多的多插件和其它配置,这里就不讲了,直接给大家提供一个一键配置方案:

bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ ~]$ source ~/.bashrc

四、编译器gcc /g++

4.1 核心认知:编译的四个阶段(ESc-iso速记)

GCC 编译 C/C++ 程序并非一步到位,而是分为预处理、编译、汇编、链接四个阶段,每个阶段完成特定任务,最终生成可执行文件。

4.1.1 阶段 1:预处理

  • 核心任务:宏替换、删除注释、条件编译、头文件展开(不进行语法检查);
  • 关键选项-E(仅执行预处理,停止后续编译);
  • 输出文件.i 后缀(预处理后的 C 文件);

实操命令

bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ test]$ touch code.c
[admin@iZbp12ear9ufvimc78fddkZ test]$ vim code.c 
[admin@iZbp12ear9ufvimc78fddkZ test]$ gcc -E code.c -o code.i
[admin@iZbp12ear9ufvimc78fddkZ test]$ ll
total 24
-rw-rw-r-- 1 admin admin    78 May 17 15:12 code.c
-rw-rw-r-- 1 admin admin 16876 May 17 15:13 code.i
  • 示例:#include <stdio.h> 在预处理阶段会将 stdio.h 的全部内容进行展开,#define MAX 10会替换所有MAX为 10,并且注释代码会进行剔除等。

4.1.2 阶段 2:编译

  • 核心任务 :检查语法错误,将预处理后的代码( .i )转换为汇编语言代码
  • 关键选项:-S(仅执行编译,停止后续流程);
  • 输出文件 :.s 后缀(汇编文件);

实操命令

bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ test]$ gcc -S code.c -o code.s
[admin@iZbp12ear9ufvimc78fddkZ test]$ ll
total 28
-rw-rw-r-- 1 admin admin   449 May 17 15:18 code.c
-rw-rw-r-- 1 admin admin 17016 May 17 15:19 code.i
-rw-rw-r-- 1 admin admin   664 May 17 15:25 code.s

说明:生成的汇编代码与 CPU 架构相关(如 x86_64、ARM),可直接查看指令逻辑。

4.1.3 阶段 3:汇编(Assembly)

  • 核心任务:将汇编代码(.s)转换为机器可识别的二进制目标文件;
  • 关键选项-c (仅执行汇编,生成目标文件);
  • 输出文件 :.o 后缀 (目标文件,二进制格式不可执行);

实操命令

bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ test]$ gcc -c code.s -o code.o
[admin@iZbp12ear9ufvimc78fddkZ test]$ ll
total 32
-rw-rw-r-- 1 admin admin   449 May 17 15:18 code.c
-rw-rw-r-- 1 admin admin 17016 May 17 15:19 code.i
-rw-rw-r-- 1 admin admin  1768 May 17 15:40 code.o
-rw-rw-r-- 1 admin admin   664 May 17 15:39 code.s
bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ test]$ objdump -d code.o

code.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	be 64 00 00 00       	mov    $0x64,%esi
   9:	bf 00 00 00 00       	mov    $0x0,%edi
   e:	b8 00 00 00 00       	mov    $0x0,%eax
  13:	e8 00 00 00 00       	callq  18 <main+0x18>
  18:	bf 00 00 00 00       	mov    $0x0,%edi
  1d:	e8 00 00 00 00       	callq  22 <main+0x22>
  22:	bf 00 00 00 00       	mov    $0x0,%edi
  27:	e8 00 00 00 00       	callq  2c <main+0x2c>
  2c:	bf 00 00 00 00       	mov    $0x0,%edi
  31:	e8 00 00 00 00       	callq  36 <main+0x36>
  36:	b8 00 00 00 00       	mov    $0x0,%eax
  3b:	5d                   	pop    %rbp
  3c:	c3                   	retq   
  • 说明:虽然目标文件已经包含机器指令,但缺少库依赖(如 printf 函数的实现),无法直接运行。
bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ test]$ ./code.o
bash: ./code.o: Permission denied

4.1.4 阶段 4:链接(Linking)

  • 核心任务 :将目标文件(.o)与系统库、第三方库链接,生成可执行文件;
  • 核心逻辑:解析未定义符号(如 printf ),从库文件(如 libc.so)中找到实现并关联;
  • 输出文件:默认名为 a.out(可通过 -o 指定名称);

实操命令

bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ test]$ gcc code.o -o code.exe
# 也可以 gcc -o code.exe code.o
[admin@iZbp12ear9ufvimc78fddkZ test]$ ll
total 44
-rw-rw-r-- 1 admin admin   449 May 17 15:18 code.c
-rwxrwxr-x 1 admin admin  8408 May 17 15:46 code.exe
-rw-rw-r-- 1 admin admin 17016 May 17 15:19 code.i
-rw-rw-r-- 1 admin admin  1768 May 17 15:40 code.o
-rw-rw-r-- 1 admin admin   664 May 17 15:39 code.s
[admin@iZbp12ear9ufvimc78fddkZ test]$ ./code.exe 
hello world hello bit!, M = 100
hello world hello bit!
hello world hello bit!
N:exist

4.1.5 一键编译(合并四阶段)

日常开发中无需分步执行,GCC/G++ 支持一键完成四阶段编译:

bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ test]$ ll
total 4
-rw-rw-r-- 1 admin admin 449 May 17 15:18 code.c
[admin@iZbp12ear9ufvimc78fddkZ test]$ gcc code.c -o code
# 也可以 gcc -o code code.c
[admin@iZbp12ear9ufvimc78fddkZ test]$ ll
total 16
-rwxrwxr-x 1 admin admin 8408 May 17 15:50 code
-rw-rw-r-- 1 admin admin  449 May 17 15:18 code.c
[admin@iZbp12ear9ufvimc78fddkZ test]$ ./code 
hello world hello bit!, M = 100
hello world hello bit!
hello world hello bit!
N:exist

本质是 GCC 自动依次执行 预处理→编译→汇编→链接,隐藏了中间文件。

4.2 GCC核心功能选项

4.2.1 核心功能速查表:

选项 功能描述 使用示例
-E 只进行预处理,不编译、汇编和链接 gcc -E main.c -o main.i
-S 编译到汇编语言,不进行汇编和链接 gcc -S main.c -o main.s
-c 编译到目标代码,生成.o文件 gcc -c main.c -o main.o
-o 指定输出文件名 gcc main.c -o myapp
-static 使用静态链接生成可执行文件 gcc main.c -static -o app_static
-g 生成调试信息,供 GDB 使用 gcc -g main.c -o debug_app
-shared 尽量使用动态库,生成较小的文件 gcc -shared lib.c -o lib.so
-O0 不进行优化(编译速度最快) gcc -O0 main.c -o app
-O1 基本优化(默认级别) gcc -O1 main.c -o app
-O2 较多优化,平衡性能与编译时间 gcc -O2 main.c -o app
-O3 最高级别优化(可能增加代码大小) gcc -O3 main.c -o app
-w 禁止所有警告信息 gcc -w main.c -o app
-Wall 开启所有常见警告信息 gcc -Wall main.c -o app

4.3 条件编译

4.3.1 条件编译的逻辑和应用场景

4.3.2 编译的过程:编译器和语言的历史

关键逻辑

  • 为什么任何语言最后都要变成二进制 -> 因为编译器只认识它
  • 编译的过程为何是那样的 -> 上面的图中有解释
  • 一定是先有语言再有编译器 的。并且语言和编译器之间是一个自举的关系

4.4 关键原理:静态链接和动态链接

链接阶段的核心是"关联库文件",GCC支持的两种链接方式,静态链接和动态链接各有优劣。

4.4.1 静态链接(Static Linking)

  • 原理 :编译时将依赖的库文件 (如 libc.a)全部复制到可执行文件中;
  • 关键选项-static;
  • 实操命令gcc hello.c -o hello_static -static ------ 强制静态链接生成可执行文件(因为GCC默认是动态链接的)
  • 安装命令sudo yum install glibc-static libstdc++-static -y
  • 优点 :可执行文件不依赖系统库移植性强
  • 缺点 :会让可执行程序变大,运行的时候,加载到内存占据更多的内存空间,浪费资源!

4.4.2 动态链接(Dynamic Linking)

  • 原理 :编译时仅记录库依赖 (如 libc.so),程序运行时才加载库文件
  • 特点:GCC 默认采用动态链接;
  • 实操命令gcc hello.c -o hello_dynamic ------ 动态链接(默认)
  • 优点 :文件体积小,库文件被多个程序共享节省内存和磁盘空间
  • 缺点 :依赖系统中对应的库文件,一旦库文件缺失所有程序都无法运行了。
bash 复制代码
[admin@iZbp12ear9ufvimc78fddkZ test]$ ll
total 860
-rw-rw-r-- 1 admin admin    449 May 17 15:18 code.c
-rwxrwxr-x 1 admin admin   8408 May 17 16:27 code_dynamic
-rwxrwxr-x 1 admin admin 861384 May 17 16:24 code_static
[admin@iZbp12ear9ufvimc78fddkZ test]$ file code_dynamic 
code_dynamic: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=104a9c2f2c81bd94ded86fd987b09fa19ad8d5f1, not stripped
[admin@iZbp12ear9ufvimc78fddkZ test]$ file code_static 
code_static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=51c74fae298b26e8e7bac41eb4c911bc5671f637, not stripped

4.4.3 查看依赖的库文件

bash 复制代码
# 动态链接的文件
[admin@iZbp12ear9ufvimc78fddkZ test]$ ldd code_dynamic 
	linux-vdso.so.1 =>  (0x00007ffc0ccf2000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f2394d45000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f2395113000)
# 静态链接的文件
[admin@iZbp12ear9ufvimc78fddkZ test]$ ldd code_static 
	not a dynamic executable

看一下动态链接和静态链接文件的大小对比,也能说明静态链接将依赖库全部进行了复制

4.4.4 核心概念对比 && 整体总结

特性 动态库(电竞馆) 静态库(个人电脑)
资源使用 共享,节省资源 独占,浪费资源
依赖性 强依赖,库缺失则全崩 独立,自给自足
更新维护 更新库即更新所有程序 每个程序需重新编译
内存占用 多个程序共享同一份 每个程序都有一份拷贝

整体总结:

  • 动态库 :像是一个共享的电竞馆,多个程序在运行时共享同一个库节省空间,但一旦库被删除(电竞馆倒闭了),所有程序都无法运行。

  • 静态库 :像是每个人都有属于自己的电脑,程序在编译时 就将库代码复制到可执行文件 中,因此程序体积大 ,但可以独立运行不依赖外部库

在编程中,我们根据需求选择使用动态库还是静态库。动态库适合多个程序共享,减少内存占用;静态库适合程序独立发布,避免依赖问题。

结束语

以上就是本篇 Linux 基础开发工具的全部内容。**从系统软件包管理器 yum/apt 快速完成环境部署,到 Vim 编辑器高效编写代码,再到 GCC/G++ 编译工具链实现程序构建,这些都是 Linux 系统编程的必备基本功。工欲善其事,必先利其器,熟练掌握基础工具,才能在后续进程、文件 IO、网络编程的学习中事半功倍。**希望对大家学习Linux能有所收获!

相关推荐
William.csj1 小时前
Linux——服务器后台运行程序指南(包含 Python 与 .sh 脚本实战)
linux·服务器·python
杨云龙UP1 小时前
MySQL主库高峰期备份引发504故障:从库手动切换接管 + 主从恢复同步 + Docker版DB2重启实战_2026-05-17
linux·运维·数据库·mysql·docker·容器·centos
lifewange1 小时前
Vim 统一替换(全局替换)
linux·编辑器·vim
用户2367829801681 小时前
Linux netstat 命令深度解析:从网络连接到端口监控的完整实现
linux
曾帅1681 小时前
linux ubuntu 挂载硬盘
linux·运维·ubuntu
Yjiokm2 小时前
proot-distro 安装指定版本 ubuntu
linux·运维·ubuntu
lifewange2 小时前
ls -ltr
linux·运维·服务器
不怕犯错,就怕不做2 小时前
linux的notifier_block内核通知链
linux·驱动开发·嵌入式硬件
say_fall2 小时前
Git完全入门指南-从概念到实战掌握版本控制的核心
linux·运维·服务器·git·学习