Ubuntu 20.04 离线编译安装 GCC 11 完整教程 - 无网络环境部署指南

前言

在某些特殊环境下(如内网服务器、安全隔离环境、生产环境等),我们无法直接通过 apt 在线安装软件。本文详细介绍在 Ubuntu 20.04 系统上离线编译安装 GCC 11 的完整流程,包括依赖准备、源码编译、离线包制作、批量部署等实用内容。

一、为什么需要离线安装 GCC

1.1 应用场景

  • 内网服务器:无法访问外网的隔离环境
  • 生产环境:出于安全考虑禁止外网访问
  • 批量部署:需要在多台服务器上安装相同版本
  • 特定版本需求:系统源中没有所需版本
  • 定制化编译:需要特定的编译选项

1.2 Ubuntu 20.04 默认 GCC 版本

# 查看系统默认 GCC 版本
gcc --version

# Ubuntu 20.04 默认版本:
# gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0

1.3 GCC 11 新特性

特性 说明
C++20 支持 更完整的 C++20 标准支持
C23 支持 实验性 C23 特性
性能优化 更好的代码优化能力
诊断改进 更友好的错误提示
RISC-V 支持 增强的 RISC-V 架构支持

二、环境准备

2.1 系统要求

配置项 最低要求 推荐配置
操作系统 Ubuntu 20.04 Ubuntu 20.04 LTS
CPU 2 核 8 核+
内存 4GB 16GB+
磁盘空间 20GB 50GB+
编译时间 约 2 小时 约 30 分钟

2.2 准备工作流程

步骤 1: 在有网络的机器上下载源码和依赖
         ↓
步骤 2: 打包所有离线文件
         ↓
步骤 3: 传输到目标机器(U 盘/光盘/内网传输)
         ↓
步骤 4: 在目标机器上安装依赖
         ↓
步骤 5: 编译安装 GCC
         ↓
步骤 6: 验证测试

三、下载源码和依赖(有网络环境)

3.1 创建下载目录

# 创建工作环境
mkdir -p ~/gcc-offline/{source,deps,install}
cd ~/gcc-offline

# 目录说明:
# source/  - GCC 源码
# deps/    - 依赖包
# install/ - 安装目标目录

3.2 下载 GCC 源码

# 方法一:从 GNU 官方下载
cd ~/gcc-offline/source
wget https://ftp.gnu.org/gnu/gcc/gcc-11.4.0/gcc-11.4.0.tar.gz

# 方法二:从镜像站点下载(国内更快)
wget https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-11.4.0/gcc-11.4.0.tar.gz

# 验证下载完整性
wget https://ftp.gnu.org/gnu/gcc/gcc-11.4.0/gcc-11.4.0.tar.gz.sig
gpg --verify gcc-11.4.0.tar.gz.sig gcc-11.4.0.tar.gz

# 解压源码
tar -xzf gcc-11.4.0.tar.gz
cd gcc-11.4.0

# 下载编译依赖(mpfr、gmp、mpc、isl)
# GCC 提供了自动下载脚本
./contrib/download_prerequisites

# 返回上级目录
cd ~/gcc-offline/source

3.3 下载编译依赖包

创建依赖下载脚本 download_deps.sh

#!/bin/bash
# download_deps.sh - 下载 GCC 编译所需的所有依赖包

set -e

DEPS_DIR=~/gcc-offline/deps
mkdir -p $DEPS_DIR
cd $DEPS_DIR

echo "正在下载 GCC 编译依赖包..."

# 基础编译工具
apt-get download \
    build-essential \
    gcc \
    g++ \
    make \
    cmake \
    autoconf \
    automake \
    libtool \
    pkg-config \
    bison \
    flex \
    texinfo \
    libgmp-dev \
    libmpfr-dev \
    libmpc-dev \
    libisl-dev \
    zlib1g-dev \
    libzstd-dev \
    libgcrypt20-dev \
    libssl-dev \
    libelf-dev \
    libexpat1-dev \
    libpython3-dev \
    wget \
    curl \
    ca-certificates

