
DroidDeck源码构建完整教程DockerNDK交叉编译PulseAudio音频模块全流程【免费下载链接】DroidDeckDroidDeck brings the SteamOS experience to Android项目地址: https://gitcode.com/gh_mirrors/dr/DroidDeckDroidDeck 是一款把 SteamOS 体验带到 Android 上的开源项目——在 Adreno 手柄/平板上运行 Steam Big Picture并通过 ARM64 Proton 玩 Windows 游戏。这篇教程带你用Docker Android NDK从零完成 DroidDeck 源码构建交叉编译 PulseAudio 13.0 音频模块、打包进pulseaudio.tzst资源包最终产出一份可安装的签名 APK并附上常见报错的快速排查方法。一、先搞清楚项目怎么跑的 在动手之前理解要构建出什么能少走很多弯路。DroidDeck 的产物是一个 Android APK核心能力由三层组成层作用关键位置音频层在 Android 上跑 PulseAudio 13.0 守护进程用 AAudio/DirectAudio 作为音频输出app/src/main/assets/pulseaudio.tzst、app/src/main/jniLibs/arm64-v8a/Linux 运行层proot preload 库让 x86/ARM64 的 Linux 程序跑在 Android 上tools/linuxfs/、tools/proot/Android 应用层Kotlin 写的启动器、会话管理、组件管理 UIapp/src/main/java/com/droiddeck/launcher/音频正是这次构建的主角仓库里预置了为 Android bionic 编译好的libpulse.so、libpulsecore-13.0.so、libpulsecommon-13.0.so位于app/src/main/jniLibs/arm64-v8a/但我们必须自己用 NDK 交叉编译两个音频输出模块sink——它们把 PulseAudio 的音频流接到 Android 的 AAudio / DirectSound 驱动上。这就是整条构建链中最值得学的部分。二、构建环境清单一次备齐不返工 ✅tools/build_local.sh 会在启动时逐项检查环境缺一样都会直接报错退出。提前对照这张清单Docker用于运行 Ubuntu 24.04 交叉编译容器构建 glibc 版 ARM64 preload 库Java 17Gradle 构建所需设置JAVA_HOME指向 JDK 17Android SDK NDK设置ANDROID_HOME或ANDROID_SDK_ROOT且sdk/ndk/下有完整 NDKsdk/platform-tools/adb必须存在命令行工具curl、tar、zstd、shasum、unzipghGitHub CLI仅当仓库内存在固定的 release 依赖Gamescope、wlroots、esync 包时需要脚本用它下载并做 sha256 校验 脚本会自动在sdk/ndk/里找版本号最高的完整 NDK目录内含source.properties。如果你曾用sdkmanager安装到一半可以显式设置DROIDDECK_NDK_VERSION指定版本。三、获取源码git clone https://gitcode.com/gh_mirrors/dr/DroidDeck cd DroidDeck四、Docker 交叉编译glibc ARM64 预加载库打开 tools/local-cross.Dockerfile 你会看到一个极简的 Dockerfile基于ubuntu:24.04安装binutils-aarch64-linux-gnu/gcc-aarch64-linux-gnu交叉工具链。tools/build_local.sh 首次运行时会自动构建镜像标签droiddeck-local-cross:24.04-v2--platform linux/amd64Apple 芯片的 Mac 上也能跑随后在容器内完成三件事tools/build_local.sh#L113-L171libfakeinput.so—— 用aarch64-linux-gnu-g -static-libstdc编译 Steam 假输入库强制静态链接 C 运行时脚本随后用readelf校验NEEDED中不得出现libstdc.so.6libblsession.so/libblfastpath.so—— 编译 tools/linuxfs/preload/ 与 tools/proot/fastpath/ 的 preload 钩子并校验socket、bind、openat等关键符号全部导出安装linuxfs覆盖层—— 桌面脚本、mangoapp等装入app/src/main/assets/linuxfs/供 APK 解压到设备。构建结束时会通过trap自动还原pulseaudio.tzst等被临时替换的文件中断也不会污染你的工作区。五、核心步骤NDK 交叉编译 PulseAudio 13.0 音频模块这是整篇文章的重点。构建脚本 tools/build_local.sh#L286-L305 分三步走1. 准备 PulseAudio 13.0 源码脚本会自动下载官方 PulseAudio 13.0 源码包并缓存到~/.cache/droiddeck-build/如果你想复用本地已有的源码树设置环境变量即可跳过下载export DROIDDECK_PA13_SOURCE_DIR/path/to/pulseaudio-13.0脚本用src/pulse/version.h.in是否存在来验证源码目录是否有效。2. 用 NDK 编译两个音频 sink真正的编译由 tools/aaudio-sink/build.sh 完成它做了几件很巧的事自动识别宿主机darwin-arm64/darwin-x86_64/linux-x86_64/linux-aarch64选择 NDK 对应的预编译工具链tools/aaudio-sink/build.sh#L15-L33Mac 和 Linux 上无需任何额外配置跳过 PulseAudio 的 configure用 tools/aaudio-sink/config.h 这份手工版 config提供版本号和特性宏PACKAGE_VERSION 13.0、HAVE_MEMFD等再配合sed生成version.h直接对着上游头文件编译单个模块调用 NDK clangAPI 26编译出module-aaudio-sink.so和module-directaudio-sink.so链接目标就是仓库里预置的libpulse*三个库tools/aaudio-sink/build.sh#L63-L64编译后做符号体检确认pa__init、pa__done等 PulseAudio 加载器要求的 7 个导出符号齐全且NEEDED依赖只允许是设备上一定存在的库libaaudio.so、libc.so等多一个都直接失败。3. 编译 DirectAudio 中继进程tools/directaudio-relay/build.sh 会编译 directaudio-relay.c——一个独立的 bionic 辅助进程它替无法直接持有音频流的驱动实例代管所有 AAudio 流通过 Unix socket 与游戏进程交接共享环形缓冲区并把麦克风共享给 Steam 客户端。构建参数要求 NDK r27、API 28并带-Wl,-z,max-page-size16384保证 16KB 大页兼容。4. 塞进 pulseaudio.tzst 资源包构建脚本会解开仓库中提交的 app/src/main/assets/pulseaudio.tzst 音频包把两个新编译的模块安装到包内的modules/arm64/目录再用zstd -19最高压缩率重新打包tools/build_local.sh#L317-L332。注意脚本有防呆检查如果提交的包里已经存在编译好的 sink会直接报错退出避免重复打包。六、一条命令完成 APK 构建环境就绪后在项目根目录执行./tools/build_local.sh默认构建 release 版可用DROIDDECK_BUILD_VARIANTdebug切换它还会依次完成Gradle 打包./gradlew assembleRelease -PndkVersion你的NDK版本产出app/build/outputs/apk/release/app-release.apk会话资源检查python3 tools/release/check_session_assets.py校验 APK 完整性音频包复检从最终 APK 里解出assets/pulseaudio.tzst确认pactl和两个 arm64 音频模块都在tools/build_local.sh#L340-L352依赖体检再开一个 Docker 容器用readelf核对 APK 里所有.so的NEEDED都能解析tools/build_local.sh#L354-L375对齐与签名zipalign -p 4对齐后用 AOSP testkeykeystore/ 下另有 release 签名指纹做 v1/v2/v3 三套签名并逐项校验确保 APK 可覆盖安装。全部通过后终端会打印 APK 路径和 SHA-256 值。七、安装到设备并验证 ./tools/deploy_local.sh该脚本会通过adb把刚构建的 APK 推送到已连接的设备。安装后打开应用、安装 Linux 运行时并启动会话如果游戏声音正常输出、麦克风可用说明你交叉编译的 PulseAudio 音频模块已经在工作了。八、常见坑位快速排查 ️报错信息原因与解法Android SDK not found未设置ANDROID_HOME/ANDROID_SDK_ROOT或 SDK 下没有platform-tools/adbNo Android NDK found under ...NDK 不完整sdkmanager中断会留下没有source.properties的目录重装或设置DROIDDECK_NDK_VERSIONDocker 报No such image且重建卡住Docker Desktop 虚拟机刚重启、镜像仓库还没加载完脚本内置了最多 1 分钟的等待重试稍候即可提示需要GitHub CLI存在release.env固定依赖Gamescope/wlroots/esync时脚本用gh下载校验包先安装gh并登录The committed audio bundle already contains a built ARM64 sink上次构建中断后pulseaudio.tzst没还原干净git checkout -- app/src/main/assets/pulseaudio.tzst恢复即可写在最后DroidDeck 的本地构建把交叉编译这件看似专业的事拆成了三个清晰的环节Docker 管 glibc 侧的 preload 库NDK 管 bionic 侧的音频模块Gradle 管最终的 APK 组装而 tools/build_local.sh 用符号校验、依赖体检、签名验证把这些环节串成了一条可靠的流水线。走通这一遍你不仅能得到属于自己的签名 APK也拿到了理解 Android 交叉编译体系的一个完整样本——推荐顺手读一下 README.md 的 Build 章节和 docs/development/ 下的开发文档继续深入。【免费下载链接】DroidDeckDroidDeck brings the SteamOS experience to Android项目地址: https://gitcode.com/gh_mirrors/dr/DroidDeck创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考