Skip to main content

xcross 2.0.2 copy "xcross: ^2.0.2" to clipboard
xcross: ^2.0.2 copied to clipboard

Build, run, and hot-reload Flutter iOS apps natively from Linux and Windows with official Swift and LLVM toolchains and no xtool runtime.

2.0.2 #

  • Sign apps that embed resource-only .bundle directories, such as GoogleCastCoreResources.bundle inside GoogleCast.framework or SwiftPM <Package>_<Target>.bundle resource bundles. Device runs no longer fail at "Signing app" with "unsupported nested code bundle". These bundles hold no code, so they are sealed as resources of the enclosing bundle like codesign does. A .bundle that declares an executable or contains Mach-O code is still rejected. (#118)
  • Exit as soon as a command finishes. A leftover stdin subscription, socket, HTTP client, timer or child process (for example after q in a run session or an auth failure) no longer keeps the CLI hanging. (#112)
  • Stop Windows plugin builds failing with "could not build Objective-C module 'UIKit'" or "module 'UIKit' is defined in both". The SDK Clang modules the plugins import are now built once before the parallel build, and a build that still loses a module cache race is retried. (#117)
  • Retry a Windows swift package resolve that crashes with an access violation (0xC0000005) on large plugin graphs. (#114)

2.0.1 #

  • Resolve packages/<package>/... shader and font paths in a package's pubspec.yaml inside that package's lib/ directory, like flutter build. Apps depending on material_ui (for example through cached_network_image) no longer fail with "shader not found: packages/material_ui/packages/material_ui/shaders/ink_sparkle.frag". (#110)

2.0.0 #

  • Breaking: split xcross clean into per-area commands. xcross flutter clean clears the project's native asset and SwiftPM build caches (what xcross clean used to do, now for both device and simulator targets). xcross compose clean clears the Compose project's xcross build output and Kotlin/Native caches. xcross sdk clean removes the installed Darwin Swift SDK along with leftover backup and staging copies. The top-level xcross clean is gone.
  • Breaking: rename xcross auth clear to xcross auth clean. The old spelling now fails with a pointer to the new one.
  • Breaking: replace xcross doctor with xcross flutter doctor and xcross compose doctor, each checking only the dependencies its own framework needs.
  • Breaking: require Swift 6.4 or newer on Linux and Windows. setup, sdk install and doctor reject older swift.org toolchains. macOS stays on the Xcode-paired Swift.
  • Breaking: resolve SwiftPM dependencies natively. xcross no longer clones URL dependencies or rewrites them to path dependencies. SwiftPM resolves the whole plugin graph itself and an xcross manifest compiler applies host fixes to every manifest it evaluates, without touching Package.swift.
  • Run on a device without a network after the first online run. When Apple's Developer Services cannot be reached, or the saved Apple ID session has expired, xcross signs with the cached certificate and provisioning profile for that app instead of failing, and says what to do when the cache cannot cover the run (no profile yet, device not in it, expired). XCROSS_OFFLINE=1 skips Apple entirely. A 20-second cap on the Apple ID access check keeps a dead network from stalling the run.
  • Ask on an app's first device build whether to register the original bundle id or an XCR- prefixed one, and save the answer as bundle_id under xcross: in pubspec.yaml (or in xcross_project.yaml for Compose). CI and IDE debug sessions use the saved value, falling back to the prefixed id only when nothing is saved. XCROSS_BUNDLE_ID=original|prefixed overrides it for a run.
  • Stop reusing Flutter SDK engine artifacts left over from an older engine. After a Flutter upgrade on Linux or Windows, flutter precache --ios artifacts are never refreshed, so xcross shipped a stale Flutter.framework that rejected the app kernel with "Invalid SDK hash" and showed a black screen. xcross now reuses SDK iOS artifacts on Linux and Windows only when the framework's FlutterEngine revision matches the SDK engine (Flutter rewrites ios-sdk.stamp there without refreshing the files, so the stamp is only trusted on macOS). Host snapshots and the patched SDK are checked against flutter_sdk.stamp. Mismatched artifacts are fetched into the xcross cache with a one-time warning naming the refresh command, and a Dart SDK from another engine is flagged too. (#93)
  • Group doctor output into project, toolchain, and deployment sections with a status header, aligned rows, dimmed locations, and a spinner while each section runs.
  • List every Compose requirement individually in xcross compose doctor, and report a missing Kotlin/Native download as a warning since the first build fetches it.
  • Build, sign, self-update and install natively on Windows ARM64, including Apple ID login through ADI. install.ps1 picks the ARM64 asset even from an emulated x64 PowerShell, and releases ship xcross-windows-arm64.zip.
  • Compile Flutter shaders with the host impellerc like flutter build, so ink sparkle, stretch and app or package shaders: entries load at runtime. Tree shake icon fonts in profile and release builds behind --[no-]tree-shake-icons.
  • Expand SwiftUI, #Preview (including UIKit and widget previews) and FoundationModels macros through the Open Apple Macros server. Release bundles ship it prebuilt from the pinned arxdeus/OpenAppleMacros fork, so the first build no longer compiles swift-syntax. Source and pub installs build the pinned revision once and cache it. tools.OpenAppleMacrosServer points xcross at another server.
  • Split Windows setup into winget, Scoop, Chocolatey and direct scripts, confirm setup scripts before running them, and install the pinned LLVM into XCROSS_LLVM_DIR when another LLVM is on PATH.
  • Preserve Flutter package licenses across iOS builds, for apps with and without native hooks, keeping compiler definitions and flavors. (#94)
  • Keep the banner link visible on dark Linux terminal themes. (#80)

1.5.1 #

  • Resolve the Dart launcher per host platform in xcross update, and harden launcher resolution and batch launches.
  • Run integration and Compose workflows on every push and fork PR without cancelling running jobs.

1.5.0 #

  • Build and run real Compose Multiplatform apps on a device from Linux and Windows: stage Compose resources, honour static frameworks, keep sibling project klibs in the link, expand $(VAR) build settings in Info.plist, and find nested iosApp layouts.
  • Speed up Compose debug links with per-library Kotlin/Native compiler caches, reuse the Gradle daemon, and compile plus dump dependencies in one Gradle invocation.
  • Link Compose apps on Windows with the official LLVM installer: fall back to llvm-ar when llvm-libtool-darwin is missing, and drop Kotlin/Native platform klibs Gradle resolves from a second distribution.
  • Link the iOS compiler runtime into the Compose runner, fixing ___isPlatformVersionAtLeast on Linux.
  • Sign an App ID the team already owns under its real bundle id instead of an XCR- qualified one, so Sign in with Apple, passkeys, push and associated domains keep working.
  • Enable the App ID capabilities a Compose app's entitlements declare, for the app and its extensions, and sign with the app's declared entitlements where the profile grants a wildcard.
  • Only delete provisioning profiles xcross created, or a lone development profile occupying the App ID's only slot. Release profiles are never deleted.
  • Repair Windows Flutter iOS builds and debug sessions, recover missing SwiftUI State macros in staged sources, and reject native asset framework symlinks that escape the framework.
  • Make examples/flutter_example build on Linux: answer xcrun --version, shim ar, and prefer a clang new enough for the SDK's libc++.
  • Rewrite arm64e.x1 stub targets so Xcode 27 SDKs link with released ld64.lld.
  • Render dim and TUI text readably on dark terminal themes.
  • Add a Compose integration workflow that builds examples/compose_app on Linux and Windows.

1.4.5 #

  • Stop cold Flutter iOS builds deadlocking on git cat-file --batch: read the process output while the requests are still being written, so a symlink-heavy SwiftPM checkout no longer fills the pipe buffer and hangs the build indefinitely.
  • Cache SwiftPM plugin builds on main under one stable key per toolchain, so a push refreshes a single cache entry instead of accumulating one per run.

1.4.4 #

  • Report the reason behind an app's SIGABRT on device: stream the device log over plain usbmux, always retain a bounded history, and print the abort reason (or the last device lines) with the crash.
  • Bump archive from 4.2.0 to 4.3.0.
  • Document the configuration section and warn against using a primary Apple ID for xcross auth.

1.4.3 #

  • Speed up incremental Flutter iOS builds substantially: only prebuild the Swift interop targets the aggregate can actually reach, skip the interop re-plan when the build manifest already carries the search paths, and derive generated-file timestamps from their content so staged sources and vendored manifests stop invalidating SwiftPM on every run.
  • Reuse one Flutter tool workspace across builds instead of a per-build temporary directory, and stop clearing the native-assets output, so flutter assemble no longer re-runs every build hook each time.
  • Stop bounding SwiftPM resolve and swift build by wall clock, and drop the integration job timeout: a cold dependency graph is slow rather than stuck, and the cap turned that into a failure.
  • Surface Apple rate limits, unify the akd client identity, and disable GrandSlam connection reuse to avoid proof-stage HTTP 429.

1.4.2 #

  • Point GrandSlam anisette X-MMe-Client-Info at akd/1.0 instead of an Xcode identity.
  • Prebuild planned Swift interop targets and re-plan the Swift build with those search paths, so cloud_firestore finds FirebaseFirestore on a cold Windows build.
  • Bound SwiftPM resolve, git clones, and binary-artifact downloads, fail instead of hanging on invisible git credential prompts, and surface SwiftPM's stdout diagnostic when resolve fails.

1.4.1 #

  • Vendor transitive SwiftPM dependencies faithfully: keep .package(path:) unnamed for manifests older than swift-tools-version 5.2, and initialize git submodules in vendored checkouts (fixes flutter_image_compress).
  • Preserve chained-fixup metadata when repairing Objective-C selrefs, fixing a launch crash in dyld4::PrebuiltObjC on apps linked with lld 19 or newer.
  • Install lld from apt.llvm.org (llvm.sh) in the apt setup script instead of the distro lld package, register an unversioned ld.lld through update-alternatives, and verify the linker in the dnf and pacman ones.
  • Report the resolved linker version in xcross doctor.

1.4.0 #

  • Add xcross config with an interactive terminal config editor and a dynamic, script-driven setup flow.
  • Support local installer builds and avoid running setup during installation.
  • Prefer build tool shims in xcrun resolution and use native executable compiler aliases for Windows native assets.
  • Repair Objective-C fast stubs sharing a selref when one stub can relocate, fixing incremental SwiftPM relinks on Linux.
  • Vendor URL dependencies declared by vendored SwiftPM packages using cached git checkouts, including transitive package manifests.
  • Improve cross-platform SwiftPM dependency resolution, binary artifact recovery, symlink materialization, and long-path staging.
  • Reuse content-validated SwiftPM plugin builds and stabilize interop flags across build retries.

1.3.6 #

  • Repair Kotlin native-asset builds on Linux, including Objective-C small-stub arguments and Mach-O fast-stub rewriting.
  • Strengthen release update verification, rollback, and recovery of missing native libraries.

1.3.5 #

  • Normalize native asset framework install names and Mach-O dylib references for correct runtime loading.
  • Cache SwiftPM build identities and artifact-junction capabilities to reduce repeated build work.
  • Strengthen toolchain and SDK cache invalidation using filesystem change metadata.
  • Update the examples repository reference.

1.3.4 #

  • Add xcross clean to clear project-local native asset and SwiftPM build caches while preserving shared caches and unrelated build output.
  • Expand xcross doctor with Windows iOS tool checks and remediation guidance.
  • Prevent source-update cleanup from deleting active temporary directories owned by concurrent xcross operations.
  • Update the examples repository reference.

1.3.3 #

  • Add xcross doctor with cross-platform checks and remediation guidance for required and optional tooling.

1.3.2 #

  • Stabilize Flutter iOS builds on Windows with native-asset tool shims, xcrun compatibility, shorter SwiftPM workspaces, reusable staged builds, and resilient transitive binary-artifact recovery.
  • Simplify SwiftPM artifact handling and improve release installation, tool-output parsing, linker argument forwarding, and cross-platform integration coverage.
  • Move examples to the dedicated examples repository and update package dependencies.

1.3.1 #

  • Fix Flutter iOS native-asset builds on Windows by using the resolved LLVM Clang as the cc host compiler and falling back from unavailable llvm-otool to llvm-objdump with compatible Mach-O inspection arguments.

1.3.0 #

  • Expand Flutter iOS compatibility with SwiftPM Firebase support, packaged native assets, dependency fonts, resilient Swift interop targets, correct UIScene window attachment, and support for read-only Flutter SDKs.
  • Improve Flutter launch and hot-reload reliability with transport-specific VM Service binding, immediate session controls while hot reload prepares, clearer diagnostics, and safer device log streaming.
  • Make wireless device sessions more reliable by bounding Developer Disk Image mounts, shortening timeout recovery, and restarting stale Wi-Fi tunnel daemons.
  • Improve update cleanup so stale source-build clones are always removed.

1.2.2 #

  • Phase release and update identity work so source-ref installs report injected normalized refs, tagged release archives report the release tag, and unreleased builds stay clearly marked until the next official update.
  • Build Linux and Windows release artifacts through the shared compile-time identity wrapper, remove the hardcoded dev version fallback from stamped release automation, and keep unreleased installs returning to the latest official release.

1.2.1 #

  • Replace the old tag-only update selector with --ref, so release tags still install verified release assets while branch and commit refs build from source before the same atomic install step.

1.2.0 #

  • Add first-class wireless device support with xcross tunnel --wifi and xcross flutter run --wifi. xcross can bootstrap RemotePairing over a trusted USB connection, reconnect saved wireless pairings, or advertise the host for cable-free pairing on iOS 27+, then start a TCP RSD tunnel and mount the Developer Disk Image automatically. (#29)
  • Discover wireless devices through pymobiledevice3 tunneld, route installs, app lookup, DDI mounting, and launches through the correct RSD transport, and surface actionable pairing, mDNS, Python, privilege, and tunnel diagnostics. (#29)
  • Launch the exact account-qualified bundle id produced during signing and installation instead of guessing from installed apps. This avoids attaching to stale xcross builds or production/TestFlight builds with the same base bundle id, which could cause kernel-version errors or denied debugging. (#28)
  • Complete App Groups support for share and action extensions. Xcode 16 synced folders and localized resources are handled correctly, Swift module names match extension principal classes, host and extensions use the same group and callback URL scheme, and Apple ID signing creates and attaches groups automatically. (#27)
  • Treat the issued provisioning profile as the source of truth for App Group entitlements. App Store Connect API keys can use a group attached manually by passing XCROSS_APP_GROUP, while unsupported group creation no longer blocks an otherwise valid install. (#27)
  • Retry Linux package installation after refreshing a stale APT index. (#29)

1.1.2 #

  • Build, embed, sign and install iOS app extensions (share and action extensions). Extension targets are read from the Xcode project, compiled against the Darwin SDK, embedded at <App>.app/PlugIns/<Name>.appex, and each is given its own App ID and provisioning profile. This is what lets plugins such as receive_sharing_intent appear in the iOS share sheet. See docs/app-extensions.md. (#23)
  • Resolve the bundle id from the application target rather than the first PRODUCT_BUNDLE_IDENTIFIER in project.pbxproj. A project with a share extension usually lists the extension's first, so xcross signed, installed and launched the extension instead of the app, showing a blank screen. (#23)
  • Expand $(MARKETING_VERSION) and $(CURRENT_PROJECT_VERSION) from the application target's build settings. The default ios/Runner/Info.plist references both, so apps were shipping a literal $(MARKETING_VERSION) as their version string. Embedded extensions inherit the app's versions, which iOS requires them to match.
  • Register App Groups declared by an app or its extensions, qualified per account (group.XCR-<TEAM>.…) because App Group ids are globally unique. Enabling the capability on the App IDs is still a manual step on developer.apple.com; xcross reuses an existing group, so the next run picks it up.

1.1.1 #

  • Detect a Swift toolchain that no longer matches the installed Darwin SDK. xcross sdk install patches the SDK with the selected toolchain's clang headers, so switching Swift afterwards made every plugin build fail with "this SDK is not supported by the compiler" and no mention of the SDK. The toolchain is now recorded at install time and checked before building, with a message naming the cause and the command that fixes it.
  • Require Swift on PATH before xcross setup and xcross sdk install, which previously failed only after a sudo prompt and a full package transaction, or after extracting tens of gigabytes.
  • Verify the Xcode archive before xcross sdk install removes the previous SDK, so a wrong path or a partial download no longer leaves the host with no SDK at all.
  • Fail the Windows release job on failing tests, and fix the 7 Windows-only test bugs that gap had been hiding.

1.1.0 #

  • Add Compose Multiplatform support: xcross compose setup, xcross compose build, and xcross compose run build, sign, install, and launch Kotlin Multiplatform iOS frameworks and .app bundles from Linux and Windows, with a --watch rebuild loop and fingerprinted builds that skip konanc when nothing changed.
  • Provision and patch the Kotlin/Native toolchain for cross-host iOS builds: spoof Apple host checks, stage an Apple toolchain and the real compiler-rt archives, keep dependency resolution off the network, and disable Apple-only debug transparent stepping.
  • Pass explicit -arch and -platform_version through the Swift runner link, and degrade a missing Windows dsymutil to a no-op.
  • Build sharedDarwinSource Flutter plugins from their darwin/ directory, and warn instead of silently dropping a plugin whose iOS manifest is missing.
  • Generate and run the Dart plugin registrant, so federated plugins that register through dartPluginClass no longer fail at first use.

1.0.5 #

  • Enhance Windows SwiftPM support and normalize staged plugin manifests.
  • Synthesize fallback Clang/Swift modules for SwiftPM checkouts, including nested modules, module shims, and Swift interop headers for Objective-C and Swift consumers.
  • Infer fallback module topology and linkage from sources, and preserve source fallback module names across rebuilds.
  • Implement #Preview through a compiler plugin instead of patching plugin sources.
  • Make Flutter plugin staging incremental, staging only iOS-reachable package entries, pruning entries the filter no longer stages, and skipping development-only trees and pigeons/.
  • Keep binary files out of the sync transform, and preserve checkout symlink identity and materialized checkout placeholders.
  • Forward symlinked headers and avoid a Clang module lock deadlock on Windows.
  • Skip cross-host Swift interface verification.

1.0.4 #

  • Resolve Flutter package configs from workspace roots.
  • Pin the iOS SDK and sysroot for Flutter plugin linking, and expose Flutter headers to Objective-C plugins.
  • Propagate the project's iOS deployment target through SwiftPM builds and generated app metadata.
  • Normalize SwiftPM linker flags and stage normalized manifests for plugin builds.
  • Skip generated imports for FFI-only Flutter plugins.

1.0.3 #

  • Teach xcross setup to install host requirements on macOS via Homebrew and to verify the Windows toolchain more clearly.
  • Find Homebrew LLVM/lld installs on Apple Silicon and Intel Macs when resolving Darwin SDK link tools.
  • Recommend using a separate Apple account for auth in the README.

1.0.2 #

  • Recover automatically when tunneld refuses to create an RSD tunnel: xcross flutter run now mounts the Developer Disk Image and starts a lockdown tunnel itself instead of stalling 60s and silently degrading to the userspace transport.
  • Say why hot reload is unavailable, and answer r/R with that reason instead of ignoring the keypress.

1.0.1 #

  • Add xcross auth clear to sign out: deletes the saved App Store Connect key, the Apple ID session and its machine attestation state, and every certificate, private key, and provisioning profile xcross minted.
  • Reject unexpected positional arguments to xcross auth instead of silently starting an Apple ID login.
  • Accept certificates and profiles Apple minted up to an hour ahead of a lagging host clock, and name both clocks in the error when it is worse.

1.0.0 #

  • Build, sign, install, launch, and hot-reload Flutter iOS apps natively on Linux and Windows.
  • Support Swift Package Manager Flutter plugins on both hosts.
  • Apple ID/password login on Linux and Windows via Android ADI / Anisette, or App Store Connect API keys on either host.
  • Remove the xtool runtime completely; xcross now owns Darwin SDK setup and uses the native device pipeline.