# 下载所有 deb 包到当前目录
# apt-get download 会自动保存到当前目录

echo "依赖包下载完成!"
ls -lh *.deb | wc -l
echo "个 deb 包已下载到 $DEPS_DIR"

3.4 使用 apt-offline(推荐)

apt-offline 是专门用于离线环境的 apt 工具:

# 在有网络的机器上安装 apt-offline
sudo apt install apt-offline

# 生成依赖列表
cd ~/gcc-offline
apt-offline set gcc-deps.sig --update --upgrade \
    --install-packages "build-essential,gcc,g++,make,bison,flex,texinfo,libgmp-dev,libmpfr-dev,libmpc-dev,libisl-dev,zlib1g-dev,libzstd-dev"

# 下载所有依赖包
apt-offline get gcc-deps.sig --bundle gcc-deps.zip --threads 10

# 查看下载内容
unzip -l gcc-deps.zip

# 打包所有文件
cd ~/gcc-offline
tar -czf gcc-offline-complete.tar.gz source/ deps/ gcc-deps.zip

3.5 创建完整的离线包

#!/bin/bash
# create_offline_package.sh - 创建完整的离线安装包

set -e

OFFLINE_ROOT=~/gcc-offline
PACKAGE_NAME=gcc-11-offline-ubuntu2004.tar.gz

cd $OFFLINE_ROOT

# 创建安装脚本
cat > install.sh << 'EOF'
#!/bin/bash
# GCC 离线安装脚本
set -e
echo "开始安装 GCC 11..."
# 脚本内容见下文
EOF
chmod +x install.sh

# 创建 README
cat > README.md << 'EOF'
# GCC 11 离线安装包

## 内容说明
- source/     : GCC 11.4.0 源码及依赖
- deps/       : 系统依赖 deb 包
- install.sh  : 自动安装脚本

## 使用方法
1. 解压安装包
2. 运行 sudo ./install.sh
3. 验证安装:gcc-11 --version

## 注意事项
- 需要 root 权限
- 确保有足够的磁盘空间(至少 20GB)
- 编译时间约 1-2 小时
EOF

# 打包
cd ~/
tar --exclude='*.sig' \
    -czf $PACKAGE_NAME \
    gcc-offline/

echo "离线包创建完成:$HOME/$PACKAGE_NAME"
ls -lh $PACKAGE_NAME

四、目标机器安装(无网络环境)

4.1 传输离线包

# 方法一:使用 U 盘
# 将 gcc-offline-complete.tar.gz 复制到 U 盘
# 在目标机器上挂载 U 盘
sudo mount /dev/sdb1 /mnt
cp /mnt/gcc-offline-complete.tar.gz ~/
sudo umount /mnt

# 方法二:使用 scp(内网传输)
# 从有网络的机器传输
scp gcc-offline-complete.tar.gz user@target-server:~/

# 方法三:使用光盘
# 刻录到光盘后挂载

4.2 解压离线包

# 创建工作目录
mkdir -p ~/gcc-install
cd ~/gcc-install

# 解压离线包
tar -xzf ~/gcc-offline-complete.tar.gz

# 查看内容
ls -lh
# source/  deps/  install.sh  README.md

4.3 安装系统依赖

方法一:使用 apt-offline

cd ~/gcc-install

# 解压依赖包
unzip gcc-deps.zip -d ./deps-extracted/

# 安装 apt-offline(如果系统没有)
# 从 deps/ 目录安装
sudo dpkg -i deps/apt-offline_*.deb

# 使用 apt-offline 安装依赖
sudo apt-offline install gcc-deps.zip --skip-signature-check

# 或者直接使用 dpkg 安装所有 deb 包
cd deps-extracted/all-packages/
sudo dpkg -i *.deb

# 修复依赖
sudo apt-get install -f -y

方法二:直接使用 dpkg 安装

cd ~/gcc-install/deps

# 安装所有 deb 包(按顺序)
sudo dpkg -i --force-all *.deb

# 修复依赖关系
sudo apt-get install -f -y

