☰
Kylin系统离线安装g++:依赖处理与本地源搭建实战
2026/9/30 3:00:01 网站建设 项目流程

刚拿到一台Kylin初始系统的服务器,网络是隔离的内网,连yum仓库都连不出去,第一个任务就是离线配置g++。这事儿听起来像一条命令的事,但真正在离线环境里做过的都知道,光是“离线”两个字就能把人折腾够呛。我这次把整个过程完整走了一遍,从识别系统版本、准备离线包、处理依赖到最后验证编译,踩了不少坑,也摸出几条高效路径。这篇文章就把完整流程和关键经验写下来,给同样在内网机房、离线部署环境里折腾Kylin的人一个可以直接抄作业的参考。

1. 先分清Kylin的Debian血统和RPM血统:这决定了离线安装姿势

1.1 两条命令识别系统的“血统”

Kylin V10和普通的CentOS/Ubuntu不太一样,市面上常见的是两个大系列。一个是服务器版(银河麒麟高级服务器操作系统V10,版本号里常带SP1/SP2/SP3),软件管理走yum/dnf,包后缀是.rpm,整体对标RHEL/CentOS生态。另一个是桌面版(银河麒麟桌面操作系统V10),软件管理走apt/dpkg,包后缀是.deb,整体对标Debian生态。问题在于,这两个系列离线配置g++的方法完全不一样,网上搜到的教程如果不先看版本直接照搬,很容易装到一半就报一堆依赖错误。

所以第一步不是找安装包,而是确认这台机器到底属于哪套体系。最简单的办法是执行:

cat /etc/os-release

看输出里的 NAME、VERSION、ID字段。出现“Kylin Server”或“Kylin Advanced Server”字样,基本走RPM体系;出现“Kylin Desktop”,大概率走DEB体系。如果还不放心,再跑一条:

which yum || which dnf which apt-get

哪个命令存在,就用哪套体系。这一步花30秒,能省后面1小时。我见过有人拿桌面版的思路去服务器版上搞,结果rpm数据库一路报错,最后只能重装系统。

1.2 别忽略CPU架构:aarch64和x86_64不通用

确认包管理体系之后,还要确认CPU架构:

uname -m

x86_64是Intel/AMD架构,aarch64是ARM架构,Kylin服务器上常见的飞腾、鲲鹏都属于后者。离线rpm/deb包必须和架构严格匹配,否则安装时直接报“架构错误”。很多人踩过这个坑:在有网机器上随手下了x86_64的包,拷到aarch64的机器上一装就废,白白浪费一次传输时间。

1.3 为什么不能照搬在线教程

在线教程普遍这么写:yum install -y gcc-c++,或者apt-get install -y g++。它之所以能一条命令搞定,是因为系统里配置了可用的软件源,包管理器自动完成依赖解析。离线环境没有可用源,yum会立刻报“Could not resolve host”之类的错误。换句话说,离线配置g++真正要解决的,不是“安装”这个动作本身,而是把在线时由包管理器自动完成的依赖解析和顺序控制,变成手工可控的流程。理解这一点,后面看到缺依赖的报错就不会慌。

2. 离线安装包从哪来:先用好手边的系统ISO,再做依赖收集

2.1 最省心的方案:挂载Kylin安装ISO当临时源

我在隔离环境配基础环境,第一选择永远是找系统安装镜像。初始系统的机器一般会随机器附带同版本ISO,直接挂载进系统看有没有软件仓库目录:

mkdir -p /mnt/kylin_iso mount -o loop /path/to/kylin.iso /mnt/kylin_iso ls /mnt/kylin_iso

RPM系的光盘里通常有 repodata 目录和 Packages 目录。只要能看到 repodata,说明ISO本身就是一套完整的离线yum源。顺手检查一下有没有g++相关包:

ls /mnt/kylin_iso/Packages | grep -E 'gcc|g\+\+'

如果有,我强烈建议直接用它建本地源,而不是手动rpm装。因为ISO里的包跟系统版本配套,依赖版本一致性最好,几乎不会出现编译时链接库版本不匹配的问题。Debian系的光盘结构是 pool/ 和 dists/,同样能当apt源用,具体写法在第3章讲。

2.2 有网同版本机器上收集依赖:RPM系

如果没有ISO,那就找一台同版本、同架构且能连网的非生产机器,在那边把依赖全部下载下来,再打包拷过去。RPM系比较标准,第一步安装yum-utils:

