首页
/ RustDesk 源码构建实战:Linux 依赖装配、vcpkg 原生库与 Docker 一键编译

RustDesk 源码构建实战:Linux 依赖装配、vcpkg 原生库与 Docker 一键编译

2026-09-04 12:09:20作者:伍霜盼Ellen

本文以 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,并额外提供 namingservice 两个辅助二进制(分别对应 src/naming.rssrc/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/scraplibs/hbb_commonlibs/enigolibs/clipboardlibs/virtual_displaylibs/portablelibs/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.tomlsciter-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.rssrc/flutter_ffi.rs 等文件已经承担 Flutter 与 Rust 核心之间的桥接。

对于构建者而言,最直接的结论是:在 Linux 上跑 cargo run 之前,必须把 libsciter-gtk.so 放到目标输出目录,否则 GUI 进程加载不到该动态库。下文两条构建路线都会覆盖这一步。

构建前置条件:Rust/C++ 环境 + vcpkg 原生库

官方文档的构建准备步骤(Építési pontok 章节)要求:

  1. 准备好 Rust、C++ 开发环境(env);
  2. 安装 vcpkg,并正确设置 VCPKG_ROOT 环境变量;
  3. 按平台安装原生库:
    • 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
  4. 运行 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_compatc++OpenSLES。这解释了文档反复强调"把 VCPKG_ROOT 设对"的原因——设错会导致链接阶段找不到原生库。

仓库本身还通过 vcpkg.json 声明了更完整的原生依赖清单,并使用本地 overlay ports 覆盖默认端口:

  • 依赖列表:aomlibjpeg-turbolibsodium(Windows arm64)、opuslibvpxlibyuvmfx-dispatch(x86/x64 的 Android/Linux 或 Windows 非 UWP 平台的硬件解码调度)、ffmpeg(静态链接时的 AMF/NVCodec/QSV 硬件编码特性)、Android 平台的 cpu-features
  • overlay ports 指向 ./res/vcpkg,该目录下实际包含 res/vcpkg/aomres/vcpkg/ffmpegres/vcpkg/libvpxres/vcpkg/libyuvres/vcpkg/mfx-dispatchres/vcpkg/opus 等定制端口(补丁、portfile.cmake 与 vcpkg.json);
  • overlay triplets 指向 res/vcpkg-triplets,提供 x64-android.cmakearm64-android.cmakearm-neon-android.cmakex86-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 捕获及其唤醒子开关)、flutterinlinelinux-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 启用 gstreamergstreamer-appgstreamer-videodbuszbus),Linux 目标还依赖 libpulse-bindinggtkwinit 等,系统库缺失会直接导致对应 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 = truecodegen-units = 1panic = '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-cacherustdesk-registry-cache)缓存。构建完成后可执行文件直接出现在宿主机的 target 目录中:

target/debug/rustdesk

或 release 版本:

target/release/rustdesk

两条注意事项(原文强调):

  1. 务必确认命令在 RustDesk 仓库根目录执行,否则构建器找不到所需文件;
  2. 目前不支持 cargo installcargo 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.soVCPKG_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(如 hwcodecdrm)。

整套构建体系的设计目标很清晰:原生音视频能力全部收敛到 vcpkg 管理的静态库中,Rust 侧通过 workspace 内 scraphbb_commonenigo 等 crate 消费它们,GUI 引擎(Sciter,后续演进为 Flutter)以动态库形式随产物分发——理解这条"系统库 → vcpkg 静态库 → workspace crate → 二进制"的链路,就能覆盖 RustDesk 在各平台从源码到可执行文件的全部构建细节。

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

项目优选

收起
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.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.79 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
988
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384