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 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 06:05:07 -05:00
co-authored by Claude Opus 5.5
parent 70eacd90ad
commit abb63d9441
2 changed files with 29 additions and 14 deletions
+27 -12
View File
@@ -646,13 +646,16 @@ TOOLCHAIN
mkdir -p "$RES" mkdir -p "$RES"
SAPLING_SPEND="" SAPLING_OUTPUT="" ASMAP_DAT="" SAPLING_SPEND="" SAPLING_OUTPUT="" ASMAP_DAT=""
find_sapling_params || true local EMBED_NODE_DATA=false
find_asmap || true should_bundle_full_node_assets && EMBED_NODE_DATA=true
if $EMBED_NODE_DATA; then
if [[ -n "$SAPLING_SPEND" && -n "$SAPLING_OUTPUT" ]]; then find_sapling_params || true
cp -f "$SAPLING_SPEND" "$RES/sapling-spend.params" find_asmap || true
cp -f "$SAPLING_OUTPUT" "$RES/sapling-output.params" 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" <<HDR cat > "$GEN/embedded_data.h" <<HDR
// Auto-generated — DO NOT EDIT (build.sh --win-release) // Auto-generated — DO NOT EDIT (build.sh --win-release)
#pragma once #pragma once
@@ -660,16 +663,27 @@ TOOLCHAIN
#include <cstddef> #include <cstddef>
#include "incbin.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" <<HDR
INCBIN(sapling_spend_params, "$RES/sapling-spend.params"); INCBIN(sapling_spend_params, "$RES/sapling-spend.params");
INCBIN(sapling_output_params, "$RES/sapling-output.params"); INCBIN(sapling_output_params, "$RES/sapling-output.params");
HDR HDR
if [[ -n "$ASMAP_DAT" ]]; then
if [[ -n "$ASMAP_DAT" ]]; then cp -f "$ASMAP_DAT" "$RES/asmap.dat"
cp -f "$ASMAP_DAT" "$RES/asmap.dat" echo "INCBIN(asmap_dat, \"$RES/asmap.dat\");" >> "$GEN/embedded_data.h"
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 else
echo 'extern "C" { static const uint8_t* g_asmap_dat_data = nullptr; }' >> "$GEN/embedded_data.h" info "Lite mode: not embedding Sapling params/asmap (the SDXL backend embeds its own)"
echo 'static const unsigned int g_asmap_dat_size = 0;' >> "$GEN/embedded_data.h" 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 fi
# ── Daemon binaries ────────────────────────────────────────────── # ── Daemon binaries ──────────────────────────────────────────────
@@ -809,6 +823,7 @@ HDR
info "Embedded resources header generated" info "Embedded resources header generated"
else else
warn "Building WITHOUT embedded resources (Sapling params not found)" 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 fi
# ── Fetch libsodium for Windows if needed ────────────────────────────── # ── Fetch libsodium for Windows if needed ──────────────────────────────
+2 -2
View File
@@ -89,8 +89,8 @@ bool hasEmbeddedResources()
const EmbeddedResource* getEmbeddedResource(const std::string& name) const EmbeddedResource* getEmbeddedResource(const std::string& name)
{ {
// Search static resource table (params, daemon binaries, etc.) // Search static resource table (params, daemon binaries, etc.)
for (const auto* res = s_resources; res->data != nullptr; ++res) { for (const auto* res = s_resources; res->filename != nullptr; ++res) {
if (name == res->filename) { if (res->data && res->size && name == res->filename) {
return res; return res;
} }
} }