RustDesk 源码构建实战:vcpkg 原生依赖、Docker 构建与核心模块结构解析
本文基于 RustDesk 仓库的阿拉伯语版 README(docs/README-AR.md)整理成文,系统讲解 RustDesk 桌面版的源码构建全流程:从 sciter 动态库与系统依赖的准备,到 vcpkg 安装音视频编码依赖(libvpx / libyuv / opus / aom)、Linux 发行版适配、Docker 容器化构建,再到项目核心目录结构(libs/hbb_common、libs/scrap、libs/enigo、src/server 等)的逐一对照。读完本文,你可以在 Ubuntu / Fedora / Arch 或 Docker 环境中从零编译出可运行的 rustdesk 可执行文件,并理解各模块在构建与运行时扮演的角色。
一、构建背景:RustDesk 的技术栈构成
RustDesk 是一个开源的自托管远程桌面应用(Remote Desktop for self-hosting),主程序完全用 Rust 编写。要构建它,需要先理解三个技术要点:
- 桌面 GUI 基于 sciter:非移动端(非 Android/iOS 且未启用 flutter feature 的目标)通过
sciter-rs绑定加载 sciter 动态库来渲染界面。这一点可以在根 Cargo.toml 中得到印证——[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]段中声明了sciter-rs依赖;构建完成后必须把对应平台的 sciter 动态库放到可执行文件旁边(见后文),否则运行时会找不到资源。 - 移动端基于 Flutter:仓库中的 flutter/ 目录(包含
lib/下的 Dart 代码与 android/ios 工程)承载手机与平板端实现,README 也说明了桌面端正在从 sciter 向 Flutter 迁移。 - 音视频编解码依赖 C/C++ 原生库:屏幕视频流的编码依赖 libvpx(VP8/VP9)、aom(AV1)、libyuv(色彩空间转换)与 opus(音频),这些原生库通过 vcpkg 统一安装,这也是构建流程中最容易出错的环节。
从根 Cargo.toml 可以看到当前包版本为 1.4.9,最低 Rust 版本要求为 1.75(rust-version = "1.75"),构建前请确认工具链满足要求。
二、前置依赖:sciter 动态库
桌面版使用 sciter 作为 GUI 框架,需要你自行下载对应平台的动态库,并在运行时将其与可执行文件放在同一目录:
| 平台 | 动态库文件 |
|---|---|
| Windows | sciter.dll(x64) |
| Linux | libsciter-gtk.so(x64) |
| macOS | libsciter.dylib |
官方文档给出了各平台的下载直链(sciter-sdk 仓库的 bin.win/bin.lnx/bin.osx 目录)。Docker 构建镜像中这一动作是自动化的:Dockerfile 执行了 wget .../c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so 并缓存到用户主目录,供后续 entrypoint 复制到 target/debug/。
三、Linux 各发行版的系统依赖
README 按发行版给出了完整的系统包安装命令,以下逐一继承并说明用途(编译器工具链、X11/Wayland 相关开发头文件、音频库等):
Ubuntu 18 / Debian 10
sudo apt install -y 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
要点:libgtk-3-dev 服务于 GTK 依赖(sciter 的 GTK 版动态库需要 GTK3 运行库);libxcb-*-dev 系列与 libxdo-dev 服务于屏幕捕获与 X11 输入模拟(对应 libs/scrap 的 X11 后端与 libs/enigo 的 xdo.rs 实现);libasound2-dev/libpulse-dev 服务于 ALSA/PulseAudio 音频路径。
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
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 看到,容器构建走的是与 Ubuntu 一致的 apt 方案,并额外安装了 libssl-dev(Linux 目标下 openssl 采用 vendored 特性,见 Cargo.toml)、libgstreamer1.0-dev、ninja-build 等;CMake 则是从源码编译了 3.30.6 版本。
四、vcpkg:原生编解码依赖的安装
标准安装步骤
按照 README 的说明,需要正确设置 VCPKG_ROOT 环境变量并安装 vcpkg,然后执行:
# 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
Windows 上使用 -static triplet 意味着以静态库形式链接,避免运行时分发 DLL。
仓库实际的依赖清单
根目录的 vcpkg.json 是 vcpkg 的真实依赖清单(manifest 模式),其中除 README 提到的四件套外还包含更多项,按用途可以这样理解:
- 视频编码:
aom、libvpx(均同时声明host: true与host: false,前者用于构建期工具链,后者用于目标产物); - 色彩转换:
libyuv; - 音频编码:
opus; - 图像:
libjpeg-turbo; - 硬件编码(条件依赖):
ffmpeg(在windows | (linux & !arm32) | osx且 static 平台下启用,并可开启amf/nvcodec/qsvfeature)与mfx-dispatch(Intel 硬编)——对应 Cargo.toml 中的hwcodec/vram编译开关; - Android 专用:
cpu-features(platform: android)。
清单还通过 vcpkg-configuration 把 overlay-ports 指向 res/vcpkg、overlay-triplets 指向 res/vcpkg-triplets:前者包含对 aom / ffmpeg / libvpx / libyuv / mfx-dispatch / opus 各端口(port)的定制补丁(例如 res/vcpkg/aom/aom-avx2.diff、ffmpeg 的 11 个 patch 文件),后者提供 x64-android.cmake、arm64-android.cmake 等 Android triplet。也就是说,直接 vcpkg install 时这些定制补丁会自动生效,这解释了为什么仓库能控制原生库的构建细节。
Linux 上按 README 的完整安装流程
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 固定 checkout 到 2023.04.15 分支;Dockerfile 同样使用 --branch 2023.04.15 --depth=1 克隆 vcpkg 并设置 VCPKG_FORCE_SYSTEM_BINARIES=1,两者保持一致,可以按此版本锁定依赖以确保构建可复现。
Fedora 下的 libvpx 修复(README 原始步骤)
在 Fedora 上直接安装 libvpx 可能因缺少 -fPIC 导致链接失败,README 给出的修复流程是进入 vcpkg 的构建产物目录,用 sed 给 Makefile 注入 -fPIC 后重新编译并把静态库拷回:
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
五、本地完整构建流程
README 给出的 Linux 端到端构建命令如下(继承原文):
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
逐步解读:
rustup安装 Rust 工具链并加载环境;- 克隆仓库后 手动创建
target/debug并放入libsciter-gtk.so:这是桌面版运行的硬要求——程序启动时需要在可执行文件所在目录找到 sciter 动态库(src/main.rs 的main会调用core_main::core_main()解析参数后进入ui::start(args)启动 sciter 界面); - 以
VCPKG_ROOT指向 vcpkg 目录运行cargo run,vcpkg 的 manifest 模式会自动读取 vcpkg.json 完成原生依赖构建与链接。
补充说明:根 Cargo.toml 除了默认二进制 rustdesk 外还声明了 naming(src/naming.rs)与 service(src/service.rs)两个 bin,分别用于命名工具与系统服务;[profile.release](Cargo.toml)开启了 LTO、strip、codegen-units = 1 等瘦身优化,因此 release 构建更慢但产物更小。常用 feature 包括 flutter(编译 Flutter 桥接)、hwcodec(硬件编码)、drm/drm-wake(Linux DRM 捕获,drm-wake 在 drm 之上额外编译显示唤醒代码)、mediacodec、screencapturekit 等,可按平台需求用 cargo run --features ... 追加。
六、Docker 构建方式
README 推荐的容器化构建分两步:
第一步:克隆仓库并构建构建镜像
git clone https://github.com/rustdesk/rustdesk
cd rustdesk
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
参数说明:rustdesk-git-cache 与 rustdesk-registry-cache 两个命名卷分别缓存 cargo 的 git 依赖与 crates 索引,首次构建较慢(需存储全部依赖),之后构建会明显加快;PUID/PGID 让容器内产物与宿主机用户权限一致。
传递额外构建参数:在命令末尾追加参数即可,例如构建优化版时追加 --release,得到的可执行文件位于:
# 默认(debug)构建
target/debug/rustdesk
# 追加 --release 后
target/release/rustdesk
这些行为可以在 entrypoint.sh 中得到源码级印证:脚本 cd "$HOME"/rustdesk 后逐个解析参数,遇到 --release 时 mkdir -p target/release 并把 libsciter-gtk.so 复制过去,遇到 --target <triple> 时调用 rustup target add 支持交叉编译,最后统一执行 VCPKG_ROOT=/vcpkg cargo build --locked $argv(--locked 保证依赖版本与 Cargo.lock 完全一致,进一步提升可复现性)。
README 特别提醒两点注意事项(原文继承):
- 必须在 RustDesk 仓库根目录下执行上述命令,否则应用可能找不到所需资源;
install、run等子命令当前不支持通过该方式透传,因为它们会试图在容器内部安装/运行程序,而不是宿主机上。
七、文件结构:核心模块逐一对照
README 的「File structure」一节列出了项目的主要目录,结合仓库实际结构对照如下(原条目中的 GitHub 路径已转换为仓库内相对路径):
| 模块 | 职责(README 描述) | 仓库内补充证据 |
|---|---|---|
| libs/hbb_common | 视频编码、文件传输、tcp/udp、部分其他工具函数与配置 | 根 crate 与其 workspace 均依赖它(Cargo.toml),同时被用作 build-dependencies(Cargo.toml) |
| libs/scrap | 屏幕捕获 | 内部按后端组织:src/x11/、src/wayland/、src/dxgi/(Windows)、src/quartz/(macOS)、src/common/drm_reader.rs 等,并提供 screenshot.rs、record-screen.rs 等示例 |
| libs/enigo | 各平台键盘/鼠标控制 | 分平台实现:src/linux/(含 xdo.rs)、src/macos/、src/win/,另有跨平台 DSL(src/dsl.rs) |
| src/ui | 桌面图形界面(sciter) | 包含 cm.tis/remote.tis/file_transfer.tis 等 TIS 脚本与对应 CSS、HTML,以及 src/ui/cm.rs、src/ui/remote.rs 等 Rust 桥接 |
| src/server | 音频/剪贴板/输入/视频等服务与网络连接 | video_service.rs、audio_service.rs、clipboard_service.rs、input_service.rs、display_service.rs、terminal_service.rs 等 |
| src/client.rs | 发起连接 | 配套 src/client/ 目录(io_loop.rs、file_trait.rs、screenshot.rs、helper.rs) |
| src/rendezvous_mediator.rs | 与 rustdesk-server 建连、等待直连或远程打洞(TCP hole punching) | 配合 stunclient 依赖(Cargo.toml)实现 NAT 类型探测与打洞 |
| src/platform | 各平台特有代码 | linux.rs、macos.rs、windows.rs、delegate.rs、gtk_sudo.rs(Linux 提权)等 |
| flutter/ | 移动端代码 | lib/ 下按 desktop/、mobile/、web/、models/、native/ 组织的 Dart 代码,以及 android/ios 平台工程与 flutter/README.md |
从 Cargo.toml 的 workspace 声明看,libs/scrap、libs/hbb_common、libs/enigo、libs/clipboard、libs/virtual_display(及其 dylib)、libs/portable、libs/remote_printer 都是工作区成员,cargo run 在根目录会一并解析它们。此外 Cargo.toml 还通过 [patch.crates-io] 把 libxdo-sys 替换为仓库内的 libs/libxdo-sys-stub,使得在没有安装 libxdo 的系统(例如纯 Wayland 环境)也能构建运行——这是对 README 依赖清单之外的一个实用细节。
八、小结:构建路径选择建议
- 本地开发调试:按第三节安装系统包 → 第四节安装 vcpkg 依赖(Fedora 用户记得做 libvpx 修复)→ 第五节执行
cargo run,把 sciter 动态库放入target/debug/后即可运行。 - CI 或无头环境、希望零环境配置:直接采用第六节 Docker 方案,利用命名卷缓存获得更快的二次构建;需要优化版时追加
--release。 - 需要硬件编码/Flutter/DRM 等能力:在第五节命令基础上按 Cargo.toml 的
[features]追加--features组合。 - 参与开发:构建与贡献规范可参考 docs/CONTRIBUTING.md,多语言界面文案维护在 src/lang/ 目录(阿拉伯语即
ar.rs)。
以上所有命令与路径均基于当前仓库的实际文件内容,构建前请以 docs/README-AR.md 原文及仓库内 Dockerfile、vcpkg.json、entrypoint.sh 为准核对版本细节(尤其是 vcpkg 固定版本 2023.04.15 与 sciter 动态库的放置位置)。
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