yum install -y yum-utils

然后带着依赖解析一起下载:

yumdownloader --resolve gcc-c++ --destdir=/tmp/kylin_gcc_rpms

--resolve参数非常关键,它会连带下载gcc、cpp、glibc-devel、libstdc++-devel这些间接依赖。下载完直接打包:

cd /tmp && tar czf gcc_rpms.tar.gz kylin_gcc_rpms

拷到目标机后解压安装。注意,目标机和下载机最好是同一个大版本,比如都是Kylin V10 SP2。小版本差异偶尔会导致glibc或libstdc++的符号版本对不上,装完能编译,但运行时可能报找不到GLIBCXX版本类错误。

2.3 有网同版本机器上收集依赖:Debian系

Debian系同样有对应思路。在有网的同版本Kylin桌面机器上执行:

apt-get install -y --download-only g++

--download-only会让apt把g++及其依赖的deb全部下载到 /var/cache/apt/archives/ 目录。然后:

ls /var/cache/apt/archives/*.deb mkdir -p /tmp/kylin_gcc_debs cp /var/cache/apt/archives/*.deb /tmp/kylin_gcc_debs/ tar czf gcc_debs.tar.gz /tmp/kylin_gcc_debs

拷到目标机后,用dpkg -i *.deb安装。如果提示缺依赖,再单独补对应的deb。也可以用 apt-rdepends 列出完整依赖树,但对于g++这种基础包,--download-only通常已经够用。

2.4 gcc-c++的完整依赖链:认识一下这几个“老演员”

为了后面报错时能看懂,先把核心依赖包的职责列出来:

包名体系作用
gcc-c++ / g++RPM / DEBC++编译器前端,提供g++命令
gcc两者都有C编译器,g++工作时调用其内部组件
cpp两者都有C/C++预处理器,负责头文件展开
libstdc++-devel / libstdc++-6-devRPM / DEBC++标准库开发包,提供iostream头文件和libstdc++.so软链
glibc-devel / libc6-devRPM / DEB系统C库开发文件,提供stdio.h等基础头文件
binutils两者都有链接器ld、汇编器as,编译链接阶段必须

RPM系安装顺序一般照着依赖方向走:cpp → glibc-devel → libstdc++-devel → gcc → gcc-c++。DEB系因为dpkg不强制严格顺序,实际操作常是一把dpkg -i *.deb下去,缺什么再补什么。把这些包名记住,后面报错基本一眼就能定位缺的是谁。

3. 核心实操:Debian系与RPM系两条安装路径

3.1 RPM系手工装:按依赖顺序 rpm -ivh

如果依赖包已经齐了,可以手工安装,顺序很重要:

cd /tmp/kylin_gcc_rpms rpm -ivh cpp-*.rpm glibc-devel-*.rpm libstdc++-devel-*.rpm gcc-*.rpm gcc-c++-*.rpm

这里尽量不要一上来就rpm -ivh *.rpm --nodeps。--nodeps相当于关掉依赖检查,短时间看是装上了,但有的包在文件层面被强行安装,实际内容不完整,编译时才会在ld链接阶段炸出“cannot find -lstdc++”之类的问题。手工按顺序装的好处是,如果缺了哪个包,rpm会明确告诉你“xxx is needed by gcc-c++”,把它补进同一句命令再跑即可。

安装完成后验证核心包是否都在:

rpm -qa | grep -E '^(gcc|g\+\+)' rpm -qa | grep -E '^(libstdc\+\+-devel|glibc-devel)'

3.2 RPM系省事法:createrepo 建本地仓库再 yum install

手工rpm装适合一次性操作,但如果你后面还要装make、cmake、openssl-devel等一堆编译依赖,我强烈建议直接把离线包做成一个本地yum仓库。先在目标机上装createrepo:

yum install -y createrepo

如果这台机器完全离线,连createrepo都没有,可以到ISO里找,或者在有网机器上把它和依赖一起下载过来。

把离线rpm统一放到一个目录,例如:

mkdir -p /opt/kylin_local_repo cp /tmp/kylin_gcc_rpms/*.rpm /opt/kylin_local_repo/

生成仓库元数据:

createrepo /opt/kylin_local_repo

然后新建 /etc/yum.repos.d/kylin-local.repo:

[kylin-local] name=Kylin Local Repo baseurl=file:///opt/kylin_local_repo enabled=1 gpgcheck=0

刷新缓存:

yum clean all yum makecache yum install -y gcc-c++

此时yum走的就是本地仓库,依赖自动解析,跟在线环境一样省心。后续再往这个目录塞新的rpm包,重新跑一遍createrepo --update /opt/kylin_local_repo就能继续使用,算是一劳永逸。

3.3 Debian系安装:dpkg -i 和本地apt源

Debian系的目标机器上,把拷贝过来的deb包全部放进一个目录:

mkdir -p /tmp/kylin_gcc_debs tar xzf gcc_debs.tar.gz -C /tmp cd /tmp/kylin_gcc_debs dpkg -i *.deb

如果dpkg提示有依赖未满足,一般有两种情况:一是部分deb没有下载到;二是安装顺序造成的“循环依赖”。前者回到有网机器上补下载,后者可以跑:

dpkg --configure -a

或者调整顺序,把libstdc++6-dev、libc6-dev这类基础包先装,再装g++。DEB系虽然不如RPM系对顺序敏感,但基础包装在前确实更稳。

如果你手里有桌面版的ISO,也可以直接用file源。先看目标系统的VERSION_CODENAME:

grep VERSION_CODENAME /etc/os-release

然后把ISO路径加入apt源:

echo "deb [trusted=yes] file:/mnt/kylin_iso <codename> main universe" >> /etc/apt/sources.list apt-get update apt-get install -y g++

trusted=yes是让apt信任本地非签名源的必要项,不加的话update会拒绝使用该源。

4. 装完别急着写代码:验证、配PATH、处理三个高频报错

4.1 第一个C++程序:把工具链真正跑起来

装完之后先确认编译器版本:

g++ --version

正常会输出类似 g++ (Kylin 10) 8.3.1 的信息。然后写个最小程序验证整套流程:

cat > hello.cpp <<'EOF' #include <iostream> int main() { std::cout << "Hello Kylin" << std::endl; return 0; } EOF g++ hello.cpp -o hello ./hello

输出 Hello Kylin,说明编译器、头文件、标准库、链接器全部正常。这一步不能省,因为有些机器g++命令能启动,但一编译就报错,下面这三个坑就是这种“半成功状态”的典型。

4.2 报错一:fatal error: iostream: No such file or directory

这个报错的意思是g++可执行文件找到了,但找不到C++标准库头文件。iostream头文件在RPM系的libstdc++-devel包、DEB系的libstdc++-6-dev包里提供。排查方法:

ls /usr/include/c++/ | head find /usr/include -name iostream

如果目录里没有iostream文件,说明开发包没装完整。回到离线包目录,找到libstdc++-devel开头的rpm或deb包,重新安装。还有一种少见情况:包装了但路径不在默认搜索范围内,可以临时设置:

export CPLUS_INCLUDE_PATH=/usr/include/c++/<版本号>

不过正常yum/dpkg安装会自动把路径放对,配置环境变量的方案只是兜底。

4.3 报错二:/usr/bin/ld: cannot find -lstdc++

编译过了预处理和编译前端,但在链接阶段挂了,提示找不到-lstdc++。这里-lstdc++对应的是libstdc++.so这个链接器输入文件。系统运行时只有libstdc++.so.6(动态库本体),开发包会额外提供一个不带版本号的软链,让链接器找到它:

ls -l /usr/lib64/libstdc++.so*

正常情况应该看到:

/usr/lib64/libstdc++.so -> libstdc++.so.6 /usr/lib64/libstdc++.so.6 -> libstdc++.so.6.0.24

如果少了第一条软链,就是缺libstdc++-devel / libstdc++-6-dev,补装后一般自动生成。这个报错的本质是开发包和运行包分离导致的,理解了这一点,以后遇到-lxxx找不到,就都知道往对应的-devel包上想。

4.4 报错三:IDE报 cannot run compiler 'g++'(Qt Creator经典问题)

这个报错在热搜里经常出现,很多人在Qt Creator或VS Code里配置工具链时看到。报错关键词是“cannot run compiler 'g++'”,或者“could not find a valid executable”。在Kylin上遇到,先不要怀疑编译器坏了,先查两件事:第一,系统是否真的装了g++;第二,IDE里填的编译器路径对不对。

终端里先跑:

which g++

正常会输出/usr/bin/g++。然后在Qt Creator中依次打开:工具 → 选项 → Kits → 编译器 → 添加 → GCC → C++,Compiler path填/usr/bin/g++,ABI选系统对应平台。特别注意:如果机器是aarch64,别把交叉编译的aarch64-linux-gnu-g++当本机编译器填进去,Kylin桌面自带的Qt套件有时会自动识别出交叉编译链,导致编译时找不到系统库。路径确认无误后回到Kits页面,把编译器和Qt版本绑到同一套Kit里。改完后先编译一个空项目验证,不要直接在业务工程里来回试探。

4.5 顺手把PATH和软链理一遍

如果which g++没有输出,说明g++的安装位置不在PATH里。用下面命令定位:

find / -name g++ -type f 2>/dev/null

找到后加软链或加PATH。最常用的是软链到/usr/bin下:

ln -s /usr/bin/g++-8 /usr/bin/g++

如果走的是源码编译GCC,新版本g++可能在/usr/local/bin/g++,而系统默认PATH里/usr/bin排在/usr/local/bin前面,可能出现系统自带的旧g++抢先被调用的情况。这种问题在纯rpm安装方式下遇不到,但离线场景下确实有人直接源码编译GCC,所以顺带提一下。需要时把/usr/local/bin提到PATH前面即可。

5. 把离线环境做成可复用工具包:本地源与依赖清单存档

5.1 从零建一个可离线复用的本地yum源

g++装完之后,基础环境并没有结束,后续大概率还要装make、cmake、boost、openssl-devel等。与其每次离线都现找包,不如定义一套固定目录和配置文件。第3章建的/opt/kylin_local_repo就是现成基础,我通常的做法是:

  1. 把该机器需要的所有离线rpm按类别分目录,如compiler/、libs/、tools/;
  2. 每个目录生成独立repodata,或者统一放一个大目录只建一个repodata;
  3. 将整个目录在部门内网共享,NFS或HTTP都行,其它机器直接配同一个baseurl。

共享的repo文件可以这样写:

[kylin-local] name=Kylin Local Repo baseurl=file:///opt/kylin_local_repo # 如果通过NFS挂载,直接用挂载后的本地路径 # 如果通过HTTP分发,则改成 baseurl=http://内网服务器ip/kylin_local_repo enabled=1 gpgcheck=0

第二台、第三台机器就都是yum install -y gcc-c++一条命令的事,跟在线环境几乎一样。这才是离线配置的最终形态:不是把某一次安装做完,而是把离线软件源搭起来。

5.2 Debian系的离线仓库:dpkg-scanpackages 生成索引

Debian系对应做法也简单。把离线deb放到统一目录,例如/opt/kylin_debs,然后安装dpkg-dev:

apt-get install -y dpkg-dev cd /opt/kylin_debs dpkg-scanpackages . /dev/null | gzip > Packages.gz

之后在/etc/apt/sources.list里加:

deb [trusted=yes] file:/opt/kylin_debs ./

apt-get update后就能install目录里的deb。这个方案对维护离线Kylin桌面环境很顺手,更新依赖时往里丢新deb再重新扫描即可。

5.3 记录依赖清单:让下一台机器2分钟配完

最后分享一个低成本高收益的习惯:在配置完成的机器上,把关键软件包清单导出存档。

RPM系:

rpm -qa | grep -E '^(gcc|g\+\+|libstdc\+\+|glibc-devel|binutils|cpp)' > /root/kylin_compiler_deps.txt

DEB系:

dpkg -l | grep -E 'gcc|g\+\+|libstdc\+\+|libc6-dev|binutils' > /root/kylin_compiler_deps.txt

这份清单配合/opt/kylin_local_repo目录里的具体rpm/deb文件,就是完整的“环境快照”。下次再来一台初始系统,对着清单核对、下载、安装,基本不会漏东西。我实际配置多台同型号机器时,从挂载ISO到g++跑通hello.cpp,单台耗时能控制在10分钟以内,关键就在于把源和清单都固化了。

最后再提一句我踩过的坑:最开始图省事,在离线机上直接rpm -ivh *.rpm --nodeps一把梭,表面全装上了,结果编译Qt程序时链接阶段逐个报缺库,补包补了整整三天。后来老老实实搭本地源、按依赖装,反而一次到位。离线配置g++这件事,真正的难度从来不是“装上”,而是“装对”。把依赖链搞清楚、把本地源建好,剩下就是机械操作了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询