首页
/ RustDesk 构建实战:从 vcpkg 依赖、Linux 原生编译到 Docker 构建的完整指南

RustDesk 构建实战:从 vcpkg 依赖、Linux 原生编译到 Docker 构建的完整指南

2026-09-05 14:49:36作者:钟日瑜

本篇指南围绕 RustDesk 仓库中的 韩国语 README 展开,系统讲解如何从源码构建这款用 Rust 编写的自托管远程桌面应用:包括 vcpkg 原生库准备、各 Linux 发行版的系统依赖安装、Docker 容器化构建的完整流程,以及仓库各源码模块的职责划分。读完后,你能够独立完成一次从干净环境到可运行二进制的完整构建,并理解每个构建步骤背后的源码依据。

项目定位与构建入口

RustDesk 是一个开源远程桌面方案,定位为 TeamViewer 的自托管替代品:数据完全掌握在自己手中,可以直接使用官方 rendezvous/relay 服务器,也可以自行部署服务器或编写自己的服务器。它支持无配置直接连接,也支持完整的私有化部署。

当前仓库版本的构建入口由 Cargo.toml 定义,几个关键事实如下:

  • 包名 rustdesk,版本 1.4.9,default-run = "rustdesk",因此直接 cargo run / cargo build 就会构建主程序;
  • rust-version = "1.75",即 Rust 工具链的最低要求为 1.75;
  • 工作区成员(Cargo.toml[workspace] 段)包含 libs/scraplibs/hbb_commonlibs/enigolibs/clipboardlibs/virtual_display(及其 dylib 子 crate)、libs/portablelibs/remote_printer 等;
  • 库目标同时产出 cdylibstaticlibrlib,供 Flutter 前端等不同宿主链接使用;
  • 额外还编译两个辅助二进制:naming(对应 src/naming.rs)和 service(对应 src/service.rs)。

桌面端 GUI 使用 Flutter 或 Sciter。官方文档标注 Sciter 已被弃用,但当前构建流程仍会准备 libsciter-gtk.so 动态库(Dockerfile 与 Docker 构建入口脚本都会拷贝它),构建产物在运行 Sciter UI 路径时仍可能依赖该库。

构建前置条件:Rust、C++ 与 vcpkg

构建 RustDesk 需要准备三类环境:Rust 开发环境、C/C++ 构建环境、vcpkg 原生依赖。

Rust 与 C++ 环境

  • Rust 工具链:rustup 安装,要求版本不低于 1.75;
  • C/C++ 工具链:gcc/g++ 或 clang。vcpkg 默认优先使用 clang 构建 C 代码(可通过 VCPKG_FORCE_SYSTEM_BINARIES 控制,见下文 Docker 部分)。

vcpkg 原生依赖

vcpkg 负责提供视频/音频编解码相关的原生库。先安装 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

仓库根目录的 vcpkg.json 是完整依赖清单,它声明的核心依赖与文档中手动安装的四件套(libvpx、libyuv、opus、aom)一致,此外还包含:

  • libjpeg-turbolibsodium(仅 Windows ARM64)、mfx-dispatch(Intel 硬件编解码分发);
  • ffmpeg,并按平台启用 amf(AMD)、nvcodec(NVIDIA)、qsv(Intel,仅 Windows)等特性;
  • 通过 overlay-ports 指向 res/vcpkg 目录的定制端口(包括 aom、ffmpeg、libvpx、libyuv 等打过补丁的版本),通过 overlay-triplets 指向 res/vcpkg-triplets 的 Android 交叉编译 triplet。

准备好环境后,最简单的本地构建命令就是:

cargo run

按发行版安装系统依赖(Linux)

不同发行版需要的开发包名称不同,官方 README 给出了四套命令,均保持完整可复制:

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

从依赖集合可以看出编译期需要的能力:nasm/yasm 用于汇编(编解码器),libxcb-*/libxfixes/libxdo 对应 X11 屏幕抓取与输入模拟(对应 libs/scraplibs/enigo 的 Linux 实现),libasound2-dev/libpulse-dev 对应音频采集,gstreamergtk3 则支撑 Linux 平台的多媒体与窗口集成。Cargo.toml 的 Linux 目标依赖也印证了这一点,例如 libxdo-syspulse(libpulse-simple-binding)、dbusgtk = "0.18" 等。值得注意的是,[patch.crates-io]libxdo-sys 打补丁到本地 libs/libxdo-sys-stub,使项目可以在未安装 libxdo 的系统(如纯 Wayland 环境)上编译。

vcpkg 安装与 Fedora 的 libvpx 修补

Linux 下安装 vcpkg 的官方步骤(固定在 2023.04.15 版本,与 Dockerfile 中的版本一致):

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

Fedora 上 libvpx 构建产物缺省不带 -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

这一步的原因:共享库和会被链入动态库的静态库必须带位置无关代码(PIC)属性,Fedora 的 GCC 默认行为与 Debian 不同,导致 libvpx 静态库链接失败。

原生完整构建流程

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 不可省略:核心 crate libs/hbb_common(视频编解码封装、配置、tcp/udp wrapper、protobuf、文件传输的 fs 函数等)是 git 子模块,若未初始化则工作区成员目录为空,构建直接失败;
  • Sciter 动态库需要放在目标输出目录(这里放在 target/debug),否则运行期加载 Sciter UI 会失败;
  • VCPKG_ROOT 必须指向 vcpkg 安装目录,cargo 构建脚本据此找到原生库。

Docker 构建方式

