RustDesk 构建与源码结构完全指南:Rust 远程桌面应用的依赖管理、Linux 本地编译与 Docker 构建实战
本文基于 RustDesk 仓库的日文版 README(docs/README-JP.md)整理扩充,系统讲解如何用 vcpkg 管理 C/C++ 原生依赖、在 Ubuntu / openSUSE / Fedora / Arch 各发行版上完成本地编译、通过 Docker 容器化构建,并结合当前仓库源码逐条印证 libs/scrap、libs/enigo 等核心模块的真实职责,帮助读者从零掌握 RustDesk 的完整构建流程与代码组织方式。
一、RustDesk 是什么:自托管优先的远程桌面
RustDesk 是一个用 Rust 编写的、开箱即用的开源远程桌面软件,定位为 TeamViewer 的自托管替代方案。其核心特性在于:
- 数据自主可控:用户可以选择使用官方公共的会合/中继服务器,也可以自建服务器(README 中提到可参考 rustdesk-server 相关项目自行部署会合/中继服务),从架构上支持私有化部署;
- 远程直连 + 中继回退:客户端先尝试通过会合服务器进行 TCP 打洞建立直连,打洞失败时自动回退到中继连接。这一点在仓库中有直接源码证据——src/rendezvous_mediator.rs 中定义了
RendezvousMediator结构体(约 L102),其handle_punch_hole方法(约 L645)负责处理打洞消息PunchHole并调用punch_hole_sent向对端发送打洞报文; - 多平台覆盖:桌面端与移动端代码均包含在仓库内,当前仓库版本为 1.4.9(见 Cargo.toml),要求 Rust 工具链版本不低于 1.75(见 Cargo.toml)。
贡献流程可参考 docs/CONTRIBUTING.md。
二、构建依赖:GUI 框架与原生 C/C++ 库
2.1 GUI 依赖:Flutter 或 Sciter
README 明确指出:桌面版 GUI 使用 Flutter 或 Sciter(已标记为非推荐/废弃),官方教程为求简明只覆盖 Sciter 路线,Flutter 的构建方式需参考 CI 配置。从 Cargo.toml 可以看到 flutter 是一个可选编译 feature(flutter = ["flutter_rust_bridge"]),默认不启用;而在非 Android/iOS 目标上,sciter-rs 是条件依赖(Cargo.toml),这与"Sciter 用于旧版桌面 UI"的定位一致。
Sciter 动态库需要预先下载并放入构建产物目录:
| 平台 | 文件 |
|---|---|
| Windows | sciter.dll |
| Linux (x64) | libsciter-gtk.so |
| macOS | libsciter.dylib |
在 Linux 上构建时,需将该 .so 放入 target/debug/(或 release 输出目录),这一点在 entrypoint.sh 与 entrypoint.sh 中有直接体现:Docker 构建流程会先 cp "$HOME"/libsciter-gtk.so target/release/(或 debug 目录),再执行 cargo build。
2.2 vcpkg 管理原生编解码库
RustDesk 的视频编解码依赖一组 C/C++ 原生库,通过 vcpkg 安装。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
从源码结构看,这些依赖在仓库根目录的 vcpkg.json 中被完整声明,且实际依赖范围比 README 的入门命令更宽:
- 基础四件套
libvpx(VP8/VP9)、libyuv(像素格式转换)、opus(音频)、aom(AV1)均同时声明了host: true与host: false两份,用于跨目标构建; - 此外还包含
libjpeg-turbo、ffmpeg(并按平台启用amf/nvcodec/qsv三个硬件加速 feature,见 vcpkg.json)、mfx-dispatch(Intel Quick Sync 分发层)等,说明 RustDesk 在 x86/x64 的 Windows、Linux 静态构建中默认启用 NVENC / AMF / QSV 硬件编码能力; - 配置中指定了 overlay-ports(res/vcpkg 下的 aom、ffmpeg、libvpx、libyuv、mfx-dispatch、opus 各目录)与 overlay-triplets(res/vcpkg-triplets,含 Android 各 ABI 的 triplet 文件),即仓库自带针对这些端口的手工补丁,构建时会自动叠加。
这也解释了为什么 libs/scrap 源码中存在大量 FFI 绑定文件(如 libs/scrap/src/bindings/vpx_ffi.h、libs/scrap/src/bindings/aom_ffi.h、libs/scrap/src/bindings/yuv_ffi.h)以及 libs/scrap/src/common/hwcodec.rs、libs/scrap/src/common/vpx.rs 等硬件编解码实现——README 中列出的 4 个 vcpkg 依赖正是这些 FFI 层在链接期的实际来源。
三、Linux 各发行版的系统依赖
README 按发行版给出了完整的包安装命令,以下原样保留并可复制执行:
3.1 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
3.2 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
3.3 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
3.4 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
这些包名与 RustDesk Linux 侧的实际依赖一一对应:libxcb-* 与 libs/scrap/src/x11(X11 屏幕捕获)、libxdo/xdotool 与 libs/enigo/src/linux/xdo.rs(X11 键鼠模拟)、libasound2-dev/libpulse-dev 与 Cargo.toml 中的 libpulse-simple-binding / libpulse-binding(音频服务,对应 src/server/audio_service.rs)、libgstreamer* 则用于 Linux 的 GStreamer 采集/解码路径。值得注意的是,libs/scrap/src/wayland 与 src/server/wayland.rs 的存在表明 Wayland 后端也已纳入构建范围,而 Cargo.toml 中还通过 [patch.crates-io] 将 libxdo-sys 替换为本地 stub(libs/libxdo-sys-stub),以便在无 libxdo 的纯 Wayland 系统上也能构建运行。
3.5 安装 vcpkg(固定版本)
README 明确要求使用 2023.04.15 标签的 vcpkg,以保证与仓库 overlay 补丁兼容:
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
仓库的 Dockerfile 印证了这一约定:容器镜像同样以 --branch 2023.04.15 --depth=1 克隆 vcpkg 并执行 install libvpx libyuv opus aom,且设置了 VCPKG_FORCE_SYSTEM_BINARIES=1 强制使用系统二进制工具链。
3.6 libvpx 修正(仅 Fedora)
Fedora 上 libvpx 的 Makefile 缺少 -fPIC,会导致链接失败。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
即先配置再向 CFLAGS/CXXFLAGS 注入 -fPIC,重编后把静态库 libvpx.a 覆盖回 vcpkg 的 installed 目录,供后续 cargo 链接使用。
四、从零开始本地编译(Linux 完整流程)
汇总 README 的完整步骤:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
git clone 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
关键点说明:
VCPKG_ROOT环境变量必须指向 vcpkg 根目录,构建脚本(build.rs)会据此查找预编译的原生库;- 默认
cargo run走 debug 构建,产物位于target/debug/rustdesk; - 入口程序为 src/main.rs:在非 Flutter 构建下,主流程是
core_main()解析参数后调用ui::start(args)启动旧版 Sciter UI;而在 Android/iOS 或启用flutterfeature 的构建下,main 仅做global_init并探测会合服务器与 NAT 类型,真正的 UI 由 Flutter 侧承载(flutter 目录,含桌面端 flutter/lib/desktop 与移动端 flutter/lib/mobile 两套页面); - 可选编译 feature(Cargo.toml)包括
hwcodec(硬件编解码)、vram、mediacodec、drm(DRM 捕获,另含drm-wake子开关用于合成器空闲唤醒)、flutter等,可按需追加--features。
五、Docker 方式构建
README 推荐的隔离构建方式,适合宿主机不想安装全部依赖的场景:
git clone https://github.com/rustdesk/rustdesk
cd rustdesk
docker build -t "rustdesk-builder" .
每次构建 RustDesk 时执行:
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
要点解析(结合仓库实现):
- 首次构建较慢,但后续构建会复用
rustdesk-git-cache/rustdesk-registry-cache两个命名卷缓存的 cargo 依赖,显著提速; - 追加参数:在命令末尾直接传入 cargo 参数即可。例如追加
--release构建优化版本——这由 entrypoint.sh 解析:检测到--release时把libsciter-gtk.so复制到target/release/并置位 release 标志;还支持--target <triple>(entrypoint.sh)来添加交叉编译目标;最终统一执行VCPKG_ROOT=/vcpkg cargo build --locked $argv(entrypoint.sh),--locked保证依赖与 Cargo.lock 严格一致; - 产物位置:构建完成后在宿主机(即挂载进容器的
$PWD)下运行target/debug/rustdesk或target/release/rustdesk。注意install、run等子命令目前不支持在容器内直接执行,因为它会在容器而非宿主机上安装/运行程序; - 镜像细节:Dockerfile 基于
debian:bullseye-slim,源码级安装了与 README 第三节一致的 gcc/clang/gtk3/libxcb/libxdo/gstreamer 等包,额外从源码编译 CMake 3.30.6,并预装 libsciter-gtk.so,最后以非特权用户user(UID 通过PUID/PGID注入以对齐宿主机文件属主)执行构建。
六、仓库文件结构导读
README 的文件结构一节是理解 RustDesk 架构的最佳入口,以下结合当前仓库逐条展开:
| 路径 | 职责(README 说明 + 源码印证) |
|---|---|
| libs/hbb_common | 视频编解码封装、配置、TCP/UDP 包装、protobuf、文件传输所用 fs 函数及其他工具函数,是整个项目的公共基础层 |
| libs/scrap | 屏幕捕获。按后端分目录:x11、wayland、quartz(macOS)、dxgi(Windows),公共逻辑在 common(含 hwcodec、drm_reader/drm_render、mediacodec 等) |
| libs/enigo | 平台相关键鼠输入模拟,linux/macos/win 三套实现(如 libs/enigo/src/linux/xdo.rs) |
| libs/clipboard | Windows / Linux / macOS 的剪贴板与文件复制粘贴实现,Unix 平台代码位于 libs/clipboard/src/platform/unix |
| src/ui | 已被废弃的 Sciter UI(非推荐),仍保留 html/css/tis 资源与 src/ui/cm.rs、src/ui/remote.rs 等桥接代码 |
| src/server | 服务端各类服务:视频 video_service.rs、音频 audio_service.rs、剪贴板 clipboard_service.rs、输入 input_service.rs、终端 terminal_service.rs、显示 display_service.rs、连接管理 connection.rs、服务入口 service.rs 等 |
| src/client.rs | 建立对端(peer)连接,start 函数(约 L181)为客户端会话起点,并包含 start_video_thread(约 L2870)与 start_audio_thread(约 L3024)等媒体线程启动逻辑 |
| src/rendezvous_mediator.rs | 与会合/中继服务器通信,负责直接连接(TCP 打洞)与中继连接的协商,handle_punch_hole 为打洞核心实现 |
| src/platform | 平台特定代码:linux.rs、macos.rs、windows.rs 及 macOS 特权脚本 privileges_scripts |
| flutter | 桌面与移动端的 Flutter UI 代码,含 pubspec.yaml、Android/iOS/macOS/Windows/Linux 各平台工程目录与 flutter/lib 页面/组件 |
从入口 src/main.rs 的 #[cfg] 分支可以看出整体形态:同一份 Rust 内核(librustdesk)同时服务于旧版 Sciter UI、Flutter UI 与移动端,平台差异通过 #[cfg(target_os = ...)] 在 Cargo.toml 中按目标拆分为 winapi/cocoa/wayland 等依赖树,这是 RustDesk 能"一次内核、多端复用"的关键。
此外 libs 下还有 README 未列出的扩展模块,如 libs/virtual_display(虚拟显示器)、libs/portable(便携版)、libs/remote_printer(远程打印),它们分别对应 [[bin]] 之外的平台扩展能力。
七、版本与适用前提
- 本文所有步骤以当前仓库状态为准:版本 1.4.9(Cargo.toml),Rust 最低版本 1.75,edition 2021;
- vcpkg 必须固定到 2023.04.15 标签,与 Dockerfile 及 README 保持一致,否则 overlay 补丁(res/vcpkg)可能不兼容;
- Sciter 路线仅覆盖旧版桌面 UI,新 UI 构建请走 Flutter 路线(feature
flutter); - 构建产物运行需确保
libsciter-gtk.so(或其他平台 Sciter 库)位于同一目录,Docker 流程由 entrypoint.sh 自动处理,本地构建需手动放置; - README 同时附有不正使用免责说明:RustDesk 开发者不认可也不支持对本软件的非伦理或非法使用(未经授权访问、控制或侵犯隐私均属严格禁止行为)。
按上述流程操作后,你将能够独立完成 RustDesk 在三大 Linux 发行版族的源码构建、Docker 容器化构建,并借助 vcpkg.json、Dockerfile 与 entrypoint.sh 等构建配置文件,快速定位依赖版本、硬件编码开关与各平台捕获/输入后端的源码位置。
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 StartedRust0623
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