142 Commits

Author SHA1 Message Date
Joel Winarske c5df09d7ee fix(env): make setup_env.sh follow the -w workspace
emb flutter now emits setup_env.sh into the resolved workspace after a
successful install, so FLUTTER_WORKSPACE matches the -w target instead of
the cwd a later bare `emb env` would default to.

emb env creates the output dir before writing (so `emb env -w <new path>`
no longer crashes on a missing dir) and warns when <workspace>/flutter is
absent. Its help and README are narrowed to its real role - regenerate
after a move and --print - since setup/flutter emit the file on the happy
path.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-18 08:29:46 -07:00
dependabot[bot] c1c7215e63 build(deps): bump actions/checkout from 5 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-18 15:12:49 +00:00
dependabot[bot] b9accd8f6b build(deps): bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-18 15:12:44 +00:00
Joel Winarske fadb4602d3 Merge pull request #27 from toyota-connected/feat/cross-ci-matrix
feat(cross): CI cross matrix, emb flutter clone fix, bootstrap --shellenv
2026-06-18 08:11:21 -07:00
Joel Winarske 1af62109e4 feat(bootstrap): add --shellenv for one-line PATH setup
--shellenv emits an eval-able export of the Dart SDK bin and the emb shim
dir, so eval "$(./bootstrap.sh --shellenv)" fetches Dart, activates emb,
and puts both on PATH in one line. The default clean-stdout bin-dir output
is unchanged.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-18 08:08:25 -07:00
Joel Winarske 32e2b5dcab fix(repo): create base dir before clone, fail gracefully
git clone runs with cwd set to the base folder, so emb flutter -w <path>
crashed with an unhandled ProcessException when <path> did not exist yet.
Run an OS-agnostic mkdir -p (createSync recursive) before cloning, and
widen the catch to ProcessException (git missing) and FileSystemException
(path uncreatable) so both return a failed RepoResult instead of crashing.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-18 08:08:25 -07:00
Joel Winarske 8e269eaaa2 feat(cross): add matrix render command and CI cross workflow
emb matrix renders a GitHub Actions {"include":[...]} matrix from the
cross: blocks of one or more manifests: one cell per (manifest x target x
supported host), each carrying the emb cross args, provider/triple, host
runner (container for hosts without a hosted runner), preflight tools, and
the sysroot_key/build_key for actions/cache.

The cross.yaml workflow renders the matrix, then validates every cell with
emb cross --dry-run (hermetic: no download/mount/ssh) as the PR gate -
ubuntu directly, fedora in a container. An opt-in build job runs the real
cross build keyed on the cache keys.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-18 08:08:25 -07:00
Joel Winarske abebccd437 Merge pull request #26 from toyota-connected/feat/cross-deploy-arch-check
feat(cross): warn on arch mismatch before deploying a bundle
2026-06-17 08:12:29 -07:00
Joel Winarske 947e6a0edb feat(cross): warn on arch mismatch before deploying a bundle
Pushing a runnable bundle whose embedder arch does not match the target
board (e.g. a native `--target local` build sent to an aarch64 board)
succeeded silently, then failed at run time on the board with a cryptic
`Exec format error`.

Before the push, `--deploy` now queries the board's arch (`uname -m`)
over the SSH connection it already uses and warns when it does not match
the bundle's arch, pointing the user at re-building with a matching
`--target`. The deploy still proceeds (the user may want to stage files
regardless); the warning just removes the surprise.

`Deployer.remoteArch` and a small `archMatches` alias-tolerant comparison
(arm64/aarch64, amd64/x86_64, armv7*/armhf) are unit-tested; the warning
was confirmed on real hardware (x86_64 bundle to an aarch64 board).

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-17 07:45:45 -07:00
Joel Winarske bcec5cc44c Merge pull request #25 from toyota-connected/feat/deploy-tar-fallback
feat(cross): tar-over-SSH deploy fallback when the target has no rsync
2026-06-17 07:02:22 -07:00
Joel Winarske 608ee05262 feat(cross): tar-over-SSH deploy fallback when the target has no rsync
`--deploy` required rsync on the board, but minimal images (raspios-lite,
Yocto) often don't ship it — the push then failed with a cryptic rsync
protocol error (code 12). Probe the target for rsync (`command -v rsync`) and
fall back to a tar-over-SSH stream (`tar -czf - | ssh … tar -xzf -`) that needs
only tar + a shell. DeployResult reports the method used; tests cover the
fallback path and the deploy log shows it.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 18:10:27 -07:00
Joel Winarske 1086dd1d53 Merge pull request #24 from toyota-connected/feat/cross-deploy
feat(cross): --deploy rsyncs the runnable bundle to a board over SSH
2026-06-16 18:04:58 -07:00
Joel Winarske a59691b932 feat(cross): --deploy rsyncs the runnable bundle to a board over SSH
Closes the cross loop: `emb cross … --build --app <app> --deploy <user@host>`
rsyncs each runnable bundle to the board (creating the remote dir first), with
the SSH port/opts reused from cross.sysroot when device-sourced. `--deploy-dir`
sets the destination; `--run` then runs `./homescreen --b=.` on the target over
SSH (single backend). Deploy without --app is a usage error.

