142 Commits

Author SHA1 Message Date
Joel Winarske c1496faf91 Merge pull request #65 from toyota-connected/feat/cross-run-local
feat(cross): run native --target local bundle with --run
2026-06-20 21:02:55 -07:00
Joel Winarske 4b84751c1b feat(cross): run native --target local bundle with --run (no deploy)
`--run` previously only fired inside the --deploy/SSH path, so for a
native `--target local` build it was silently ignored. Launch the
freshly-built embedder against the assembled app bundle on this host
(`<embedder> -b <app-bundle>`, single embedder only). A non-native
cross-build without --deploy is skipped with a warning, since its binary
is a foreign arch and would only fail with `Exec format error`.

Also fix _artifactFor: skip CMakeFiles/** compiler-probe binaries, which
are ELF executables too and were shadowing the real shell/homescreen in
the heuristic scan — corrupting the run hint, local run, and deploy.

Signed-off-by: Joel Winarske <joel.winarske@outlook.com>
2026-06-20 20:56:35 -07:00
Joel Winarske a0a7e8edbc Merge pull request #64 from toyota-connected/fix/homescreen-bundle-flag
fix(bundle,cross): use ivi-homescreen -b flag, not --b=
2026-06-20 20:28:10 -07:00
Joel Winarske 16ab1fd572 fix(bundle,cross): use ivi-homescreen -b flag, not --b=
ivi-homescreen registers the option as "b,bundle" (cxxopts), so the long
form is --bundle and --b= is rejected — the embedder fails to start. Only
the short -b <dir> form works. Fix the runnable run command executed over
SSH (cross --run), the bundle/runnable hints, tests, and docs.

Signed-off-by: Joel Winarske <joel.winarske@outlook.com>
2026-06-20 20:24:54 -07:00
Joel Winarske 8c5e9ee224 Merge pull request #63 from toyota-connected/fix/packagekit-connect-retry
fix(pkg): retry transient packagekit connect on fresh boot
2026-06-20 20:05:03 -07:00
Joel Winarske 3ce655a566 fix(pkg): retry transient packagekit connect on fresh boot
Right after boot — notably under WSL — the system D-Bus and its
on-demand activation plumbing can be momentarily not-ready. In that
window PkClient.connect() fails near-instantly with
PkServiceUnavailableException (no daemon spawn is even attempted),
which made `emb doctor` report the packagekit backend as permanently
unavailable even though the package was installed and the daemon
activates fine seconds later.

Give _connect() a single retry after a short delay on that specific
exception so a startup race no longer surfaces as a hard failure.
Caching and all callers (isAvailable/missing/simulate/install/
availableUpdates) route through _connect(), so they inherit it.

Signed-off-by: Joel Winarske <joel.winarske@linux.com>
2026-06-20 19:57:50 -07:00
Joel Winarske dda6cd741e Merge pull request #62 from toyota-connected/fix/augment-download-retry
fix(cross): retry transient augment-source downloads
2026-06-20 07:56:18 -07:00
Joel Winarske 8c849812e0 Merge pull request #61 from toyota-connected/docs/app-extends
docs(cross): document + demonstrate app-layer extends
2026-06-20 07:54:06 -07:00
Joel Winarske df4c1759c2 fix(cross): retry transient augment-source downloads
A cross build fetches each augment source (e.g. libdisplay-info) on every CI
job, so a single upstream hiccup — observed as a gitlab 500 on the
libdisplay-info tarball — failed the whole job. Retry the download up to 4 times
with linear backoff on transient responses (HTTP 5xx / 429) and network
(IOException) errors; 4xx and the like still fail fast.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-20 07:53:16 -07:00
Joel Winarske 8417e3a0e8 docs(cross): document + demonstrate app-layer extends
Add a README subsection ("Layered manifests: extends, board → project → app")
covering both extends forms (<board> and <dir>#<target>) and the merge rules,
with project and app manifest snippets.

Add examples/cross/app-extends.emb.yaml: an app target that extends the rpi
family file's rpi5-bookworm target (which extends the board) and overlays an
app-specific dev package — a real three-layer chain. A cross_command test
--dry-runs it so it stays valid.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-20 07:13:21 -07:00
Joel Winarske 10b9eaf902 Merge pull request #60 from toyota-connected/feat/cross-extends-project
feat(cross): cross-file extends — app layer over a project target
2026-06-20 06:52:15 -07:00
Joel Winarske c45952bd58 feat(cross): cross-file extends — app layer over a project target
`cross.extends` gains a second form alongside the board reference:
  - <board>        : a target in emb's shipped board library (hardware).
  - <dir>#<target> : a target in another emb project at <dir> (the project
                     layer) — e.g. a Flutter app extending an ivi-homescreen
                     target, so plugin config (DISABLE_PLUGINS/PLUGINS_DIR,
                     plugin -dev packages) lives with the app.

This completes the layering: app -> project -> board. <dir> is resolved relative
to the extending manifest's project root (the .emb/ parent in .emb/ mode, else
the manifest's dir); the referenced project's own extends chain is applied via
resolve(), and the same merge rules apply (maps deep-merge, backends/cpu_flags
replace, sysroot.dev_packages union). Reference cycles across projects are
detected and reported.

Tests cover the three-layer merge (hardware from board, backends from project,
plugins from app, dev_packages unioned across all three) plus unknown-target
and missing-project errors.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-20 06:46:28 -07:00
Joel Winarske 74af17ac46 Merge pull request #59 from toyota-connected/feat/publish-skip-before-resolve
perf(cross): --publish skip-on-exists before the resolve
2026-06-19 18:38:37 -07:00
Joel Winarske e91c9b93b4 perf(cross): --publish skip-on-exists before the resolve
The image tag is content-addressed by the manifest alone (sysroot key + toolset
hash), so the "already published?" check no longer needs a resolved profile.
Move it ahead of provider.resolve(): when the image exists, --publish now skips
the toolchain/sysroot download + extract entirely instead of resolving just to
discover it can skip.

This is why a cache-evicted publish job previously spent ~2 min re-resolving a
sysroot only to skip; it now returns in seconds regardless of the sandbox cache.
The post-resolve skip-check in _publishImage is removed (the early check is
authoritative and emits the same tag); --force / --no-push paths are unchanged.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-19 18:36:34 -07:00
Joel Winarske bed992081c Merge pull request #58 from toyota-connected/fix/image-hwdata
fix(cross): bake hwdata into the toolchain image for libdisplay-info
2026-06-19 18:32:08 -07:00
Joel Winarske 52bf5f10e0 fix(cross): bake hwdata into the toolchain image for libdisplay-info
libdisplay-info 0.2.0's meson build reads /usr/share/hwdata/pnp.ids on the build
machine to bake the PNP-ID table into the library; without it `meson setup`
fails ("File /usr/share/hwdata/pnp.ids does not exist"). Add hwdata to the image
toolset alongside build-essential. Toolset change re-keys the image tag, so
publish rebuilds it automatically.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-19 18:29:44 -07:00
Joel Winarske c5509e71b7 Merge pull request #57 from toyota-connected/feat/build-timings
feat(cross): emit per-phase build timings (augment, build)
2026-06-19 18:04:16 -07:00
Joel Winarske 3498ddb691 feat(cross): emit per-phase build timings (augment, build)
A --build run now reports how long each phase took, alongside the existing
resolve time from the progress spinner:
  augment       : libdisplay-info staged (42.1s)
  build         : 1 backend(s) in 63.4s

This makes emb's cache-hit speedup measurable in CI (a warm consume build shows
resolve in seconds, no download/extract) and surfaces where cold time goes.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-19 18:01:06 -07:00
Joel Winarske b147711714 Merge pull request #56 from toyota-connected/feat/image-toolset-key
feat(cross): content-address the toolchain image by sysroot + toolset
2026-06-19 18:00:02 -07:00
Joel Winarske 802ebe5b6f feat(cross): content-address the toolchain image by sysroot + toolset
The publish skip-on-exists keyed only on sysroot_key, which omits the baked
toolset (the Dockerfile's base image, apt list, and slim prune list). A toolset
change with an unchanged sysroot (e.g. adding build-essential) left the old
image in place — skip-on-exists matched and never rebuilt.

The published image's primary tag is now `<sysrootKey>-<toolsetHash>`, where the
toolset hash covers the emitted Dockerfile + .dockerignore (ToolchainImage.
tagFor/imageTag). An emitter/toolset change yields a new tag, so publish
rebuilds and re-points the aliases. The baked in-image paths stay keyed by
sysrootKey, so a consume build still cache-hits; the build matrix references the
moving :<os> alias, so it always gets the latest image.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-19 17:57:54 -07:00
Joel Winarske 4aa659fcbe Merge pull request #55 from toyota-connected/fix/image-native-compiler
fix(cross): bake a native compiler into the toolchain image; surface augment errors
2026-06-19 17:49:07 -07:00
Joel Winarske 9cc7a92305 fix(cross): bake a native compiler into the toolchain image; surface augment errors
The toolchain image shipped cmake/ninja/meson but no native C/C++ compiler.
Rebuilding an `augment` library (libdisplay-info via meson) at consume time
then failed at `meson setup` — meson needs a build-machine compiler to
configure even a cross build. (Local validation missed it: that sysroot already
had the augment baked in, so meson was skipped.)

- dockerfile_emitter: add build-essential (gcc/g++/libc6-dev/make). Confirmed
  in a debian:bookworm-slim container: meson setup fails without it, succeeds
  with it.
- overlay_builder._check: surface stdout as well as stderr — meson/cmake write
  their diagnostics to stdout, so failures previously showed only a bare
  "meson setup failed (exit 1)".

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-19 17:46:57 -07:00
Joel Winarske 14b6c3b003 Merge pull request #54 from toyota-connected/fix/apt-deb822-sources
fix(cross): read deb822 apt sources (trixie/raspios) for -dev resolution
2026-06-19 17:19:08 -07:00
Joel Winarske c8b6d34c15 fix(cross): read deb822 apt sources (trixie/raspios) for -dev resolution
The arm-gnu provider resolved the -dev closure only from one-line `deb …`
sources (sources.list + sources.list.d/*.list). Trixie (Debian 13) and current
raspios ship their sources in deb822 format (sources.list.d/*.sources with
Types/URIs/Suites/Components), so resolution failed with "no apt sources …
(cannot resolve -dev)".

- aptIndexUrls now parses both formats: one-line entries and deb822 stanzas
  (multi-value URIs/Suites/Components, trailing-slash URIs normalized,
  deb-src and Enabled:no skipped).
- _readAptSources also reads sources.list.d/*.sources and separates files with
  a blank line so one-line and deb822 stanzas never merge.

Fixes the publish-trixie job; publish-bookworm (one-line sources) already
worked. Tests cover deb822 and mixed one-line+deb822 inputs.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2026-06-19 17:16:58 -07:00
Joel Winarske 7720208b29 Merge pull request #53 from toyota-connected/feat/publish-key-tag
fix(cross): --publish always pushes + skip-checks the immutable sysroot key
2026-06-19 16:58:46 -07:00