diff --git a/CMakeLists.txt b/CMakeLists.txt index 10a6a50..e63529f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -820,9 +820,21 @@ ${CMAKE_SOURCE_DIR}/res/fonts/NotoEmoji-Subset.ttf;\ ${CMAKE_SOURCE_DIR}/res/fonts/TwemojiMozilla-Color.ttf" ) +# Embed ui.toml + default_banlist via INCBIN (same pattern as fonts) - zero configure cost, no +# generated header, so editing them re-assembles one tiny TU instead of recompiling every includer. +configure_file( + ${CMAKE_SOURCE_DIR}/src/embedded/embedded_text.cpp.in + ${CMAKE_BINARY_DIR}/generated/embedded_text.cpp + @ONLY) +set_source_files_properties( + ${CMAKE_BINARY_DIR}/generated/embedded_text.cpp + PROPERTIES OBJECT_DEPENDS + "${CMAKE_SOURCE_DIR}/res/themes/ui.toml;${CMAKE_SOURCE_DIR}/res/default_banlist.txt") + add_executable(ObsidianDragon ${APP_SOURCES} ${CMAKE_BINARY_DIR}/generated/embedded_fonts.cpp + ${CMAKE_BINARY_DIR}/generated/embedded_text.cpp ${IMGUI_SOURCES} ${QRCODE_SOURCES} ${GLAD_SOURCES} @@ -1045,20 +1057,6 @@ if(LANG_FILES) message(STATUS " Language files: ${LANG_FILES}") endif() -# Embed ui.toml into the binary so it's always available at runtime -include(${CMAKE_SOURCE_DIR}/cmake/EmbedResources.cmake) -file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/generated) -embed_resource( - ${CMAKE_SOURCE_DIR}/res/themes/ui.toml - ${CMAKE_BINARY_DIR}/generated/ui_toml_embedded.h - ui_toml -) -embed_resource( - ${CMAKE_SOURCE_DIR}/res/default_banlist.txt - ${CMAKE_BINARY_DIR}/generated/default_banlist_embedded.h - default_banlist -) - # Note: xmrig is embedded via build.sh (embedded_data.h) for Windows builds, # following the same pattern as daemon embedding. @@ -1276,6 +1274,7 @@ if(BUILD_TESTING) src/resources/embedded_resources.cpp src/util/secure_vault.cpp src/util/platform.cpp + ${CMAKE_BINARY_DIR}/generated/embedded_text.cpp src/util/coalescing_writer.cpp src/util/logger.cpp src/util/lite_server_probe.cpp diff --git a/cmake/EmbedResources.cmake b/cmake/EmbedResources.cmake deleted file mode 100644 index b86fd5c..0000000 --- a/cmake/EmbedResources.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# CMake script to embed binary files as C arrays - -function(embed_resource RESOURCE_FILE OUTPUT_FILE VAR_NAME) - file(READ "${RESOURCE_FILE}" HEX_CONTENT HEX) - - # Convert hex to C array format - string(LENGTH "${HEX_CONTENT}" HEX_LENGTH) - math(EXPR BYTE_COUNT "${HEX_LENGTH} / 2") - - set(ARRAY_CONTENT "") - set(INDEX 0) - while(INDEX LESS HEX_LENGTH) - string(SUBSTRING "${HEX_CONTENT}" ${INDEX} 2 BYTE) - string(APPEND ARRAY_CONTENT "0x${BYTE},") - math(EXPR INDEX "${INDEX} + 2") - math(EXPR BYTE_NUM "${INDEX} / 2") - math(EXPR MOD "${BYTE_NUM} % 16") - if(MOD EQUAL 0) - string(APPEND ARRAY_CONTENT "\n ") - endif() - endwhile() - - # Generate header file - set(HEADER_CONTENT "// Auto-generated embedded resource - DO NOT EDIT -#pragma once -#include -#include - -namespace embedded { - -inline constexpr unsigned char ${VAR_NAME}_data[] = { - ${ARRAY_CONTENT} -}; - -inline constexpr size_t ${VAR_NAME}_size = ${BYTE_COUNT}; - -} // namespace embedded -") - - file(WRITE "${OUTPUT_FILE}" "${HEADER_CONTENT}") - message(STATUS "Embedded ${RESOURCE_FILE} -> ${OUTPUT_FILE} (${BYTE_COUNT} bytes)") -endfunction() diff --git a/src/app.cpp b/src/app.cpp index d29b3bd..56685d9 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -89,13 +89,8 @@ #include "ui/schema/skin_manager.h" #include "util/perf_log.h" -// Embedded ui.toml (generated at build time) — fallback when file not on disk -#if __has_include("ui_toml_embedded.h") -#include "ui_toml_embedded.h" -#define HAS_EMBEDDED_UI_TOML 1 -#else -#define HAS_EMBEDDED_UI_TOML 0 -#endif +// Embedded ui.toml (INCBIN) — fallback when file not on disk +#include "embedded/embedded_text.h" #include "imgui.h" #include @@ -367,25 +362,23 @@ bool App::loadBaseUiSchema() std::string schemaPath = util::Platform::getExecutableDirectory() + "/res/themes/ui.toml"; bool loaded = false; -#if HAS_EMBEDDED_UI_TOML // If on-disk ui.toml exists but differs in size from the embedded // version, a newer wallet binary is running against stale theme // files. Overwrite the on-disk copy so layout matches the binary. if (std::filesystem::exists(schemaPath)) { std::error_code ec; auto diskSize = std::filesystem::file_size(schemaPath, ec); - if (!ec && diskSize != static_cast(embedded::ui_toml_size)) { + if (!ec && diskSize != static_cast(g_ui_toml_size)) { DEBUG_LOGF("[INFO] ui.toml on disk (%ju bytes) differs from embedded (%zu bytes) — updating\n", - (uintmax_t)diskSize, embedded::ui_toml_size); + (uintmax_t)diskSize, (size_t)g_ui_toml_size); std::ofstream ofs(schemaPath, std::ios::binary | std::ios::trunc); if (ofs.is_open()) { - ofs.write(reinterpret_cast(embedded::ui_toml_data), - embedded::ui_toml_size); + ofs.write(reinterpret_cast(g_ui_toml_data), + g_ui_toml_size); ofs.close(); } } } -#endif if (std::filesystem::exists(schemaPath)) { loaded = ui::schema::UISchema::instance().loadFromFile(schemaPath); @@ -393,13 +386,9 @@ bool App::loadBaseUiSchema() // Fallback: load from build-time embedded data when file not on disk // (e.g., single-file Windows distribution without res/ directory) if (!loaded) { -#if HAS_EMBEDDED_UI_TOML - std::string embedded(reinterpret_cast(embedded::ui_toml_data), - embedded::ui_toml_size); + std::string embedded(reinterpret_cast(g_ui_toml_data), + g_ui_toml_size); ui::schema::UISchema::instance().loadFromString(embedded, "embedded"); -#else - DEBUG_LOGF("Warning: ui.toml not found at %s and no embedded fallback\n", schemaPath.c_str()); -#endif } return ui::schema::UISchema::instance().isLoaded(); } diff --git a/src/app_network.cpp b/src/app_network.cpp index b41cbb1..5f1b4ee 100644 --- a/src/app_network.cpp +++ b/src/app_network.cpp @@ -54,7 +54,7 @@ #include "util/pool_registry.h" #include "ui/notifications.h" #include "ui/schema/skin_manager.h" -#include "default_banlist_embedded.h" +#include "embedded/embedded_text.h" #include "util/amount_format.h" #include "util/http_download.h" #include "data/exchange_info.h" @@ -3742,8 +3742,8 @@ void App::applyDefaultBanlist() if (!state_.connected || !rpc_ || !worker_) return; // Parse the embedded default_banlist.txt (compiled from res/default_banlist.txt) - std::string data(reinterpret_cast(embedded::default_banlist_data), - embedded::default_banlist_size); + std::string data(reinterpret_cast(g_default_banlist_data), + g_default_banlist_size); std::vector ips; size_t pos = 0; diff --git a/src/embedded/embedded_text.cpp.in b/src/embedded/embedded_text.cpp.in new file mode 100644 index 0000000..9858dd5 --- /dev/null +++ b/src/embedded/embedded_text.cpp.in @@ -0,0 +1,4 @@ +// DragonX Wallet - INCBIN text-resource embedding (CMake-generated). Do NOT edit the generated copy. +#include "incbin.h" +INCBIN(ui_toml, "@CMAKE_SOURCE_DIR@/res/themes/ui.toml"); +INCBIN(default_banlist, "@CMAKE_SOURCE_DIR@/res/default_banlist.txt"); diff --git a/src/embedded/embedded_text.h b/src/embedded/embedded_text.h new file mode 100644 index 0000000..8f98fd0 --- /dev/null +++ b/src/embedded/embedded_text.h @@ -0,0 +1,10 @@ +#pragma once +#include +// Defined in generated/embedded_text.cpp via INCBIN (.incbin). Data is NOT NUL-terminated; +// every consumer passes an explicit size. Size is `unsigned int`. +extern "C" { + extern const unsigned char g_ui_toml_data[]; + extern const unsigned int g_ui_toml_size; + extern const unsigned char g_default_banlist_data[]; + extern const unsigned int g_default_banlist_size; +} diff --git a/src/util/platform.cpp b/src/util/platform.cpp index 9a284e1..aa3531b 100644 --- a/src/util/platform.cpp +++ b/src/util/platform.cpp @@ -15,13 +15,8 @@ #include #include -// Embedded ui.toml (generated at build time) -#if __has_include("ui_toml_embedded.h") -#include "ui_toml_embedded.h" -#define HAS_EMBEDDED_UI_TOML 1 -#else -#define HAS_EMBEDDED_UI_TOML 0 -#endif +// Embedded ui.toml (INCBIN) +#include "embedded/embedded_text.h" #include #ifdef _WIN32 @@ -562,20 +557,7 @@ void Platform::ensureObsidianDragonSetup() // Use the build-time embedded copy first; fall back to the // bundled file on disk. std::string content; -#if HAS_EMBEDDED_UI_TOML - content.assign(reinterpret_cast(embedded::ui_toml_data), - embedded::ui_toml_size); -#else - { - fs::path bundled = fs::path(getExecutableDirectory()) / "res" / "themes" / "ui.toml"; - std::ifstream src(bundled); - if (src.is_open()) { - std::ostringstream ss; - ss << src.rdbuf(); - content = ss.str(); - } - } -#endif + content.assign(reinterpret_cast(g_ui_toml_data), g_ui_toml_size); if (!content.empty()) { // Patch the theme metadata so the example is clearly