yams/docs/developer/mobile-builds.md

7.7 KiB

Mobile Build Pipeline

This repository builds libyams_mobile as a C ABI corpus library. The library is intended to be embedded by higher-level app shells such as Flutter, not to host inference itself.

Current CI Lane

This page documents the mobile library lane and its expected packaging shape. A dedicated mobile-artifacts.yml workflow is not currently tracked in this repository, so treat the workflow details below as the lane contract to re-enable rather than as an active CI guarantee.

The lane should guarantee:

  • Build libyams_mobile with YAMS_ENABLE_MOBILE_BINDINGS=true
  • Keep the mobile lane library-only by disabling plugin, CLI, and MCP targets
  • Compile the Catch2 mobile ABI and daemon protocol suites
  • Run the mobile ABI suite and daemon protocol suite
  • Verify that the shared library exports every YAMS_MOBILE_API symbol declared in mobile_bindings.h
  • Package a downloadable artifact containing:
    • lib/ with the built shared library
    • include/yams/api/mobile_bindings.h
    • manifest.json
  • Validate all host/mobile Conan target profiles before building

Current artifact platforms:

  • linux-x86_64
  • macos-arm64

Expected reusable CI entrypoints when the lane is enabled:

  • scripts/ci/build_mobile_lane.sh
  • scripts/ci/run_mobile_lane.sh
  • scripts/ci/resolve_mobile_target.sh
  • scripts/ci/check_mobile_profiles.sh

Target Matrix

The mobile build lane now has named targets with separate Conan host profiles and separate default build directories:

Target Conan host profile Default build dir Packaging role
host-linux-x86_64 conan/profiles/host-linux-clang build/mobile-host-linux-x86_64 Host-native CI artifact
host-linux-arm64 conan/profiles/host-linux-clang-arm build/mobile-host-linux-arm64 Host-native packaging input
host-macos-arm64 conan/profiles/host-macos-apple-clang build/mobile-host-macos-arm64 Host-native CI artifact
host-macos-x86_64 conan/profiles/host-macos-apple-clang-x86 build/mobile-host-macos-x86_64 Host-native packaging input
ios-device-arm64 conan/profiles/host-ios-apple-clang-device-arm64 build/mobile-ios-device-arm64 .xcframework device slice
ios-sim-arm64 conan/profiles/host-ios-apple-clang-sim-arm64 build/mobile-ios-sim-arm64 .xcframework simulator slice
android-arm64 conan/profiles/host-android-clang-arm64 build/mobile-android-arm64 .aar arm64-v8a slice
android-x86_64 conan/profiles/host-android-clang-x86_64 build/mobile-android-x86_64 .aar x86_64 slice

The lane should validate all of those profiles with Conan, even if only the host-native targets are built in a given workflow run.

For platform targets, the shared build entrypoint now forwards machine-local toolchain paths into Conan automatically:

  • iOS targets infer tools.apple:sdk_path from YAMS_IOS_DEVICE_SDK_PATH, YAMS_IOS_SIMULATOR_SDK_PATH, or xcrun
  • Android targets infer tools.android:ndk_path from YAMS_ANDROID_NDK_PATH, ANDROID_NDK_ROOT, or ANDROID_NDK_HOME, and require the selected NDK root to contain build/cmake/android.toolchain.cmake
  • Cross-builds also resolve protoc from the build machine instead of the target protobuf package, so daemon IPC code generation no longer tries to execute Android/iOS binaries on the host

Manual workflow dispatch should be able to attempt full platform packaging:

  • package_ios=true builds ios-device-arm64 and ios-sim-arm64, then assembles YamsMobile.xcframework
  • package_android=true builds android-arm64 and android-x86_64, then assembles a thin .aar

Local Commands

Build the mobile lane locally:

scripts/ci/build_mobile_lane.sh Debug host-macos-arm64

Run verification:

scripts/ci/run_mobile_lane.sh build/mobile-host-macos-arm64
scripts/ci/check_mobile_abi.sh build/mobile-host-macos-arm64/src/mobile/libyams_mobile.dylib

Package a bundle:

scripts/ci/package_mobile_bindings.sh build/mobile-host-macos-arm64 build/mobile-host-macos-arm64/mobile-artifacts

Validate the full profile set:

scripts/ci/check_mobile_profiles.sh

Resolve a target to its profile/build-dir mapping:

scripts/ci/resolve_mobile_target.sh ios-device-arm64

Build an iOS xcframework locally:

scripts/ci/build_ios_xcframework.sh Release build/mobile-ios-packages

Build an Android AAR locally:

YAMS_ANDROID_NDK_PATH=/path/to/ndk scripts/ci/build_android_aar.sh Release build/mobile-android-packages

Build Cleanup Direction

This lane is intentionally narrow. It validates the current corpus ABI and artifact packaging without pretending the repo already ships native iOS/Android SDK bundles.

The wrapper boundary is documented in packaging/mobile/README.md.

The next packaging layers should be built on top of this lane:

  1. iOS: produce an .xcframework from device + simulator builds and publish it as a release artifact.
  2. Android: produce a JNI/AAR wrapper containing the C ABI library for supported ABIs.
  3. Flutter: consume those release artifacts from a thin plugin package rather than rebuilding the YAMS core inside the app repo.

That split keeps this repo responsible for the native corpus library and ABI validation, while the Flutter repo owns Dart bindings, platform plugin glue, and UX.

Initial packaging helpers now exist for the wrapper layer:

  • iOS cross-build + .xcframework orchestration: scripts/ci/build_ios_xcframework.sh
  • iOS .xcframework assembly: scripts/ci/package_ios_xcframework.sh
  • Android cross-build + .aar orchestration: scripts/ci/build_android_aar.sh
  • Android .aar assembly: scripts/ci/package_android_aar.sh

The repo now has orchestration scripts for the actual iOS/Android target builds, but those still depend on platform SDK availability in CI or on the local machine.

Cross-Build Notes

Separate iOS and Android profiles now live in conan/profiles/ so each platform can evolve independently instead of sharing a generic mobile config.

iOS profiles:

  • conan/profiles/host-ios-apple-clang-device-arm64
  • conan/profiles/host-ios-apple-clang-sim-arm64

Android profiles:

  • conan/profiles/host-android-clang-arm64
  • conan/profiles/host-android-clang-x86_64

Those profiles are a clean source of truth for target settings, but real cross-builds still depend on machine-local SDK wiring:

  • iOS: Xcode plus any required Conan Apple SDK configuration such as tools.apple:sdk_path
  • Android: Android NDK plus Conan/host configuration such as tools.android:ndk_path

The default CI path still keeps host-native builds green. Platform packaging is opt-in on manual dispatch so failures in Apple/Android toolchain provisioning do not mask corpus ABI regressions.

Current validation state:

  • the previous fmt/10.2.1 simulator blocker was removed by forcing header-only fmt on iOS and Android builds in Conan
  • mobile Conan builds now also force header-only spdlog to avoid Apple SDK-specific failures in the compiled spdlog + fmt path
  • the shared mobile lane now disables plugins, CLI, and MCP builds so cross targets only configure the corpus library and its direct dependencies
  • host-native mobile builds are green again with that narrower contract
  • Android cross-builds now complete Meson setup, use native /opt/homebrew/bin/protoc for daemon IPC code generation, and proceed into real target compilation
  • iOS simulator validation is now reaching later dependency builds under the real Apple SDK toolchain
  • Android direct target builds now auto-forward the NDK path instead of only working through the AAR wrapper script