[software development] 【笔记整理】Deepin V25(x86_64)上搭建LoongArch64 交叉编译环境
Tofloor
poster avatar
kookboy
deepin
11 hours ago
Author

我的笔记本电脑是x86_64的CPU架构,平时Vibe Coding出来的项目应用程序都是基于这个架构,对于使用龙芯架构的电脑的朋友来说,就没法安装使用我社区分享的这些应用程序。于是,昨晚在网上搜索了一些资料并尝试在本机上搭建交叉编译环境,期间还把deepin的桌面系统搞漰了,无意间卸载了大部分桌面组件。还好我安装着Hermes Agent ,虽然系统登陆窗口没了,进不了系统和桌面。就在手机微信上指挥我的Hermes帮我进行修复,期间,重新安装组件时下载又特别慢,搞了近两个小时,才终于恢复deepin桌面系统。

对搭建交叉编译环境过程中,我都是使用AI工具,有不少的坑,也遇到不少问题。搭建完成后,成功构建了前久参加社区比赛的作品---Deskmon桌面系统监视的龙芯版本。分享给一两个网友测试,目前还没收到反馈信息。

AI把这个笔记不断修改完善后,我想了想,还是把它分享出来给有需要的网友一个借鉴参考的地方。也希望社区的专业开发者大佬们对笔记存在的问题进行指正!applaud

在 Deepin V25(x86_64)上搭 LoongArch64 交叉编译环境,有两条成熟路径:优先用 Deepin/Debian 仓库里的 gcc-loongarch64-linux-gnu 系列包(最干净,跟系统包管理集成);仓库没有或版本不满足时,直接用龙芯官方预编译工具链。下面把两种方式都给你,并附上验证和依赖处理方法。

💡 Deepin 25 采用了基于 OSTree 的部分不可变布局,/usr/lib 等目录对 root 也是只读的。常规软件安装请使用 apt 命令(它会通过系统机制正确处理),至于将工具链解压到 /opt 等目录,也建议通过 sudo 进行操作以遵循系统规范。

⚠️ 先看:按项目类型选路线,别搭错环境

两条路线不是二选一,而是适用场景不同。选错了会卡在"编译器能跑、但链接不到目标库":

项目类型 推荐路线 原因
内核、裸 C/C++ 程序、静态链 方案二(龙芯官方 GCC15 工具链) 只要 glibc,工具链自带 sysroot 够用,且 GCC 版本新
只依赖 libc 的 Makefile/Autotools 小工具 方案一或二均可 都能编
依赖发行版第三方库的应用(Qt6/DTK6/GTK 等) 必须方案一 + apt multiarch 官方工具链只有 glibc,没有 Qt6/DTK6 的 .so 和头文件,链接阶段必报 cannot find -lDtk6Widget;apt 多架构才能拉到 loong64 版的这些库
需要打.deb 交叉包 必须方案一 + apt multiarch dpkg-buildpackage -a loong64 要靠 multiarch 让 dh_shlibdeps 算准依赖

一句话:官方 GCC15 工具链适合编"自包含"的东西,apt multiarch 适合编"依赖系统库"的东西。 如果你搭环境的目的是给 deskmon 这种 DTK6/Qt6 应用打 loong64 deb,直接走方案一,官方工具链用不上。

方案一:通过 apt 安装仓库工具链(推荐先试)

Deepin V25 的仓库里已经可以安装 LoongArch64 的交叉编译器,包名遵循 Debian 命名规范:

sudo apt update
sudo apt install -y \
  gcc-loongarch64-linux-gnu \
  g++-loongarch64-linux-gnu \
  binutils-loongarch64-linux-gnu \
  cpp-loongarch64-linux-gnu

如果编译时提示找不到目标架构的库,再补运行时/开发库:

sudo apt install -y libc6-dev-loongarch64-cross

装完后可以直接调用:

loongarch64-linux-gnu-gcc --version

方案二:龙芯官方预编译工具链(仓库版本不够时用)

Deepin 仓库里的交叉 GCC 版本往往比较老,如果你需要较新的编译器(比如 GCC 15、binutils 2.45),从龙芯 build-tools 发布页拿预编译包更省事:

