RustDesk 源码构建实战:Linux 依赖装配、vcpkg 原生库与 Docker 一键编译
本文以 RustDesk 官方 README 的构建章节为核心,完整讲解如何从零搭建 RustDesk 的本地开发环境:Rust 与 C++ 工具链准备、vcpkg 原生音视频库(libvpx / libyuv / opus / aom)的安装与 VCPKG_ROOT 配置、Ubuntu/Fedora/Arch 三大发行版的依赖安装命令,以及基于仓库自带 Dockerfile 的容器化构建流程。读完本文,你可以独立在 Linux 主机或 Docker 容器中编译出 debug / release 版本的可执行文件,并理解构建脚本与构建脚本(build.rs)背后的实现逻辑。
项目定位:一个用 Rust 编写的自托管远程桌面
RustDesk 是一个用 Rust 编写的远程桌面软件,无需任何配置即可工作,支持带安装或不带安装两种运行方式;数据完全由使用者自己掌控,不依赖第三方托管。网络层有三种可选方案:直接使用 RustDesk 的公共 rendezvous/relay 服务器、自建服务器、或自己实现一套服务器。社区也欢迎提交代码、翻译等任何形式的贡献,入门可参阅 docs/CONTRIBUTING.md。
当前仓库快照中,Cargo.toml 声明项目版本为 1.4.9,最低 Rust 版本要求为 rust-version = "1.75",主二进制名为 rustdesk,并额外提供 naming、service 两个辅助二进制(分别对应 src/naming.rs 与 src/service.rs)。
仓库文件结构(构建者视角)
官方文档给出的模块划分如下,这也是理解构建产物的关键地图:
| 路径 | 职责 |
|---|---|
| libs/hbb_common | 视频编解码封装、配置、tcp/udp 封装、protobuf、文件传输用的 fs 函数及其他工具函数 |
| libs/scrap | 屏幕捕获(screen capture) |
| libs/enigo | 各平台的键盘/鼠标控制 |
| src/ui | 桌面端 GUI |
| src/server | 音频/剪贴板/输入/视频服务与网络连接 |
| src/client.rs | 发起对端(peer)连接 |
| src/rendezvous_mediator.rs | 与 RustDesk 服务器通信,等待直连(TCP 打洞)或中继连接建立 |
| src/platform | 平台相关代码 |
| flutter | 移动端 Flutter 代码 |
从 Cargo.toml 的 workspace 定义可以看到,libs/scrap、libs/hbb_common、libs/enigo、libs/clipboard、libs/virtual_display、libs/portable、libs/remote_printer 均为同一个 Cargo workspace 的成员 crate,说明文档中列出的模块与实际的 crate 边界一致。
GUI 依赖:Sciter 动态库与 Flutter
文档明确说明:桌面版使用 Sciter 作为 GUI 引擎,需要使用者自行安装对应的动态库(Windows 为 sciter.dll、Linux 为 libsciter-gtk.so、macOS 为 libsciter.dylib,可从 sciter-sdk 项目下载对应平台版本);手机版使用 Flutter,并且后续桌面端也有可能从 Sciter 迁移到 Flutter。
这一点在仓库中已有明确痕迹:
- Cargo.toml 中
sciter-rs依赖被限定在非移动端平台(cfg(not(any(target_os = "android", target_os = "ios")))),同时存在flutter_rust_bridge可选依赖与flutter = ["flutter_rust_bridge"]feature 开关; - flutter/ 目录包含完整的 Android / iOS / Linux / macOS / Windows 平台工程;
- 从 src 目录结构看,
src/flutter.rs、src/flutter_ffi.rs等文件已经承担 Flutter 与 Rust 核心之间的桥接。
对于构建者而言,最直接的结论是:在 Linux 上跑 cargo run 之前,必须把 libsciter-gtk.so 放到目标输出目录,否则 GUI 进程加载不到该动态库。下文两条构建路线都会覆盖这一步。
构建前置条件:Rust/C++ 环境 + vcpkg 原生库
官方文档的构建准备步骤(Építési pontok 章节)要求:
- 准备好 Rust、C++ 开发环境(env);
- 安装 vcpkg,并正确设置
VCPKG_ROOT环境变量; - 按平台安装原生库:
- 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:
- 运行
cargo run。
这四个库分别对应 RustDesk 的核心能力:libvpx(VP8/VP9 视频编码)、aom(AV1)、libyuv(颜色格式转换)、opus(音频编码)。
VCPKG_ROOT 并非摆设,构建脚本确实会在编译期读取它。从 build.rs 源码看,Android 目标的构建会执行 std::env::var("VCPKG_ROOT") 取出 vcpkg 根目录(若设置了 VCPKG_INSTALLED_ROOT 则优先使用),再拼出 installed/<target>/lib 作为链接搜索路径,并链接 ndk_compat、c++、OpenSLES。这解释了文档反复强调"把 VCPKG_ROOT 设对"的原因——设错会导致链接阶段找不到原生库。
仓库本身还通过 vcpkg.json 声明了更完整的原生依赖清单,并使用本地 overlay ports 覆盖默认端口:
- 依赖列表:
aom、libjpeg-turbo、libsodium(Windows arm64)、opus、libvpx、libyuv、mfx-dispatch(x86/x64 的 Android/Linux 或 Windows 非 UWP 平台的硬件解码调度)、ffmpeg(静态链接时的 AMF/NVCodec/QSV 硬件编码特性)、Android 平台的cpu-features; - overlay ports 指向
./res/vcpkg,该目录下实际包含 res/vcpkg/aom、res/vcpkg/ffmpeg、res/vcpkg/libvpx、res/vcpkg/libyuv、res/vcpkg/mfx-dispatch、res/vcpkg/opus 等定制端口(补丁、portfile.cmake 与 vcpkg.json); - overlay triplets 指向 res/vcpkg-triplets,提供
x64-android.cmake、arm64-android.cmake、arm-neon-android.cmake、x86-android.cmake四个 Android 定制 triplet。
因此手动执行 vcpkg install libvpx libyuv opus aom 时,仓库根目录的 vcpkg.json 会自动套用这些 overlay 补丁,保证编出的静态库与 RustDesk 的链接要求兼容。
此外,Cargo.toml 定义了一批影响二进制形态的 feature 开关,按需加 --features 即可:hwcodec(启用 scrap 的硬件编解码)、vram(显存直通,依赖 hwcodec)、mediacodec(Android MediaCodec)、drm / drm-wake(Wayland DRM 捕获及其唤醒子开关)、flutter、inline、linux-pkg-config 等。
Linux 原生构建全流程
第一步:按发行版安装系统依赖
官方文档给出了三套发行版(Ubuntu 18 / Debian 10、Fedora 28 / CentOS 8、Arch / Manjaro)的一键安装命令:
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
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
这些包大体对应三类用途:C/C++ 编译工具链(gcc/g++/clang/cmake/nasm/yasm)、X11 与输入相关开发库(libxcb-*、libxdo、libXfixes、xdotool)、音频与 GUI 运行时(libasound2/pulseaudio/alsa、libgtk-3)。对照 libs/scrap/Cargo.toml 可印证:屏幕捕获的 Wayland 支持依赖 gstreamer 系列 crate(wayland feature 启用 gstreamer、gstreamer-app、gstreamer-video、dbus、zbus),Linux 目标还依赖 libpulse-binding、gtk、winit 等,系统库缺失会直接导致对应 crate 编译失败。
第二步:安装 vcpkg(固定 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
注意这里特意 git checkout 2023.04.15 固定了 vcpkg 版本。仓库中的 Dockerfile 同样以 --branch 2023.04.15 --depth=1 克隆 vcpkg 并安装 libvpx libyuv opus aom,两处版本保持一致——从源码结构看,这是为保证不同构建路径下原生库 ABI 一致而刻意钉住的版本。
第三步(仅 Fedora):修复 libvpx 的 -fPIC 问题
Fedora 上 vcpkg 编译 libvpx 时生成的 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
第四步:安装 Rust 并编译运行
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
# 从 sciter-sdk 下载 Linux x64 的 GUI 动态库
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=$HOME/vcpkg cargo run把 vcpkg 根目录以临时环境变量的形式注入本次 cargo 调用,构建脚本借此定位installed/x64-linux/lib下的静态库;libsciter-gtk.so必须放在 cargo 的输出目录(debug 构建为target/debug)内,进程启动时才能加载 GUI 引擎;- 若希望产物更小更快,可改用 release 配置——Cargo.toml 的
[profile.release]已开启lto = true、codegen-units = 1、panic = 'abort'、strip = true等体积优化选项。
Docker 构建:一条 build + 一条 run
对于不想污染宿主环境的场景,仓库提供了官方 Dockerfile。流程是:克隆仓库后构建构建器镜像:
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
首次构建会明显慢于后续构建,因为依赖尚未被两个 cargo 缓存卷(rustdesk-git-cache、rustdesk-registry-cache)缓存。构建完成后可执行文件直接出现在宿主机的 target 目录中:
target/debug/rustdesk
或 release 版本:
target/release/rustdesk
两条注意事项(原文强调):
- 务必确认命令在 RustDesk 仓库根目录执行,否则构建器找不到所需文件;
- 目前不支持
cargo install、cargo run等其他 cargo 子命令用于容器内构建,因为它们会在容器里直接启动程序而非产出宿主可用的二进制。
这些行为背后是 entrypoint.sh 的参数解析逻辑,值得逐行理解:
- 进入
$HOME/rustdesk并 source~/.cargo/env; - 扫描参数:遇到
--release时创建target/release目录、把libsciter-gtk.so复制进去,并置release=1;遇到--target <triple>时调用rustup target add <triple>增加交叉编译目标;其余参数原样保留; - 若非 release 构建,同样把
libsciter-gtk.so复制到target/debug/; - 最后以
VCPKG_ROOT=/vcpkg cargo build --locked <原参数>收尾。
因此 Docker 路线的"追加构建参数"方式就是把参数写在 docker run 命令末尾(如追加 --release 得到优化版 release 构建),entrypoint 会自动完成 sciter 库归位与 rustup target 安装。再看 Dockerfile 本体:基于 debian:bullseye-slim,安装 g++/gcc/nasm/yasm/libgtk-3-dev/clang/libxcb-*/libasound2-dev/libpulse-dev 等系统包(与上文 Ubuntu 发行版命令同源,另加 gstreamer 开发包、libssl、ninja),编译安装 CMake 3.30.6,固定克隆 vcpkg 2023.04.15 分支并安装四个原生库,预下载 libsciter-gtk.so,用 rustup 安装 Rust 工具链,并设置 VCPKG_FORCE_SYSTEM_BINARIES=1 让 vcpkg 复用系统二进制工具。
小结:构建路径选择与验证清单
- 日常开发(Linux):按发行版装系统依赖 → vcpkg 固定 2023.04.15 并安装四个原生库(Fedora 加做 libvpx -fPIC 修补)→ 放好
libsciter-gtk.so→VCPKG_ROOT=$HOME/vcpkg cargo run。 - 容器化 / 跨机器复现:
docker build一次,docker run任意次,产物落在宿主机target/debug/或target/release/。 - 验证要点:
VCPKG_ROOT指向的目录下存在installed/<triplet>/lib的静态库(build.rs 按此路径链接);输出目录中存在libsciter-gtk.so;需要硬件编解码时按 Cargo.toml 的 feature 列表追加--features(如hwcodec、drm)。
整套构建体系的设计目标很清晰:原生音视频能力全部收敛到 vcpkg 管理的静态库中,Rust 侧通过 workspace 内 scrap、hbb_common、enigo 等 crate 消费它们,GUI 引擎(Sciter,后续演进为 Flutter)以动态库形式随产物分发——理解这条"系统库 → vcpkg 静态库 → workspace crate → 二进制"的链路,就能覆盖 RustDesk 在各平台从源码到可执行文件的全部构建细节。
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