简介这份资源面向在 Ubuntu 18.04 环境下需要离线部署 GCC 编译工具链的开发者和运维人员尤其适合内网服务器、无外网条件的实验环境或需要固定编译器版本的项目。压缩包共 25 个文件以 24 个 deb 安装包和 1 个 sh 脚本为主整体约 20.05MBdeb 包覆盖 gcc-7、cpp-7、binutils 及 libasan4、libgomp1、libquadmath0 等运行库与开发依赖sh 脚本用于批量安装省去逐条执行 dpkg 的繁琐。资源围绕 gcc7 与 dpkg 离线安装场景组织版本对应 Ubuntu 18.04 官方源可帮助读者在断网机器上一次性补齐编译环境避免依赖缺失导致的安装中断。目前已有 3205 人学习下载适合需要快速搭建 C/C 编译环境、排查依赖冲突或研究 deb 包依赖关系的读者参考使用。1. 从一次 gcc 版本错配说起ubuntu18.04 上装 gcc7 到底难在哪很多人以为 Ubuntu 18.04 自带 gcc 就能直接编译一切直到某天接手一个老项目Makefile里写死了-stdc11链接时却报undefined reference to __cxa_throw_bad_array_new_length翻来覆去查才发现系统默认的 gcc 版本和项目要求的 gcc7 对不上。Ubuntu 18.04 默认源里是 gcc-7.5.0但很多场景下你需要的是精确的 gcc7 小版本或者需要同时保留系统默认 gcc 不动只额外装一套 gcc7 工具链。更麻烦的是有些离线环境根本连不上 apt 源只能靠ubuntu18.04gcc.zip这种打包好的离线资源手动 dpkg 安装。这篇笔记就是记录我在 Ubuntu 18.04 上把 gcc7 装干净、配好 alternatives、验证编译链路完整的全过程包括 dpkg 离线安装的依赖顺序、常见报错怎么救。如果你正卡在gcc: error trying to exec cc1plus或者dpkg: dependency problems这类问题上下面的步骤可以直接抄。2. 装前环境核对gcc7 在 ubuntu18.04 上的版本选择与依赖清单2.1 先确认系统里已经有什么动手之前先摸清底细别上来就 dpkg。我一般会跑这三条命令把当前 gcc 状态、系统架构、apt 源里可用的 gcc 版本一次性看清楚# 查看当前默认 gcc 版本和路径 gcc --version which gcc ls -l /usr/bin/gcc* # 确认系统架构决定下载 amd64 还是 i386 包 dpkg --print-architecture uname -m # 查看 apt 源里 gcc-7 相关包的可用版本 apt-cache policy gcc-7 g-7 cpp-7逻辑说明gcc --version看的是当前PATH里优先命中的那个 gccls -l /usr/bin/gcc*能看出系统里到底装了几个版本的 gcc 以及软链接指向。dpkg --print-architecture输出amd64就下 64 位包输出i386就下 32 位包下错了 dpkg 会直接报架构不匹配。apt-cache policy是判断能不能走在线安装的关键——如果源里有 gcc-7 且版本满足要求优先用 apt别折腾离线包。Ubuntu 18.04 的默认源里 gcc-7 版本是 7.5.0-3ubuntu1~18.04这个版本对绝大多数需要 gcc7 的项目都够用。但如果你手上的ubuntu18.04gcc.zip里打包的是特定小版本比如 7.4.0 或 7.3.0那就得走 dpkg 离线安装因为 apt 源里不一定有那个精确版本。2.2 离线包依赖关系梳理ubuntu18.04gcc.zip解压后通常是一堆.deb文件核心包和依赖包混在一起。gcc7 的 dpkg 安装不是单个包能搞定的依赖链大致是这样的包名作用是否必须gcc-7-basegcc7 基础文件必须cpp-7预处理器必须gcc-7C 编译器必须g-7C 编译器按需libgcc-7-devgcc7 运行时库和头文件必须libstdc-7-devC 标准库头文件装 g-7 时必须libasan4 / libubsan0sanitizer 运行时按需binutils链接器 as/ld系统通常已有常见做法是先把所有.deb放到一个目录里用dpkg -i *.deb一次性装但这样如果依赖顺序不对会报一堆错。更稳的方式是用dpkg -i配合apt-get install -f补依赖但离线环境下apt-get install -f可能连不上源。所以我一般会手动按依赖顺序装先gcc-7-base再cpp-7再libgcc-7-dev最后gcc-7和g-7。提示如果 zip 包里带了binutils的 deb先确认系统里ld --version是否可用。Ubuntu 18.04 默认自带 binutils 2.30一般不需要额外装但如果你在容器里操作基础镜像可能被裁剪过缺 binutils 会导致 gcc 编译时找不到as和ld。3. dpkg 离线安装 gcc7从解压到 alternatives 配置3.1 解压与包完整性检查拿到ubuntu18.04gcc.zip之后先解压到一个干净目录别直接在/tmp里操作避免重启后文件丢失# 创建专门的工作目录 mkdir -p /opt/gcc7-offline cd /opt/gcc7-offline # 解压 zip 包 unzip ~/ubuntu18.04gcc.zip -d . # 查看解压出来的 deb 包列表和大小 ls -lh *.deb逻辑说明-d .指定解压到当前目录ls -lh看每个 deb 的大小正常 gcc-7 的 deb 包在 8MB 到 30MB 之间如果某个包只有几 KB可能是下载不完整或者 zip 损坏。我遇到过 zip 包传输过程中断导致gcc-7_7.5.0-3ubuntu1~18.04_amd64.deb只有 0 字节的情况dpkg 装的时候报format error所以这一步别省。检查完包大小后用dpkg-deb -I快速看每个包的元信息确认版本号和架构# 逐个查看 deb 包的版本和架构信息 for f in *.deb; do echo $f dpkg-deb -I $f | grep -E Version|Architecture done逻辑说明dpkg-deb -I读取 deb 包的控制信息grep过滤出版本和架构。如果发现某个包的 Architecture 是i386而你的系统是amd64直接把这个包剔掉别装否则 dpkg 会报package architecture (i386) does not match system (amd64)。3.2 按依赖顺序执行 dpkg 安装确认包没问题后按依赖顺序装。我一般写一个简单的循环脚本按包名排序后逐个装遇到依赖错误就停下来看# 按依赖顺序安装先装基础包 sudo dpkg -i gcc-7-base_*.deb sudo dpkg -i cpp-7_*.deb sudo dpkg -i libgcc-7-dev_*.deb sudo dpkg -i libstdc-7-dev_*.deb # 再装主编译器包 sudo dpkg -i gcc-7_*.deb sudo dpkg -i g-7_*.deb # 如果还有 sanitizer 相关的包 sudo dpkg -i libasan4_*.deb libubsan0_*.deb 2/dev/null逻辑说明dpkg -i是直接安装本地 deb 包不解决依赖。先装gcc-7-base是因为cpp-7和gcc-7都依赖它libgcc-7-dev提供libgcc_s.so和头文件必须在gcc-7之前装好否则 gcc 装完后编译会报找不到crtbegin.o。2/dev/null是忽略 sanitizer 包不存在时的报错因为不是所有 zip 包都带这些。如果中间某一步报dependency problems别慌先看具体缺什么# 查看当前系统中未满足的依赖 sudo dpkg --audit # 或者针对具体包查依赖状态 dpkg -l | grep -E ^i[^i] | head -20逻辑说明dpkg --audit列出所有处于半安装或配置失败状态的包dpkg -l输出中第一列是iU或iF的表示安装不完整。根据缺的依赖名回到 zip 包里找对应的 deb或者如果系统能连内网源用sudo apt-get install -f自动补齐。3.3 配置 alternatives 让 gcc7 可控切换装完 gcc-7 之后系统里会有/usr/bin/gcc-7和/usr/bin/g-7但默认的gcc命令还是指向原来的版本。我一般用update-alternatives来管理这样可以在 gcc7 和系统默认 gcc 之间自由切换不用改PATH# 注册 gcc-7 到 alternatives 系统 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 \ --slave /usr/bin/g g /usr/bin/g-7 # 注册系统默认 gcc假设是 gcc-7.5.0 对应的 /usr/bin/gcc-7 # 如果系统原本就有 gcc用以下命令注册为较低优先级 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 # 交互式选择默认 gcc 版本 sudo update-alternatives --config gcc逻辑说明--install的第一个参数是链接路径第二个是组名第三个是实际可执行文件路径第四个是优先级。优先级数字越大越优先被自动选中。--slave表示 g 跟随 gcc 一起切换这样不会出现 gcc 是 7 而 g 还是旧版本的错位。--config gcc会列出所有已注册的 gcc 版本输入编号即可切换。注意如果你在 Docker 容器里操作update-alternatives可能因为缺少/etc/alternatives目录而报错先mkdir -p /etc/alternatives再执行。配置完成后验证一下# 验证切换结果 gcc --version g --version # 查看 alternatives 当前指向 update-alternatives --display gcc逻辑说明gcc --version应该输出gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0或你安装的精确版本。update-alternatives --display gcc会显示当前链接指向哪个路径、优先级多少、有哪些可选版本。4. 编译验证与常见报错排查gcc7 装完不一定就能用4.1 最小编译测试用例装完不验证等于没装。我习惯用一个最小的 C 和 C 程序分别测编译和链接/* test_c.c - 测试 C 编译和链接 */ #include stdio.h int main(void) { printf(gcc7 C compile OK\n); return 0; }// test_cpp.cpp - 测试 C 编译和标准库链接 #include iostream #include vector int main() { std::vectorint v {1, 2, 3}; std::cout gcc7 C compile OK, vector size v.size() std::endl; return 0; }编译命令# 编译 C 程序 gcc-7 -o test_c test_c.c ./test_c # 编译 C 程序显式指定标准 g-7 -stdc11 -o test_cpp test_cpp.cpp ./test_cpp逻辑说明-stdc11是显式指定 C 标准gcc7 默认是 gnu14但很多老项目需要 c11。如果编译 C 时链接报undefined reference to std::__cxx11::basic_string...说明libstdc版本不对检查libstdc-7-dev是否装好。./test_c和./test_cpp能正常输出就说明编译链路通了。4.2 常见报错与修复现象一gcc: error trying to exec cc1plus: execvp: No such file or directory原因装了gcc-7但没装g-7或者g-7装了但cc1plus不在 gcc 的搜索路径里。cc1plus是 C 编译器的实际后端属于g-7包。解决确认g-7已安装然后检查/usr/lib/gcc/x86_64-linux-gnu/7/cc1plus是否存在。如果不存在重新 dpkg 安装g-7包。现象二dpkg: error processing archive gcc-7_*.deb (--install): package architecture (i386) does not match system (amd64)原因下载的 deb 包架构和系统不匹配。ubuntu18.04gcc.zip里可能混了 32 位和 64 位的包。解决用dpkg-deb -I确认每个包的 Architecture只保留amd64的包重新安装。现象三/usr/bin/ld: cannot find -lstdc原因libstdc-7-dev没装或者装了但链接器找不到库路径。解决dpkg -L libstdc-7-dev | grep libstdc查看库文件实际路径确认/usr/lib/gcc/x86_64-linux-gnu/7/libstdc.so存在。如果不存在重新安装该 deb 包。现象四update-alternatives: error: alternative link /usr/bin/gcc is already managed by gcc原因之前已经注册过 gcc 的 alternatives重复注册会报这个错。解决先sudo update-alternatives --remove gcc /usr/bin/gcc-7移除旧注册再重新--install。或者直接用--config切换不需要重复注册。现象五编译时提示fatal error: bits/cconfig.h: No such file or directory原因libstdc-7-dev的头文件路径没被 g 正确识别通常是因为 g 的 include 搜索路径里缺少/usr/include/x86_64-linux-gnu/c/7。解决检查/usr/include/x86_64-linux-gnu/c/7/bits/cconfig.h是否存在。如果不存在说明libstdc-7-dev装得不完整重新 dpkg 安装。如果存在但 g 找不到用g-7 -v -E -x c /dev/null查看实际的 include 搜索路径确认路径是否在列表中。5. 装完怎么验证跑通三条命令确认 gcc7 环境可用装完 gcc7 之后我习惯用三条命令做最终验收覆盖版本、编译、链接三个层面。第一条看版本和 alternatives 状态# 验收命令 1确认 gcc/g 版本和 alternatives 指向 gcc --version | head -1 g --version | head -1 update-alternatives --query gcc | grep -E Value|Priority逻辑说明head -1只取版本号那一行避免输出太多。update-alternatives --query gcc输出当前链接的实际指向路径和优先级确认Value: /usr/bin/gcc-7说明切换生效。第二条做实际编译链接测试用一个带数学库和 C 标准库的混合用例# 验收命令 2编译一个使用数学库和 STL 的测试程序 cat /tmp/gcc7_verify.cpp EOF #include iostream #include cmath #include vector #include algorithm int main() { std::vectordouble vals {1.0, 4.0, 9.0, 16.0}; for (auto v : vals) v std::sqrt(v); std::sort(vals.begin(), vals.end()); std::cout min vals.front() max vals.back() std::endl; return 0; } EOF g-7 -stdc11 -O2 -o /tmp/gcc7_verify /tmp/gcc7_verify.cpp -lm /tmp/gcc7_verify逻辑说明-lm显式链接数学库-O2开启优化std::sqrt和std::sort分别测试数学库和 STL 模板的链接是否正常。输出min1 max4说明编译、链接、运行全链路通。第三条检查 dpkg 包状态确保没有半安装的包残留# 验收命令 3检查 gcc7 相关包的安装状态 dpkg -l | grep -E gcc-7|cpp-7|g\\-7|libgcc-7|libstdc\\-7 | awk {print $1, $2, $3} # 期望输出每行第一列都是 ii表示正常安装逻辑说明dpkg -l第一列ii表示包已正确安装并配置iU表示解压了但未配置iF表示配置失败。如果出现非ii的状态用sudo dpkg --configure -a重新配置所有未完成的包。三条命令都通过之后这套 gcc7 环境就算真正跑通了。从那以后我每次装完 gcc 都强制走一遍这三条验收命令尤其是dpkg -l那一步因为 alternatives 配好了不代表包状态干净半安装的包可能在后续编译时突然报错提前查出来比事后救火省事得多。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?