
wgpu 在 Android 与 iOS 上运行测试交叉编译配置与 adb/ssh 设备端执行完整指南【免费下载链接】wgpuA cross-platform, safe, pure-Rust graphics API.项目地址: https://gitcode.com/GitHub_Trending/wg/wgpuwgpu 作为跨平台 Rust 图形 API其 GPU 集成测试tests/tests/wgpu-gpu默认在桌面平台上运行但要验证 VulkanAndroid与 MetaliOS后端在真机上的行为需要将测试二进制交叉编译后部署到设备上执行。本文基于仓库内的 docs/running-tests-on-android-and-ios.md 完整展开如何在宿主机构建aarch64-linux-android与aarch64-apple-ios测试二进制如何通过adb/ssh将其传输到设备并以正确环境执行包括完整的.cargo/config.toml交叉链接配置、PowerShell runner 脚本与 iOS 越狱设备的 entitlements 文件。读完后你可以独立搭建一套真机测试流程并用 docs/testing.md 中描述的测试体系尤其 GPU 测试在移动端进行回归验证。整体思路宿主交叉编译 设备端执行文档给出的核心方法是三段式在宿主上通过 Cargo 的 per-targetrunner机制交叉编译出设备端可执行文件runner 脚本PowerShell 编写负责用adb push或scp把二进制推送到设备的可执行目录通过adb shell或ssh在设备上以正确的LD_LIBRARY_PATH或 entitlements 环境运行并把退出码传回使cargo test/nextest 能正常判定成败。Cargo 的runner配置是整套方案的关键一旦在.cargo/config.toml中为特定 target 指定runner该 target 下所有通过cargo test运行的测试二进制都会在构建完成后自动交给这个脚本处理无需改动任何测试代码。需要先说明适用前提仓库的 CI.github/workflows/ci.yml中Android aarch64 与 iOS aarch64 矩阵项见 ci.yml L111-L116 与 L153-L158执行的是Check native分支即用 clippy 编译全部目标与测试--tests --benches --all-features保证测试代码能针对这两个 target 通过编译而在设备上真正运行这些测试正是本文档要解决的、CI 不覆盖的环节。仓库工具链由 rust-toolchain.toml 指定为 Rust 1.93交叉编译前可用rustup target add aarch64-linux-android aarch64-apple-ios添加对应目标。AndroidNDK 交叉链接配置.cargo/config.toml 完整配置原文档给出的 Android 配置如下...为需替换的占位符version是 API 级别host是 NDK 预构建工具链的主机目录名如linux-x86_64[target.aarch64-linux-android] # Runner script is written in powershell runner [pwsh, -File, runner locationrun-on-android.ps1] rustflags [ -C, linkerclang, -C, link-arg-fuse-ldlld, -C, link-arg--targetaarch64-linux-android, -C, link-arg--sysrootndk/sysroot location, -C, link-arg-Bndk/sysroot location/usr/lib/aarch64-linux-android/version, -C, link-arg-Lndk/sysroot location/usr/lib/aarch64-linux-android/version, -C, link-arg-Lndk/sysroot location/usr/lib/aarch64-linux-android, -C, link-arg-Lndk location/toolchains/llvm/prebuilt/host/lib/clang/20/lib/linux/aarch64 ]逐行解释这些 rustflags 的作用linkerclang--targetaarch64-linux-android显式用 clang 作为交叉链接器并指定 Android 目标三元组绕开 rust-lld 对 Android Bionic sysroot 的适配差异-fuse-ldlld链接阶段使用 LLD与 NDK 工具链保持一致--sysroot指向 NDK 的sysroot目录提供 Bionic 头文件与库三个-B/-L项分别把按 API 级别划分的 Bionic 库目录usr/lib/aarch64-linux-android/version和通用库目录加入链接搜索路径最后一个-L指向 NDK 内置 clang 的资源目录中的lib/linux/aarch64用于让编译器找到libc_shared.so等 C 运行时——这也解释了文档后文所有 Android 二进制都链接libc_shared.so记得把它放在二进制旁边的说明。对照仓库 CI 的做法可以印证这些要点ci.yml L277-L284 在 Android 任务中把$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin加入PATH让cccrate 自动探测到 NDK 的clang并显式设置AR_aarch64_linux_androidllvm-ar因为 Android SDK 的归档工具名不符合常规同时 ci.yml L38 全局设置了PKG_CONFIG_ALLOW_CROSS: 1注释明确写着 allow android to work因为若干依赖 crate 在构建期需要pkg-config而交叉环境下默认会被拒绝。在本地复现 Android 构建时同样建议设置该环境变量并保证 NDK 的bin目录在PATH中。run-on-android.ps1 runner 脚本完整脚本来自原文档runner location替换为你的脚本存放路径param( [string]$BinaryPath ) $ErrorActionPreference Stop # /data/local/tmp is the most common directory where arbitrary binaries can be run $RemoteDir /data/local/tmp/runner $BinaryName Split-Path -Leaf $BinaryPath $RemotePath $RemoteDir/$BinaryName adb push --sync $BinaryPath $RemotePath *$null adb shell chmod 755 $RemotePath $EscapedArgs $args | ForEach-Object { if ($_ -match ) { $_ } else { $_ } } $LinuxArgs $EscapedArgs -join # Set LD_LIBRARY_PATH to the location of libc_shared.so $DeviceCmd cd $RemoteDir LD_LIBRARY_PATH$RemoteDir ./$BinaryName $LinuxArgs adb shell $DeviceCmd exit $LASTEXITCODE脚本要点目标目录/data/local/tmp是 Android 上少数允许任意二进制执行的目录脚本将其下的runner子目录作为远程工作区adb push --sync推入测试二进制chmod 755赋予执行权限参数转义逻辑把含空格的参数加引号后拼接保证cargo test传入的测试过滤参数如 test name 参数能原样到达设备端运行时通过LD_LIBRARY_PATH$RemoteDir找到与二进制同目录的libc_shared.so——这就是把 libc_shared.so 副本放在二进制旁边的具体落地方式用adb push将该 so 一并推到$RemoteDir结尾exit $LASTEXITCODE把设备端测试退出码交还给 cargo使测试框架能正确判定通过/失败。设备端运行的是哪些后端从 wgpu-hal/Cargo.toml 的 target 条件依赖看Android 上可用的后端与依赖结构是明确的vulkanfeature 中包含android_system_propertiesL91-L95glesfeature 依赖ndk-sysL114-L116且cfg(target_os android)下额外声明了android_system_properties与ndk-sys依赖L312-L314。因此在 Android 上运行 wgpu-gpu 测试时Vulkan主流路径与 GLES 后端都可能被#[apply(gpu_test!)]harness 枚举到这正是真机执行对覆盖移动端驱动问题不可替代的原因。iOS越狱设备 sysroot 交叉编译文档开头就给出两个关键前提iOS 通常不提供 shell 访问与sshd因此设备必须越狱交叉编译只需要一份 iOS sysroot 拷贝所以Linux 和 Windows 主机同样可以尝试macOS 之外需额外设置SDKROOT。.cargo/config.toml 完整配置[target.aarch64-apple-ios] # Runner script is written in powershell runner [pwsh, -File, runner locationrun-on-ios.ps1] rustflags [ -C, linkerclang, -C, link-arg-fuse-ldlld, -C, link-arg--targetaarch64-apple-ios, -C, link-arg--sysrootsysroot location, -C, link-arg-miphoneos-version-minminversion, -C, link-arg-rpath, -C, link-argexecutable_path/Frameworks, -Lnativesysroot location/usr/lib, -Lframeworksysroot location/System/Library/Frameworks, ]与 Android 配置的关键差异在于 Apple 链接语义-miphoneos-version-minminversion声明最低部署 iOS 版本clang 会据此选择可用的符号-rpath executable_path/Frameworks是 Mach-O 的动态库搜索路径写法等价于 ELF 的LD_LIBRARY_PATH机制-Lnative与-Lframework分别对应 Apple 平台的普通库搜索路径与 Framework 搜索路径如Metal.framework、IOSurface.framework。从 wgpu-hal/Cargo.toml 的结构可以印证 iOS 构建的依赖形态metalfeatureL72-L90依赖objc2-metal、objc2-core-foundation等 Objective-C 绑定 crate且仅在 Apple 平台激活cfg(target_vendor apple)下还声明了这些 objc2 系依赖L294-L306。这意味着 iOS 交叉编译时 C 语言代码与 objc 绑定的编译都由 sysroot clang 承担与本文 rustflags 的设定完全对应。macOS 之外的主机Linux/Windows必须设置SDKROOT环境变量指向 sysroot 位置。文档解释了原因构建期依赖如cc-rs在非 macOS 环境下无法使用xcrun探测 SDK设置SDKROOT后它们会直接使用该路径从而避免构建失败。run-on-ios.ps1 runner 脚本param( [string]$BinaryPath ) $SshTarget target usertarget host $BinaryName Split-Path -Leaf $BinaryPath # Select one of the following paths depending on rootless or rootful jailbreak $RemoteDir /var/jb/var/mobile/runner #$RemoteDir /var/root/runner $RemotePath $RemoteDir/$BinaryName $EscapedArgs $args | ForEach-Object { if ($_ -match ) { $_ } else { $_ } } $LinuxArgs $EscapedArgs -join $DeviceCmd ./$BinaryName $LinuxArgs ssh $SshTarget test -f $RemotePath if ($LASTEXITCODE -ne 0) { scp -q $BinaryPath $SshTarget:$RemotePath $DeviceCmd chmod 755 $BinaryName ldid -Sent.xml $BinaryName $DeviceCmd } ssh $SshTarget cd $RemoteDir $DeviceCmd exit $LASTEXITCODE脚本逻辑先通过ssh target test -f $RemotePath探测远程是否已存在同名二进制不存在时才执行scp上传并用ldid -Sent.xml注入 entitlementsent.xml必须放在 runner 目录中若已存在则跳过传输与签名直接运行——这使同一测试二进制的重复执行cargo test 的常规节奏不必反复传文件$RemoteDir二选一是由越狱类型决定的rootless越狱使用/var/jb/var/mobile/runnerrootful越狱使用/var/root/runner脚本中已给出两个变体供切换同样以exit $LASTEXITCODE结束向 cargo 回传设备端测试结果。iOS 为何必须注入 entitlementsent.xml由于 iOS 的安全机制一个要在**无容器no container**环境下运行并访问 IOKit 的用户客户端类GPU 驱动接口正属于此类的二进制必须携带特定 entitlements。这就是脚本要求设备上安装ldid工具并用ent.xml签名的原因。完整ent.xml需与二进制同目录放置由ldid -Sent.xml读取!DOCTYPE plist PUBLIC -//Apple//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd plist version1.0 dict keyplatform-application/key true/ keycom.apple.private.security.container-required/key false/ keycom.apple.security.iokit-user-client-class/key array stringAGXCommandQueue/string stringAGXDevice/string stringAGXDeviceUserClient/string stringAGXSharedUserClient/string stringIOSurfaceRootUserClient/string /array /dict /plist三个键分别对应文档描述的两个目的platform-application true声明自己是平台级应用是获取私有 entitlements 的前提com.apple.private.security.container-required false允许进程在沙盒容器之外运行run without a containercom.apple.security.iokit-user-client-class列表授权访问 IOKit 的指定用户客户端类。其中AGXCommandQueue、AGXDevice、AGXDeviceUserClient、AGXSharedUserClient正是 Apple GPUAGX 驱动的 Metal 驱动接口IOSurfaceRootUserClient则是 GPU 缓冲共享IOSurface所必需的类——这与 wgpu 在 iOS 上走 Metal 后端objc2-metal绑定见上文 wgpu-hal/Cargo.toml L72-L90的运行时需求完全吻合。实操要点与限制汇总项目AndroidiOS目标三元组aarch64-linux-androidaarch64-apple-ios交叉编译工具NDKsysroot clang/lld见 rustflagsiOS sysroot任意主机均可非 macOS 需设SDKROOT传输通道adb pushscp设备需 sshd即越狱执行通道adb shell在/data/local/tmp下运行ssh到越狱设备运行时依赖libc_shared.so与二进制同目录LD_LIBRARY_PATHldident.xml注入 entitlements环境准备设备开启 ADB 调试越狱rootless 用/var/jb/var/mobile/runnerrootful 用/var/root/runner退出码回传exit $LASTEXITCODEexit $LASTEXITCODE需要注意的限制与前提两条流程的 runner 脚本均用 PowerShellpwsh编写Windows 上开箱即用Linux/macOS 需安装 pwsh 并保证adbAndroid或ssh/scpiOS可用Android 配置中 NDK 的 clang 资源目录写死了clang/20路径使用其他 NDK 大版本时需按实际目录调整该-L项iOS 方案对设备有硬性要求越狱 ldid且 CI 中 iOS 任务仅保证编译通过ci.yml L111-L116 的kind: native走 clippy 检查真机执行完全依赖本文的 runner 方案具体要运行哪些测试遵循 docs/testing.md 的测试分类移动端 GPU 测试位于tests/tests/wgpu-gpu可参考cargo xtask test --test wgpu-gpu的本地跑法在移动端则等价地由 runner 逐个执行编译出的测试二进制而仅验证 API 校验逻辑的wgpu-validation类测试基于 noop 后端、无需真机。按以上配置完成后cargo test --target aarch64-linux-android或aarch64-apple-ios即可像在本机一样发起测试Cargo 完成交叉构建后自动调用 runner二进制被推送到设备执行结果退出码驱动整个测试框架的成败判定——这就是 wgpu 仓库把移动端测试从能编译推进到能验证的完整链路。【免费下载链接】wgpuA cross-platform, safe, pure-Rust graphics API.项目地址: https://gitcode.com/GitHub_Trending/wg/wgpu创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考