# 验证依赖安装
gcc --version
make --version
bison --version
flex --version

方法三:手动安装关键依赖

# 安装基础编译工具
sudo dpkg -i deps/build-essential_*.deb
sudo dpkg -i deps/gcc-9_*.deb
sudo dpkg -i deps/g++-9_*.deb
sudo dpkg -i deps/make_*.deb

# 安装 GCC 编译依赖
sudo dpkg -i deps/libgmp-dev_*.deb
sudo dpkg -i deps/libmpfr-dev_*.deb
sudo dpkg -i deps/libmpc-dev_*.deb
sudo dpkg -i deps/libisl-dev_*.deb

# 安装工具
sudo dpkg -i deps/bison_*.deb
sudo dpkg -i deps/flex_*.deb
sudo dpkg -i deps/texinfo_*.deb

# 修复依赖
sudo apt-get install -f -y

五、编译安装 GCC

5.1 准备编译环境

# 进入源码目录
cd ~/gcc-install/source/gcc-11.4.0

# 确认依赖已下载
ls -d mpfr gmp mpc isl
# 应该显示这 4 个目录

# 创建编译目录(不要在源码目录中编译)
mkdir -p ~/gcc-install/build
cd ~/gcc-install/build

5.2 配置编译选项

# 配置 GCC 编译选项
../gcc-11.4.0/configure \
    --prefix=/opt/gcc-11 \
    --enable-languages=c,c++,fortran,go \
    --disable-multilib \
    --disable-libsanitizer \
    --enable-checking=release \
    --with-gmp=/usr \
    --with-mpfr=/usr \
    --with-mpc=/usr \
    --with-isl=/usr \
    --disable-libstdcxx-pch \
    --with-system-zlib \
    --enable-__cxa_atexit \
    --enable-clocale=gnu \
    --enable-gnu-unique-object \
    --enable-gnu-indirect-function \
    --enable-libstdcxx-debug \
    --enable-libstdcxx-time=yes \
    --with-tune=generic \
    --with-arch_32=i686 \
    --build=x86_64-linux-gnu \
    --host=x86_64-linux-gnu \
    --target=x86_64-linux-gnu

# 配置选项说明:
# --prefix           : 安装目录
# --enable-languages : 启用的编程语言
# --disable-multilib : 禁用多库(节省空间)
# --with-system-zlib : 使用系统 zlib

5.3 优化配置选项(可选)

# 更快的编译配置(减少编译时间)
../gcc-11.4.0/configure \
    --prefix=/opt/gcc-11 \
    --enable-languages=c,c++ \
    --disable-multilib \
    --disable-bootstrap \
    --disable-libsanitizer \
    --with-system-zlib

# --disable-bootstrap : 禁用自举编译(加快编译速度)
# 注意:这样编译的 GCC 可能不够稳定,仅用于测试

5.4 开始编译

# 查看 CPU 核心数
nproc

# 开始编译(使用所有 CPU 核心)
# 编译时间约 1-2 小时(取决于配置和硬件)
make -j$(nproc)

# 或者限制核心数(避免内存不足)
make -j4

# 监控编译进度
watch -n 5 'ps aux | grep gcc | wc -l'

# 查看编译日志
tail -f make.log 2>&1 | tee make.log

5.5 安装 GCC

# 编译完成后安装
sudo make install

# 安装时间约 5-10 分钟

# 验证安装
ls -lh /opt/gcc-11/bin/
# 应该包含:gcc, g++, gcc-11, g++-11 等

六、配置和使用

6.1 配置环境变量

# 临时使用(当前会话)
export PATH=/opt/gcc-11/bin:$PATH
export LD_LIBRARY_PATH=/opt/gcc-11/lib64:$LD_LIBRARY_PATH

# 永久配置(添加到 ~/.bashrc)
echo '' >> ~/.bashrc
echo '# GCC 11' >> ~/.bashrc
echo 'export PATH=/opt/gcc-11/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/opt/gcc-11/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc

# 使配置生效
source ~/.bashrc

