Skip to content

feat(config): flip .backend = .bgfx to the extracted package by default (#386 Phase 6c) - #419

Merged
apotema merged 3 commits into
mainfrom
feat/386-flip-bgfx-default
Jun 30, 2026
Merged

feat(config): flip .backend = .bgfx to the extracted package by default (#386 Phase 6c)#419
apotema merged 3 commits into
mainfrom
feat/386-flip-bgfx-default

Conversation

@apotema

@apotema apotema commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

bgfx becomes the first default-external backend

config.builtinProvider(.bgfx) now returns the labelle-bgfx provider (v0.2.0), so .backend = .bgfx transparently fetches + builds the out-of-tree backend instead of the bundled backends/bgfx slot. The enum-as-shorthand preserves the .bgfx tag, so every platform keeps working: desktop via the manifest splice, android via the enum sections (which pull from b.dependency("labelle_bgfx") → the fetched package). Both flip-blockers are already fixed (#416, #417).

Real CI validation of the flipped android path

The bgfx Android .so cross-build job builds examples/bgfx-android (.backend = .bgfx) — so on this PR it cross-compiles the flipped external bgfx for Android end-to-end. Green = the flip's android path works through CI.

Test rework (bgfx is now external, not bundled)

  • backend_registry: the all-bundled guard now expects bgfx external (tag preserved, named "bgfx"); the "not external" case uses raylib.
  • deps_linker: stagesSdlGamepad/stagesAndroidGamepad no longer stage siblings for bgfx (external = self-contained, carries its own gamepad packages).
  • build_zig: the bgfx-artifacts test overrides to the in-tree package via a local path + project_dir (desktop splice); exe-naming tests switch to raylib; the core-import loop drops bgfx.

Compatibility & validation

  • Existing projects are unaffected — they pin older assembler releases; this flip only takes effect for projects on the assembler version that ships it.
  • On-device (Galaxy Tab A7) external bgfx builds + runs crash-free and behaves identically to bundled.
  • ⚠️ Recommended final check before this ships in a release: a clean-render confirmation against a version-matched stack. FP's current pins have a gfx/core mismatch that black-screens both bundled and external bgfx (not the flip) — so a matched-pin render check is the honest gate. I'd hold merge until that's confirmed.

Next (Phase 6c continued)

With the flip proven, the bundled backends/bgfx becomes removable (slim step), and the same pattern repeats for the remaining backends (each needs a manifest first; sdl/wgpu also need window-contract conformance).

Summary by CodeRabbit

  • Bug Fixes
    • Updated backend handling so bgfx is resolved as an external backend package (instead of bundled built-in behavior), including updated cache validation and cache fetch logic driven by the effective backend package.
    • Adjusted SDL/Android gamepad staging so bgfx no longer stages sibling SDL/Android assets that bundled backends would inherit.
    • Updated build generation/linking behavior to match the new bgfx external resolution.
  • Tests
    • Updated unit and build tests to reflect the bgfx extraction behavior, including tightened “no core import” coverage and backend configuration changes for naming expectations.

…lt (#386 Phase 6c)

`builtinProvider(.bgfx)` now returns the labelle-bgfx provider package
(github.com/labelle-toolkit/labelle-bgfx v0.2.0), so `.backend = .bgfx`
transparently fetches + builds the OUT-OF-TREE backend instead of the bundled
`backends/bgfx` slot. bgfx is the first backend fully external by default.

The enum-as-shorthand preserves the `.bgfx` tag, so every platform path keeps
working: desktop via the manifest splice, android via the enum sections (which
pull from `b.dependency("labelle_bgfx")` → fetched package). Both flip-blockers
are already fixed (#416 callback guard, #417 enum-fallthrough).

Test rework (bgfx is now external, not bundled):
- backend_registry: the all-bundled guard now expects bgfx external (tag
  preserved, named "bgfx"); the "not external" case uses raylib (still bundled).
- deps_linker: stagesSdlGamepad/stagesAndroidGamepad no longer stage siblings
  for bgfx (external = self-contained, carries its own gamepad packages).
- build_zig: the bgfx-artifacts test overrides to the in-tree package via a
  local path + project_dir (desktop splice); the exe-naming tests switch to
  raylib (they test naming, not bgfx); the core-import loop drops bgfx.

Existing projects on older assembler releases are unaffected (they pin those
versions). On-device (Galaxy Tab A7) external bgfx builds + runs crash-free and
behaves identically to bundled. NOTE: a clean-render confirmation against a
VERSION-MATCHED stack is the recommended final check before this ships in a
release (FP's current pins have a gfx/core mismatch that black-screens BOTH
bundled and external — not the flip).
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 941ec3c5-b144-42a3-b421-18d7a336b5f6

📥 Commits

Reviewing files that changed from the base of the PR and between 20099a6 and f86a305.

📒 Files selected for processing (1)
  • src/config.zig
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/config.zig

📝 Walkthrough

Walkthrough

bgfx is reclassified from a bundled built-in backend to an external PluginDep in builtinProvider. Tests in backend_registry, deps_linker, and build_zig_tests are updated, and cache handling now uses effectiveBackendPackage() for backend package probing and fetching.

Changes

bgfx extracted as external backend

Layer / File(s) Summary
builtinProvider: bgfx mapped to external PluginDep
src/config.zig
The .bgfx switch case now returns a PluginDep with repo and version 0.2.0 instead of null.
backend_registry tests for external bgfx
src/backend_registry.zig
Built-in config test switches to .raylib; enum-as-shorthand loop asserts bgfx satisfies isExternal()/effectiveBackendPackage() != null while all other built-ins remain bundled.
cache resolution uses effective backend package
src/cache/resolve.zig, src/cache_cmd.zig
validateCache and ensureCache now branch on cfg.effectiveBackendPackage() instead of cfg.backend_package when probing and fetching backend packages.
deps_linker staging tests for external bgfx
src/deps_linker.zig
stagesSdlGamepad and stagesAndroidGamepad tests updated so extracted bgfx does not stage SDL/Android siblings, while bundled raylib and sokol still do.
build_zig_tests updates for external bgfx
test/build_zig_tests.zig
bgfx artifact test supplies explicit backend_package override; core-import loop removes .bgfx; exe-naming tests switch backend from .bgfx to .raylib.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐇 Hop hop, bgfx takes flight,
External now, not bundled tight.
Raylib stays tucked in its burrow bed,
While cache paths follow the package thread.
The tests all cheer with a gentle squeak—
New backend paths are neat and neat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: making .bgfx use the extracted package by default.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/386-flip-bgfx-default

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request extracts the bgfx backend into an external package, updating the project configuration to resolve .bgfx to its external repository and adjusting tests across backend_registry.zig, deps_linker.zig, and build_zig_tests.zig to reflect its new external, self-contained status. Feedback was provided to update an outdated comment block in src/config.zig that incorrectly states no backends have been extracted yet.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/config.zig
// .repo = "github.com/labelle-toolkit/labelle-bgfx",
// .version = "X.Y.Z" },
.raylib, .sokol, .sdl, .bgfx, .wgpu, .null => null,
.bgfx => .{ .name = "bgfx", .repo = "github.com/labelle-toolkit/labelle-bgfx", .version = "0.2.0" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The comment block directly above this line (lines 613–617) states that 'No backend has been extracted yet — all ship bundled.' This is now outdated and incorrect because bgfx has been extracted to an external package in this pull request. Please update or remove that comment block to prevent confusion for future developers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — the comment now says bgfx is extracted (resolves to the labelle-bgfx provider) and the rest are still bundled, instead of the stale 'no backend extracted yet'.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
src/backend_registry.zig (1)

231-248: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin the extracted provider metadata in this regression test.

Right now this only proves that .bgfx is “some” external provider named "bgfx". If the repo or pinned tag drifts from src/config.zig, these tests still pass and the break moves to fetch/build time. Assert the exact repo and version here too.

Suggested test hardening
         if (cfg.backend == .bgfx) {
             try std.testing.expect(cfg.isExternal());
-            try std.testing.expect(cfg.effectiveBackendPackage() != null);
+            const dep = cfg.effectiveBackendPackage().?;
             try std.testing.expectEqualStrings("bgfx", cfg.backendName());
+            try std.testing.expectEqualStrings("github.com/labelle-toolkit/labelle-bgfx", dep.repo);
+            try std.testing.expectEqualStrings("0.2.0", dep.version);
         } else {
             try std.testing.expect(!cfg.isExternal());
             try std.testing.expect(cfg.effectiveBackendPackage() == null);
             try std.testing.expectEqualStrings(f.name, cfg.backendName());
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/backend_registry.zig` around lines 231 - 248, The bgfx regression test in
the `enum-as-shorthand` case only checks that `.bgfx` is external and named
`"bgfx"`, so it can miss drift in the pinned provider metadata. Strengthen the
`cfg` assertions in this test to also verify the exact extracted backend package
fields from `effectiveBackendPackage()`, specifically the expected `repo` and
`version` values that match `src/config.zig`, while keeping the existing checks
for `isExternal()` and `backendName()`.
src/config.zig (1)

618-619: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update the builtinProvider contract comment in the same change.

This branch makes the nearby “Every built-in maps to null today” note false, so the docs now describe the opposite behavior for .bgfx. Please refresh that comment here so future extractions/tests don’t inherit stale assumptions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config.zig` around lines 618 - 619, Update the stale builtinProvider
contract comment near the .bgfx mapping so it no longer says every built-in maps
to null; the current builtinProvider behavior now returns a real provider for
.bgfx while the other built-ins still map to null. Refresh the comment in this
area to accurately describe the mixed behavior, keeping it aligned with the
builtinProvider and built-in mapping cases so future tests/extractions do not
rely on outdated assumptions.
test/build_zig_tests.zig (1)

110-115: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep one desktop test on the shorthand .bgfx path.

This case now forces backend_package, and effectiveBackendPackage() makes that win over builtinProvider(.bgfx). If the new default labelle-bgfx mapping regresses on desktop, this test still passes because it only exercises the local override. Please add a companion desktop test that leaves backend_package unset and verifies the shorthand path resolves labelle_bgfx correctly.

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/backend_registry.zig`:
- Around line 231-248: The bgfx regression test in the `enum-as-shorthand` case
only checks that `.bgfx` is external and named `"bgfx"`, so it can miss drift in
the pinned provider metadata. Strengthen the `cfg` assertions in this test to
also verify the exact extracted backend package fields from
`effectiveBackendPackage()`, specifically the expected `repo` and `version`
values that match `src/config.zig`, while keeping the existing checks for
`isExternal()` and `backendName()`.

In `@src/config.zig`:
- Around line 618-619: Update the stale builtinProvider contract comment near
the .bgfx mapping so it no longer says every built-in maps to null; the current
builtinProvider behavior now returns a real provider for .bgfx while the other
built-ins still map to null. Refresh the comment in this area to accurately
describe the mixed behavior, keeping it aligned with the builtinProvider and
built-in mapping cases so future tests/extractions do not rely on outdated
assumptions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4dedd289-9ab6-41db-a90a-dcc4a48c0899

📥 Commits

Reviewing files that changed from the base of the PR and between 4544eea and bc0da72.

📒 Files selected for processing (4)
  • src/backend_registry.zig
  • src/config.zig
  • src/deps_linker.zig
  • test/build_zig_tests.zig

apotema added 2 commits June 29, 2026 22:31
…flip)

validateCache + ensureCache checked the raw `.backend_package` field, which is
null for a flipped built-in (`.backend = .bgfx` resolves via builtinProvider, not
an explicit package). So a flipped backend was never fetched — ensureCache said
'all cached' and generate then failed staging with ExternalBackendNeedsManifest.
Route both through `cfg.effectiveBackendPackage()` (the same accessor
resolveBackendPackage uses) so an extracted built-in is fetched like any
external backend.

Caught by the bgfx Android .so cross-build CI job once #419 flipped bgfx; locally
masked by the monorepo sibling-fallback + explicit-config paths.
@apotema
apotema merged commit b43a4b6 into main Jun 30, 2026
6 checks passed
@apotema
apotema deleted the feat/386-flip-bgfx-default branch June 30, 2026 01:47
apotema added a commit that referenced this pull request Jun 30, 2026
…hase 6c)

bgfx is now resolved out-of-tree (`.backend = .bgfx` → the labelle-bgfx provider,
flipped in #419 and on-device-validated), so the in-tree `backends/bgfx/` slot is
dead weight. Delete it (~the whole src/templates/libs/manifest tree) and the
coverage that built it in-tree:

- Remove the `bgfx-build` CI job (`cd backends/bgfx && zig build test` + the
  standalone example). The bgfx backend's unit tests now run in labelle-bgfx's
  own CI (labelle-bgfx#1); its desktop+android builds are still exercised here
  via the examples-integration `bgfx-external` step and the `bgfx-android-build`
  job (both fetch the package).
- `bgfx-android-build` cache key now hashes the example + config (it pinned the
  deleted `backends/bgfx/build.zig.zon`).
- Drop the desktop bgfx-artifacts unit test (no in-tree package to resolve;
  coverage moved to labelle-bgfx + the splice tests) and the bgfx case from the
  in-tree-template preview regression list.

Other backends keep their bundled slots; only bgfx leaves. First backend fully
out of the assembler bundle.
apotema added a commit that referenced this pull request Jun 30, 2026
…hase 6c) (#420)

bgfx is now resolved out-of-tree (`.backend = .bgfx` → the labelle-bgfx provider,
flipped in #419 and on-device-validated), so the in-tree `backends/bgfx/` slot is
dead weight. Delete it (~the whole src/templates/libs/manifest tree) and the
coverage that built it in-tree:

- Remove the `bgfx-build` CI job (`cd backends/bgfx && zig build test` + the
  standalone example). The bgfx backend's unit tests now run in labelle-bgfx's
  own CI (labelle-bgfx#1); its desktop+android builds are still exercised here
  via the examples-integration `bgfx-external` step and the `bgfx-android-build`
  job (both fetch the package).
- `bgfx-android-build` cache key now hashes the example + config (it pinned the
  deleted `backends/bgfx/build.zig.zon`).
- Drop the desktop bgfx-artifacts unit test (no in-tree package to resolve;
  coverage moved to labelle-bgfx + the splice tests) and the bgfx case from the
  in-tree-template preview regression list.

Other backends keep their bundled slots; only bgfx leaves. First backend fully
out of the assembler bundle.
apotema added a commit that referenced this pull request Jun 30, 2026
)

* chore(slim): remove the bundled bgfx backend — it's extracted (#386 Phase 6c)

bgfx is now resolved out-of-tree (`.backend = .bgfx` → the labelle-bgfx provider,
flipped in #419 and on-device-validated), so the in-tree `backends/bgfx/` slot is
dead weight. Delete it (~the whole src/templates/libs/manifest tree) and the
coverage that built it in-tree:

- Remove the `bgfx-build` CI job (`cd backends/bgfx && zig build test` + the
  standalone example). The bgfx backend's unit tests now run in labelle-bgfx's
  own CI (labelle-bgfx#1); its desktop+android builds are still exercised here
  via the examples-integration `bgfx-external` step and the `bgfx-android-build`
  job (both fetch the package).
- `bgfx-android-build` cache key now hashes the example + config (it pinned the
  deleted `backends/bgfx/build.zig.zon`).
- Drop the desktop bgfx-artifacts unit test (no in-tree package to resolve;
  coverage moved to labelle-bgfx + the splice tests) and the bgfx case from the
  in-tree-template preview regression list.

Other backends keep their bundled slots; only bgfx leaves. First backend fully
out of the assembler bundle.

* fix(stage): skip zig-pkg/.labelle when hardlinking a local package

hardlinkTree skipped .zig-cache/zig-out/.git but copied zig-pkg/ and .labelle/.
Staging a local backend package that's a real repo checkout (e.g. a backend repo
shipping an example inside itself) then walked:
  - zig-pkg/<hash>/upstream/.../node_modules/... — deep enough that copyFile hit
    NameTooLong, which crashed staging (and tripped an invalid free on the way out).
  - .labelle/ — the in-repo example's own generated output, copied back into the stage.

Neither is part of a package's importable modules, so skip both alongside the
existing build/VCS dirs. Unblocks examples that live inside a backend package repo
(labelle-bgfx/examples/*) resolving the backend via its local checkout.
apotema added a commit that referenced this pull request Jun 30, 2026
…lt (#386 step 4) (#428)

builtinProvider(.wgpu) → labelle-wgpu 0.1.0, so `.backend = .wgpu` now fetches the
OUT-OF-TREE backend by default — wgpu is the second default-external backend
(after bgfx #419). Desktop-only, loop-style, no android/callback complications.

Test rework (same class as the bgfx flip):
- backend_registry enum-as-shorthand: wgpu joins bgfx as external (tag preserved).
- build_zig "links wgpu glfw artifact": point at a local wgpu pkg + project_dir so
  the manifest splice resolves in-tree (it now resolves external by default).
- build_zig no-backend_input-override loop: drop wgpu (now external, exercised by
  the external tests) — only the bundled null backend remains in that loop.

The cache fetch-path (effectiveBackendPackage in validate/ensureCache) + the
externalUsesEnumPath guard already landed with the bgfx flip, so wgpu inherits them.
apotema added a commit that referenced this pull request Jun 30, 2026
…lt (#386 step 4) (#431)

* feat(config): flip .backend = .null to the extracted package by default (#386 step 4)

builtinProvider(.null) → labelle-null 0.1.0 — null is the third default-external
backend (after bgfx #419, wgpu #428). Pure-Zig, zero deps, empty link fragment.

Notable: generateTestsTarget (#83) forces .backend=.null for every project's
`zig build test`, so that universal test target now fetches labelle-null (cached,
pure-Zig — the no-system-libs property still holds). The null headless +
plugin-controllers examples + the is_tests_target codegen now resolve external null.

Test rework (same class as the bgfx/wgpu flips): backend_registry enum-shorthand
(null joins bgfx/wgpu external), and the 4 build_zig `.backend=.null` tests
(null-wires-modules, no-override, the two is_tests_target tests) now point at a
local null pkg + project_dir so the manifest splice resolves. Inherited the cache
fetch-path + externalUsesEnumPath from the earlier flips.

* fix(cache): fetch the tests-target null backend for every project

The flip surfaced this (CI: a raylib project's tests-target generate failed
ExternalBackendNeedsManifest): generateTestsTarget (#83) forces .backend=.null
for EVERY project's `zig build test`, but validateCache/ensureCache only
considered the project's OWN backend — so external labelle-null was never
reported missing or fetched for a non-null project. Account for the tests-target
null in both (dedup when the project already IS null). No-op while null is bundled.

* test(cache): account for the tests-target null in validateCache external tests

The two external-backend validateCache tests now also see the tests-target's
external null in the missing set (every project validates null post-flip). Assert
the project backend specifically (local stub) + expect both fakebackend AND null
for the remote case.
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