# 到 https://github.com/loongson/build-tools/releases 下载
# 例如 x86_64-cross-tools-loongarch64-binutils_2.45-gcc_15.1.0-glibc_2.42.tar.xz
# 不带 glibc 的版本即可用于交叉编译

sudo mkdir -p /opt/loongarch64_cross-toolchain
sudo tar -vxf x86_64-cross-tools-loongarch64-binutils_2.45-gcc_15.1.0-glibc_2.42.tar.xz \
  -C /opt/loongarch64_cross-toolchain/

export PATH=/opt/loongarch64_cross-toolchain/cross-tools/bin:$PATH

验证:

loongarch64-unknown-linux-gnu-gcc --version

📌 两种方案的编译器前缀不一样:apt 装的是 loongarch64-linux-gnu-,龙芯官方包是 loongarch64-unknown-linux-gnu-。后面写 CROSS_COMPILECC 时要对应上。

为了让环境变量永久生效,把 export PATH=... 加到 ~/.bashrc 末尾即可。

配置交叉编译环境变量

无论哪种方案,编译前建议导出这几个变量:

export ARCH=loongarch64
export CROSS_COMPILE=loongarch64-linux-gnu-   # 或 loongarch64-unknown-linux-gnu-

实际编译示例

Makefile 项目

make CC=loongarch64-linux-gnu-gcc \
     CXX=loongarch64-linux-gnu-g++ \
     AR=loongarch64-linux-gnu-ar

Autotools 项目configure):

./configure \
  CC=loongarch64-linux-gnu-gcc \
  CXX=loongarch64-linux-gnu-g++ \
  --host=loongarch64-linux-gnu \
  --build=$(dpkg-architecture -qDEB_BUILD_GNU_TYPE)

如果 configure 报"不支持 loongarch64",需要更新 config.subconfig.guess

wget -O config.sub https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
wget -O config.guess https://git.savannah.gnu.org/cgit/config.git/plain/config.guess

CMake 项目

cmake -DCMAKE_SYSTEM_NAME=Linux \
      -DCMAKE_C_COMPILER=loongarch64-linux-gnu-gcc \
      -DCMAKE_CXX_COMPILER=loongarch64-linux-gnu-g++ \
      ..

处理目标库依赖(sysroot)

当你编译的程序需要链接 LoongArch64 的第三方库时,手头的 x86_64 系统里没有对应的 .so这一步是交叉编译最容易踩坑的地方,处理思路按你选的编译器路线分:

路线 A:apt 多架构(方案一用户,依赖发行版库时首选)

gcc-loongarch64-linux-gnu 本身不带目标库,要靠 apt 的 multiarch 机制把 loong64 版的库装到本机:

sudo dpkg --add-architecture loong64
sudo apt update
sudo apt install -y <某个库>:loong64

装完后库落在 /usr/lib/loong64-linux-gnu,头文件落在 /usr/include,交叉编译器和 pkg-config 会自动按 loong64 三元组找到它们,无需手动指定 sysroot。CMake 也无需 --sysroot,开 CMAKE_FIND_ROOT_PATH_MODE_*ONLY 即可。

✅ Deepin V25 crimson 源 loong64 架构齐全,实测含 qt6-base-dev:loong64libdtk6{core,gui,widget}-dev:loong64,版本与 amd64 对齐。

📌 Deepin 打包特殊点:loong64 版的 CMake 配置文件装在 /usr/lib/loongarch64-linux-gnu/cmake/(GNU 三元组路径),不是 /usr/lib/loong64-linux-gnu/cmake/(dpkg 架构名路径)。好在交叉编译器的搜索路径含 /usr/lib/loongarch64-linux-gnu,CMake 用 CMAKE_SYSTEM_PROCESSOR=loong64 时会自动命中,无需手动处理。

⚠️ 必须先读下一个章节《踩坑实录》linux-libc-dev:loong64:amd64/usr/include/linux/ 存在文件冲突(deepin 打包 bug),直接 apt install libc6-dev:loong64 会卡死,需用假包绕过。

