diff options
| author | Czarek Nakamoto <cyjan@mrcyjanek.net> | 2026-03-09 10:07:34 +0100 |
|---|---|---|
| committer | Czarek Nakamoto <cyjan@mrcyjanek.net> | 2026-03-09 10:07:34 +0100 |
| commit | 9dbfe09710351f66a489a6a5d7ec98d6f00df392 (patch) | |
| tree | 5c3bf00cdc5edd7ca16bca1ad508ba88db87315f | |
| parent | e5057c88047aeef0ebf3e6fd3d288dc237b00602 (diff) | |
update
| -rw-r--r-- | .gitignore | 6 | ||||
| -rw-r--r-- | patches/monero/0016-serialize-cache-to-JSON.patch | 463 | ||||
| -rw-r--r-- | patches/monero/0017-drop-generate_translations_header.c-requirement.patch | 123 | ||||
| -rw-r--r-- | patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch | 39 | ||||
| -rw-r--r-- | patches/monero/0019-fix-mingw-build-issues.patch | 46 | ||||
| -rw-r--r-- | patches/monero/0020-fix-remove-flaky-test.patch | 27 |
6 files changed, 701 insertions, 3 deletions
@@ -8,6 +8,6 @@ contrib/depends/_ contrib/depends/_native contrib/depends/simplybs *_libwallet2_api_c/build -monero -wownero -zano
\ No newline at end of file +./monero +./wownero +./zano diff --git a/patches/monero/0016-serialize-cache-to-JSON.patch b/patches/monero/0016-serialize-cache-to-JSON.patch new file mode 100644 index 0000000..38aaee4 --- /dev/null +++ b/patches/monero/0016-serialize-cache-to-JSON.patch @@ -0,0 +1,463 @@ +From e6785290c24eb48d6b6aec8e1831b96f65cd3bfd Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto <cyjan@mrcyjanek.net> +Date: Tue, 12 Aug 2025 07:09:14 -0400 +Subject: [PATCH 16/20] serialize cache to JSON + +--- + src/wallet/CMakeLists.txt | 1 + + src/wallet/api/wallet.cpp | 5 + + src/wallet/api/wallet.h | 2 + + src/wallet/api/wallet2_api.h | 3 + + src/wallet/wallet2.h | 6 + + src/wallet/wallet_cache_to_json.cpp | 368 ++++++++++++++++++++++++++++ + 6 files changed, 385 insertions(+) + create mode 100644 src/wallet/wallet_cache_to_json.cpp + +diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt +index b163212b7..196ad671f 100644 +--- a/src/wallet/CMakeLists.txt ++++ b/src/wallet/CMakeLists.txt +@@ -38,6 +38,7 @@ set(wallet_sources + message_store.cpp + message_transporter.cpp + wallet_rpc_payments.cpp ++ wallet_cache_to_json.cpp + ) + + monero_find_all_headers(wallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}") +diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp +index 107f516f3..c24b4a97d 100644 +--- a/src/wallet/api/wallet.cpp ++++ b/src/wallet/api/wallet.cpp +@@ -3474,4 +3474,9 @@ void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command + #endif + } + ++std::string WalletImpl::serializeCacheToJson() const ++{ ++ return std::string(m_wallet->serialize_cache_to_json()); ++} ++ + } // namespace +diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h +index bfe81c590..98c03b9c1 100644 +--- a/src/wallet/api/wallet.h ++++ b/src/wallet/api/wallet.h +@@ -335,6 +335,8 @@ private: + bool getWaitsForDeviceSend(); + + bool getWaitsForDeviceReceive(); ++ ++ virtual std::string serializeCacheToJson() const override; + }; + + +diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h +index fcb8187d4..3d11929f9 100644 +--- a/src/wallet/api/wallet2_api.h ++++ b/src/wallet/api/wallet2_api.h +@@ -1217,6 +1217,9 @@ struct Wallet + static void setDeviceReceivedData(unsigned char* data, size_t len); + static void setDeviceSendData(unsigned char* data, size_t len); + static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)); ++ ++ //! serialize wallet cache to JSON ++ virtual std::string serializeCacheToJson() const = 0; + }; + + /** +diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h +index d07dc7e8b..37a2447d2 100644 +--- a/src/wallet/wallet2.h ++++ b/src/wallet/wallet2.h +@@ -1436,6 +1436,12 @@ private: + FIELD(m_background_sync_data) + END_SERIALIZE() + ++ /*! ++ * \brief Serialize wallet cache fields to JSON ++ * \return const char* pointing to JSON string containing all cache fields ++ */ ++ const char* serialize_cache_to_json() const; ++ + /*! + * \brief Check if wallet keys and bin files exist + * \param file_path Wallet file path +diff --git a/src/wallet/wallet_cache_to_json.cpp b/src/wallet/wallet_cache_to_json.cpp +new file mode 100644 +index 000000000..4743852ca +--- /dev/null ++++ b/src/wallet/wallet_cache_to_json.cpp +@@ -0,0 +1,368 @@ ++#include "wallet2.h" ++#include "serialization/binary_archive.h" ++#include "serialization/json_archive.h" ++#include "serialization/serialization.h" ++#include <sstream> ++#include <iomanip> ++ ++namespace tools ++{ ++ ++static void write_escaped_json_string(std::ostream& os, const std::string& str) ++{ ++ for (char c : str) { ++ switch (c) { ++ case '"': os << "\\\""; break; ++ case '\\': os << "\\\\"; break; ++ case '\n': os << "\\n"; break; ++ case '\r': os << "\\r"; break; ++ case '\t': os << "\\t"; break; ++ case '\b': os << "\\b"; break; ++ case '\f': os << "\\f"; break; ++ default: os << c; break; ++ } ++ } ++} ++ ++static void post_process_json(std::string& json) ++{ ++ // ": ," --> ": null," ++ size_t pos = 0; ++ while ((pos = json.find(": ,", pos)) != std::string::npos) { ++ json.replace(pos, 3, ": null,"); ++ pos += 7; ++ } ++ ++ // ": }" --> ": null}" ++ pos = 0; ++ while ((pos = json.find(": }", pos)) != std::string::npos) { ++ json.replace(pos, 3, ": null}"); ++ pos += 7; ++ } ++ ++ // ": ]" --> ": null]" ++ pos = 0; ++ while ((pos = json.find(": ]", pos)) != std::string::npos) { ++ json.replace(pos, 3, ": null]"); ++ pos += 7; ++ } ++ ++ // "key": number"hexstring" --> "key": "numberhexstring" ++ pos = 0; ++ while (pos < json.length()) { ++ size_t colon_pos = json.find(": ", pos); ++ if (colon_pos == std::string::npos) break; ++ ++ size_t value_start = colon_pos + 2; ++ if (value_start >= json.length()) break; ++ ++ if (std::isdigit(json[value_start])) { ++ size_t quote_pos = json.find('"', value_start); ++ if (quote_pos != std::string::npos && quote_pos < json.find_first_of(",}]", value_start)) { ++ size_t closing_quote = json.find('"', quote_pos + 1); ++ if (closing_quote != std::string::npos && closing_quote < json.find_first_of(",}]", value_start)) { ++ std::string digits; ++ size_t digit_end = value_start; ++ while (digit_end < quote_pos && std::isdigit(json[digit_end])) { ++ digits += json[digit_end]; ++ digit_end++; ++ } ++ ++ if (digit_end == quote_pos && !digits.empty()) { ++ std::string hex_part = json.substr(quote_pos + 1, closing_quote - quote_pos - 1); ++ ++ std::string replacement = "\"" + digits + hex_part + "\""; ++ json.replace(value_start, closing_quote - value_start + 1, replacement); ++ pos = value_start + replacement.length(); ++ continue; ++ } ++ } ++ } ++ } ++ ++ pos = colon_pos + 1; ++ } ++} ++ ++const char* wallet2::serialize_cache_to_json() const ++{ ++ static std::string json_result; ++ ++ try ++ { ++ std::stringstream oss; ++ json_archive<true> ar(oss, true); // true for pretty printing ++ ++ ar.begin_object(); ++ ++ // MAGIC_FIELD("monero wallet cache") ++ std::string magic = "monero wallet cache"; ++ ar.tag("magic"); ++ ar.serialize_blob((void*)magic.data(), magic.size()); ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to serialize magic field\"}"; ++ return json_result.c_str(); ++ } ++ ++ // VERSION_FIELD(2) ++ uint32_t version = 2; ++ ar.tag("version"); ++ ar.serialize_varint(version); ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to serialize version field\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_blockchain) - hashchain type, has serialization support ++ ar.tag("m_blockchain"); ++ if (!::serialization::serialize(ar, const_cast<hashchain&>(m_blockchain))) { ++ json_result = "{\"error\":\"Failed to serialize m_blockchain\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_transfers) - transfer_container (std::vector<transfer_details>) ++ ar.tag("m_transfers"); ++ if (!::serialization::serialize(ar, const_cast<transfer_container&>(m_transfers))) { ++ json_result = "{\"error\":\"Failed to serialize m_transfers\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_account_public_address) - cryptonote::account_public_address ++ ar.tag("m_account_public_address"); ++ if (!::serialization::serialize(ar, const_cast<cryptonote::account_public_address&>(m_account_public_address))) { ++ json_result = "{\"error\":\"Failed to serialize m_account_public_address\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_key_images) - serializable_unordered_map<crypto::key_image, size_t> ++ ar.tag("m_key_images"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::key_image, size_t>&>(m_key_images))) { ++ json_result = "{\"error\":\"Failed to serialize m_key_images\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_unconfirmed_txs) - serializable_unordered_map<crypto::hash, unconfirmed_transfer_details> ++ ar.tag("m_unconfirmed_txs"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, unconfirmed_transfer_details>&>(m_unconfirmed_txs))) { ++ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_txs\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_payments) - payment_container (serializable_unordered_multimap<crypto::hash, payment_details>) ++ ar.tag("m_payments"); ++ if (!::serialization::serialize(ar, const_cast<payment_container&>(m_payments))) { ++ json_result = "{\"error\":\"Failed to serialize m_payments\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_tx_keys) - serializable_unordered_map<crypto::hash, crypto::secret_key> ++ ar.tag("m_tx_keys"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, crypto::secret_key>&>(m_tx_keys))) { ++ json_result = "{\"error\":\"Failed to serialize m_tx_keys\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_confirmed_txs) - serializable_unordered_map<crypto::hash, confirmed_transfer_details> ++ ar.tag("m_confirmed_txs"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, confirmed_transfer_details>&>(m_confirmed_txs))) { ++ json_result = "{\"error\":\"Failed to serialize m_confirmed_txs\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_tx_notes) - serializable_unordered_map<crypto::hash, std::string> ++ ar.tag("m_tx_notes"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::string>&>(m_tx_notes))) { ++ json_result = "{\"error\":\"Failed to serialize m_tx_notes\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_unconfirmed_payments) - serializable_unordered_multimap<crypto::hash, pool_payment_details> ++ ar.tag("m_unconfirmed_payments"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_multimap<crypto::hash, pool_payment_details>&>(m_unconfirmed_payments))) { ++ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_payments\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_pub_keys) - serializable_unordered_map<crypto::public_key, size_t> ++ ar.tag("m_pub_keys"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, size_t>&>(m_pub_keys))) { ++ json_result = "{\"error\":\"Failed to serialize m_pub_keys\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_address_book) - std::vector<tools::wallet2::address_book_row> ++ ar.tag("m_address_book"); ++ if (!::serialization::serialize(ar, const_cast<std::vector<tools::wallet2::address_book_row>&>(m_address_book))) { ++ json_result = "{\"error\":\"Failed to serialize m_address_book\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_scanned_pool_txs[0]) - std::unordered_set<crypto::hash> ++ ar.tag("m_scanned_pool_txs_0"); ++ if (!::serialization::serialize(ar, const_cast<std::unordered_set<crypto::hash>&>(m_scanned_pool_txs[0]))) { ++ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[0]\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_scanned_pool_txs[1]) - std::unordered_set<crypto::hash> ++ ar.tag("m_scanned_pool_txs_1"); ++ if (!::serialization::serialize(ar, const_cast<std::unordered_set<crypto::hash>&>(m_scanned_pool_txs[1]))) { ++ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[1]\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_subaddresses) - serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index> ++ ar.tag("m_subaddresses"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index>&>(m_subaddresses))) { ++ json_result = "{\"error\":\"Failed to serialize m_subaddresses\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_subaddress_labels) - std::vector<std::vector<std::string>> - manual JSON serialization ++ oss << ", \n \"m_subaddress_labels\": ["; ++ for (size_t i = 0; i < m_subaddress_labels.size(); ++i) { ++ if (i > 0) oss << ", "; ++ oss << "\n ["; ++ for (size_t j = 0; j < m_subaddress_labels[i].size(); ++j) { ++ if (j > 0) oss << ", "; ++ oss << "\""; ++ write_escaped_json_string(oss, m_subaddress_labels[i][j]); ++ oss << "\""; ++ } ++ oss << "]"; ++ } ++ oss << "\n ]"; ++ ++ // FIELD(m_additional_tx_keys) - serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>> ++ ar.tag("m_additional_tx_keys"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>>&>(m_additional_tx_keys))) { ++ json_result = "{\"error\":\"Failed to serialize m_additional_tx_keys\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_attributes) - serializable_unordered_map<std::string, std::string> - manual JSON serialization ++ oss << ", \n \"m_attributes\": {"; ++ bool first_attr = true; ++ for (const auto& attr : m_attributes) { ++ if (!first_attr) oss << ", "; ++ first_attr = false; ++ oss << "\n \""; ++ write_escaped_json_string(oss, attr.first); ++ oss << "\": \""; ++ write_escaped_json_string(oss, attr.second); ++ oss << "\""; ++ } ++ oss << "\n }"; ++ ++ // FIELD(m_account_tags) - std::pair<serializable_map<std::string, std::string>, std::vector<std::string>> - manual JSON serialization ++ oss << ", \n \"m_account_tags\": {"; ++ oss << "\n \"tags_map\": {"; ++ bool first_tag = true; ++ for (const auto& tag : m_account_tags.first) { ++ if (!first_tag) oss << ", "; ++ first_tag = false; ++ oss << "\n \""; ++ write_escaped_json_string(oss, tag.first); ++ oss << "\": \""; ++ write_escaped_json_string(oss, tag.second); ++ oss << "\""; ++ } ++ oss << "\n },"; ++ oss << "\n \"account_list\": ["; ++ for (size_t i = 0; i < m_account_tags.second.size(); ++i) { ++ if (i > 0) oss << ", "; ++ oss << "\n \""; ++ write_escaped_json_string(oss, m_account_tags.second[i]); ++ oss << "\""; ++ } ++ oss << "\n ]"; ++ oss << "\n }"; ++ ++ // FIELD(m_ring_history_saved) - bool ++ // ar.tag("m_ring_history_saved"); ++ // ar.serialize_blob(&m_ring_history_saved, sizeof(m_ring_history_saved)); ++ // if (!ar.good()) { ++ // json_result = "{\"error\":\"Failed to serialize m_ring_history_saved\"}"; ++ // return json_result.c_str(); ++ // } ++ ++ // FIELD(m_last_block_reward) - uint64_t ++ ar.tag("m_last_block_reward"); ++ ar.serialize_int(m_last_block_reward); ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to serialize m_last_block_reward\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_tx_device) - serializable_unordered_map<crypto::hash, std::string> ++ ar.tag("m_tx_device"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::string>&>(m_tx_device))) { ++ json_result = "{\"error\":\"Failed to serialize m_tx_device\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_device_last_key_image_sync) - uint64_t ++ ar.tag("m_device_last_key_image_sync"); ++ ar.serialize_int(m_device_last_key_image_sync); ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to serialize m_device_last_key_image_sync\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_cold_key_images) - serializable_unordered_map<crypto::public_key, crypto::key_image> ++ ar.tag("m_cold_key_images"); ++ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, crypto::key_image>&>(m_cold_key_images))) { ++ json_result = "{\"error\":\"Failed to serialize m_cold_key_images\"}"; ++ return json_result.c_str(); ++ } ++ ++ // FIELD(m_rpc_client_secret_key) - crypto::secret_key ++ // ar.tag("m_rpc_client_secret_key"); ++ // ar.serialize_blob(&m_rpc_client_secret_key, sizeof(m_rpc_client_secret_key)); ++ // if (!ar.good()) { ++ // json_result = "{\"error\":\"Failed to serialize m_rpc_client_secret_key\"}"; ++ // return json_result.c_str(); ++ // } ++ ++ // Version-dependent fields ++ if (version >= 1) { ++ // FIELD(m_has_ever_refreshed_from_node) - bool ++ // ar.tag("m_has_ever_refreshed_from_node"); ++ // ar.serialize_blob(&m_has_ever_refreshed_from_node, sizeof(m_has_ever_refreshed_from_node)); ++ // if (!ar.good()) { ++ // json_result = "{\"error\":\"Failed to serialize m_has_ever_refreshed_from_node\"}"; ++ // return json_result.c_str(); ++ // } ++ } ++ ++ if (version >= 2) { ++ // FIELD(m_background_sync_data) - background_sync_data_t ++ ar.tag("m_background_sync_data"); ++ if (!::serialization::serialize(ar, const_cast<background_sync_data_t&>(m_background_sync_data))) { ++ json_result = "{\"error\":\"Failed to serialize m_background_sync_data\"}"; ++ return json_result.c_str(); ++ } ++ } ++ ++ ar.end_object(); ++ ++ if (!ar.good()) { ++ json_result = "{\"error\":\"Failed to finalize JSON serialization\"}"; ++ return json_result.c_str(); ++ } ++ ++ json_result = oss.str(); ++ ++ // Post-process to fix malformed JSON ++ post_process_json(json_result); ++ ++ return json_result.c_str(); ++ } ++ catch (const std::exception& e) ++ { ++ json_result = "{\"error\":\"Failed to serialize wallet cache: " + std::string(e.what()) + "\"}"; ++ return json_result.c_str(); ++ } ++} ++ ++} // namespace tools +\ No newline at end of file +-- +2.50.1 (Apple Git-155) + diff --git a/patches/monero/0017-drop-generate_translations_header.c-requirement.patch b/patches/monero/0017-drop-generate_translations_header.c-requirement.patch new file mode 100644 index 0000000..f6549dc --- /dev/null +++ b/patches/monero/0017-drop-generate_translations_header.c-requirement.patch @@ -0,0 +1,123 @@ +From 6aa368c9613a1a7b7f2f1ce1f025962d40827c67 Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto <cyjan@mrcyjanek.net> +Date: Fri, 20 Feb 2026 08:03:01 +0100 +Subject: [PATCH 17/20] drop generate_translations_header.c requirement + +--- + CMakeLists.txt | 9 +---- + translations/CMakeLists.txt | 79 +++++++++++++------------------------ + 2 files changed, 30 insertions(+), 58 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index cef44dd1b..ce5e1b557 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -666,16 +666,11 @@ endfunction () + # Generate header for embedded translations + # Generate header for embedded translations, use target toolchain if depends, otherwise use the + # lrelease and lupdate binaries from the host +-include(ExternalProject) +-ExternalProject_Add(generate_translations_header +- SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/translations" +- BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/translations" +- STAMP_DIR ${LRELEASE_PATH} +- CMAKE_ARGS -DLRELEASE_PATH=${LRELEASE_PATH} +- INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "") ++add_subdirectory(translations) + include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations") + add_subdirectory(external) + ++ + # Final setup for libunbound + include_directories(${UNBOUND_INCLUDE_DIR}) + +diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt +index 3b43360f8..d88a78ced 100644 +--- a/translations/CMakeLists.txt ++++ b/translations/CMakeLists.txt +@@ -30,54 +30,31 @@ cmake_minimum_required(VERSION 3.5) + + project(translations) + +-# when crosscompiling import the executable targets from a file +-IF(CMAKE_CROSSCOMPILING) +- message(WARNING "CrossCompiling") +- SET(IMPORT_EXECUTABLES "${CMAKE_CURRENT_BINARY_DIR}/ImportExecutables.cmake" CACHE FILEPATH "Point it to the export file from a native build") +- INCLUDE(${IMPORT_EXECUTABLES}) +-ENDIF(CMAKE_CROSSCOMPILING) +- +-# only build the generator if not crosscompiling +-IF(NOT CMAKE_CROSSCOMPILING) +- add_executable(generate_translations_header generate_translations_header.c) +-ENDIF(NOT CMAKE_CROSSCOMPILING) +- +-if(LRELEASE_PATH STREQUAL "") +- find_program(LRELEASE lrelease) +-else() +- set(LRELEASE ${LRELEASE_PATH}/lrelease) +-endif() +- +-if(LRELEASE STREQUAL "LRELEASE-NOTFOUND") +- set(ts_files "") +- message(WARNING "lrelease program not found, translation files not built") +-else() +- execute_process(COMMAND ${LRELEASE} -version +- RESULT_VARIABLE lrelease_ret) +- if(NOT lrelease_ret EQUAL "0") +- set(ts_files "") +- message(WARNING "lrelease program not working, translation files not built") +- else() +- file(GLOB ts_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.ts) +- foreach(ts_file ${ts_files}) +- string(REPLACE ".ts" ".qm" qm_file "${ts_file}") +- add_custom_command(TARGET generate_translations_header +- PRE_BUILD +- COMMAND ${LRELEASE} "${CMAKE_CURRENT_SOURCE_DIR}/${ts_file}" -qm "${qm_file}" +- WORKING_DIRECTORY "${CMAKE_CURRENT_BIN_DIR}") +- endforeach() +- endif() +-endif() +- +-string(REPLACE ".ts" ".qm" qm_files "${ts_files}") +- +-add_custom_command(TARGET generate_translations_header +- POST_BUILD +- COMMAND $<TARGET_FILE:generate_translations_header> ${qm_files} +- WORKING_DIRECTORY "${CMAKE_CURRENT_BIN_DIR}" +- COMMENT "Generating embedded translations header") +- +-# export the generator target to a file, so it can be imported (see above) by another build +-IF(NOT CMAKE_CROSSCOMPILING) +- EXPORT(TARGETS generate_translations_header FILE ${CMAKE_CURRENT_BINARY_DIR}/ImportExecutables.cmake ) +-ENDIF(NOT CMAKE_CROSSCOMPILING) ++add_custom_target(generate_translations_header) ++ ++file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/translation_files.h" ++"#ifndef TRANSLATION_FILES_H ++#define TRANSLATION_FILES_H ++ ++#include <string> ++ ++static const struct embedded_file { ++ const std::string *name; ++ const std::string *data; ++} embedded_files[] = { ++ {NULL, NULL} ++}; ++ ++static bool find_embedded_file(const std::string &name, std::string &data) { ++ const struct embedded_file *p; ++ for (p = embedded_files; p->name != NULL; p++) { ++ if (*p->name == name) { ++ data = *p->data; ++ return true; ++ } ++ } ++ return false; ++} ++ ++#endif /* TRANSLATION_FILES_H */ ++") +-- +2.50.1 (Apple Git-155) + diff --git a/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch b/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch new file mode 100644 index 0000000..84b4b99 --- /dev/null +++ b/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch @@ -0,0 +1,39 @@ +From 960a5efe59725eab4c03ce8025de8fc0fbffaacf Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto <cyjan@mrcyjanek.net> +Date: Tue, 3 Mar 2026 13:55:59 +0100 +Subject: [PATCH 18/20] depends: remove icu4c monero-project/monero#8880 + +--- + CMakeLists.txt | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ce5e1b557..25e034301 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1117,20 +1117,15 @@ if(MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj") + set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32;bcrypt) + if(DEPENDS) +- set(ICU_LIBRARIES icuio icui18n icuuc icudata icutu iconv) ++ set(ICU_LIBRARIES iconv) + else() + # This is an extremely ugly hack to get around Boost not being built with static ICU. + # We reported the issue, we are waiting for upstream to fix this issue: https://github.com/boostorg/boost/issues/1079#issue-3384962885 + # This hack links shared ICU libs to avoid linker errors we get in MSYS2 compilation (undefined symbols to ICU). + set(OLD_LIB_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a") +- find_library(ICUIO_LIBRARIES NAMES icuio REQUIRED) +- find_library(ICUIN_LIBRARIES NAMES icuin REQUIRED) +- find_library(ICUUC_LIBRARIES NAMES icuuc REQUIRED) +- find_library(ICUDT_LIBRARIES NAMES icudt REQUIRED) +- find_library(ICUTU_LIBRARIES NAMES icutu REQUIRED) + find_library(ICONV_LIBRARIES NAMES iconv REQUIRED) +- set(ICU_LIBRARIES ${ICUIO_LIBRARIES} ${ICUIN_LIBRARIES} ${ICUUC_LIBRARIES} ${ICUDT_LIBRARIES} ${ICUTU_LIBRARIES} ${ICONV_LIBRARIES}) ++ set(ICU_LIBRARIES ${ICUIO_LIBRARIES} ${ICONV_LIBRARIES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES}) + endif() + elseif(APPLE OR OPENBSD OR ANDROID) +-- +2.50.1 (Apple Git-155) + diff --git a/patches/monero/0019-fix-mingw-build-issues.patch b/patches/monero/0019-fix-mingw-build-issues.patch new file mode 100644 index 0000000..a9e7b5c --- /dev/null +++ b/patches/monero/0019-fix-mingw-build-issues.patch @@ -0,0 +1,46 @@ +From 2d4ed0b13eea96b25a574e8a87644df75c16ffb0 Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto <cyjan@mrcyjanek.net> +Date: Wed, 4 Mar 2026 14:52:14 +0100 +Subject: [PATCH 19/20] fix: mingw build issues + +--- + contrib/epee/include/serialization/keyvalue_serialization.h | 1 + + contrib/epee/src/abstract_http_client.cpp | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h +index fbbddc7d2..5104f284d 100644 +--- a/contrib/epee/include/serialization/keyvalue_serialization.h ++++ b/contrib/epee/include/serialization/keyvalue_serialization.h +@@ -26,6 +26,7 @@ + + #pragma once + ++#include <cstdint> + #include <type_traits> + #include <boost/utility/value_init.hpp> + #include <boost/foreach.hpp> +diff --git a/contrib/epee/src/abstract_http_client.cpp b/contrib/epee/src/abstract_http_client.cpp +index ed4a193d9..2352c7d62 100644 +--- a/contrib/epee/src/abstract_http_client.cpp ++++ b/contrib/epee/src/abstract_http_client.cpp +@@ -3,6 +3,7 @@ + #include "net/http_base.h" + #include "net/net_parse_helpers.h" + #include "misc_log_ex.h" ++#include <cmath> + + #undef MONERO_DEFAULT_LOG_CATEGORY + #define MONERO_DEFAULT_LOG_CATEGORY "net.http" +@@ -39,7 +40,7 @@ namespace net_utils + while (num_char >= radix) + { + temp = num_char % radix; +- num_char = (int)floor((float)num_char / (float)radix); ++ num_char = (int)std::floor((float)num_char / (float)radix); + csTmp = get_hex_vals()[temp]; + } + +-- +2.50.1 (Apple Git-155) + diff --git a/patches/monero/0020-fix-remove-flaky-test.patch b/patches/monero/0020-fix-remove-flaky-test.patch new file mode 100644 index 0000000..1075db5 --- /dev/null +++ b/patches/monero/0020-fix-remove-flaky-test.patch @@ -0,0 +1,27 @@ +From 81eb38a5add85266cc0d2aa39ecba9d62337f4b1 Mon Sep 17 00:00:00 2001 +From: Czarek Nakamoto <cyjan@mrcyjanek.net> +Date: Thu, 5 Mar 2026 18:12:53 +0100 +Subject: [PATCH 20/20] fix: remove flaky test + +--- + CMakeLists.txt | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 25e034301..19417f072 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -235,9 +235,7 @@ add_library(l3 OBJECT incorrect_source.cpp) + "-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}" + "-DEXPECT_SUCCESS=${EXPECT}" + ) +- if (NOT ${SUCCESS} STREQUAL ${EXPECT}) +- message(FATAL_ERROR "Undefined symbols test failure: expect(${EXPECT}), success(${SUCCESS})") +- endif() ++ + file(REMOVE_RECURSE "${TEST_PROJECT}") + endforeach() + endfunction() +-- +2.50.1 (Apple Git-155) + |
