oscortex_cli 0.1.0 copy "oscortex_cli: ^0.1.0" to clipboard
oscortex_cli: ^0.1.0 copied to clipboard

Build and run Flutter apps for OSCortex. Compiles a Flutter project into a universal .osx bundle (native aarch64 + x86_64 in one artifact) and previews it in an emulator across architectures.

osx — the OSCortex app toolchain #

Build and preview Flutter apps for OSCortex, a Rust microkernel with a Flutter shell. OSCortex apps ship as .osx bundles. Flutter's own toolchain doesn't target OSCortex, so this package adds the missing init / build / run steps and hides the internals.

A single osx build produces a universal bundle that is native for both aarch64 and x86_64 — app developers never pick an architecture, and never touch the engine, gen_snapshot, or the bundle format by hand.

osx init     set up the OSCortex build target for a Flutter app
osx build    compile the app into a universal .osx bundle (both arches)
osx run      boot OSCortex in an emulator to preview (host arch fast, other emulated)

Install #

dart pub global activate oscortex_cli

This puts an osx executable on your path (ensure ~/.pub-cache/bin is in PATH). To run from a checkout instead:

cd tools/osx-cli
dart pub get
dart run bin/osx.dart --help

Prerequisites #

Tool Needed for Notes
Flutter (3.41.x) init, build Produces the asset bundle + AOT kernel. Must be on PATH.
Docker build Runs the per-arch gen_snapshot (Linux ELF) in a container.
QEMU run qemu-system-aarch64 and/or qemu-system-x86_64.
OSCortex source tree all The CLI orchestrates scripts in the repo. See Locating the OSCortex tree.

osx init checks all of these and tells you what's missing.


Commands #

osx init #