路线 B:龙芯官方 CLFS sysroot(方案二用户,需要非发行版库时用)

官方 GCC15 工具链只带了 glibc,不带任何第三方库。如果你的程序只依赖 libc,它的 target/ 目录够用;一旦要链 Qt6/DTK6/GTK 这类库,光靠官方工具链会直接链接失败。补库有两种做法:

  1. 仍然回 apt multiarch 拉 loong64 库(推荐,库最全、版本对齐发行版)——即和路线 A 合流,这时官方工具链其实只剩"GCC 版本更新"这一个优势,多数情况不值得为它放弃 apt 的库管理。
  2. 用龙芯官方 CLFS sysroot(库较全但版本独立,不跟发行版走):

CLFS-for-LoongArch 下载 loongarch64-clfs-system-8.0-sysroot.tar.xz,解压后编译时指定:

./configure --host=loongarch64-linux-gnu \
 --with-sysroot=/path/to/sysroot

或在 GCC 命令行加 --sysroot=/path/to/sysroot

⚠️ 实测结论:纯 C/C++ 程序用官方工具链 --sysroot=target/ 没问题;但只要牵涉发行版第三方库,apt multiarch 是唯一省心的路,官方工具链的 sysroot 凑不齐那些库。

踩坑实录:linux-libc-dev 文件冲突(apt multiarch 路线必看)

走路线 A 装 loong64 dev 包时,libc6-dev:loong64 会拽来 linux-libc-dev:loong64,而这个包装不上——这是 Deepin V25 打包的一个 bug,本节给出验证过的解法。

根因

linux-libc-dev 声明了 Multi-Arch: same,按规范各架构文件路径应完全一致、仅内容不同。但 deepin 的 loong64 版和 amd64 版各自有架构特有的头文件,两版 839 个文件都落在 /usr/include/linux//usr/include/drm/ 等同一路径,dpkg 解压 loong64 版时发现文件名与 amd64 版已有文件冲突,直接 abort。

# 失败现象:dpkg 反复尝试,始终 half-installed → not-installed
dpkg: 处理归档 .../linux-libc-dev_25.01.01.28_loong64.deb (--unpack) 时出错:
尝试覆盖共享的 '/usr/share/doc/linux-libc-dev/changelog.gz',
它与软件包 linux-libc-dev:amd64 中的其他实例不同

解法:造一个假包满足依赖

交叉编译器实际从 linux-libc-dev-loong64-cross 包(装在 /usr/loongarch64-linux-gnu/include/)找内核头,根本不需要真正的 linux-libc-dev:loong64。所以造一个空壳包骗过依赖检查即可。

第 1 步:准备假包目录

mkdir -p /tmp/fake-linux-libc-dev/DEBIAN
mkdir -p /tmp/fake-linux-libc-dev/usr/share/doc/linux-libc-dev

第 2 步:写 control 文件(关键是 Multi-Arch: same

cat > /tmp/fake-linux-libc-dev/DEBIAN/control << 'EOF'
Package: linux-libc-dev
Architecture: loong64
Version: 25.01.01.28
Multi-Arch: same
Provides: linux-kernel-headers
Maintainer: cross-build 
Description: Stub package to satisfy cross-build dependency (fake)
 空壳包,仅满足 libc6-dev:loong64 对 linux-libc-dev:loong64 的依赖。
 真正的内核头由 linux-libc-dev-loong64-cross 提供。
EOF

第 3 步:拷贝 doc 文件Multi-Arch: same 要求各架构 doc 文件 md5 一致)

cp /usr/share/doc/linux-libc-dev/changelog.gz /tmp/fake-linux-libc-dev/usr/share/doc/linux-libc-dev/
cp /usr/share/doc/linux-libc-dev/copyright    /tmp/fake-linux-libc-dev/usr/share/doc/linux-libc-dev/

第 4 步:打包并安装

cd /tmp
dpkg-deb --build --root-owner-group fake-linux-libc-dev linux-libc-dev_25.01.01.28_loong64.deb
sudo dpkg -i linux-libc-dev_25.01.01.28_loong64.deb
sudo dpkg --configure -a

