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"
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" <<HDR
// Auto-generated — DO NOT EDIT (build.sh --win-release)
#pragma once
@@ -660,16 +663,27 @@ TOOLCHAIN
#include <cstddef>
#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_output_params, "$RES/sapling-output.params");
HDR
if [[ -n "$ASMAP_DAT" ]]; then
cp -f "$ASMAP_DAT" "$RES/asmap.dat"
echo "INCBIN(asmap_dat, \"$RES/asmap.dat\");" >> "$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 ──────────────────────────────
+2 -2
View File
@@ -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;
}
}