# 或者创建 /etc/profile.d/ 脚本(系统级)
sudo tee /etc/profile.d/gcc11.sh << 'EOF'
export PATH=/opt/gcc-11/bin:$PATH
export LD_LIBRARY_PATH=/opt/gcc-11/lib64:$LD_LIBRARY_PATH
export MANPATH=/opt/gcc-11/share/man:$MANPATH
EOF

sudo chmod +x /etc/profile.d/gcc11.sh

6.2 配置替代方案(update-alternatives)

# 注册 GCC 11 到 alternatives 系统
sudo update-alternatives \
    --install /usr/bin/gcc gcc /opt/gcc-11/bin/gcc-11 100 \
    --slave /usr/bin/g++ g++ /opt/gcc-11/bin/g++-11 \
    --slave /usr/bin/gcc-ar gcc-ar /opt/gcc-11/bin/gcc-ar \
    --slave /usr/bin/gcc-ranlib gcc-ranlib /opt/gcc-11/bin/gcc-ranlib \
    --slave /usr/bin/gcc-nm gcc-nm /opt/gcc-11/bin/gcc-nm

# 注册 GFortran(如果编译了)
sudo update-alternatives \
    --install /usr/bin/gfortran gfortran /opt/gcc-11/bin/gfortran-11 100

# 切换 GCC 版本
sudo update-alternatives --config gcc

# 输出示例:
# 有 2 个候选项可提供 gcc
#
#   选择        路径                  优先级  状态
# ------------------------------------------------------------
# * 0            /usr/bin/gcc-9            90        自动模式
#   1            /usr/bin/gcc-9            90        手动模式
#   2            /opt/gcc-11/bin/gcc-11   100        手动模式
#
# 要维持当前值[*]请按<回车键>,或者键入选择的编号:2

6.3 验证安装

# 检查 GCC 版本
gcc --version
gcc-11 --version

# 应该显示:
# gcc (GCC) 11.4.0
# Copyright (C) 2021 Free Software Foundation, Inc.

# 检查 G++ 版本
g++ --version
g++-11 --version

# 检查安装路径
which gcc
which gcc-11

# 检查库路径
ldconfig -p | grep gcc-11

6.4 测试编译

创建测试文件 test_gcc11.cpp

// test_gcc11.cpp - 测试 GCC 11 新特性
#include <iostream>
#include <vector>
#include <ranges>  // C++20 特性

int main() {
    std::vector nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // C++20 ranges 特性
    auto even = nums | std::views::filter([](int n) { return n % 2 == 0; })
                       | std::views::transform([](int n) { return n * n; });
    
    std::cout << "GCC 11 C++20 Ranges Test:" << std::endl;
    for (int n : even) {
        std::cout << n << " ";
    }
    std::cout << std::endl;
    
    // C++17 结构化绑定
    auto [first, second] = std::make_pair(10, 20);
    std::cout << "Structured binding: " << first << ", " << second << std::endl;
    
    std::cout << "GCC 11 test passed!" << std::endl;
    return 0;
}
# 使用 GCC 11 编译
g++-11 -std=c++20 -o test_gcc11 test_gcc11.cpp

# 运行测试
./test_gcc11

# 输出:
# GCC 11 C++20 Ranges Test:
# 4 16 36 64 100 
# Structured binding: 10, 20
# GCC 11 test passed!

七、创建可复用离线包

7.1 打包已编译的 GCC

# 在其他机器上直接安装已编译的 GCC
cd /opt
sudo tar -czf gcc-11-compiled.tar.gz gcc-11/

# 传输到目标机器
scp gcc-11-compiled.tar.gz user@target-server:/opt/

# 在目标机器上解压
cd /opt
sudo tar -xzf gcc-11-compiled.tar.gz

# 配置环境变量
sudo tee /etc/profile.d/gcc11.sh << 'EOF'
export PATH=/opt/gcc-11/bin:$PATH
export LD_LIBRARY_PATH=/opt/gcc-11/lib64:$LD_LIBRARY_PATH
EOF

