Skip to content

ci: build every engine arch from one gclient sync (single job, serial) - #22

Draft
jwinarske wants to merge 6 commits into
mainfrom
adopt-build-engine-sh
Draft

ci: build every engine arch from one gclient sync (single job, serial)#22
jwinarske wants to merge 6 commits into
mainfrom
adopt-build-engine-sh

Conversation

@jwinarske

@jwinarske jwinarske commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Replaces the four per-arch engine workflows with one job that syncs the engine
source once
and builds every (arch, runtime-mode) from that single closure,
driving the shared scripts/build-engine.sh recipe (the same recipe emb and the
Yocto layer call).

Why

The old matrix ran four jobs, each doing its own full gclient sync — the
same arch-independent flutter monorepo + DEPS, tens of GB, fetched four times.
The closure does not depend on the target arch; only the sysroot, gn triple, and
out dir do. So: sync once, add each arch's Debian sysroot side by side under
build/linux/, build each target into its own out dir.

Single shared patched tree

The patch series is applied once to the shared tree, so the superset must
coexist across arches (patches/series-all):

  • 0003-gn-riscv only adds riscv as a valid --linux-cpu — inert for others.
  • 0005-fml / 0007-atk are arch-neutral source fixes (0007 is a no-op on the
    older glib in the CI sysroots).
  • swiftshader-0002 is now arch-conditional (GN if/else on current_cpu):
    riscv64's Reactor gets llvm-16, every other arch keeps the llvm-10 it was
    validated against. Previously an unconditional llvm-10 -> llvm-16 bump, which
    would have silently switched arm64 (it also uses the LLVM Reactor —
    supports_subzero is false for arm64 and riscv64) onto an unvalidated llvm-16.
    Both llvm trees are already vendored, so no non-riscv build changes.

Serial, not parallel

One ninja -j nproc already saturates the cores, so running arches/modes
concurrently adds no throughput — only memory pressure (overlapping LTO release
links exhaust RAM). Builds run serially; each packaged combo's out dir is pruned
to bound disk (all combos share one checkout); per-combo ::group:: log sections
keep progress legible.

Before merge

  • Remove the temporary push: trigger (kept so the workflow can be exercised
    from this branch; workflow_dispatch only works once it is on the default
    branch).
  • Green validation run on the self-hosted runners (riscv64 + x86_64 already
    went green under the previous matrix form; the recipe itself is unchanged).

Note: the self-hosted runner shares the build machine with graphics testing;
the "Flutter Engine" workflow is currently disabled while that machine is being
looked at, so validation is deferred.

jwinarske and others added 3 commits August 13, 2026 13:09
…e.sh

The four per-arch workflows each inlined the same depot_tools/gclient/gn/ninja/
prepare-sdk orchestration, differing only by arch, triple, and sysroot. Replace
them with a single matrix workflow that drives scripts/build-engine.sh — the
shared recipe (also consumed by emb and, next, a meta-flutter Yocto recipe), so
the orchestration lives in exactly one place.

- Add scripts/build-engine.sh: fetch (gclient sync) + build (patch -> gn ->
  ninja -> prepare-sdk) phases; derives linux_cpu/triple/sysroot from the arch,
  applies the per-arch patch series, and stages engine-sdk/. Validated locally
  producing byte-comparable engines for x86_64/arm64/riscv64/armv7hf.
- Add patches/series-{default,riscv64}: the existing per-arch patch sets, with a
  strip level so the recipe applies the same patches git apply reads today (no
  patch files changed).
- flutter-engine.yaml matrix builds all arches x their modes (arm64/armv7hf/
  x86_64: debug/debug-unopt/profile/release; riscv64: debug/profile/release),
  preserving the exact linux-engine-sdk-<mode>-<arch>-<srcrev> tag names and the
  draft/upload release flow.

Signed-off-by: Joel Winarske <joel.winarske@linux.com>
workflow_dispatch only works once a workflow is on the default branch, so add a
branch-scoped push trigger (default srcrev, release=false) to exercise this on
the adoption branch. Revert this commit before merging.

Signed-off-by: Joel Winarske <joel.winarske@linux.com>
Rework the engine workflow from a four-way per-arch matrix — each job doing its
own full gclient sync — into one job that fetches the source closure ONCE and
builds every (arch, runtime-mode) from it.

The closure (flutter monorepo + DEPS) is arch-independent, so it is synced once;
each arch adds only its Debian sysroot (installed side by side under
build/linux/) and its own gn invocation + out dir. That removes three redundant
multi-tens-of-GB syncs per run.

The patch series is applied once to the shared tree. For that to be safe the
superset (patches/series-all) must coexist across arches: 0003 only adds riscv
as a valid --linux-cpu, 0005/0007 are arch-neutral source fixes, and
swiftshader-0002 is made arch-conditional (GN if/else on current_cpu) so riscv64
gets llvm-16 while every other arch keeps the llvm-10 Reactor it was validated
against. Both llvm trees are already vendored, so this changes no non-riscv build.

Builds run serially: one ninja -j nproc already saturates the cores, so parallel
arches/modes add no throughput, only memory pressure (overlapping LTO release
links exhaust RAM). Each packaged combo's out dir is pruned to bound disk, since
all combos now share one checkout. Per-combo log groups keep progress legible.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
@jwinarske jwinarske changed the title ci: consolidate per-arch engine builds into one matrix on build-engine.sh ci: build every engine arch from one gclient sync (single job, serial) Aug 17, 2026
The self-hosted runner shares the build machine with interactive work; a full
-j nproc sync/ninja starves it. Set EMB_JOBS=nproc-1 (min 1) in the job env so
both the gclient sync and every ninja build leave one core free.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
The release-mode LTO link is a single-threaded RAM spike that EMB_JOBS cannot
bound, and the self-hosted runner shares the machine with interactive work. Set
EMB_NO_LTO=1 for non-release runs (push + release=false dispatch); release=true
keeps LTO so published engines stay production builds. The release input is read
via an env var, not inlined, to avoid run-step injection.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
Empty commit to exercise the reworked workflow on the self-hosted runner via the
temporary push trigger. Drop before merge along with the push trigger.

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant