Rust-based build worker for the Perry ecosystem. Handles ALL compilation for every platform: Linux, Android, Windows, iOS, and macOS. Cross-compiles iOS/macOS using ld64.lld + Apple SDK sysroot, and Windows using lld-link + xwin. Connects to perry-hub via WebSocket, receives build jobs, and reports artifacts back. Precompiled bundles for iOS/macOS/Windows are re-queued by the hub to sign-only workers.
- Rust (tokio async runtime)
- WebSocket client: tokio-tungstenite
- HTTP client: reqwest
src/
main.rs # Entry point, CLI args
worker.rs # WebSocket connection to hub, job dispatch loop
config.rs # Configuration (env vars)
lib.rs # Library root
build/
pipeline.rs # Build orchestration (Linux + Android pipelines)
compiler.rs # Invokes perry compiler
assets.rs # Icon generation (PNG, Android mipmap densities)
cleanup.rs # Temp directory management
package/
linux.rs # AppImage, .deb, .tar.gz packaging
android.rs # Gradle project generation, APK/AAB building
signing/
linux.rs # No-op (future: GPG signing)
android.rs # Android keystore signing
publish/
linux.rs # No-op (future: Flatpak/Snap/GitHub Releases)
playstore.rs # Google Play Store upload (REST API)
queue/
job.rs # Job manifest and credential types
ws/
messages.rs # WebSocket protocol message types
cargo build --release
PERRY_BUILD_PERRY_BINARY=~/projects/perry/target/release/perry ./target/release/perry-builder-linuxPerry 5.14+ uses the LLVM backend (not Cranelift). LLVM 18 must be installed on the
host (apt install llvm-18 clang-18 lld-18). The builder automatically:
- Adds
/usr/lib/llvm-18/binto PATH for direct builds - Sets
PERRY_LLVM_*env vars pointing to LLVM 18 tools for Docker builds - Mounts
/usr/lib/llvm-18/{bin,lib}into Docker containers
PERRY_HUB_URL— Hub WebSocket URL (default:ws://localhost:3457)PERRY_BUILD_PERRY_BINARY— Path to the perry compiler binaryPERRY_BUILD_ANDROID_HOME— Android SDK path (falls back toANDROID_HOME)PERRY_WORKER_NAME— Optional worker name
- AppImage (default) — requires
appimagetoolon PATH - .deb — requires
dpkg-debon PATH - tar.gz — no external tools needed
Advertises ["linux", "android", "windows", "ios", "macos"] to the hub.
- Linux/Android: native compilation, full pipeline
- Windows: cross-compiled using
lld-link+ xwin sysroot → precompiled bundle → hub re-queues to Windows sign worker (Azure VM) - iOS: cross-compiled using
ld64.lld+ Apple SDK sysroot at/opt/apple-sysroot/ios/→ precompiled bundle → hub re-queues asios-signto macOS worker - macOS: cross-compiled using
ld64.lld+ Apple SDK sysroot at/opt/apple-sysroot/macos/→ precompiled bundle → hub re-queues asmacos-signto macOS worker
- Uses
ld64.lld(LLVM's Mach-O linker) +libLLVM.so.18, mounted into Docker containers - Apple SDK sysroot (~140MB): headers + .tbd stubs at
/opt/apple-sysroot/{ios,macos}/ - All Apple libs (perry-runtime, perry-stdlib, perry-ui) cross-compile from Linux using
clang+SDKROOT CC_aarch64_apple_ios=clang+SDKROOTenv vars for ring/cc-rs crates- Linker flags:
-dead_stripdirectly (not-Wl,-dead_strip) for ld64.lld compatibility
Supports running multiple builds in parallel (default 2, via PERRY_MAX_CONCURRENT_BUILDS).
Each build runs in its own Docker container (when PERRY_DOCKER_ENABLED=true).
Builds are spawned as tokio tasks with a shared WS write channel.
When enabled (PERRY_DOCKER_ENABLED=true), builds run in Docker containers:
- Project dir mounted writable (perry writes .o files during compilation)
- Perry binary + libs mounted read-only from
/opt/perry-src/target/ - Rust toolchain mounted read-only
- Resource limits: 4GB RAM, 2 CPUs, no-new-privileges
- Network enabled (
--network=host) for native lib cargo builds
- Uses
lld-link(LLVM's MSVC-compatible linker) via Rust toolchain - xwin sysroot at
PERRY_WINDOWS_SYSROOTfor Windows SDK import libraries strip_duplicate_objects_from_libremoves perry_runtime duplicates from UI staticlibs using rlib- rlib for
perry-ui-windowsbuilt locally duringupdate_perry(cross-compile works for this crate) - Windows .lib files (perry_stdlib, perry_runtime) copied from Azure VM via
update_windows_libs
PERRY_MAX_CONCURRENT_BUILDS— Max parallel builds (default: 2)PERRY_DOCKER_ENABLED— Enable Docker isolation (default: false)PERRY_DOCKER_IMAGE— Docker image name (default: perry-build)PERRY_WINDOWS_SYSROOT— Path to xwin Windows SDK sysrootPERRY_IOS_SYSROOT— Path to iOS Apple SDK sysroot (default:/opt/apple-sysroot/ios)PERRY_MACOS_SYSROOT— Path to macOS Apple SDK sysroot (default:/opt/apple-sysroot/macos)
- Worker connects to hub WebSocket, sends
worker_hellowith capabilities +max_concurrent - Hub assigns jobs → worker receives
job_assign, spawns build as async task - Each build: download tarball → compile (in Docker if enabled) → package → sign → upload
- For cross-platform targets:
- Windows: cross-compile → precompiled bundle → hub re-queues as
windows-signto Azure VM - iOS: cross-compile → precompiled .app bundle → hub re-queues as
ios-signto macOS worker - macOS: cross-compile → precompiled .app bundle → hub re-queues as
macos-signto macOS worker
- Windows: cross-compile → precompiled bundle → hub re-queues as
- Progress/logs streamed via shared WS channel, multiple builds run concurrently
- hub — the hub server this worker connects to
- builder-macos — macOS/iOS sign-only worker
- perry — compiler + CLI