Docker 路径适合不想在宿主机安装整套工具链的场景。仓库根目录提供了 Dockerfile,基础镜像为 debian:bullseye-slim,容器内一次性装好:gcc/g++、git、curl、nasm、yasm、libgtk-3-dev、clang、各 libxcb/libxfixes/libxdo 开发包、libasound2/libpulse、gstreamer、ninja-build,并从源码编译 CMake 3.30.6,再安装 vcpkg 2023.04.15libvpx libyuv opus aom,同时预下载 libsciter-gtk.so、安装 rustup 工具链。构建步骤:

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:把宿主机仓库挂载到容器工作目录,构建结果直接写回宿主机;
  • 两个 cargo 命名卷缓存:git 依赖与 registry 缓存跨构建复用,首次构建需编译全部依赖,速度较慢,之后显著加快;
  • PUID/PGID:让容器内 user 的 UID/GID 与宿主一致,避免产物文件属主问题。

传入 docker run 的额外参数由仓库根目录的 entrypoint.sh 处理,其逻辑从源码看非常清晰:

  • --release:设置 release 模式,并把 libsciter-gtk.so 拷贝到 target/release/;
  • --target <triple>:调用 rustup target add 支持交叉编译;
  • 其余参数原样透传给最终命令:
VCPKG_ROOT=/vcpkg cargo build --locked $argv

即最终执行的是 cargo build --locked,保证依赖版本锁定。构建产物在宿主机仓库目录中:

target/debug/rustdesk      # 默认(debug)构建
target/release/rustdesk    # 追加 --release 参数

两个注意事项(来自文档与源码行为):

  • 命令必须在仓库根目录执行,否则应用可能找不到所需资源;
  • cargo installcargo run 这类子命令不受支持,因为容器入口固定执行 cargo build,而安装/运行发生在容器内而非宿主机上。

另外 Cargo.toml[profile.release] 启用了 lto = truecodegen-units = 1panic = 'abort'strip = true,release 构建会做链接期优化并裁剪符号,产物体积更小,但编译耗时也更长。

可选编译特性

--release 外,cargo 的 feature 开关决定了构建出的二进制包含哪些能力(Cargo.toml [features] 段):

Feature 作用
flutter 启用 flutter_rust_bridge,构建 Flutter UI 所需的桥接
hwcodec 硬件编解码(依赖 scrap 的 hwcodec)
vram 显存直接读取路径
mediacodec Android MediaCodec 支持
drm / drm-wake Wayland/DRM 屏幕抓取;drm-wake 额外包含唤醒空闲关闭显示输出的注入逻辑(源码注释说明该逻辑与纯抓取是不同性质的操作,可独立裁剪)
linux-pkg-config Linux 下通过 pkg-config 查找 opus/scrap 依赖,而不是走 vcpkg
use_dasp(默认) 音频重采样后端,可选 use_rubatouse_samplerate 替换

例如只构建 DRM 抓取路径而不包含显示唤醒代码,可使用 --features drm;包含唤醒逻辑则用 --features drm-wake

仓库文件结构与核心模块

文档给出的文件结构是理解 RustDesk 代码组织的地图,以下各条目均与仓库实际目录对应,并结合源码做了补充:

  • libs/hbb_common:视频编解码封装、配置、tcp/udp wrapper、protobuf、文件传输的 fs 函数及通用工具。该目录是 git 子模块(见 .gitmodules),克隆后需执行 git submodule update --init --recursive 初始化;
  • libs/scrap:屏幕抓取,按平台拆分为 x11、wayland、quartz(macOS)、dxgi/watermark 等抓取源,并提供 vpx、aom、mediacodec、drm 等编解码/采集后端;
  • libs/enigo:跨平台键盘/鼠标控制,含 linux(nix/xdo)、macos、win 三套实现与 DSL 封装;
  • libs/clipboard:Windows、Linux、macOS 的文件与文本剪贴板实现;
  • src/ui:已弃用的 Sciter UI(tis/html/css 与 cm.rsremote.rs 等);
  • src/server:音频/剪贴板/输入/视频服务与网络连接,包括 video_service.rsaudio_service.rsinput_service.rsdisplay_service.rsclipboard_service.rs 等;
  • src/client.rs:客户端连接发起入口,其中的 pub async fn start(...)(src/client.rs#L181)负责建立与被控端的会话;
  • src/rendezvous_mediator.rs:与 rendezvous/relay 服务器通信,等待直连(TCP 打洞成功)或中继连接建立——该文件是 NAT 穿透逻辑的核心;
  • src/platform:平台相关代码,含 windows(ACL、MSI 注册表、服务交互)、macos、linux、特权安装脚本等;
  • flutter:桌面与移动端 Flutter 前端,lib/ 下按 desktopmobilemodelsutils 等模块组织,通过 flutter_rust_bridge 与 Rust 核心通信。

从源码结构看,一次远程会话的路径大致是:Flutter UI 经 FFI 调用 src/client.rs::start 发起连接,由 rendezvous_mediator.rs 向服务器发起 rendezvous 握手并完成打洞/中继协商,成功后客户端与 src/server 中各服务模块(视频、音频、输入、剪贴板)建立对应通道。

小结与验证要点

按本文流程构建时,可逐项自检:

  1. VCPKG_ROOT 已导出且 vcpkg 中四个核心库安装成功(libvpxlibyuvopusaom);
  2. 子模块已初始化,libs/hbb_common 目录非空;
  3. Sciter 动态库已放入 target/debug(或 target/release);
  4. 产物 target/debug/rustdesktarget/release/rustdesk 可执行,且执行位置为仓库根目录。

整套构建链(原生 + Docker)都以当前仓库的 Dockerfileentrypoint.shvcpkg.jsonCargo.toml 为准;若仓库更新导致依赖版本变化,请以这些文件中的实际声明为准。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
504
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384