Run from the root of your Flutter app. It:

  1. Confirms you're in a Flutter project.
  2. Locates the OSCortex source tree (records it for later commands).
  3. Verifies the toolchain (Flutter, Docker, QEMU, host arch + accelerator).
  4. Fetches the pinned prebuilt engine and gen_snapshot for both architectures (via the repo's engine-port/fetch-engine.sh; the pin lives in engine-port/artifact.config).
  5. Writes .osx/config.json (display name, engine pin, OSCortex tree, version).
cd my_flutter_app
osx init
osx init --name "My App"        # override the launcher display name
osx init --skip-fetch           # record config + verify only (no download)

osx build #

Compiles the current app into .osx bundles. The pipeline:

host    flutter pub get
host    flutter build bundle                 -> build/flutter_assets/
host    frontend_server --aot --tfa           -> build/app_aot.dill   (arch-neutral)
docker  gen_snapshot[arm64]  (linux/arm64)    -> libapp-arm64.so
docker  gen_snapshot[x64]    (linux/amd64)    -> libapp-x64.so
pack    per-arch  My App-arm64.osx / My App-x64.osx
pack    universal My App.osx   (both snapshots in one bundle)
osx build                       # both arches + the universal bundle
osx build --arch arm64          # one arch only (no universal bundle)
osx build --name "My App"       # override display name
osx build --output-dir dist     # write bundles somewhere else
osx build --no-assets           # skip staging build/flutter_assets

Outputs land in build/osx/ by default:

build/osx/
  My App.osx            ← universal (fat) bundle — ship this
  My App-arm64.osx      ← aarch64-only bundle
  My App-x64.osx        ← x86_64-only bundle
  flutter_assets/       ← fonts, manifests, shaders (arch-neutral)

The AOT kernel (app_aot.dill) is architecture-neutral and built once on the host. Only gen_snapshot is per-arch, and it's a Linux binary, so build runs it in a throwaway ubuntu:22.04 container with the matching --platform. On Apple Silicon the x86_64 snapshot is produced under emulation (correct, just slower).

osx run (alias osx preview) #

Boots OSCortex in QEMU so you can preview across architectures. The host-native arch runs with hardware acceleration (HVF on macOS, KVM on Linux); the other arch is emulated with TCG.

osx run                         # boot the host arch, accelerated
osx run --arch x64              # boot x86_64 (emulated on an arm64 host)
osx run --arch arm64            # boot aarch64 (emulated on an x86_64 host)
osx run --image path/to.iso     # boot a specific image
osx run --headless              # no window; serial on stdio
osx run --serial-log /tmp/s.log # capture guest serial to a file
osx run --release v0.1.2        # pick the release the ISO is fetched from

Image selection, in order:

  1. --image <path> if given.
  2. A local aarch64 .kernel (checked under ~/OSCortex-run/, or OSCORTEX_KERNEL) — the fastest, most reliable interactive path on Apple Silicon.
  3. Otherwise the release .iso for the target arch, downloaded and cached under <oscortex>/.image-cache/.

In the window: click to capture the mouse, Ctrl+Alt+G to release, close the window (or Ctrl-A X when headless) to quit.


The universal .osx bundle #

OSCortex .osx bundles start with a fixed 112-byte header (OSCP magic, name, version, and a single AOT snapshot length) — see the kernel's app registry. That v1 layout carries one snapshot.

osx build emits a universal bundle that is a strict, backward-compatible superset:

offset 0    ┌───────────────────────────────┐
            │ v1 header (OSCP, version 1)    │  ← unchanged; aot_len covers the
            │   aot_len = primary snapshot   │     host-arch (primary) snapshot
offset 112  ├───────────────────────────────┤
            │ primary AOT snapshot           │  ← an unmodified OS boots THIS arch
            ├───────────────────────────────┤
            │ OSXM index                     │  ← (arch token, offset, length)×N
            │ other AOT snapshot(s)          │
            └───────────────────────────────┘
  • An OS that only understands v1 reads the header and the first snapshot — it always boots the primary (host) arch, so a fat bundle never bricks an older build.
  • An arch-aware loader reads the OSXM index and picks the matching arch at install/run time.

For maximum compatibility today, build also writes plain per-arch v1 bundles (-arm64.osx / -x64.osx). Their bytes are identical to what the project's tools/oscortex-pack.py produces. See Status for the kernel-side selection that's still pending.


Locating the OSCortex tree #

osx orchestrates scripts inside the OSCortex repo. It finds the tree via, in order:

  1. --oscortex-root <path>
  2. OSCORTEX_ROOT environment variable
  3. oscortexRoot recorded in your app's .osx/config.json (written by init)
  4. The repo this CLI itself lives in (when run from a checkout)
export OSCORTEX_ROOT=~/src/oscortex
# or
osx init --oscortex-root ~/src/oscortex

Status / known limitations #

Area State
osx init (fetch both engines, config, prereqs) Works.
osx build (both arches + universal bundle) Works. Per-arch v1 bundles are byte-identical to oscortex-pack.py; the universal bundle is verified v1-readable.
osx run (HVF/KVM host arch + TCG other arch) Works for both arches; auto-fetches the release ISO; prefers a local .kernel on aarch64.
Kernel-side arch selection from the fat bundle Pending. Today's kernel reads only the v1 header (one arch). The universal bundle's OSXM index is the forward path; until the kernel learns to select, install the per-arch bundle that matches the target.
osx run side-loading a freshly built app on boot Not yet. run boots the OS image (shell + core apps). Installing your own .osx into a running guest uses the package pipeline.
build without Docker Not supported — gen_snapshot is a Linux binary. A native macOS/Windows gen_snapshot would remove this dependency.

License #

Dual-licensed: AGPL-3.0-or-later or a commercial license. See the LICENSE and LICENSE-COMMERCIAL files in the OSCortex repository.

0
likes
130
points
16
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Build and run Flutter apps for OSCortex. Compiles a Flutter project into a universal .osx bundle (native aarch64 + x86_64 in one artifact) and previews it in an emulator across architectures.

License

AGPL-3.0 (license)

Dependencies

args, path

More

Packages that depend on oscortex_cli