龙芯 loongnix25 下载工具 FluxDown 安装小记
- 2026-09-30 06:53:11
昨天刚在这台龙芯 3A6000 上装好了 Gopeed。这次换 FluxDown——一个功能更"重"的下载器,协议支持更全,还带插件系统。它同样没有 loongarch64 的包,但绕开的路子跟上次不完全一样。
先说结论
FluxDown 在龙芯 loongnix 25(loongarch64)上可以完整跑起来,界面、协议支持与官方一致。走的是服务端 + 浏览器界面的形态。
为什么不能是桌面版?三条路我都试过:
最后落地的是三段式组装:

后端在本机编译成 loong64 原生代码,界面从官方 x64 二进制里精确取出,两边拼起来。 界面是官方原版,功能一点不打折。
为什么龙芯装不了桌面版
FluxDown 的技术栈是 Rust 引擎 + Flutter 界面。Rust 这边完全没问题——官方工具链原生支持 loongarch64;卡住的是界面:
- Flutter 没有 loongarch64 支持
,桌面版的界面编不出来。 项目主分支另写了一套 GPUI 纯 Rust 桌面界面(GPUI 是上游图形框架),理论上能编,但它依赖一个体量极大的上游仓库,在龙芯上从零构建的成本高得不成比例。
那么退一步:用官方的界面,自己只编后端,行不行?
这里有个关键发现——FluxDown 的架构天生是"引擎与界面解耦"的。下载引擎是一个零 FFI 的纯 Rust 库,仓库里同时提供了多个宿主:
native/ ├── engine 下载引擎(纯 Rust,零 FFI) ├── server 服务端(axum)+ Web 界面 ├── cli 命令行客户端 ├── daemon 常驻服务 └── ... 也就是说,服务端版本本身就带界面,而且这个界面不是 Flutter Web,是正经的 React 单页应用。这条路一下就通了大半。
那为什么不干脆自己编前端
按理说,后端能编、前端是普通网页,那前端也一起编了不就行了?我一开始就是这么想的,结果被三行 npm 结果拦住了。
前端是 React + Vite 8 + Tailwind 4 的组合。这几个工具都依赖"原生加速模块"(用 Rust 或 C++ 写的二进制包),我逐个查了 loongarch64 版本是否发布:
@rollup/rollup-linux-loong64-gnu | |
@esbuild/linux-loong64 | |
@rolldown/binding-linux-loong64-gnu | 无 |
@tailwindcss/oxide-linux-loong64-gnu | 无 |
lightningcss-linux-loong64-gnu | 无 |
三个"无",而且都是关键路径上的:Vite 8 的打包内核是 Rolldown,Tailwind 4 的样式引擎是 Oxide——缺了它们,前端构建根本跑不起来。
这件事说明一个规律:前端工具链的"Rust 化"反而扩大了架构适配的缺口。 以前纯 JS 的工具随便什么架构都能跑,现在关键环节换成了原生二进制,上游不发对应架构的包,下游就彻底卡死。
所以前端只能取官方编译好的产物。
第一步:从官方二进制里取出界面
思路和上次给 Gopeed 取界面一样,但细节不同——这次嵌的是 Rust 的资源表。
服务端的构建脚本用 include_bytes! 把前端产物编译进二进制,表结构大致是:
struct EmbeddedAsset { path: &str, // 资源路径 bytes: &[u8], // 内容 content_type: &str, etag: &str, // 校验值 } 解析下来两个有利条件:
指针以虚拟地址(vaddr)形式直接落盘 ,链接期已解析完重定位,不用碰 .rela.dyn;每个资源都带 ETag ,格式是 <fnv1a64 校验>-<字节长度>——这意味着提取之后可以逐文件自校验,不需要靠人工判断"看起来对不对"。
提取脚本的工作方式:拿一个已知文件名做锚点,双向步进还原出完整的表(表在二进制里是连续存放的),再用"路径排列的升序性"剔除可能存在的伪表,最后逐个文件验证 ETag。
结果:
提取 8 个文件 / 6.04 MB index.html assets/index-*.js 1,209,504 B assets/index-*.css favicon.svg / icons.svg fonts/MiSans-{Regular,Medium,Semibold}.ttf ETag 自校验 8/8 通过 8 个文件全部通过校验,这是"一个文件都没漏、没坏"最硬的证据。
为了保险,又做了一次交叉验证:把提取出的 5 个公共资源与源码仓库里的同名文件逐个字节比对(cmp),结果完全一致;再检查 JS 里有没有引用未提取的动态分块,确认是单 bundle,无遗漏。
第二步:在本机编译后端
后端是 Rust,编译本身是常规操作,但有两个环境问题必须处理。
问题一:git 依赖拉不下来
项目的依赖里有一处 git 依赖(重写了某个下载库的分支),而 github.com 在这台机器上直连不通。
最省事的办法是改全局 git 配置,但我不喜欢——这会污染整个系统的行为,别的项目也会被影响。
改用环境变量方式,只对当前 shell生效:
# 让 cargo 用 git 命令行拉取(libgit2 不读下面的环境变量) export CARGO_NET_GIT_FETCH_WITH_CLI=true # 把 github.com 的请求重写到加速镜像 export GIT_CONFIG_COUNT=1 export GIT_CONFIG_KEY_0="url.https://gh-proxy.com/https://github.com/.insteadOf" export GIT_CONFIG_VALUE_0="https://github.com/" 写完退出 shell 就失效,不写任何全局配置文件,干净。
这里有个容易踩的点:
CARGO_NET_GIT_FETCH_WITH_CLI=true是必须的。cargo 默认用 libgit2 拉代码,而 libgit2 不读上面那两个GIT_CONFIG_*环境变量——不切成 git 命令行,代理改写根本不生效。
问题二:默认编译配置太慢
仓库的 release 配置是为了"压体积"设计的:
opt-level = "z" # 优化体积而非速度 lto = "fat" # 全程序链接时优化 codegen-units = 1 # 单单元编译 这套设置在小体积项目上没问题,但在龙芯上编译耗时不可接受。我用环境变量覆盖,不改仓库里的任何文件:
export CARGO_PROFILE_RELEASE_LTO=thin export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=8 export CARGO_PROFILE_RELEASE_OPT_LEVEL=2 还有个必要动作:把要裁剪的模块排掉。主分支里那几个桌面界面模块依赖前面说的巨型上游仓库,编译它们纯属浪费时间。把工作区的成员列表收窄,只保留引擎、协议、服务端和命令行:
members = ["native/engine", "native/engine-protocol", "native/protocol", "native/api", "native/server", "native/cli"] 以及告诉构建脚本界面资源在哪:
export FLUXDOWN_EMBED_WEBROOT=~/opt/fluxdown-web-dist 准备就绪,一条命令:
cd ~/opt/fluxdown-src cargo build --release -p fluxdown_server -p fluxdown_cli 10 分 25 秒后产出两个文件:
fluxdown-server | ||
fluxdown |
第三步:补一个版本号
装完发现界面底部显示的是版本号 dev。
翻代码就明白了——版本号是编译期注入的:
option_env!("FLUXDOWN_SERVER_VERSION") option_env! 在编译时求值,没设这个环境变量就取不到值。带上版本号重编一次就好:
FLUXDOWN_SERVER_VERSION=0.4.8-rc.6 cargo build --release -p fluxdown_server 这类"编译期注入"的设计值得留意:配置不是运行时读的,改配置文件没用,必须重新编译。升级版本时也别忘了带上这个变量,否则界面上永远显示 dev。
验证:三项都是实测

第一,界面资源逐项对齐。 9 项静态资源全部返回 HTTP 200,字节数与提取结果完全一致,包括 assets/index-*.js(1,209,504 字节)和字体 MiSans-Regular.ttf(1,688,528 字节)。
第二,服务端接口正常。
{ "app": "FluxDown", "message": "pong", "version": "0.4.8-rc.6", "language": "zh", "linkPlatform": "server" } 第三,端到端下载测试。 建任务下载 5 MB 测试文件,等任务进入完成状态,比对源文件与下载文件的 MD5——完全一致;命令行工具的独立模式(add --local,不依赖服务端)同样通过。测试任务、测试文件、临时数据目录在验证结束后全部清理。
怎么用
服务默认只监听 127.0.0.1:17800,浏览器打开就能用。
第一次进入会让你设定访问密钥——这是官方的安全设计,不会自动生成,也不会打印到日志里。密钥规则是至少 8 位且同时包含字母和数字。设好之后,命令行工具记一次即可:
fluxdown config set token <你的密钥> 之后就能直接下任务了:
fluxdown add https://example.com/package.tar.gz ~/.local/bin/fluxdown-server | |
~/.local/bin/fluxdown | |
~/.local/bin/fluxdown-web | |
~/.local/share/applications/fluxdown.desktop | |
~/.local/share/fluxdown | |
~/opt/fluxdown-src | |
~/opt/fluxdown-web-dist |
协议覆盖 HTTP/HTTPS、FTP、BitTorrent 与磁力、eD2K、HLS/DASH 流媒体,另有插件体系与 ffmpeg / yt-dlp 托管下载,可在界面里直接安装。
三条安全提醒
第一,不要把监听地址改成 0.0.0.0 就直接用。 服务端的访问密钥虽然存在,但默认不强制——必须先在界面里设好密钥,再考虑对外开放。启动脚本里已经硬编码成 127.0.0.1。
第二,编译期嵌入的界面目录不要删。 它不在源码仓库里(源码不含构建产物),是编译的必要输入。清理磁盘时如果把它一起删掉,下次升级就得重新下载官方包再提取一遍。
第三,服务端的 --version 参数不存在。 敲下去不会打印版本,而是直接启动并进入监听状态,还会顺手创建默认数据目录。查版本请用接口:
curl -s http://127.0.0.1:17800/ping 和 Gopeed 那次有什么不同
两台下载器都装在同一个龙芯上,路子相似但差异不小,整理成一张表:
//go:embed | include_bytes! | |
一个有意思的对比:FluxDown 的界面是普通网页,反而更好验证——浏览器打开就能看、能截图、能逐个资源核对字节数;Gopeed 的界面是 CanvasKit 渲染,截图时依赖图形栈,验证基本只能靠接口返回值。
还有一个体会:同样是"官方只发 x64 包",能不能绕开,取决于项目自己的架构分层。 FluxDown 把引擎、服务端、界面拆得很干净,还自带 headless 服务端,所以绕开的成本很低;如果它是一个前后端焊死、只发桌面版的软件,这条路就走不通了。
选型时多看一眼项目的目录结构,比看功能列表更能判断它能不能在你的架构上落地。
参考文档
项目与源码
FluxDown 主仓库:https://github.com/zerx-lab/FluxDown 官网:https://fluxdown.zerx.dev 本次所用版本: server-v0.4.8-rc.6(源码 commit026c0a5a314a)官方服务端包: FluxDown-Server-0.4.8-rc.6-linux-x64.tar.gz
本机安装路径
~/.local/bin/fluxdown-server | |
~/.local/bin/fluxdown | |
~/.local/bin/fluxdown-web | |
~/.local/share/applications/fluxdown.desktop | |
~/.local/share/fluxdown | |
~/opt/fluxdown-src | |
~/opt/fluxdown-web-dist | |
~/opt/fluxdown-env.sh |
构建参数备忘
fluxdown_serverfluxdown_cli | |
CARGO_NET_GIT_FETCH_WITH_CLI=trueGIT_CONFIG_* 改写 | |
thinO2 | |
FLUXDOWN_SERVER_VERSION | |
FLUXDOWN_EMBED_WEBROOT | |