# 验证
source /etc/profile.d/gcc11.sh
gcc-11 --version

7.2 创建自动化安装脚本

#!/bin/bash
# install_gcc11_offline.sh - GCC 11 离线自动安装脚本

set -e

GCC_ROOT=/opt/gcc-11
OFFLINE_PACKAGE=$1

if [ -z "$OFFLINE_PACKAGE" ]; then
    echo "用法:$0 <离线包路径>"
    exit 1
fi

echo "=========================================="
echo "GCC 11 离线安装脚本"
echo "=========================================="

# 检查 root 权限
if [ "$EUID" -ne 0 ]; then
    echo "请使用 root 权限运行此脚本"
    exit 1
fi

# 创建临时目录
WORK_DIR=$(mktemp -d)
echo "工作目录:$WORK_DIR"

# 解压离线包
echo "解压离线包..."
tar -xzf "$OFFLINE_PACKAGE" -C "$WORK_DIR"

# 安装依赖
echo "安装系统依赖..."
cd "$WORK_DIR/deps"
dpkg -i --force-all *.deb 2>/dev/null || true
apt-get install -f -y

# 检查是否已有编译好的 GCC
if [ -d "$WORK_DIR/gcc-11" ]; then
    echo "发现预编译的 GCC,直接安装..."
    cp -r "$WORK_DIR/gcc-11" /opt/
    
    # 配置环境变量
    cat > /etc/profile.d/gcc11.sh << 'EOF'
export PATH=/opt/gcc-11/bin:$PATH
export LD_LIBRARY_PATH=/opt/gcc-11/lib64:$LD_LIBRARY_PATH
EOF
    chmod +x /etc/profile.d/gcc11.sh
    
    echo "GCC 11 安装完成!"
    echo "运行 'source /etc/profile.d/gcc11.sh' 或重新登录以生效"
else
    echo "需要编译安装,请运行编译步骤..."
    echo "源码位于:$WORK_DIR/source/gcc-11.4.0"
    echo "请执行以下命令:"
    echo "  cd $WORK_DIR/build"
    echo "  ../source/gcc-11.4.0/configure --prefix=/opt/gcc-11 ..."
    echo "  make -j\$(nproc)"
    echo "  make install"
fi

# 清理
rm -rf "$WORK_DIR"

echo "=========================================="
echo "安装完成!"
echo "=========================================="
gcc-11 --version 2>/dev/null || echo "请运行:source /etc/profile.d/gcc11.sh"

7.3 批量部署脚本

#!/bin/bash
# deploy_gcc11.sh - 批量部署 GCC 11 到多台服务器

SERVERS=(
    "192.168.1.101"
    "192.168.1.102"
    "192.168.1.103"
)

OFFLINE_PACKAGE="gcc-11-offline-ubuntu2004.tar.gz"
INSTALL_SCRIPT="install_gcc11_offline.sh"

for server in "${SERVERS[@]}"; do
    echo "部署到服务器:$server"
    
    # 传输文件
    scp "$OFFLINE_PACKAGE" root@$server:/root/
    scp "$INSTALL_SCRIPT" root@$server:/root/
    
    # 远程执行安装
    ssh root@$server << 'ENDSSH'
cd /root
chmod +x install_gcc11_offline.sh
./install_gcc11_offline.sh gcc-11-offline-ubuntu2004.tar.gz
ENDSSH
    
    echo "服务器 $server 部署完成"
    echo "----------------------------------------"
done

echo "所有服务器部署完成!"

八、故障排查

8.1 常见问题

问题 1:依赖包缺失

# 错误信息:
# configure: error: Building GCC requires the following packages...

# 解决方法:
# 1. 查看缺少的依赖
./contrib/download_prerequisites

# 2. 手动下载缺失的依赖
cd ~/gcc-install/deps
apt-get download libgmp-dev libmpfr-dev libmpc-dev

# 3. 安装依赖
sudo dpkg -i *.deb
sudo apt-get install -f -y

问题 2:编译时内存不足

# 错误信息:
# c++: fatal error: Killed signal terminated program cc1plus