⚠️ 假包必须Multi-Arch: same 和与 amd64 版一致的 changelog.gz + copyright,否则 dpkg 的共享文件一致性检查会拒绝。doc 文件从已装的 amd64 版直接拷即可。

如果之前装到一半卡住了

apt install 中途失败会留下大量 iU(解压未配置)状态的 loong64 包。修复顺序:

# 1) 卸掉装失败的 linux-libc-dev:loong64(强制忽略依赖)
sudo dpkg --remove --force-all linux-libc-dev:loong64

# 2) 恢复本机 amd64 版(可能被 apt 搞丢)
sudo apt install --reinstall -y linux-libc-dev:amd64
# 若 apt 也卡住,用 dpkg 直接装缓存里的 deb:
# sudo dpkg -i /var/cache/apt/archives/linux-libc-dev_*_amd64.deb

# 3) 装假包
sudo dpkg -i /tmp/linux-libc-dev_25.01.01.28_loong64.deb

# 4) 配完所有卡住的 loong64 包
sudo dpkg --configure -a

# 5) 确认无残留
dpkg -l | grep ':loong64' | awk '$1!="ii"'   # 期望无输出

💡 假包装好后不要用 apt-get install -f 去"修复"依赖——它会试图用真包替换假包,又触发冲突。只要 dpkg --configure -a 干净就别动。

apt pin:防止 dist-upgrade 替换假包

假包版本号和源里真包相同(25.01.01.28),apt dist-upgrade 会认为该"替换"假包、重新触发文件冲突。用 apt pin 彻底封死:

sudo tee /etc/apt/preferences.d/linux-libc-dev-loong64-pin << 'EOF'
Package: linux-libc-dev:loong64
Pin: release *
Pin-Priority: -1
EOF

Pin-Priority: -1 让 apt 永不安装/升级 linux-libc-dev:loong64,dist-upgrade 自动跳过。验证:

apt-cache policy linux-libc-dev:loong64
# 候选版本应为 (无),优先级 -1

⚠️ 不要试图抬高假包版本号来阻止升级Multi-Arch: same 要求各架构版本完全一致,假包版本号若与 amd64 版(25.01.01.28)不同,dpkg 会拒绝同时配置两个架构,导致 amd64 和 loong64 都变成 half-configured。apt pin 是唯一正确的解法。

保留假包

假包不要卸载。一旦卸掉,libc6-dev:loong64 的依赖记录悬空,apt upgradeapt install -f 会尝试装真包,重新陷入冲突循环。假包只有 1.6 KB,无副作用。配合上面的 apt pin,dist-upgrade 也不会碰它。

验证编译产物

编译完后务必确认产物确实是 LoongArch64 架构:

file ./your_binary
# 期望输出:ELF 64-bit LSB executable, LoongArch, version 1 (SYSV), dynamically linked

readelf -A ./your_binary | grep -i loongarch

如果需要在 x86_64 主机上直接跑起来测试,可以借助 QEMU 用户态模拟:

sudo apt install qemu-user-static
qemu-loongarch64 -L /opt/loongarch64_cross-toolchain/cross-tools/sysroot ./your_binary

交叉打 deb 包(dpkg-buildpackage -a loong64)

给 loong64 架构打 deb 包,核心是 dpkg-buildpackage -a loong64 + 一个 CMake 交叉工具链文件。下面以 deskmon(DTK6/Qt6 CMake 项目)为例。

第 1 步:写 CMake 交叉工具链文件

项目里放一个 cmake/loong64-toolchain.cmake

set(CMAKE_SYSTEM_NAME      Linux)
set(CMAKE_SYSTEM_PROCESSOR loong64)
set(CMAKE_C_COMPILER   loongarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER loongarch64-linux-gnu-g++)
# 只在目标根路径下查找,避免误命中本机 amd64 库
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

第 2 步:debian/rules 按架构分叉

# 本机 amd64 用自定义 jm-prefix 工具链;交叉构建走 CMAKE_TOOLCHAIN_FILE
override_dh_auto_configure:
ifeq ($(DEB_HOST_ARCH),loong64)
    dh_auto_configure -- -DCMAKE_TOOLCHAIN_FILE="$(CURDIR)/cmake/loong64-toolchain.cmake"
