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>
--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>
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>
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>
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>
`--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>
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>
`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>
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>
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>
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>
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>
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>
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>