ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Ubuntu 20.04离线安装gcc:依赖准备与本地源搭建全指南

Ubuntu 20.04离线安装gcc:依赖准备与本地源搭建全指南 简介为解决Ubuntu 20.04系统在无网络环境下安装GCC的依赖难题资源包内整合了完整的离线安装组件。其中包含30个.deb格式依赖文件覆盖libc6-dev、libgcc-9-dev、binutils、cpp等核心工具链另附1个自动化安装脚本do.sh无需网络即可完成安装。整体大小仅29.83MB便于通过U盘拷贝至目标机器。当前已有8674人学习/下载适合运维人员、嵌入式开发者在隔离网络或内网环境中快速部署GCC。使用该资源读者可直接获得打包好的依赖项和安装脚本免去手动逐条下载与匹配版本的繁琐过程显著提升离线环境下的搭建效率。1. Ubuntu 20.04离线安装gcc内网机器装编译器的依赖难题远比想象的深Ubuntu 20.04离线安装gcc听起来就是把deb包拷过去双击真做起来才知道水有多深。我第一次在断网的生产服务器上执行apt install gcc半小时后只看到超时和一堆依赖报错时才意识到离线场景里“能不能装”和“装完能不能编译”是两码事。gcc在focal仓库里是元包它牵着gcc-9、cpp-9、gcc-9-base、libgcc-s1和libc6-dev一串链任何一个版本没对齐得到的都是“依赖问题尚未配置”。这篇文章把离线安装gcc的完整资源流讲透——适配Ubuntu 20.04覆盖依赖准备、本地源搭建、dpkg兜底安装和五个高频踩坑点适合刚接管内网系统的运维也适合在虚拟机上做离线实验的开发者。2. 先搞懂gcc依赖链为什么离线安装不能只拷一个deb包2.1 gcc是元包真正干活的是gcc-9与cpp-9在Ubuntu 20.04代号focal的仓库里gcc指向的是9.4.0版本。如果你用apt download gcc下载拿到的只是一个很小的deb里面只是元数据和符号链接真正的编译器可执行文件在/usr/bin/gcc-9头文件、内建库libgcc、libstdc则分布在gcc-9-base和libstdc-9-dev等包里。这是一个典型的元包设计你执行gcc命令实际调用的是/usr/bin/gcc-9它再调用cpp预处理器和cc1编译器前端。这个结构直接决定了离线安装的复杂度。我在内网机器上第一次用dpkg -i装单个gcc的deb时系统立刻报“依赖关系不足需要cpp-9、gcc-9、gcc-9-base”当时我还以为是下载的包损坏后来用dpkg -I gcc_9.4.0-1ubuntu1~20.04_amd64.deb查看包的元信息才明白那条依赖链根本绕不过去。依赖链的核心部分在Ubuntu 20.04 amd64架构下是这样的gcc → gcc-9 9.4.0gcc-9 → cpp-9 9.4.0、gcc-9-base 9.4.0cpp-9 → gcc-9-base、libgcc-s1编译器最终要生成可执行文件还得有libc6-dev提供标准C库头文件和crt1.o这些启动文件如果你要编译C还要再拉一层libstdc-9-dev和g-9所以离线安装gcc的本质就是把这一组版本完全匹配的deb包准备齐并让它们在目标机器上被正确安装。版本号里的“”不是随便写的gcc-9和cpp-9必须完全同版本比如9.4.0-1ubuntu1~20.04差一个补丁号都会让dpkg拒绝安装。2.2 两条主路线的取舍deb包缓存 vs 源码编译在实际操作前先给离线安装定个路线。路线一是“deb包缓存”在一台能联网、系统和目标机器同为Ubuntu 20.04的电脑上用apt把gcc及其全部依赖下载下来再把这一堆deb拷贝到内网机器上用离线方式安装。这条路我推荐给绝大多数场景理由有三个第一安装后的gcc与你平时用apt装出来的效果完全一样后续dpkg能正常管理第二下载时间通常只要几分钟受控且可复现第三依赖关系依然由apt解析出错概率远低于手工指定。路线二是“源码编译”下载gcc-9.4.0.tar.xz源码包自己编译。听起来更“通用”但离线环境下这是个无底洞。gcc源码包只包含编译器本体编译前要解决gmp、mpfr、mpc这几个数学库依赖它们没有系统包就得先编译源码编译时还要用--with-gmp这类参数传给configure。更要命的是目标机器上很可能连make都没有又得先给make找离线包。整个构建流程顺利也要一到两小时中途任何一步缺了依赖都只能从头排查。除非你需要定制gcc内部特性或者目标机器不是标准Ubuntu 20.04仓库可覆盖的版本我不建议走源码编译。还有一些变体路子比如装miniconda然后在conda环境里装gcc或者用docker镜像自带的编译器。但它们都改变不了“gcc不在系统PATH”的问题很多脚本编译时用gcc命令会直接找不到反而多出一个黑匣子。做内核模块编译、系统级软件构建还是把系统gcc装扎实最省心。对比项deb包缓存路线源码编译路线操作步骤联网下载依赖、拷贝、离线安装下载源码、编译依赖库、编译gcc依赖处理apt自动解析版本匹配手工解决gmp/mpfr/mpc等依赖系统集成度跟apt安装完全一致二进制在自定义路径需额外配置适用场景标准Ubuntu 20.04内网环境定制gcc版本或非标准系统失败概率低主要在版本错位上高依赖链环环相扣提示如果目标机器架构是arm64上面两条路线的依赖细节都会变。deb包缓存路线必须拿arm64架构的deb源码编译则要额外配置aarch64交叉编译环境两条路都不轻松。3. 在有网机器上准备离线包apt-get拉取依赖、架构核验与本地源索引3.1 核心命令apt-get install --download-only把整条链一次拉齐有网准备机上稳定做法是先清空apt缓存再从零下载避免把旧的、版本不匹配的deb混进安装包。执行以下命令sudo apt-get clean sudo apt-get update sudo apt-get install --download-only gcc g libc6-dev这里解释一下为什么是这三个包。gcc是C编译器元包装上它系统才会有/usr/bin/gccg是C编译器元包内网项目绝大多数会编译到C代码一次带齐省得后面再补libc6-dev是标准C库开发包缺了它就算gcc装好编译最简单的printf程序也会报stdio.h找不到。--download-only参数让apt只下载、不安装下载的deb全部落到/var/cache/apt/archives目录。注意apt会在下载结束时提示“已下载但尚未安装”这是预期行为不是错误。下载完成后这样检查文件ls -lh /var/cache/apt/archives/*.deb | grep -E gcc|cpp|libc6|libstdc|libgcc|binutils正常情况下你至少会看到gcc-9、gcc-9-base、cpp-9、libgcc-s1、libc6-dev、libc6这几个包如果装了g还会有g-9、libstdc-9-dev、libstdc6。binutils也必不可少它是汇编器as、链接器ld、目标文件工具objdump这些底层工具链的集合编译链接全要靠它。3.2 把deb集中到一个干净目录并生成本地源索引/var/cache/apt/archives里可能混着之前下载过的其他软件包直接全部拷走会污染离线包。我一般会新建一个目录只拷贝本次下载的deb然后在该目录下生成apt源索引这样后面在内网机器上就能用apt命令加本地源安装而不是手工对付一堆debmkdir -p ~/gcc-offline cp -a /var/cache/apt/archives/*.deb ~/gcc-offline/ cd ~/gcc-offline dpkg-scanpackages . /dev/null | gzip Packages.gz tar -czvf ~/gcc-offline.tar.gz ~/gcc-offlinedpkg-scanpackages会扫描当前目录下所有deb包把每个包的包名、版本、依赖关系、文件列表信息汇总成Packages.gz这个文件就是apt识别本地仓库的索引。/dev/null参数表示不加载额外的override描述文件对于纯gcc离线包来说没必要。如果你在这台机器上执行dpkg-scanpackages提示命令找不到先装一下dpkg-devsudo apt-get install dpkg-dev最后把整个目录打包方便通过U盘、内网共享目录或scp转移到目标机器。打包时建议用tar.gz不要用zipdeb文件里的权限位和符号链接在tar格式下保留得更完整。3.3 动手下载前先核验架构arm64和amd64的deb不能混用这是我见过最隐蔽的翻车点。很多人家里有网机器是x86_64内网服务器却是ARM架构于是拿amd64的deb装到arm64系统上dpkg直接报“架构不匹配”。核验命令很简单dpkg --print-architecture uname -m两台机器都执行一遍。dpkg --print-architecture输出amd64或arm64uname -m输出x86_64或aarch64这两组对应关系是amd64 ↔ x86_64arm64 ↔ aarch64。准备机器的输出必须和目标机器一致否则下载的包装不上。如果目标机器确实是arm64不要试图在amd64机器上靠dpkg --add-architecture arm64来混过下载apt确实可以下载arm64的deb但手动把依赖链逐层拉全会让你怀疑人生。正确做法是找一台同为arm64的Ubuntu 20.04机器、云主机或QEMU模拟的arm64虚拟机在上面按3.1和3.2的流程跑一遍一次就能出齐全部arm64依赖包。3.4 版本对齐不要用apt download单独下载gcc有些教程会让你用apt download gcc来获取deb这条路我强烈不建议。apt download和apt-get download只会下载命令行里指定的那一个包不会递归下载依赖。用它拿到的gcc元包拷到内网机器照样是依赖缺失。apt-get install --download-only或者apt install --download-only才是对的做法它会递归解析gcc、g、libc6-dev的完整依赖树一次下载到位。版本对齐上还有一个容易忽视的点准备机器的apt源配置最好和目标机器保持一致。比如准备机用的是focal-updates仓库目标机器只配了focal基础仓库那下载到的gcc可能带了补丁版本目标机器上如果没有对应的源本地apt解析时就会认为版本不满足。稳妥起见准备机和目标机器都用Ubuntu官方源镜像或者都统一某个内网镜像源。4. 在无网Ubuntu 20.04上实操本地apt源、dpkg批量安装与编译验收4.1 方式一把离线目录配置成本地apt源这是我最推荐的安装方式因为apt会自动读取Packages.gz中的依赖关系按正确顺序安装所有deb不需要手工控制顺序。先把打包好的gcc-offline.tar.gz拷贝到目标机器并解压sudo tar -xzvf gcc-offline.tar.gz -C /opt解压后会得到/opt/root/gcc-offline这样的完整路径。然后新建一个apt源文件echo deb [trustedyes] file:///opt/root/gcc-offline ./ | sudo tee /etc/apt/sources.list.d/gcc-offline.list这里file://前缀表示本地目录源./表示Packages.gz就在该目录自身。[trustedyes]是必须的因为本地目录没有Release文件也没有GPG签名不加这个参数apt会在update时拒绝使用该源。接下来刷新源并安装sudo apt-get update sudo apt-get install -y gcc gapt会从本地源里找到gcc、g以及全部依赖自动完成安装。这个方式的优点很明显依赖解析交给apt顺序错误、版本不对这些手工dpkg常见问题基本不会出现。安装完成后把刚才的list文件删掉或注释掉避免以后apt update时反复扫描这个本地目录sudo rm -f /etc/apt/sources.list.d/gcc-offline.list sudo apt-get update4.2 方式二dpkg -i *.deb批量兜底如果目标机器上apt本身有问题或者你不想改动sources.list可以用dpkg直接批量安装所有deb。当年我从U盘把离线包拷到内网机器后就是暴力操作cd /opt/root/gcc-offline sudo dpkg -i *.deb第一次执行几乎必定报错因为*.deb按文件名ASCII排序展开安装顺序并不完全是依赖顺序dpkg会在遇到未满足的依赖时跳过当前包。关键技巧是再执行一遍sudo dpkg -i *.deb第二遍时前面的包已经装好之前被跳过的包这时依赖满足就能补装成功。少数情况下需要第三次这属于dpkg迭代安装的典型行为。如果迭代两次后仍有报错可以用apt来修复sudo apt-get install -f-f选项会尝试修复dpkg记录中处于未配置状态的包把它解析出的依赖补装上去。但这个方法的前提是apt能找到对应依赖包如果离线目录里不包含那些包它一样无能为力。所以dpkg方式只作为兜底我仍然推荐4.1的本地apt源方案。4.3 编译验证不跑一次helloworld不算装完安装结束不是看gcc --version能输出版本号就完了我吃过亏的地方恰好在这里gcc本体装好了头文件却缺失--version正常一编译就报错。所以完整验证要分为两步。先看版本和工具链gcc --version which gcc ldd /usr/bin/gcc-9ldd命令能确认动态链接库是否完整如果输出里出现“not found”说明libc6库有问题需要回头补包。然后写一个真正用到头文件和链接器的C程序#include stdio.h int main(void) { printf(gcc offline install ok\n); return 0; }gcc hello.c -o hello ./hello编译能过、输出能出说明编译器、汇编器、链接器、C标准库头文件这一整条链都通了。想更严格一点可以再编译一个用到数学库的程序强制走一遍-lm链接流程#include stdio.h #include math.h int main(void) { printf(sqrt(2)%.6f\n, sqrt(2.0)); return 0; }gcc math_test.c -o math_test -lm ./math_test这样连libm的链接都验证掉了。C验证同理写个简单的.cpp文件用g编译。四个验证全部通过才算真正完成了Ubuntu 20.04离线安装gcc的全流程。5. 离线安装gcc避坑指南五个真实翻车案例与排查方法5.1 现象dpkg -i报“依赖问题尚未配置”gcc命令找不到有网机器上下好了全套deb拷到内网机器执行dpkg -i *.deb输出一堆警告最后gcc仍然无法使用。原因基本有两种一是安装顺序不对dpkg第一次没有按依赖顺序装二是离线包里本身就少了某个依赖。我遇到的是第一种第二次运行dpkg -i *.deb就把问题解决了。如果你运行两次后仍然报同样的依赖缺失说明这个缺失的deb根本没在原目录里需要回到有网机器重新用apt-get install --download-only补齐。解决优先用本地apt源方式安装让apt自动解析如果坚持dpkg至少运行两遍再不行执行apt-get install -f。查具体缺什么包可以直接运行gcc --version看第一个报错或者dpkg -l | grep gcc确认哪些包处于iU状态。5.2 现象gcc版本看着正常编译却报fatal error: stdio.h: No such file or directory这个案例是典型的“装了编译器却没装开发库”。gcc --version能输出说明gcc本体和gcc-9、cpp-9都装好了但stdio.h头文件在libc6-dev包而不是gcc包里。很多新手第一次离线安装只下载了gcc一个元包没想到头文件是独立分发的。解决回到有网机器一定把libc6-dev加进下载列表即本章第3.1节里的apt-get install --download-only gcc g libc6-dev。在内网机器上验证dpkg -l libc6-dev看到ii状态才是正确安装。缺头文件这个错和缺库文件不一样它往往在编译早期阶段就暴露非常迷惑人。5.3 现象配置本地apt源后apt-get update报“没有Release文件”把离线目录配成apt源执行apt-get update时报错说file:///...目录没有Release文件无法安全使用。原因就是本地目录只有Packages.gz没有Release和InRelease签名文件apt为了保证软件源可验证默认拒绝这种无签名源。解决在sources.list那行加上[trustedyes]echo deb [trustedyes] file:///opt/root/gcc-offline ./ | sudo tee /etc/apt/sources.list.d/gcc-offline.list这个参数明确告诉apt“我相信这个源”跳过Release签名检查。update通过后安装就正常了。注意这里不要手动伪造Release文件一是格式复杂容易出错二是trustedyes更简单直接。5.4 现象离线安装后gcc还是旧版本怎么看都是gcc-7内网机器原本就有一套老工具链比如gcc-7你离线装好了gcc-9执行gcc --version输出的却还是7.5.0。这种情况不是安装失败而是Ubuntu里多版本gcc并存时/usr/bin/gcc是一个符号链接由update-alternatives机制管理。新装的gcc-9没被设置为默认值符号链接仍指向旧版。解决先看链接指向ls -l /usr/bin/gcc* update-alternatives --config gcc后者会列出所有已注册的gcc版本输入编号选择gcc-9即可。如果update-alternatives里没出现新装的gcc-9说明gcc-9包没有注册替代项可以手动注册sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 100这是gcc升级后为什么还是旧版本这个老问题在离线环境下的同款翻车姿势原理和在线环境完全一样。5.5 现象拷贝的deb在目标机器上报“架构不匹配”在amd64准备机上认真跑完了下载流程人也到了内网结果安装时dpkg报“ Architecture amd64”不匹配目标机器直接拒绝。这个问题出在准备阶段没有先核验目标机器架构。尤其是ARM服务器、开发板这类设备看起来都是Linux但包格式完全不同。解决在第3章流程开始前先在两台机器上分别执行dpkg --print-architecture确认输出一致。目标机器是arm64时准备机也必须是arm64环境强烈建议直接开一台arm64云主机或在QEMU里跑Ubuntu 20.04来下载依赖。等踩过这个坑你就会明白为什么我在3.3节反复强调先核验架构再下载。6. 把离线安装固化成SOP一条命令生成离线包、一条命令上机装配到这一步手动安装流程你已经完整跑通了但内网环境往往不止一台机器。为了不让自己重复踩坑我把这套流程固化成两个脚本下载一次就能批量复制到多台内网机器。有网准备机的脚本我日常是这样写的#!/bin/bash # 在联网的Ubuntu 20.04机器上执行生成gcc离线安装包 set -euo pipefail ARCH$(dpkg --print-architecture) OUTgcc-offline-${ARCH}-$(date %Y%m%d) mkdir -p ${OUT} sudo apt-get clean sudo apt-get update sudo apt-get install --download-only -y gcc g libc6-dev cp -a /var/cache/apt/archives/*.deb ${OUT}/ cd ${OUT} dpkg-scanpackages . /dev/null | gzip Packages.gz cd .. tar -czvf ${OUT}.tar.gz ${OUT}脚本末尾归档文件的目录名带着架构和日期比如gcc-offline-amd64-20250610.tar.gz一眼就能看出用途。set -euo pipefail确保任何一步失败就立即退出不会生成残缺的离线包。目标机器侧只需要三步我也把它写成了脚本#!/bin/bash # 在无网Ubuntu 20.04机器上执行从tar包完成gcc离线安装 set -euo pipefail sudo tar -xzvf gcc-offline-*.tar.gz -C /opt echo deb [trustedyes] file:///opt/$(ls -d gcc-offline-*)/ ./ | sudo tee /etc/apt/sources.list.d/gcc-offline.list sudo apt-get update sudo apt-get install -y gcc g脚本化最大的收益不只是省时间而是可验证。我每次执行完都会强制追加一遍第4.3节的测试程序编译把hello.c和math_test.c一起放进SOP流程里跑不通就当场失败绝不带着“应该装好了吧”的侥幸心理离开现场。从那以后我每次接手内网环境都会在这个SOP清单里先核架构、再核libc6-dev、最后跑测试编译整套动作五分钟左右。离线安装gcc的坑不算深难的是每次踩完都复盘成一条命令、一张清单下一次不用再交学费。这套资源和流程希望能帮到你照着走一遍Ubuntu 20.04离线装gcc就不再是玄学。本文还有配套的精品资源点击获取
返回列表