From abb63d944146b8c60a1d947aad3eaa4a16aa355a Mon Sep 17 00:00:00 2001 From: DanS Date: Sun, 11 Oct 2026 06:05:07 -0500 Subject: [PATCH] build(win-release): stop embedding Sapling params/asmap in the Lite exe The Windows release embeds its resources into the exe through a generated INCBIN header. The Lite build got the same param and asmap entries as the full node, so ObsidianDragonLite.exe carried sapling-spend.params, sapling-output.params and asmap.dat (about 53 MB) that it never reads: the SDXL backend embeds its own copy of the params, and Lite already skips extracting full-node-only resources. build_release_win now writes the param and asmap INCBINs only for the full node (should_bundle_full_node_assets). Lite gets null/zero stubs for those three symbols and still embeds images, themes and xmrig. Two fixes make that safe: - getEmbeddedResource() stopped at the first table entry with null data, so with the params stubbed out the Lite lookup ended before xmrig: mining would report itself available but never find the embedded binary. It now walks to the end of the table and skips null payloads. This also fixes a full-node build without asmap, whose lookup ended at the null asmap entry and hid the daemon and xmrig entries. - full and Lite builds share build/windows. When the full-node build cannot find the params, the generated header is now deleted, so a Lite header left behind by an earlier Lite build is not compiled into it (the node would then never start, because the startup job would take the embedded-extraction path and never copy the loose params). Measured on release builds: - ObsidianDragonLite.exe: 159,788,544 -> 106,120,192 bytes (-53.7 MB, of which about 0.28 MB is the ImGui demo stubs); - the Lite header has no param or asmap INCBINs and the resource object holds only the xmrig payload; a sample of sapling-spend.params occurs once in the exe instead of twice (the remaining copy is the backend's); - the full-node header is byte-identical to before. Not verifiable here (Windows runtime): the Lite exe starting without embedded params, and mining through the embedded xmrig. Lite installs from older versions may still hold about 53 MB of extracted params and asmap in %APPDATA%\ObsidianDragonLite\dragonx; nothing deletes them. Co-Authored-By: Claude Opus 5.5 --- build.sh | 39 +++++++++++++++++++--------- src/resources/embedded_resources.cpp | 4 +-- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/build.sh b/build.sh index 26097c6..6bdbe08 100755 --- a/build.sh +++ b/build.sh @@ -646,13 +646,16 @@ TOOLCHAIN mkdir -p "$RES" SAPLING_SPEND="" SAPLING_OUTPUT="" ASMAP_DAT="" - find_sapling_params || true - find_asmap || true - - if [[ -n "$SAPLING_SPEND" && -n "$SAPLING_OUTPUT" ]]; then - cp -f "$SAPLING_SPEND" "$RES/sapling-spend.params" - cp -f "$SAPLING_OUTPUT" "$RES/sapling-output.params" + local EMBED_NODE_DATA=false + should_bundle_full_node_assets && EMBED_NODE_DATA=true + if $EMBED_NODE_DATA; then + find_sapling_params || true + find_asmap || true + fi + # Lite needs no Sapling params/asmap (its backend embeds its own), so it always gets a header for + # images/themes/xmrig; the full node still requires the params to be found. + if ! $EMBED_NODE_DATA || [[ -n "$SAPLING_SPEND" && -n "$SAPLING_OUTPUT" ]]; then cat > "$GEN/embedded_data.h" < #include "incbin.h" +HDR + if $EMBED_NODE_DATA; then + cp -f "$SAPLING_SPEND" "$RES/sapling-spend.params" + cp -f "$SAPLING_OUTPUT" "$RES/sapling-output.params" + cat >> "$GEN/embedded_data.h" <> "$GEN/embedded_data.h" + if [[ -n "$ASMAP_DAT" ]]; then + cp -f "$ASMAP_DAT" "$RES/asmap.dat" + echo "INCBIN(asmap_dat, \"$RES/asmap.dat\");" >> "$GEN/embedded_data.h" + else + echo 'extern "C" { static const uint8_t* g_asmap_dat_data = nullptr; }' >> "$GEN/embedded_data.h" + echo 'static const unsigned int g_asmap_dat_size = 0;' >> "$GEN/embedded_data.h" + fi else - echo 'extern "C" { static const uint8_t* g_asmap_dat_data = nullptr; }' >> "$GEN/embedded_data.h" - echo 'static const unsigned int g_asmap_dat_size = 0;' >> "$GEN/embedded_data.h" + info "Lite mode: not embedding Sapling params/asmap (the SDXL backend embeds its own)" + for sym in sapling_spend_params sapling_output_params asmap_dat; do + echo "extern \"C\" { static const uint8_t* g_${sym}_data = nullptr; }" >> "$GEN/embedded_data.h" + echo "static const unsigned int g_${sym}_size = 0;" >> "$GEN/embedded_data.h" + done fi # ── Daemon binaries ────────────────────────────────────────────── @@ -809,6 +823,7 @@ HDR info "Embedded resources header generated" else warn "Building WITHOUT embedded resources (Sapling params not found)" + rm -f "$GEN/embedded_data.h" # never compile a stale header left by the other variant in this shared build dir fi # ── Fetch libsodium for Windows if needed ────────────────────────────── diff --git a/src/resources/embedded_resources.cpp b/src/resources/embedded_resources.cpp index eb4f157..b6bfdd1 100644 --- a/src/resources/embedded_resources.cpp +++ b/src/resources/embedded_resources.cpp @@ -89,8 +89,8 @@ bool hasEmbeddedResources() const EmbeddedResource* getEmbeddedResource(const std::string& name) { // Search static resource table (params, daemon binaries, etc.) - for (const auto* res = s_resources; res->data != nullptr; ++res) { - if (name == res->filename) { + for (const auto* res = s_resources; res->filename != nullptr; ++res) { + if (res->data && res->size && name == res->filename) { return res; } }