New Deployer (push + runArgv) drives rsync/ssh through the ProcessRunner seam;
hermetic tests cover the argv and transport. Validated end-to-end with a real
SSH/rsync round-trip: build → assemble → deploy, all pieces landing on the
remote.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 17:58:45 -07:00
Joel Winarske 1e21b42280 Merge pull request #23 from toyota-connected/feat/cross-runnable-bundle
feat(cross): --app assembles a runnable bundle (embedder + engine + app)
2026-06-16 17:52:22 -07:00
Joel Winarske c19fc631d4 Merge pull request #22 from toyota-connected/fix/disable-completion-autoinstall
fix: don't auto-install shell completion on every run
2026-06-16 17:51:32 -07:00
Joel Winarske 7347403c16 feat(cross): --app assembles a runnable bundle (embedder + engine + app)
`emb cross <pkg> --target <board> --build --app <flutter-app>` builds the
Flutter app for the target arch (reusing the engine fetch + AOT + assemble
pipeline) and drops the cross-built embedder beside it, producing a complete
runnable tree per backend:

  <buildRoot>/runnable[-<backend>]/
    homescreen
    data/flutter_assets/ …
    data/icudtl.dat
    lib/libapp.so
    lib/libflutter_engine.so

runnable on the target as `./homescreen --b=.`. `--mode` picks debug/profile/
release; `--tar` also emits a .tar.gz. New RunnableBundle assembler (install +
tar) with hermetic tests. Validated end-to-end: native local embedder +
wonderous release bundle assembled into a runnable x86-64 tree.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 17:48:00 -07:00
Joel Winarske 9389ce7b04 fix: don't auto-install shell completion on every run
CompletionCommandRunner auto-installs completion files to $XDG_CONFIG_HOME on
each invocation. A workspace setup_env.sh can point XDG_CONFIG_HOME into the
build tree, where a path component may be a file — so an unrelated command
(e.g. `emb --help`) failed with "FileSystemException: Not a directory". Disable
auto-install; completion is still available via `emb install-completion-files`.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 17:41:46 -07:00
Joel Winarske 4c2067e231 Merge pull request #21 from toyota-connected/feat/cross-defines-backend-selector
feat(cross): per-project cross config — defines/cmake_args, backend, platform & local selectors
2026-06-16 17:17:44 -07:00
Joel Winarske 4590c126b4 Merge remote-tracking branch 'origin/main' into feat/cross-defines-backend-selector 2026-06-16 17:15:37 -07:00
Joel Winarske 179b538539 fix(cross): build-all-backends.sh uses this checkout's emb
The wrapper ran whatever `emb` was on PATH, which fails if the global emb
predates --target/--backend. Default to `dart run <repo>/bin/emb.dart` (this
checkout) so it works on a feature branch before emb is re-installed; EMB=...
overrides. Source dir is absolutized and cwd preserved.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 16:57:56 -07:00
Joel Winarske a99f2344aa docs(cross): add build-all-backends.sh wrapper
A tiny script that drops all-backends.emb.yaml next to a given ivi-homescreen
checkout and runs `emb cross … --target local --build` for every backend.
Extra args (e.g. --backend, --deb) pass through.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 16:52:39 -07:00
Joel Winarske bacb50d8bf docs(cross): add all-backends example for native multi-backend builds
Move the "build every ivi-homescreen backend" manifest into examples/cross/ as
a tracked reference. It builds all six backends (wayland-egl/-vulkan,
drm-kms-egl/-vulkan, software, headless-egl) natively via the built-in `local`
target, exercising the cross.backends matrix + a shared cross.defines
(DISABLE_PLUGINS). Documented in the examples README; added a --dry-run test.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 16:51:19 -07:00
Joel Winarske a627a42a47 feat(cross): built-in local/host target for native dev-machine builds
Add an implicit `local` target (alias `host`) that builds the embedder natively
on the dev machine — no cross toolchain, no image/sysroot download, host
compiler + system libraries. A LocalCrossProvider.resolve() returns a profile
with no toolchain file and an empty sysroot, so the existing build/clean/deb
flow runs a plain native CMake/Meson build.

It is the default when a manifest defines cross.targets and no --target is
given, so `emb cross . --build` builds for the dev box while `--target rpi5`
cross-builds. A single cross: block with no targets still cross-builds by
default (backward compatible); `--target local` forces native there too.

The shared backends/defines/cmake_args/package apply; cross-only fields
(image_url, toolchain_version, cpu_flags) and augment staging are skipped.
CrossBuilder gains neutralizeHostEnv (false for native) so the host compiler
env is preserved rather than blanked.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 16:43:20 -07:00
Joel Winarske 088941bdd8 feat(cross): multi-platform manifests via cross.targets + --target
Switch between boards (rpi4/rpi5/rpi-zero-2w/radxa-zero3, …) from a single
manifest. Shared config lives at the cross: level; each platform under
cross.targets overrides only what differs (image_url, cpu_flags). Select one
with --target <name>; --list-targets prints the defined platforms. A manifest
with no targets behaves exactly as before (one implicit target).

Working dirs are content-hash keyed via a two-tier scheme so same-triple boards
no longer collide and identical sysroots are shared:
- sysrootKey (excludes cpu_flags) names the toolchain+sysroot dir, so cpu-only
  variants on one image (rpi4/rpi5/zero-2w) share a single extraction.
- buildKey (full config) names the per-board build dir; the emitted cmake
  toolchain file is cpu-named so variants coexist in the shared sysroot dir.
A different image (radxa) gets its own sysroot.

cross-build/cross/yocto-sdk dirs and --clean are updated to the keyed names.
Adds examples/cross/raspberry-pi-family.emb.yaml and README docs.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-16 16:19:41 -07:00
Joel Winarske 05f53bcfaa Merge pull request #20 from toyota-connected/fix/cross-usr-merge-after-dev
fix(cross): normalize usr-merge after -dev staging; surface overlay build errors
2026-06-16 16:01:07 -07:00