3. Linux 环境搭建:Ubuntu/Debian 系包管理器配置、CentOS/RHEL 系包管理器配置、源码编译安装 GCC

Linux 下的编译环境搭建,说白了就是搞定两件事:包管理器和编译器。包管理器帮你省去手动下载依赖的麻烦,编译器则是整个工具链的核心。我这些年踩过的坑,十有八九都跟这两样有关。

咱们先看一张整体流程图,把本章的知识脉络理清楚。

Linux 编译环境搭建知识体系 编译环境搭建 Debian/Ubuntu 系 apt / apt-get 换源 / 依赖解决 CentOS/RHEL 系 yum / dnf EPEL / 版本锁定 源码编译 GCC 下载 / 配置 / make 多版本管理 💡 核心原则:能用包管理器就别手动编译,除非你需要特定版本或定制选项 包管理器解决 90% 的依赖问题,源码编译解决剩下 10% 的定制需求

3.1 Ubuntu/Debian 系:apt 的配置与加速

Ubuntu 和 Debian 用的是 apt(底层是 dpkg)。我个人习惯拿到新机器第一件事就是换源。为什么?默认源在国外,下载速度能让你怀疑人生。

换源操作:编辑 /etc/apt/sources.list,把 archive.ubuntu.com 换成国内镜像,比如 mirrors.aliyun.com 或 mirrors.tuna.tsinghua.edu.cn。

具体步骤很简单:

# 备份原文件
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

# 编辑源列表(以 Ubuntu 22.04 为例)
sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

# 更新索引
sudo apt update

安装编译工具链,一条命令搞定:

sudo apt install build-essential
# 这个包包含了 gcc, g++, make, dpkg-dev 等核心工具
注意:apt update 只是刷新软件包列表,不会升级软件。要升级才用 apt upgrade。我曾经在项目交付前手滑执行了 apt upgrade,结果 GCC 从 9 升到 11,项目代码编译不过……嗯,从那以后我养成了锁版本的习惯。

如果你需要特定版本的 GCC,可以这样:

# 查看可用版本
apt list --all-versions gcc

# 安装指定版本
sudo apt install gcc-9 g++-9

# 切换默认版本(通过 update-alternatives)
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 90

3.2 CentOS/RHEL 系:yum/dnf 的配置与技巧

CentOS 7 及更早版本用 yum,CentOS 8 之后用 dnf。其实 dnf 就是 yum 的下一代,命令用法几乎一样。

RHEL 系最大的痛点是官方仓库软件版本偏老。GCC 可能还停留在 4.8 或 8.x,而你需要 C++17 甚至 C++20 的支持。这时候就需要 EPEL 和 SCL 了。

仓库源 用途 启用命令
BaseOS / AppStream 系统默认仓库,基础软件 默认启用
EPEL Extra Packages,补充软件包 sudo dnf install epel-release
SCL (Software Collections) 提供较新版本的开发工具 sudo dnf install centos-release-scl
PowerTools 开发依赖包仓库 sudo dnf config-manager --set-enabled powertools

安装开发工具组的命令:

# CentOS 7
sudo yum groupinstall "Development Tools"

# CentOS 8 / Rocky Linux / AlmaLinux
sudo dnf groupinstall "Development Tools"
版本锁定技巧:生产环境千万别随便升级 GCC。用 dnf versionlock 插件锁定版本:
sudo dnf install python3-dnf-plugin-versionlock
sudo dnf versionlock add gcc-*

如果你需要 GCC 11 或 12,可以用 SCL 或直接安装 Red Hat 的 GCC Toolset:

# 启用 SCL
sudo dnf install centos-release-scl

# 安装 GCC 11
sudo dnf install devtoolset-11-gcc devtoolset-11-gcc-c++

# 启用(临时生效)
scl enable devtoolset-11 bash

# 或者永久添加到 .bashrc
echo "source /opt/rh/devtoolset-11/enable" >> ~/.bashrc

3.3 源码编译安装 GCC:从下载到多版本管理

说实话,源码编译 GCC 是我最不想干的事。编译一次少说半小时,多则两三个小时。但有些场景你躲不开:

  • 需要 GCC 的某个特定版本(比如 13.2 的新特性)
  • 需要定制编译选项(比如开启 LTO、Graphite 优化)
  • 包管理器里没有你想要的版本

下面是我总结的最小化编译步骤:

# 1. 下载源码(以 GCC 13.2.0 为例)
wget https://ftp.gnu.org/gnu/gcc/gcc-13.2.0/gcc-13.2.0.tar.xz
tar -xf gcc-13.2.0.tar.xz
cd gcc-13.2.0

# 2. 下载依赖(GMP, MPFR, MPC 等)
./contrib/download_prerequisites

# 3. 创建独立构建目录(强烈建议!)
mkdir build && cd build

# 4. 配置
../configure --prefix=/usr/local/gcc-13.2 \
             --enable-languages=c,c++,fortran \
             --disable-multilib \
             --enable-lto

# 5. 编译(-j 参数根据 CPU 核心数调整)
make -j$(nproc)

# 6. 安装
sudo make install
避坑指南:我曾经直接在源码目录下执行 ./configure && make,结果编译到一半磁盘满了,想清理都麻烦。记住:永远在 build 目录下编译,这样想重来直接 rm -rf build 就行。

编译完成后,怎么管理多个 GCC 版本?我推荐用 update-alternatives 或者直接写环境变量脚本:

# 方式一:update-alternatives(Debian 系)
sudo update-alternatives --install /usr/local/bin/gcc gcc /usr/local/gcc-13.2/bin/gcc 130

# 方式二:写一个切换脚本
cat > ~/switch-gcc.sh << 'EOF'
#!/bin/bash
export PATH=/usr/local/gcc-13.2/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/gcc-13.2/lib64:$LD_LIBRARY_PATH
export CC=gcc
export CXX=g++
EOF

# 使用时 source 一下
source ~/switch-gcc.sh

编译时间太长怎么办?我一般这样优化:

  • 用 make -j$(nproc) 并行编译,别用单核
  • 只编译你需要的语言:--enable-languages=c,c++,别开 Java、Ada、Go
  • 关闭 multilib:--disable-multilib,省掉一半编译量
  • 如果内存够,用 --enable-linker-plugin-flags 加速链接
我的个人习惯:源码编译的 GCC 安装到 /usr/local/gcc-<version>,然后用软链接管理。这样想切版本就改个 PATH,不会污染系统自带的 GCC。

最后说一句:能用包管理器就别手动编译。但如果你真的需要源码编译,记住上面这些步骤和坑,能帮你省下至少半天时间。