Repository navigation
Reference the prepare hook through GEA_PROGRAM_HOOK and clean up stale asset manifests - #75
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
dashersw
left a comment
There was a problem hiding this comment.
Thanks for this. The diagnosis is right, and the generator change fixes the reported case: an Apple app with no embeddedAssets.storage links again. Notes, most important first:
1. The fix depends on every link including the generated assets unit. gea_app_entry.cpp still has an undefined weak reference whenever gea_embedded_assets_generated.cpp is not linked beside it. apple build-macos.sh adds that file only [[ -f "$GENERATED_ASSETS_CPP" ]], and the no-program smoke path (macos_smoke_app.cpp) may not produce one. Either case gives the same Undefined symbols _gea_embedded_assets_prepare. A weak default in gea_app_entry.cpp itself, in the !GEA_LINKED_HOOK_DEFAULTS branch, would fix every non-COFF link at the root. You mention this as an alternative, and I think it is the sturdier one. The generator's weak default can stay as well.
2. Merge order with geastack/windows#7. With GEA_PROGRAM_HOOK, the Windows reference becomes ordinary, and no /alternatename default exists until windows#7 lands. These two must merge together, and the Windows side has never been built or linked. Under the ordinary reference, if (gea_embedded_assets_prepare) is also always true, so clang-cl will emit -Wpointer-bool-conversion. The cycle-collection hooks already do the same, so this is only a nit.
3. The prepare() result is ignored (gea_app_entry.cpp:107). This predates the PR, but the PR now runs the hook for every app. If a file-backed bundle is missing or corrupt, prepare returns false, init carries on, and images built straight from the zero-filled GEA_FILE_ASSET_BUFFER arrays render blank, with no log line. It should at least log.
4. Multi-app binaries. The new comment justifies weak because a bundled binary links several apps' assets. The file-backed branch (generator line 303) still emits a strong definition, though, so two storage-backed apps in one resident build fail with duplicate symbol. Making it weak would let the linker silently pick one app's loader instead. Resident mode also drops gea_app_entry.cpp (build-macos.sh:1058), so no app's prepare runs there at all. A single global hook can't serve per-app bundles. This is out of scope here, but the comment should not imply the weak default solves multi-app.
5. Stale manifest. When an app drops storage, the generator writes the no-bundle .cpp but leaves the old ${outCpp}.assets.json behind, so deploy tooling can still push the old bundle. This predates the PR, but it is cheap to fix here: remove the file when bundle is null.
6. Test coverage. The new check links the generated unit against a plain strong extern declaration, not against gea_app_entry.cpp's actual hook reference. The configuration that actually broke (entry linked, generated unit absent or lacking the symbol) is still untested. The check also sits inside the file-bundle test after the ASan runs, and the final success line doesn't mention it.
7. Nit. The if (!bundle) block sits about 30 lines from the strong definition it pairs with. Writing it as the else of the if (bundle) at line 301, plus the no-assets branch, keeps both definitions of the hook together.
81cbe9f gave every non-bundle app a weak gea_embedded_assets_prepare from the generator, so this drops the definition 7ed9224 added there and restores the file-bundle test. The GEA_PROGRAM_HOOK spelling stays: next to that weak definition, a plain weak reference is the pair lld-link reports as a duplicate symbol. Also from the review on geastack#75: the asset bundle loader logs when storage is not mounted, its one silent failure, and a build without file storage removes the deployment manifest an earlier storage-backed build left. New test_embedded_assets_prepare.mjs links the real gea_app_entry.cpp object with generated units for apps with no storage, no assets and file-backed assets, and checks that the hook resolves; it fails with the generator from before 81cbe9f.
|
Thanks for the review. I saw 81cbe9f put the generator fallback on main, so I've reduced this PR to what main doesn't have. Pushed 3909378; the branch's cumulative diff applies cleanly on 81cbe9f. Windows (point 2). With 81cbe9f, This PR keeps the
Run on 81cbe9f plus this PR:
I couldn't run the smoke path from point 1: |
|
Following up on the Windows point with a real Windows run: https://github.com/nejdetkadir/windows/actions/runs/39495396424 (job
The units are minimal stand-ins for those lines, not a full Windows build of an app. |
gea_app_entry.cpp references gea_embedded_assets_prepare weakly, but the generator defined it only for apps with a file-backed asset bundle. Apple's ld rejects a weak reference nothing defines, so since 0.1.43 every iOS and macOS app without gea.embeddedAssets.storage fails to link, the blank starter included. ELF targets kept linking and skipped the call. The generator now defines it weakly for every app without a bundle and returns true, since embedded assets need no preparation. It is weak like gea_embedded_asset_lookup because a bundled binary links several apps' generated assets. The reference goes through GEA_PROGRAM_HOOK like the other hooks a program defines, so a target with GEA_LINKED_HOOK_DEFAULTS references it as an ordinary symbol.
81cbe9f gave every non-bundle app a weak gea_embedded_assets_prepare from the generator, so this drops the definition 7ed9224 added there and restores the file-bundle test. The GEA_PROGRAM_HOOK spelling stays: next to that weak definition, a plain weak reference is the pair lld-link reports as a duplicate symbol. Also from the review on geastack#75: the asset bundle loader logs when storage is not mounted, its one silent failure, and a build without file storage removes the deployment manifest an earlier storage-backed build left. New test_embedded_assets_prepare.mjs links the real gea_app_entry.cpp object with generated units for apps with no storage, no assets and file-backed assets, and checks that the hook resolves; it fails with the generator from before 81cbe9f.
3909378 to
b23bcae
Compare
dashersw
left a comment
There was a problem hiding this comment.
Thanks, all points addressed. Merging together with geastack/windows#7.
Problem
gea_app_entry.cppdeclaresgea_embedded_assets_preparewith a plain__attribute__((weak)). Since 81cbe9f the generator gives every non-bundle app a weak definition of it. On COFF a weak reference meeting a weak definition is a duplicate, aswin32_hook_defaults.cppin geastack/windows describes. Linked with clang-cl and lld-link 23.1.3 on macOS (not a Windows build), the exact line 44 and the generator's line 254 give:The review on this PR also asked for a test of the configuration that broke on Apple, a log when file-backed assets fail to prepare, and removal of a stale deployment manifest.
Change
gea_app_entry.cpp: declare the hook withGEA_PROGRAM_HOOK, like the cycle-collection hooks, so a target withGEA_LINKED_HOOK_DEFAULTSreferences it as an ordinary symbol. Link a default for the embedded-assets prepare hook windows#7 adds its/alternatenamedefault; the two should land together.asset_bundle.h: log when storage is not mounted, the loader's one silent failure.gea-file-asset-bundle.mjs: a build without file storage removes the.assets.jsonan earlier storage-backed build left.test_embedded_assets_prepare.mjs: links the realgea_app_entry.cppobject (-r) with generated units for apps with no storage, no assets and file-backed assets, and checks that the hook resolves. Skips on Windows.test_embedded_assets_manifest.mjsandtest_embedded_weak_symbols.mjs: the manifest removal and theGEA_PROGRAM_HOOKspelling.The branch is on 4fd69f1. Its diff applies cleanly on 81cbe9f, and the new prepare test needs 81cbe9f.
Target matrix
Application::init(lldb)raspberry-pi-os)Tests
Run on 81cbe9f plus this PR:
test_embedded_weak_symbols.mjsexits 0.test_embedded_assets_prepare.mjsfails with the generator from before 81cbe9f (U _gea_embedded_assets_preparewith ld64,wwith GNU ld), and the manifest test fails with main'sgea-file-asset-bundle.mjs. The 13 steps ofbouncing-balls-regressions.ymlpass locally.Notes for review
_gea_embedded_asset_lookupfromhost/image.cpp. A weak default there would compete with the generator's weak lookup, since ld64 and GNU ld take the first weak definition in link order. I left it alone.Summary by CodeRabbit
Bug Fixes
Tests