scrcpy 源码编译完全指南:从系统依赖安装到跨平台交叉编译
本文基于 scrcpy 仓库的官方构建文档 doc/build.md 编写,覆盖客户端(C/SDL2/FFmpeg)与服务端(Android APK)两套构建产物的完整流程:环境依赖安装、Meson/Ninja 构建命令、预编译服务端替代方案,以及官方发布流水线中的交叉编译做法。读完之后,你可以在 Linux、Windows、macOS 上独立构建出可运行、可安装的 scrcpy,并理解每个构建选项在源码中对应的实际行为。
使用哪个分支:master 与 dev
仓库有两个主要分支,构建前需要先搞清楚自己拿到的代码处于哪个状态:
master:包含最新的正式发行版(release),是项目的默认主页分支;dev:当前开发分支,dev上的每个提交都会进入下一个发行版。
如果你打算贡献代码,应基于最新的 dev 分支发起提交。就“构建并得到一个稳定可发布的二进制”而言,选择 master 即可——官方发布物正是从该分支流程生成的(本仓库当前版本号为 3.3.4,见 meson.build 中的 version: '3.3.4')。
如果只需要安装最新发行版而不想自己编译,可参考简化的安装流程 doc/linux.md。
构建前置条件
adb
构建(以及后续运行)需要 adb。它包含在 Android SDK platform-tools 中,或由发行版直接打包(包名 adb)。
在 Windows 上,需要下载 platform-tools 压缩包,并把以下文件解压到 PATH 可访问的目录:
adb.exeAdbWinApi.dllAdbWinUsbApi.dll
scrcpy 的发行版打包中也附带了这些文件(见 release/build_windows.sh 末尾将 adb 产物拷贝进 dist/ 的步骤)。
FFmpeg 与 LibSDL2
客户端要求 FFmpeg 和 LibSDL2,按各自官方说明安装即可。构建脚本对最低版本有明确要求,见 app/meson.build:
| 依赖 | 最低版本 | 备注 |
|---|---|---|
libavformat |
>= 57.33 |
FFmpeg 容器读写 |
libavcodec |
>= 57.37 |
FFmpeg 编解码 |
libavutil |
任意(随 FFmpeg) | FFmpeg 基础库 |
libswresample |
任意(随 FFmpeg) | 音频重采样 |
sdl2 |
>= 2.0.5 |
窗口与事件处理 |
libavdevice |
视功能 | 仅当启用 V4L2 时(Linux 专属) |
libusb-1.0 |
视功能 | 仅当启用 HID/OTG 时 |
最后两条是可选的:V4L2 特性只在 Linux 下启用且额外依赖 libavdevice,USB HID/OTG 特性依赖 libusb-1.0(见 app/meson.build 中 v4l2_support 与 usb_support 的条件编译逻辑)。
分系统的依赖安装
Linux
从包管理器安装所需包。
Debian/Ubuntu
# runtime dependencies
sudo apt install ffmpeg libsdl2-2.0-0 adb libusb-1.0-0
# client build dependencies
sudo apt install gcc git pkg-config meson ninja-build libsdl2-dev \
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev \
libswresample-dev libusb-1.0-0-dev
# server build dependencies
sudo apt install openjdk-17-jdk
在较老的系统上(例如 Ubuntu 16.04),meson 版本过旧,此时可以从 pip3 安装:
sudo apt install python3-pip
pip3 install meson
Fedora
# enable RPM fusion free
sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
# client build dependencies
sudo dnf install SDL2-devel ffms2-devel libusb1-devel libavdevice-free-devel meson gcc make
# server build dependencies
sudo dnf install java-devel
Windows
方式一:从 Linux 交叉编译(推荐,也是官方发布物的构建方式)
在 Debian 上安装 mingw 工具链:
sudo apt install mingw-w64 mingw-w64-tools libz-mingw-w64-dev
构建服务端还需要 JDK:
sudo apt install openjdk-17-jdk
然后在仓库根目录执行发布脚本:
./release.sh
从源码看,release/release.sh 会依次执行服务端测试、客户端测试、服务端构建、build_windows.sh 32/64、build_linux.sh x86_64,最后打包并生成 SHA-256 校验和,产物汇总在 release/output/ 中。其中 release/build_windows.sh 的关键步骤:
- 通过 app/deps/ 下的脚本(
sdl.sh、ffmpeg.sh、dav1d.sh、libusb.sh、adb_windows.sh)从源码构建 Win32/Win64 依赖并安装到统一目录; - 调用
meson setup时传入--cross-file=cross_win32.txt或cross_win64.txt(仓库根目录下的交叉编译配置 cross_win32.txt、cross_win64.txt),并带上--buildtype=release --strip -Db_lto=true -Dcompile_server=false -Dportable=true; - 把
scrcpy.exe、scrcpy-console.bat、scrcpy-noconsole.vbs、图标、依赖 DLL 和 adb 文件汇集到该架构的dist/目录。
注意发布构建中使用了 -Dcompile_server=false:Windows 客户端的发布包并不内嵌服务端,服务端另行单独发布(见下文“预编译服务端”)。
方式二:在 MSYS2 中直接编译
在 Windows 上需要 MSYS2 环境。从 MSYS2 终端安装所需包:
# runtime dependencies
pacman -S mingw-w64-x86_64-SDL2 \
mingw-w64-x86_64-ffmpeg \
mingw-w64-x86_64-libusb
# client build dependencies
pacman -S mingw-w64-x86_64-make \
mingw-w64-x86_64-gcc \
mingw-w64-x86_64-pkg-config \
mingw-w64-x86_64-meson
如需 32 位版本,把 x86_64 替换为 i686:
# runtime dependencies
pacman -S mingw-w64-i686-SDL2 \
mingw-w64-i686-ffmpeg \
mingw-w64-i686-libusb
# client build dependencies
pacman -S mingw-w64-i686-make \
mingw-w64-i686-gcc \
mingw-w64-i686-pkg-config \
mingw-w64-i686-meson
MSYS2 不提供 Java,所以如果要构建服务端,需手动安装 Java 并加入 PATH:
export PATH="$JAVA_HOME/bin:$PATH"
执行后续通用构建步骤时,请确认使用的是 MSYS2 内的 MinGW 终端,而不是普通的 Windows CMD/PowerShell。
macOS
用 Homebrew 安装:
# runtime dependencies
brew install sdl2 ffmpeg libusb
# client build dependencies
brew install pkg-config meson
如果要构建服务端,另外安装 Java 17 并加入 PATH:
brew install openjdk@17
export JAVA_HOME="$(/usr/libexec/java_home --version 1.17)"
export PATH="$JAVA_HOME/bin:$PATH"
JAVA_HOME 的取值需与实际安装的 JDK 匹配,如提示版本不存在,请按本机 JDK 实际情况调整版本参数。
Docker
原构建文档同时推荐了 Docker 方案,指引到一个第三方的 scrcpy-docker 镜像项目,适合希望隔离依赖环境的场景(本文按仓库要求不给出外部链接)。
通用构建步骤
克隆代码
以非 root 用户克隆项目:
git clone https://gitcode.com/GitHub_Trending/sc/scrcpy
cd scrcpy
构建
可以只构建客户端:即将推送到 Android 设备的服务端二进制与你的系统和架构无关。这时可以直接使用预编译服务端,从而不需要 Java 和 Android SDK。
方案一:从源码构建全部组件
安装 Android SDK(例如通过 Android Studio),并把 ANDROID_SDK_ROOT 指向其目录:
# Linux
export ANDROID_SDK_ROOT=~/Android/Sdk
# Mac
export ANDROID_SDK_ROOT=~/Library/Android/sdk
# Windows
set ANDROID_SDK_ROOT=%LOCALAPPDATA%\Android\sdk
然后构建:
meson setup x --buildtype=release --strip -Db_lto=true
ninja -Cx # DO NOT RUN AS ROOT
注意:ninja 必须以非 root 用户执行(只有 ninja install 需要 root)。这一约束在服务端构建的包装脚本中有明确体现:server/scripts/build-wrapper.sh 检测到 root(EUID == 0)时会直接跳过 Gradle 调用并打印提示,目的是避免在 root 下触发 Gradle 下载整套依赖污染 /root/.gradle。
从源码链路看,服务端的构建过程是:server/meson.build 注册了一个 custom_target,调用 server/scripts/build-wrapper.sh,再由其调用仓库根目录的 gradlew(Gradle wrapper)执行 assembleRelease(debug 构建时执行 assembleDebug),最后把 server/build/outputs/apk/release/server-release-unsigned.apk 拷贝为 scrcpy-server 并安装到 share/scrcpy 目录。客户端则不受 ANDROID_SDK_ROOT 影响——真正需要它的是这条 Gradle 链路。
方案二:使用预编译服务端
使用与当前 master 分支匹配的发行版服务端 scrcpy-server-v3.3.4(SHA-256:8588238c9a5a00aa542906b6ec7e6d5541d9ffb9b5d0f6e1bc0e365e2303079e,可从项目 v3.3.4 发行版工件中获取),下载后在 Meson 配置阶段指定路径:
meson setup x --buildtype=release --strip -Db_lto=true \
-Dprebuilt_server=/path/to/scrcpy-server
ninja -Cx # DO NOT RUN AS ROOT
两点说明:
- 服务端只与匹配版本的客户端兼容(这份服务端对应
master分支,即当前 3.3.4); - 从 server/meson.build 可以看到,
-Dprebuilt_server指定的是相对路径时,会相对仓库根目录解析(脚本内自动补../前缀),构建时该文件会被原样拷贝为scrcpy-server并安装到share/scrcpy。
Meson 配置选项详解
除 --buildtype、--strip、-Db_lto 等 Meson 通用选项外,项目自定义了以下选项(定义在 meson_options.txt):
| 选项 | 类型 | 默认值 | 作用 |
|---|---|---|---|
compile_app |
boolean | true |
是否构建客户端 |
compile_server |
boolean | true |
是否构建服务端 |
prebuilt_server |
string | 空 | 预编译服务端的路径(设置后跳过 Gradle 构建,直接拷贝) |
portable |
boolean | false |
让 scrcpy 从可执行文件同目录查找 scrcpy-server |
static |
boolean | false |
使用静态链接的依赖 |
server_debugger |
boolean | false |
启动服务端调试器并等待客户端附加 |
v4l2 |
boolean | true |
在受支持时启用 V4L2 特性(Linux,依赖 libavdevice) |
usb |
boolean | true |
在受支持时启用 HID/OTG 特性(依赖 libusb-1.0) |
这些选项如何落地,可以从 meson.build 与 app/meson.build 中一一对应:
compile_app/compile_server控制是否进入subdir('app')与subdir('server')(meson.build);v4l2只在host_machine.system() == 'linux'时真正生效,并会额外链接libavdevice、编译 app/src/v4l2_sink.c;usb选项则决定 app/src/usb/ 下的 HID/OTG 源文件是否参与编译,并链接libusb-1.0;static会透传给每个dependency()的static:参数,即发布版 Linux 包采用的静态依赖构建方式(release/build_linux.sh 使用-Dstatic=true -Dportable=true);portable会写入生成的config.h(PORTABLE宏),改变客户端定位scrcpy-server的策略:优先从可执行文件所在目录读取,而不是固定的/usr/local/share/scrcpy;- 另外,app/meson.build 还在配置阶段写入了
adb reverse隧道默认端口区间常量 27183–27199(运行时可被--port覆盖),属于构建期注入的行为参数。
不安装直接运行
构建完成后,无需安装即可运行:
./run x [options]
从 run 脚本可以看到,它接收构建目录名(上例为 x)和其余 scrcpy 参数,先校验目录存在,然后设置两个环境变量再执行 app/scrcpy:
SCRCPY_ICON_PATH="app/data/icon.png" \
SCRCPY_SERVER_PATH="$BUILDDIR/server/scrcpy-server" \
"$BUILDDIR/app/scrcpy" "$@"
这解释了构建产物如何被“装配”起来:SCRCPY_ICON_PATH 提供窗口图标,SCRCPY_SERVER_PATH 告诉客户端去推送到设备的服务端在哪里——正式安装时这两个信息分别由安装目录和 share/scrcpy 提供。
安装与卸载
构建成功后,可把 scrcpy 安装到系统:
sudo ninja -Cx install # Windows 上不需要 sudo
安装的文件包括:
/usr/local/bin/scrcpy(主程序)/usr/local/share/scrcpy/scrcpy-server(推送到设备的服务端)/usr/local/share/man/man1/scrcpy.1(man 页)/usr/local/share/icons/hicolor/256x256/apps/scrcpy.png(应用图标)/usr/local/share/zsh/site-functions/_scrcpy(zsh 补全)/usr/local/share/bash-completion/completions/scrcpy(bash 补全)
以上安装规则均能在 app/meson.build 中找到对应语句(install_man、图标与补全脚本的 install_data),此外在 Linux 上还会额外安装应用启动器条目 scrcpy.desktop 与 scrcpy-console.desktop 到 share/applications。安装后即可直接运行 scrcpy。
卸载:
sudo ninja -Cx uninstall # Windows 上不需要 sudo
构建过程中的细节与验证
几个与构建行为相关、但容易踩坑的细节,均有源码依据:
- 测试只在 debug 构建中生成:app/meson.build 中所有单元测试(
test_cli、test_adb_parser、test_str等,位于 app/tests/)仅在buildtype == 'debug'时编译注册,原因是 release 构建不执行断言。若希望跑测试,可用meson setup x --buildtype=debug后执行meson test -Cx。 - 根构建文件的全局配置:meson.build 声明 C 语言、C11 标准、
warning_level=2、release 时去掉调试符号(b_ndebug=if-release),并要求 meson>= 0.49——这就是老系统上 meson 过旧会失败的原因,也解释了 Debian/Ubuntu 小节中用 pip3 升级 meson 的做法。 - 发布版 Linux 客户端是静态 + 便携构建:release/build_linux.sh 使用
-Dstatic=true -Dportable=true -Dcompile_server=false,并先用 app/deps/ 下的脚本从源码静态构建 FFmpeg/SDL2/dav1d/libusb,保证发布包不依赖目标机器的系统库版本。 - 服务端与客户端必须版本匹配:预编译服务端方案下,客户端版本由 meson.build 的项目版本号(当前 3.3.4)决定,务必选用同版本的服务端工件。
小结
scrcpy 的构建体系可以概括为:客户端走 Meson + Ninja(依赖 FFmpeg 与 SDL2,最低版本由 app/meson.build 锁定),服务端由 Meson 通过 Gradle wrapper 触发 Android 构建,或用 -Dprebuilt_server 完全绕开 Java/Android SDK。按本文的依赖安装步骤配好环境后,meson setup x --buildtype=release --strip -Db_lto=true && ninja -Cx 即能得到完整产物;日常验证用 ./run x,交付部署用 sudo ninja -Cx install。所有构建选项、安装路径与测试行为均可在 meson_options.txt、meson.build、app/meson.build、server/meson.build 中逐一核对。
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 StartedRust0622
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