else
    dh_auto_configure -- -DCMAKE_PREFIX_PATH="$(HOME)/jm-prefix/usr"
endif

⚠️ 如果本机用非系统路径的 cmake(如 jm-prefix),PATHLD_LIBRARY_PATH 要保留(cmake 本身是 amd64 本机程序,两种架构都要用),只隔离 CMAKE_PREFIX_PATH——否则交叉构建时 cmake 报 cannot open shared object file: librhash.so.0

第 3 步:debian/control 追加交叉编译器

Build-Depends:
 cmake,
 debhelper-compat (= 13),
 ...
 gcc-loongarch64-linux-gnu [!amd64],
 g++-loongarch64-linux-gnu [!amd64],

第 4 步:构建

dpkg-buildpackage -a loong64 -b -us -uc -d
# 产出 ../yourpkg_version_loong64.deb

dh_shlibdeps 会自动分析产物的 loong64 依赖(libdtk6corelibqt6core6 等),无需手写 Depends


推荐路线总结

  • 编内核 / 纯 C/C++ / 静态链:龙芯官方 GCC15 工具链,版本新、sysroot 自带 glibc 够用。
  • 编依赖发行版库的应用(Qt6/DTK6/GTK…)或打 loong64 debapt install gcc-loongarch64-linux-gnu + dpkg --add-architecture loong64 拉 loong64 库,不要用官方工具链(它的 sysroot 没有这些库,链接会失败)。

两者技术上可共存、靠 PATH 顺序切换,但别混用:一个项目要么全走 apt 体系,要么全走官方工具链 + 手补 sysroot,否则编译器找的库和链接器找的库会对不上。

实测踩坑:给 deskmon(DTK6/Qt6 应用)搭环境时遇到三个坑,均已验证解法:

  1. 官方工具链缺第三方库:先装了龙芯官方 GCC15 工具链,结果 CMake find_package(Qt6) / find_package(Dtk6Widget) 全部失败——官方 sysroot 里根本没有这些库的 cmake 配置文件。改走 apt multiarch 后,loong64 版 Qt6 6.8.0 / DTK6 6.7.47 一次到位,和本机 amd64 版本完全对齐。
  2. linux-libc-dev 文件冲突(deepin 打包 bug):linux-libc-dev:loong64:amd64/usr/include/linux/ 路径冲突,装不上。解法见《踩坑实录》——造一个 Multi-Arch: same 空壳包满足依赖,真正的内核头由 linux-libc-dev-loong64-cross 提供。
  3. 非系统 cmake 的 librhash 依赖:本机用 jm-prefix 的 cmake,交叉构建时若把 LD_LIBRARY_PATH 一起守卫掉,cmake 自身跑不起来。解法:PATH/LD_LIBRARY_PATH 保留,只隔离 CMAKE_PREFIX_PATH

最终产出 deskmon_1.0.3_loong64.debdh_shlibdeps 自动算准依赖,file 确认为 ELF 64-bit LSB executable, LoongArch

附:【deepin 插件开发活动】DeskMon —— DTK6 原生桌面系统监控 龙芯版下载,欢迎测试!

deskmon_1.0.3_loong64.deb.zip

Reply Favorite View the author
All Replies
avatar
米饭虚拟机-nana版
deepin
8 hours ago
#1

我觉得可以在github actions配置 编译龙芯版软件 的docker镜像 proud

Reply View the author
avatar
nihaoxye
deepin
6 hours ago
#2

支持,很有技术含量。

Reply View the author
avatar
小琥在发呆
deepin
6 hours ago
#3

作为多年的龙架构使用者,更需要的是在龙架构上通过二进制运行x86、ARM上的软件,希望大哥有空可以搞搞

Reply View the author
avatar
kookboy
deepin
2 hours ago
#4
米饭虚拟机-nana版

我觉得可以在github actions配置 编译龙芯版软件 的docker镜像 proud

没用过github actions,大佬出个教程吧~agree

Reply View the author