RustDesk 自建远程桌面源码构建指南:依赖准备、容器化编译与核心模块结构解析
RustDesk 是一个用 Rust 编写、面向自托管场景的开源远程桌面方案,其官方 README 完整覆盖了从系统依赖安装、vcpkg 编码器编译到 Docker 容器化构建的全流程,并给出了仓库核心目录的职责划分。本文以该文档为骨架,结合 Cargo.toml、Dockerfile 与 entrypoint.sh 等仓库内实际文件,还原每个构建步骤背后的实现依据,并进一步通过 src/rendezvous_mediator.rs、src/server 等源码印证远程连接链路的核心模块分工,读完后可独立完成 Linux 下的源码编译与容器化构建,并快速定位各功能模块所在代码位置。
项目定位:零配置可用、数据自管的远程桌面
官方 README 对项目的定义是:“Yet another remote desktop solution, written in Rust”,核心卖点是开箱即用(Works out of the box with no configuration required)与数据完全自控(You have full control of your data, with no concerns about security)。在网络架构上,RustDesk 提供三种部署选择:
- 直接使用项目方的 rendezvous/relay 中继服务器;
- 自建服务器(set up your own);
- 自行编写 rendezvous/relay 服务器(rustdesk-server-demo),即服务端逻辑与客户端仓库解耦,客户端代码中与之对接的部分集中在 src/rendezvous_mediator.rs。
同时 README 明确附带了滥用免责条款(Misuse Disclaimer):开发者不认可也不支持任何非伦理或非法用途,未经授权的访问、控制或侵犯隐私均违背项目准则,作者对软件被滥用不承担责任。
从当前仓库的实际版本信息看:
- Cargo.toml 中标注的版本为 1.4.9,要求最低 Rust 版本 1.75(
rust-version = "1.75"),默认运行目标为rustdesk二进制(default-run = "rustdesk"),同时产出librustdesk静态/动态库供嵌入(crate-type = ["cdylib", "staticlib", "rlib"])。 - GUI 层目前处于双轨并行状态:Sciter(已标记 deprecated)与 Flutter。src/main.rs 中通过编译期条件分派——启用
flutterfeature 或目标平台为 Android/iOS 时走 Flutter 入口;否则调用ui::start(args)启动 Sciter UI。
构建依赖总览:Rust + C++ 环境 + vcpkg 编码器
README 的 “Raw Steps to build” 给出三步最小构建路径,这里逐条展开并补充仓库内的对应证据。
第一步:准备 Rust 与 C++ 构建环境
桌面版 GUI 使用 Flutter 或 Sciter(已弃用)。README 特别说明其构建教程仅针对 Sciter(“since it is easier and more friendly to start”),因为流程更短;Flutter 版本则需参考项目 CI 配置。此外需要自行下载 Sciter 动态库:
| 平台 | 动态库文件 |
|---|---|
| Windows | sciter.dll |
| Linux | libsciter-gtk.so |
| macOS | libsciter.dylib |
第二步:安装 vcpkg 并编译编码器
vcpkg 是 RustDesk 编译 C/C++ 依赖(视频编码器、音频编解码器)的统一入口,必须正确设置 VCPKG_ROOT 环境变量。README 给出的安装命令:
- Windows:
vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static
- Linux / macOS:
vcpkg install libvpx libyuv opus aom
这四枚依赖正是远程桌面的性能核心:libvpx(VP8/VP9 视频编码)、libyuv(YUV 像素格式转换)、opus(低延迟音频编码)、aom(AV1 编码)。
从仓库清单文件 vcpkg.json 可以看到实际构建时依赖远不止这四个:manifest 中还声明了 libjpeg-turbo(截图/文件传输图像压缩)、Windows ARM64 平台的 libsodium(加密库)、mfx-dispatch(Intel 硬件编解码)以及 ffmpeg(在静态构建下按平台启用 amf/nvcodec/qsv 硬件编码 feature)。该 manifest 同时配置了项目自带的覆盖端口与 triplet:overlay-ports: ./res/vcpkg、overlay-triplets: ./res/vcpkg-triplets,对应的补丁与 portfile 位于 res/vcpkg(例如 aom 的 AVX2 修复、ffmpeg 的 11 组编译补丁、libvpx 的 UWP 支持补丁等)和 res/vcpkg-triplets(四个 Android 架构 triplet)。这解释了 README 中 Linux 手工安装只需列 4 个包,而完整产物却包含 ffmpeg 硬编码能力的原因。
第三步:cargo run
cargo run
配合 src/main.rs 可以看出,cargo run 默认执行的是 Sciter UI 分支:先在非 Flutter 目标下调用 crate::core_main::core_main() 完成参数解析与服务启动,成功后进入 ui::start(args)。
Linux 分发行构建详解
README 针对四种主流 Linux 发行版给出了依赖安装命令,以下为完整继承:
Ubuntu 18(Debian 10)
sudo apt install -y zip g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev \
libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake make \
libclang-dev ninja-build libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
openSUSE Tumbleweed
sudo zypper install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libXfixes-devel cmake alsa-lib-devel gstreamer-devel gstreamer-plugins-base-devel xdotool-devel
Fedora 28(CentOS 8)
sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libxdo-devel libXfixes-devel pulseaudio-libs-devel cmake alsa-lib-devel gstreamer1-devel gstreamer1-plugins-base-devel
Arch(Manjaro)
sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pipewire
这些包清单与 Dockerfile 中 debian:bullseye-slim 基础镜像安装的 apt 包基本一致(g++/gcc/git/curl/nasm/yasm/libgtk-3-dev/clang/libxcb-*-dev/libxdo-dev/libasound2-dev/libpulse-dev/gstreamer 等),Docker 构建环境可以视为 Ubuntu 依赖清单的容器化复刻,另外 Dockerfile 还额外从源码编译了 CMake 3.30.6 并设置 VCPKG_FORCE_SYSTEM_BINARIES=1 强制使用系统二进制。
安装 vcpkg(README 固定版本 2023.04.15)
git clone https://github.com/microsoft/vcpkg
cd vcpkg
git checkout 2023.04.15
cd ..
vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus aom
注意 README 特意固定了 vcpkg 的 release 版本 2023.04.15,Dockerfile 同样使用 --branch 2023.04.15 --depth=1 拉取 vcpkg,保证两条构建路径的 C 依赖版本一致、可复现。
libvpx 的 fPIC 修复(仅 Fedora 需要)
Fedora 上静态库需要开启位置无关代码,README 给出的补丁流程:
cd vcpkg/buildtrees/libvpx/src
cd *
./configure
sed -i 's/CFLAGS+=-I/CFLAGS+=-fPIC -I/g' Makefile
sed -i 's/CXXFLAGS+=-I/CXXFLAGS+=-fPIC -I/g' Makefile
make
cp libvpx.a $HOME/vcpkg/installed/x64-linux/lib/
cd
即手动进入 vcpkg 的构建树,重新 configure 后用 sed 给 C/CXX 编译参数注入 -fPIC,再把生成的 libvpx.a 覆盖回 installed/x64-linux/lib/。
编译并运行
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
git clone --recurse-submodules https://github.com/rustdesk/rustdesk
cd rustdesk
mkdir -p target/debug
wget https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so
mv libsciter-gtk.so target/debug
VCPKG_ROOT=$HOME/vcpkg cargo run
关键点解析:
--recurse-submodules:仓库使用 git submodule 组织部分依赖,漏掉会编译失败;libsciter-gtk.so必须预先放入target/debug/,因为 Sciter UI 运行时按可执行文件同目录查找动态库;Docker 构建中的 entrypoint.sh 也执行了同样的动作(cp "$HOME"/libsciter-gtk.so target/debug/);--release构建时产物位于target/release/,入口脚本会把 Sciter 库同样复制到target/release/下。
Docker 容器化构建:一键环境与增量缓存
README 推荐的另一条路径是 Docker 构建,适合不想在宿主机安装整套工具链的开发者。
构建构建镜像
git clone https://github.com/rustdesk/rustdesk
cd rustdesk
git submodule update --init --recursive
docker build -t "rustdesk-builder" .
执行编译
docker run --rm -it -v $PWD:/home/user/rustdesk -v rustdesk-git-cache:/home/user/.cargo/git -v rustdesk-registry-cache:/home/user/.cargo/registry -e PUID="$(id -u)" -e PGID="$(id -g)" rustdesk-builder
参数含义:
-v $PWD:/home/user/rustdesk:把当前仓库挂载进容器作为编译目录;- 两个 named volume 分别缓存 cargo 的 git 依赖与 registry 依赖,首次构建较慢,后续构建显著提速;
PUID/PGID注入宿主机当前用户 UID/GID,避免容器内 root 用户生成的target/文件在宿主机上出现权限问题。
追加构建参数与产物位置
任意额外参数可直接追加到命令末尾的 <OPTIONAL-ARGS> 位置。例如构建优化版:
docker run ... rustdesk-builder --release
产物随构建类型落在宿主机仓库的 target 目录:
target/debug/rustdesk
或:
target/release/rustdesk
README 给出两条明确限制:
- 必须从 RustDesk 仓库根目录运行,否则程序可能找不到所需资源;
cargo install、cargo run等子命令不通过此方式支持,因为那会在容器内而非宿主机上安装/执行程序。
入口脚本的实现印证
上述行为的实现在 entrypoint.sh:它先 cd $HOME/rustdesk 并加载 ~/.cargo/env,然后循环解析传入参数——识别到 --release 时置位 release=1 并拷贝 Sciter 库到 target/release/;识别到 --target <triple> 时调用 rustup target add 安装交叉目标;最终执行的是:
VCPKG_ROOT=/vcpkg cargo build --locked $argv
即只做 cargo build --locked(--locked 锁定 Cargo.lock 中的依赖版本,保证可复现),其余参数原样透传给 cargo build,这与 README 的说明逐条对应。
文件结构与核心模块职责
README 的 “File Structure” 一节是理解仓库的索引,以下完整保留其职责描述,并将原文指向 GitHub 的链接转换为仓库内相对路径,便于直接跳转阅读:
| 模块 | 路径 | 职责(README 原文职责) |
|---|---|---|
| hbb_common | libs/hbb_common | 视频编解码封装、配置、tcp/udp 封装、protobuf、文件传输的 fs 函数及其他工具函数 |
| scrap | libs/scrap | 屏幕采集(screen capture) |
| enigo | libs/enigo | 各平台键鼠控制 |
| clipboard | libs/clipboard | Windows/Linux/macOS 的文件复制粘贴实现 |
| Sciter UI | src/ui | 已废弃的 Sciter UI |
| server | src/server | 音频/剪贴板/输入/视频服务与网络连接 |
| client | src/client.rs | 发起对端连接 |
| rendezvous mediator | src/rendezvous_mediator.rs | 与 rustdesk-server 通信,等待远程直连(TCP 打洞)或中继连接 |
| platform | src/platform | 平台相关代码 |
| flutter | flutter | 桌面与移动端的 Flutter 代码 |
从源码结构看,这份索引与实现高度吻合,可以补充几点细节:
- workspace 组织:Cargo.toml 的
[workspace]将libs/scrap、libs/hbb_common、libs/enigo、libs/clipboard、libs/virtual_display、libs/portable、libs/remote_printer列为成员 crate——比 README 索引多出的virtual_display(Windows 虚拟显示器)、portable(便携模式壳)与remote_printer(远程打印驱动)是 Windows 侧扩展能力; - 打洞与中继逻辑:README 称 rendezvous mediator “wait for remote direct (TCP hole punching) or relayed connection”,src/rendezvous_mediator.rs 中确实实现了
handle_punch_hole处理PunchHole消息、punch_udp_hole建立 UDP 通道等函数,验证了“先尝试 TCP 直连打洞、失败再走中继”的双通道设计; - 服务端模块:src/server 下的
audio_service.rs、clipboard_service.rs、input_service.rs、video_service.rs、terminal_service.rs、connection.rs等文件一一对应 README 所述“audio/clipboard/input/video services, and network connections”,其中 src/server/connection.rs 是全仓库最大的服务文件(约 7400 行),承载远端会话的核心会话逻辑; - 命令行入口:src/core_main.rs 中的
core_main()解析--elevate、--run-as-system、--quick_support、--no-server等进程模式参数,Flutter 路径下还会识别--connect、--file-transfer、--port-forward、--terminal等由 GUI 触发的新连接参数; - Wayland 兼容性:Cargo.toml 通过
[patch.crates-io]将libxdo-sys替换为仓库内 libs/libxdo-sys-stub 的桩实现,使得在未安装 libxdo 的纯 Wayland 系统上也能构建运行,这与 Linux 依赖清单中同时提供 X11 开发库和 pipewire 的做法相一致。
小结
RustDesk 官方 README 构建文档的价值在于它同时给出了手工构建的透明路径(系统包 + vcpkg + cargo run)和容器化的可复现路径(Dockerfile + entrypoint.sh + 增量缓存),两条路径共享同一套 2023.04.15 版 vcpkg 依赖基线。结合 Cargo.toml 的 workspace/feature 划分、vcpkg.json 的完整依赖 manifest 与 src/ 各服务模块,可以完整回答三个问题:编解码依赖从哪里来、Sciter 库为何要放进 target 目录、以及“直连打洞 + 中继”的远程链路落在哪些源码文件中。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00