# 解决方法:
# 1. 减少并行编译的核心数
make -j2  # 只用 2 个核心

# 2. 增加 swap 空间
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 3. 禁用 bootstrap(减少内存使用)
../gcc-11.4.0/configure --prefix=/opt/gcc-11 --disable-bootstrap

问题 3:找不到共享库

# 错误信息:
# error while loading shared libraries: libstdc++.so.6: cannot open shared object file

# 解决方法:
# 1. 更新库缓存
sudo ldconfig

# 2. 检查库路径
ldconfig -p | grep libstdc++

# 3. 添加库路径到配置文件
echo "/opt/gcc-11/lib64" | sudo tee /etc/ld.so.conf.d/gcc11.conf
sudo ldconfig

# 4. 或者设置环境变量
export LD_LIBRARY_PATH=/opt/gcc-11/lib64:$LD_LIBRARY_PATH

问题 4:编译时间过长

# 优化编译速度:

# 1. 禁用不必要的语言
../gcc-11.4.0/configure \
    --prefix=/opt/gcc-11 \
    --enable-languages=c,c++ \  # 只编译 C 和 C++
    --disable-multilib \
    --disable-bootstrap

# 2. 使用 ccache 加速
sudo apt install ccache
export CC="ccache gcc"
export CXX="ccache g++"

# 3. 使用 distcc 分布式编译(多台机器)
sudo apt install distcc
export CC="distcc gcc"
export CXX="distcc g++"

8.2 调试命令

# 查看 GCC 配置信息
gcc-11 -v

# 查看编译选项
gcc-11 -Q --help=target

# 查看支持的语言
gcc-11 -v --help

# 测试编译简单程序
echo 'int main(){return 0;}' | gcc-11 -x c - -o /tmp/test && echo "OK"

# 查看链接的库
ldd /opt/gcc-11/bin/gcc-11

# 检查库路径
gcc-11 -print-search-dirs
gcc-11 -print-libgcc-file-name

九、卸载和清理

9.1 卸载 GCC 11

# 如果使用 update-alternatives 注册
sudo update-alternatives --remove gcc /opt/gcc-11/bin/gcc-11
sudo update-alternatives --remove g++ /opt/gcc-11/bin/g++-11

# 删除安装目录
sudo rm -rf /opt/gcc-11

# 删除环境变量配置
sudo rm -f /etc/profile.d/gcc11.sh
sudo rm -f /etc/ld.so.conf.d/gcc11.conf

# 更新库缓存
sudo ldconfig

# 从 bashrc 中移除(如果添加了)
sed -i '/GCC 11/d' ~/.bashrc
sed -i '/\/opt\/gcc-11/d' ~/.bashrc
source ~/.bashrc

9.2 清理编译文件

# 清理编译目录(释放空间)
cd ~/gcc-install
rm -rf build/

# 清理源码目录(可选)
rm -rf source/gcc-11.4.0/

# 保留离线包以便后续使用
# gcc-offline-complete.tar.gz

总结

本文详细介绍了在 Ubuntu 20.04 上离线编译安装 GCC 11 的完整流程:

  1. 环境准备:系统要求、目录结构、工作流程
  2. 下载源码:GCC 源码、依赖包、download_prerequisites
  3. 制作离线包:apt-offline 工具、打包脚本
  4. 目标机器安装:传输方式、依赖安装方法
  5. 编译配置:configure 选项、编译优化
  6. 安装配置:环境变量、update-alternatives
  7. 验证测试:版本检查、C++20 特性测试
  8. 批量部署:预编译包、自动化脚本
  9. 故障排查:常见问题和解决方案
  10. 卸载清理:完整卸载步骤

通过本文的方法,你可以:

  • ✅ 在无网络环境中安装最新 GCC
  • ✅ 批量部署到多台服务器
  • ✅ 自定义编译选项
  • ✅ 保留离线包重复使用

建议在生产环境部署前,先在测试环境充分验证。如有问题,欢迎留言讨论!🚀


附:资源下载

发表回复

后才能评论