Skip to content

Fold Apple SPM support into llamadart#198

Merged
leehack merged 17 commits into
mainfrom
apple-spm-native-runtimes
Jun 6, 2026
Merged

Fold Apple SPM support into llamadart#198
leehack merged 17 commits into
mainfrom
apple-spm-native-runtimes

Conversation

@leehack
Copy link
Copy Markdown
Owner

@leehack leehack commented Jun 5, 2026

Summary

  • Fold the macOS LiteRT-LM native-assets fix and the Apple SPM runtime work into one PR against main; Fix macOS LiteRT-LM runtime packaging #196 is closed as folded into this branch.
  • Route Apple SPM binary targets through leehack/llamadart-native@b9536 and leehack/litert-lm-native@v0.13.1, so Apple SPM and native-assets paths consume the same native repos.
  • Keep the root llamadart package as the Apple SPM integration point instead of adding a separate package.
  • Use Apple SPM automatically for Flutter Apple builds on both iOS and macOS; standalone Dart macOS runs keep the native-assets dylib fallback.
  • Remove the llamadart_apple_spm user define from the hook path and example app configuration.
  • Set downstream Apple floors to iOS 16.4 and macOS 14.0, matching the native repo artifacts that need to be linked together.
  • Add a local darwin/llamadart/Artifacts/*.xcframework fallback for branch-local SPM testing while keeping release URLs as the published path.
  • Update llama.cpp FFI bindings for b9536, wire the native SPM macOS LiteRT-LM layout, and keep pure Dart/native-assets behavior for desktop Dart consumers.
  • Make the Flutter GGUF smoke configurable by model URL/path and backend, and stream large model downloads to disk so real Gemma 4 device tests do not buffer multi-GB files in memory.
  • Keep generated version-0.7.0 docs unchanged; current docs and maintainer docs describe the native version-management flow.

Native Release Status

  • leehack/llamadart-native@b9536 is published with llamadart-native-apple-xcframework-b9536.zip.
  • leehack/litert-lm-native@v0.13.1 is published with the Apple XCFramework zips used by Package.swift.
  • Package.swift now uses checksums from the uploaded GitHub release assets, not local test zips.
  • GitHub release asset digests were checked against the Package.swift checksums for all Apple binary targets.

Post-Release Remote SPM Validation

  • Temporarily moved darwin/llamadart/Artifacts/ aside and removed SwiftPM build state so Package.swift could only expose remote GitHub release binary targets.
  • swift package dump-package --package-path darwin/llamadart
    • Confirmed all Apple binary targets used remote URLs for leehack/llamadart-native and leehack/litert-lm-native.13.1, with final uploaded checksums.
  • flutter clean && rm -rf build/macos/SourcePackages && flutter pub get && flutter build macos --debug from example/chat_app
    • Passed with the local fallback artifacts hidden.
  • Gemma 4 llama.cpp/GGUF through Flutter SPM using URL model loading:
    • macOS Metal: flutter test integration_test/smoke_test.dart -d macos --dart-define=LLAMADART_GGUF_MODEL_URL=http://127.0.0.1:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=metal
    • macOS CPU: flutter test integration_test/smoke_test.dart -d macos --dart-define=LLAMADART_GGUF_MODEL_URL=http://127.0.0.1:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=cpu
    • iOS simulator Metal: flutter test integration_test/smoke_test.dart -d 2E5F57B6-0C84-4B7D-8FC6-3AE46498246D --dart-define=LLAMADART_GGUF_MODEL_URL=http://127.0.0.1:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=metal
    • iOS simulator CPU: flutter test integration_test/smoke_test.dart -d 2E5F57B6-0C84-4B7D-8FC6-3AE46498246D --dart-define=LLAMADART_GGUF_MODEL_URL=http://127.0.0.1:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=cpu
  • Gemma 4 LiteRT-LM through Flutter SPM using URL model loading:
    • macOS CPU: flutter test --run-skipped -t local-only integration_test/litert_lm_chat_service_e2e_test.dart -d macos --dart-define=LITERT_LM_MODEL_URL=http://127.0.0.1:8787/gemma-4-E2B-it.litertlm --dart-define=LITERT_LM_E2E_BACKEND=cpu
    • macOS GPU: flutter test --run-skipped -t local-only integration_test/litert_lm_chat_service_e2e_test.dart -d macos --dart-define=LITERT_LM_MODEL_URL=http://127.0.0.1:8787/gemma-4-E2B-it.litertlm --dart-define=LITERT_LM_E2E_BACKEND=gpu
    • iOS simulator CPU: flutter test --run-skipped -t local-only integration_test/litert_lm_chat_service_e2e_test.dart -d 2E5F57B6-0C84-4B7D-8FC6-3AE46498246D --dart-define=LITERT_LM_MODEL_URL=http://127.0.0.1:8787/gemma-4-E2B-it.litertlm --dart-define=LITERT_LM_E2E_BACKEND=cpu
  • Real iPad remote-SPM build/install attempts:
    • flutter drive --publish-port ... -d 00008103-001A59063EC0801E --dart-define=LLAMADART_GGUF_MODEL_URL=http://192.168.1.107:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=metal built and installed, then blocked waiting for Dart VM service discovery over wireless.
    • flutter drive ... -d 00008103-001A59063EC0801E --dart-define=LLAMADART_GGUF_MODEL_URL=http://192.168.1.107:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=cpu also built and installed, then hit the same wireless VM-service discovery/local-network permission blocker.

Current Validation

  • git diff --check
  • dart test -p vm -j 1 test/unit/hook/build_hook_litert_lm_integration_test.dart test/unit/hook/native_bundle_config_test.dart
    • Run without a local llamadart_native_path override; the hook resolves leehack/llamadart-native@b9536 and LiteRT-LM 0.13.1.
  • swift package dump-package from darwin/llamadart with local Artifacts/ temporarily hidden.
    • Confirmed remote binary targets point at leehack/llamadart-native@b9536 and leehack/litert-lm-native@v0.13.1 with the uploaded checksums.
  • gh release view b9536 --repo leehack/llamadart-native --json tagName,assets,url
  • gh release view v0.13.1 --repo leehack/litert-lm-native --json tagName,assets,url

Earlier Branch Validation

  • dart test test/unit/backends/litert_lm/litert_lm_runtime_test.dart test/unit/tooling/macos_litert_lm_prepare_app_script_test.dart
  • flutter build macos --debug from example/chat_app
  • swift package dump-package from darwin/llamadart
  • iOS simulator Flutter smoke with local SPM artifacts:
    • flutter clean && flutter pub get && flutter test integration_test/smoke_test.dart -d 2E5F57B6-0C84-4B7D-8FC6-3AE46498246D
  • macOS Flutter smoke with local SPM artifacts:
    • flutter clean && flutter pub get && flutter test integration_test/smoke_test.dart -d macos
  • Pure Dart/native-assets smoke with temporary local native path override to the locally built b9536 bundle:
    • dart test test/integration/backends/llama_cpp/native_symbol_integration_test.dart
    • dart test test/integration/inference_smoke_test.dart
  • Hook tests with the same temporary local override before b9536 was published:
    • dart test -p vm -j 1 test/unit/hook --exclude-tags local-only
  • Gemma 4 LiteRT-LM CPU path:
    • Pure Dart/native-assets macOS: dart run tool/litert_lm_chat_features_smoke.dart .dart_tool/litert_lm_models/gemma-4-E2B-it.litertlm cpu
    • Flutter macOS SPM: flutter test --run-skipped -t local-only integration_test/litert_lm_chat_service_e2e_test.dart -d macos --dart-define=LITERT_LM_MODEL_URL=http://127.0.0.1:8787/gemma-4-E2B-it.litertlm --dart-define=LITERT_LM_E2E_BACKEND=cpu
    • Flutter iOS simulator SPM: flutter test --run-skipped -t local-only integration_test/litert_lm_chat_service_e2e_test.dart -d 2E5F57B6-0C84-4B7D-8FC6-3AE46498246D --dart-define=LITERT_LM_MODEL_URL=http://127.0.0.1:8787/gemma-4-E2B-it.litertlm --dart-define=LITERT_LM_E2E_BACKEND=cpu
    • Real iPad SPM: flutter drive --publish-port --driver=test_driver/integration_test.dart --target=integration_test/litert_lm_chat_service_e2e_test.dart -d 00008103-001A59063EC0801E --dart-define=LITERT_LM_MODEL_URL=http://192.168.1.107:8787/gemma-4-E2B-it.litertlm --dart-define=LITERT_LM_E2E_BACKEND=cpu
  • Gemma 4 LiteRT-LM GPU path:
    • Pure Dart/native-assets macOS: dart run tool/litert_lm_chat_features_smoke.dart .dart_tool/litert_lm_models/gemma-4-E2B-it.litertlm gpu
    • Flutter macOS SPM: flutter test --run-skipped -t local-only integration_test/litert_lm_chat_service_e2e_test.dart -d macos --dart-define=LITERT_LM_MODEL_URL=http://127.0.0.1:8787/gemma-4-E2B-it.litertlm --dart-define=LITERT_LM_E2E_BACKEND=gpu
    • iOS GPU is intentionally rejected by the current LiteRT-LM platform gate; simulator returned Available LiteRT-LM backends: cpu.
  • Gemma 4 llama.cpp/GGUF CPU path:
    • Pure Dart/native-assets macOS: dart run tool/gguf_chat_features_smoke.dart models/gemma-4-E2B-it-Q4_K_S.gguf cpu
    • Flutter macOS SPM: flutter test integration_test/smoke_test.dart -d macos --dart-define=LLAMADART_GGUF_MODEL_URL=http://127.0.0.1:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=cpu
    • Flutter iOS simulator SPM: flutter test integration_test/smoke_test.dart -d 2E5F57B6-0C84-4B7D-8FC6-3AE46498246D --dart-define=LLAMADART_GGUF_MODEL_URL=http://127.0.0.1:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=cpu
    • Real iPad SPM: flutter drive --publish-port --driver=test_driver/integration_test.dart --target=integration_test/smoke_test.dart -d 00008103-001A59063EC0801E --dart-define=LLAMADART_GGUF_MODEL_URL=http://192.168.1.107:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=cpu
  • Gemma 4 llama.cpp/GGUF Metal path:
    • Pure Dart/native-assets macOS: dart run tool/gguf_chat_features_smoke.dart models/gemma-4-E2B-it-Q4_K_S.gguf metal
    • Flutter macOS SPM: flutter test integration_test/smoke_test.dart -d macos --dart-define=LLAMADART_GGUF_MODEL_URL=http://127.0.0.1:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=metal
    • Flutter iOS simulator SPM: flutter test integration_test/smoke_test.dart -d 2E5F57B6-0C84-4B7D-8FC6-3AE46498246D --dart-define=LLAMADART_GGUF_MODEL_URL=http://127.0.0.1:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=metal
    • Real iPad SPM: flutter drive --publish-port --driver=test_driver/integration_test.dart --target=integration_test/smoke_test.dart -d 00008103-001A59063EC0801E --dart-define=LLAMADART_GGUF_MODEL_URL=http://192.168.1.107:8788/gemma-4-E2B-it-Q4_K_S.gguf --dart-define=LLAMADART_GGUF_BACKEND=metal
  • Verified bundled Apple deployment targets with vtool -show-build:
    • iOS simulator llama.framework: minOS 16.4
    • iOS simulator LiteRtLm.framework and CLiteRTLM.framework: minOS 15.0
    • iOS simulator llamadart.framework: minOS 16.4
    • macOS LiteRtLm.framework and libLiteRt.dylib: universal x86_64/arm64, minOS 14.0
    • macOS llama.framework: universal x86_64/arm64, minOS 13.3
  • dart format hook/build.dart lib/src/hook/native_bundle_config.dart test/unit/hook/build_hook_litert_lm_integration_test.dart
  • dart format lib/src/backends/litert_lm/litert_lm_runtime.dart
  • dart format hook/build.dart lib/src/backends/litert_lm/litert_lm_runtime.dart lib/src/backends/llama_cpp/bindings.dart lib/src/backends/llama_cpp/llama_cpp_service.dart example/chat_app/integration_test/smoke_test.dart
  • git diff --check

Remaining Caveat

  • A plain swift build from darwin/llamadart is not a useful final gate because the package target imports FlutterMacOS; SwiftPM can parse the manifest and expose the binary targets, while Flutter/Xcode provides the Flutter framework in the real build.

@leehack leehack changed the title Add Apple SPM native runtime package Fold Apple SPM support into llamadart Jun 5, 2026
@leehack leehack changed the base branch from fix-macos-litert-runtime to main June 5, 2026 23:50
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

Chat app preview removed for leehack/llamadart-chat-pr-198.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jun 6, 2026

Codecov Report

❌ Patch coverage is 78.78788% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.59%. Comparing base (a0f6b4c) to head (e9dd629).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
lib/src/hook/native_bundle_config.dart 86.36% 3 Missing ⚠️
lib/src/backends/litert_lm/litert_lm_runtime.dart 71.42% 2 Missing ⚠️
lib/src/backends/llama_cpp/llama_cpp_service.dart 50.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #198      +/-   ##
==========================================
+ Coverage   80.57%   80.59%   +0.01%     
==========================================
  Files          85       85              
  Lines       11392    11407      +15     
==========================================
+ Hits         9179     9193      +14     
- Misses       2213     2214       +1     
Flag Coverage Δ
unittests 80.59% <78.78%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@leehack leehack marked this pull request as ready for review June 6, 2026 11:24
Copilot AI review requested due to automatic review settings June 6, 2026 11:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR folds Apple Swift Package Manager (SPM) support and the macOS LiteRT-LM native-assets fix into llamadart, aligning Apple and native-assets runtime sources and updating the pinned native runtime revisions.

Changes:

  • Add an Apple SPM integration under darwin/llamadart and route Flutter iOS/macOS builds to use SPM (with iOS 16.4 / macOS 14.0 floors), while keeping standalone Dart macOS on the native-assets fallback.
  • Update native runtime pins (llamadart-native@b9536, litert-lm-native@v0.13.1), refresh LiteRT-LM runtime loading expectations (embedded StreamProxy), and adjust hook defaults so non-Android targets default to llama_cpp only.
  • Update docs, examples, CI smoke coverage, and hook/runtime-selection parsing (including OS-level overrides and exact-target precedence).

Reviewed changes

Copilot reviewed 51 out of 55 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
website/docs/platforms/support-matrix.md Updates pinned versions, runtime defaults, and documents the Apple SPM path and new floors.
website/docs/platforms/native-build-hooks.md Documents new default runtime-family behavior and Apple SPM behavior for Flutter iOS/macOS.
website/docs/maintainers/runtime-ownership.md Clarifies ownership boundaries for Apple SPM artifacts across repos.
website/docs/maintainers/release-workflow.md Adds release checklist for keeping hook pins and SPM pins aligned.
website/docs/maintainers/native-and-web-sync.md Defines the invariant: native-assets and SPM must resolve the same native releases; adds sync checklist.
website/docs/guides/backend-selection.md Updates backend/runtime selection docs to match new defaults and per-OS/per-target config.
website/docs/getting-started/installation.md Bumps the example native tag pin to b9536.
website/docs/examples/overview.md Notes chat app opts into both runtime families; others use defaults.
website/docs/examples/chat-app.md Documents chat app runtime-family selection and platform limitations.
tool/testing/test_matrix.dart Updates test-matrix descriptions to reflect new LiteRT-LM smoke behavior.
tool/macos_litert_lm_prepare_app.sh Updates macOS prepare logic to skip when SPM runtime is detected; stages dylibs into LiteRtLmRuntime/.
tool/macos_fair_litert_vs_llamadart.sh Removes StreamProxy framework expectation (StreamProxy now embedded).
tool/litert_lm_library_smoke.dart Adds a library/symbol smoke test for LiteRT-LM runtime loading in CI.
test/unit/tooling/macos_litert_lm_prepare_app_script_test.dart Updates tests for new macOS runtime staging layout (libraries instead of frameworks).
test/unit/hook/native_bundle_config_test.dart Adds OS-level runtime/backend override tests and updates default-runtime expectations.
test/unit/hook/build_hook_litert_lm_integration_test.dart Updates LiteRT-LM hook integration expectations for SPM/process lookup and unavailable iOS x86_64 simulator runtime.
test/unit/hook/build_hook_linux_integration_test.dart Updates Linux hook tests for new default runtime selection behavior.
test/unit/hook/build_hook_integration_test.dart Updates Windows hook tests for new defaults and adds “all runtimes” coverage.
test/unit/hook/build_hook_android_integration_test.dart Updates Android hook test expectations after StreamProxy removal.
test/unit/backends/litert_lm/litert_lm_runtime_test.dart Updates runtime lookup candidates and required-libraries lists after StreamProxy embedding and SPM lookup changes.
README.md Updates docs for runtime defaults, pins, and Apple SPM behavior.
pubspec.yaml Adds Flutter SDK constraint and declares iOS/macOS plugin metadata for shared Darwin source.
lib/src/hook/native_bundle_config.dart Implements per-OS platform keys + exact-target precedence for runtime/backend selection; changes defaults (Android vs others).
lib/src/backends/llama_cpp/llama_cpp_service.dart Adjusts Apple backend-module loading behavior and adds iOS Frameworks search path for fallback lookups.
lib/src/backends/llama_cpp/bindings.dart Regenerates/updates FFI bindings to match b9536 headers.
lib/src/backends/litert_lm/litert_lm_runtime.dart Updates LiteRT-LM version, Apple SPM/process lookup handling, and embedded StreamProxy loading.
hook/build.dart Updates pins and LiteRT-LM bundle spec structure; adds Apple SPM early-return path; changes runtime defaults and LiteRT-LM cache validation strategy.
example/README.md Notes GGUF + LiteRT-LM routing in chat app and updated runtime download wording.
example/chat_app/test/litert_lm_benchmark_app_test.dart Adds tests for benchmark backend selection and documents-relative model resolution.
example/chat_app/README.md Documents opting into both runtime families and clarifies platform support for LiteRT-LM.
example/chat_app/pubspec.yaml Opts the chat app into both runtime families with per-target exclusions where bundles aren’t published.
example/chat_app/macos/Runner.xcworkspace/contents.xcworkspacedata Removes Pods reference from workspace.
example/chat_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme Adds a pre-build “prepare” action consistent with SwiftPM flow.
example/chat_app/macos/Runner.xcodeproj/project.pbxproj Removes CocoaPods wiring; adds SwiftPM package reference; updates macOS deployment target to 14.0.
example/chat_app/macos/Podfile Removes CocoaPods configuration for macOS.
example/chat_app/macos/Podfile.lock Removes CocoaPods lockfile for macOS.
example/chat_app/macos/Flutter/GeneratedPluginRegistrant.swift Adds llamadart plugin registration import/call.
example/chat_app/macos/Flutter/Flutter-Release.xcconfig Removes Pods xcconfig include.
example/chat_app/macos/Flutter/Flutter-Debug.xcconfig Removes Pods xcconfig include.
example/chat_app/lib/litert_lm_benchmark_app.dart Improves backend selection defaults and resolves model paths via Documents on iOS (and via path_provider).
example/chat_app/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved Adds SwiftPM resolution for iOS workspace dependencies.
example/chat_app/ios/Runner.xcworkspace/contents.xcworkspacedata Removes Pods reference from workspace.
example/chat_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme Adds a pre-build “prepare” action consistent with SwiftPM flow.
example/chat_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved Adds SwiftPM resolution for iOS project workspace dependencies.
example/chat_app/ios/Runner.xcodeproj/project.pbxproj Removes CocoaPods wiring; adds SwiftPM package reference.
example/chat_app/ios/Podfile Removes CocoaPods configuration for iOS.
example/chat_app/ios/Podfile.lock Removes CocoaPods lockfile for iOS.
example/chat_app/ios/Flutter/Release.xcconfig Removes Pods xcconfig include.
example/chat_app/ios/Flutter/Debug.xcconfig Removes Pods xcconfig include.
example/chat_app/integration_test/smoke_test.dart Makes GGUF smoke configurable and streams downloads to disk to avoid buffering multi-GB models.
darwin/llamadart/Sources/llamadart/LlamadartPlugin.swift Adds a minimal Flutter plugin class to ensure SPM-linked symbols are present for process lookup.
darwin/llamadart/Package.swift Adds SwiftPM manifest with binary targets pinned to llamadart-native/litert-lm-native release assets and checksums (with local Artifacts fallback).
CHANGELOG.md Adds an Unreleased entry (currently only mentions runtime-default changes).
.github/workflows/sync_native_bindings.yml Updates workflow name and checklist; includes darwin/llamadart/Package.swift in PR paths.
.github/workflows/litert_lm_smoke.yml Adds native library smoke step and makes engine smoke conditional on model download; updates version resolution and cache usage.
Files not reviewed (2)
  • example/chat_app/ios/Runner.xcworkspace/contents.xcworkspacedata: Language not supported
  • example/chat_app/macos/Runner.xcworkspace/contents.xcworkspacedata: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hook/build.dart
Comment thread CHANGELOG.md
@leehack leehack merged commit 31766f9 into main Jun 6, 2026
11 checks passed
@leehack leehack deleted the apple-spm-native-runtimes branch June 6, 2026 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants