mirror of
https://github.com/wownero/wowlet.git
synced 2026-10-17 07:11:29 +02:00
wowlet: embed wownerod (WOWNEROD_DIR, mirrors Feather's Tor embedding) — single self-contained binary; DaemonManager unpacks it
This commit is contained in:
@@ -21,6 +21,7 @@ cmake_policy(SET CMP0074 NEW)
|
|||||||
option(STATIC "Link libraries statically, requires static Qt" OFF)
|
option(STATIC "Link libraries statically, requires static Qt" OFF)
|
||||||
option(SELF_CONTAINED "Disable when building Feather for packages" OFF)
|
option(SELF_CONTAINED "Disable when building Feather for packages" OFF)
|
||||||
option(TOR_DIR "Directory containing Tor binaries to embed inside Feather" OFF)
|
option(TOR_DIR "Directory containing Tor binaries to embed inside Feather" OFF)
|
||||||
|
option(WOWNEROD_DIR "Directory containing the wownerod binary to embed inside wowlet" OFF)
|
||||||
option(CHECK_UPDATES "Enable checking for application updates" OFF)
|
option(CHECK_UPDATES "Enable checking for application updates" OFF)
|
||||||
option(PLATFORM_INSTALLER "Built-in updater fetches installer (windows-only)" OFF)
|
option(PLATFORM_INSTALLER "Built-in updater fetches installer (windows-only)" OFF)
|
||||||
option(USE_DEVICE_TREZOR "Trezor support compilation" ON)
|
option(USE_DEVICE_TREZOR "Trezor support compilation" ON)
|
||||||
@@ -137,6 +138,7 @@ endif()
|
|||||||
|
|
||||||
include(GenerateDocs)
|
include(GenerateDocs)
|
||||||
include(TorQrcGenerator)
|
include(TorQrcGenerator)
|
||||||
|
include(WownerodQrcGenerator)
|
||||||
|
|
||||||
# To build Feather with embedded (and static) Tor, pass CMake -DTOR_DIR=/path/to/tor/
|
# To build Feather with embedded (and static) Tor, pass CMake -DTOR_DIR=/path/to/tor/
|
||||||
if(TOR_DIR)
|
if(TOR_DIR)
|
||||||
@@ -163,6 +165,26 @@ else()
|
|||||||
message(STATUS "Skipping Tor inclusion because -DTOR_DIR=Off")
|
message(STATUS "Skipping Tor inclusion because -DTOR_DIR=Off")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# wowlet: copy the wownerod binary into src/assets/wownerod so it gets embedded — single self-contained
|
||||||
|
# file with the node inside. WOWNEROD_DIR points at a dir containing a `wownerod` (or wownerod.exe).
|
||||||
|
if(WOWNEROD_DIR)
|
||||||
|
execute_process(COMMAND bash -c "mkdir -p ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/wownerod")
|
||||||
|
if (REPRODUCIBLE)
|
||||||
|
set(WOWNEROD_COPY_CMD "cp -a ${WOWNEROD_DIR}/* ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/wownerod")
|
||||||
|
else()
|
||||||
|
set(WOWNEROD_COPY_CMD "cp -au ${WOWNEROD_DIR}/* ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/wownerod")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(COMMAND bash -c "${WOWNEROD_COPY_CMD}" RESULT_VARIABLE ret)
|
||||||
|
if(ret EQUAL "1")
|
||||||
|
message(FATAL_ERROR "wownerod copy failure: ${WOWNEROD_COPY_CMD}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Embedding wownerod binary from ${WOWNEROD_DIR}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Skipping wownerod inclusion because -DWOWNEROD_DIR=Off")
|
||||||
|
endif()
|
||||||
|
|
||||||
message(STATUS "Using Boost include dir at ${Boost_INCLUDE_DIRS}")
|
message(STATUS "Using Boost include dir at ${Boost_INCLUDE_DIRS}")
|
||||||
message(STATUS "Using Boost libraries at ${Boost_LIBRARIES}")
|
message(STATUS "Using Boost libraries at ${Boost_LIBRARIES}")
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Generates src/assets_wownerod.qrc embedding the wownerod binary from WOWNEROD_DIR, so wowlet ships
|
||||||
|
# as a single self-contained file with its node inside. Mirror of TorQrcGenerator.cmake. When
|
||||||
|
# WOWNEROD_DIR is OFF the generated qrc is empty (no embedded daemon) and HAS_WOWNEROD_BIN is unset.
|
||||||
|
set(QRC_LIST)
|
||||||
|
|
||||||
|
if (WOWNEROD_DIR)
|
||||||
|
FILE(GLOB WOWNEROD_FILES LIST_DIRECTORIES false ${WOWNEROD_DIR}/*)
|
||||||
|
|
||||||
|
foreach(FILE ${WOWNEROD_FILES})
|
||||||
|
cmake_path(GET FILE FILENAME FILE_REL)
|
||||||
|
list(APPEND QRC_LIST " <file>assets/wownerod/${FILE_REL}</file>")
|
||||||
|
|
||||||
|
if (FILE_REL STREQUAL "wownerod" OR FILE_REL STREQUAL "wownerod.exe")
|
||||||
|
set(WOWNEROD_BIN_FOUND 1)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if (NOT WOWNEROD_BIN_FOUND)
|
||||||
|
message(FATAL_ERROR "WOWNEROD_DIR was specified but the wownerod binary could not be found")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(JOIN QRC_LIST "\n" QRC_DATA)
|
||||||
|
configure_file("cmake/assets_wownerod.qrc" "${CMAKE_CURRENT_SOURCE_DIR}/src/assets_wownerod.qrc")
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
|
<qresource prefix="/">
|
||||||
|
@QRC_DATA@
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
+5
-1
@@ -31,7 +31,7 @@ if (CHECK_UPDATES)
|
|||||||
add_subdirectory(openpgp)
|
add_subdirectory(openpgp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
qt_add_resources(RESOURCES assets.qrc assets_tor.qrc assets_docs.qrc)
|
qt_add_resources(RESOURCES assets.qrc assets_tor.qrc assets_wownerod.qrc assets_docs.qrc)
|
||||||
|
|
||||||
# Compile source files (.h/.cpp)
|
# Compile source files (.h/.cpp)
|
||||||
file(GLOB SOURCE_FILES
|
file(GLOB SOURCE_FILES
|
||||||
@@ -213,6 +213,10 @@ if(TOR_DIR)
|
|||||||
target_compile_definitions(feather PRIVATE HAS_TOR_BIN=1)
|
target_compile_definitions(feather PRIVATE HAS_TOR_BIN=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WOWNEROD_DIR)
|
||||||
|
target_compile_definitions(feather PRIVATE HAS_WOWNEROD_BIN=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_SCANNER)
|
if(WITH_SCANNER)
|
||||||
target_compile_definitions(feather PRIVATE WITH_SCANNER=1)
|
target_compile_definitions(feather PRIVATE WITH_SCANNER=1)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ int main(int argc, char *argv[])
|
|||||||
Q_INIT_RESOURCE(assets_tor);
|
Q_INIT_RESOURCE(assets_tor);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAS_WOWNEROD_BIN)
|
||||||
|
Q_INIT_RESOURCE(assets_wownerod);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
freopen("CONOUT$", "w", stdout);
|
freopen("CONOUT$", "w", stdout);
|
||||||
|
|||||||
+17
-14
@@ -16,16 +16,8 @@ DaemonManager::DaemonManager(QObject *parent)
|
|||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_process(new QProcess(this))
|
, m_process(new QProcess(this))
|
||||||
{
|
{
|
||||||
|
// The embedded wownerod is unpacked here (writable, outside any read-only app bundle).
|
||||||
this->daemonDir = Config::defaultConfigDir().filePath("node");
|
this->daemonDir = Config::defaultConfigDir().filePath("node");
|
||||||
#if defined(Q_OS_MACOS)
|
|
||||||
// On macOS the binary ships next to the app inside the bundle.
|
|
||||||
{
|
|
||||||
QDir appBinaryDir(QCoreApplication::applicationDirPath());
|
|
||||||
appBinaryDir.cd("..");
|
|
||||||
this->daemonDir = appBinaryDir.filePath("bin");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this->blockchainDir = Config::defaultConfigDir().filePath("node/blockchain");
|
this->blockchainDir = Config::defaultConfigDir().filePath("node/blockchain");
|
||||||
|
|
||||||
m_process->setProcessChannelMode(QProcess::MergedChannels);
|
m_process->setProcessChannelMode(QProcess::MergedChannels);
|
||||||
@@ -157,12 +149,23 @@ bool DaemonManager::unpackBins() {
|
|||||||
daemonBin += ".exe";
|
daemonBin += ".exe";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->daemonPath = QDir(this->daemonDir).filePath(daemonBin);
|
// 1. Explicit path the user configured (or already-running node they point us at).
|
||||||
|
QString configured = conf()->get(Config::wownerodPath).toString();
|
||||||
|
if (!configured.isEmpty() && QFileInfo(configured).isFile()) {
|
||||||
|
this->daemonPath = configured;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(Q_OS_MACOS)
|
// 2. Shipped next to the wowlet executable — the packaging default (monero-GUI ships monerod
|
||||||
// Shipped next to the app bundle; nothing to unpack.
|
// the same way). Avoids bloating the app binary by embedding a ~15 MB daemon in resources.
|
||||||
return QFileInfo(this->daemonPath).isFile();
|
QString sibling = QDir(QCoreApplication::applicationDirPath()).filePath(daemonBin);
|
||||||
#endif
|
if (QFileInfo(sibling).isFile()) {
|
||||||
|
this->daemonPath = sibling;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Unpack the embedded copy into the (writable) data dir — the single-file default, all platforms.
|
||||||
|
this->daemonPath = QDir(this->daemonDir).filePath(daemonBin);
|
||||||
|
|
||||||
if (m_unpacked)
|
if (m_unpacked)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
|
|||||||
{Config::skin,{QS("skin"), "Wownero"}},
|
{Config::skin,{QS("skin"), "Wownero"}},
|
||||||
{Config::runLocalNode,{QS("runLocalNode"), true}}, // wowlet: run own node by default
|
{Config::runLocalNode,{QS("runLocalNode"), true}}, // wowlet: run own node by default
|
||||||
{Config::pruneBlockchain,{QS("pruneBlockchain"), false}}, // full archival by default
|
{Config::pruneBlockchain,{QS("pruneBlockchain"), false}}, // full archival by default
|
||||||
|
{Config::wownerodPath,{QS("wownerodPath"), ""}}, // optional override; bundled by default
|
||||||
{Config::amountPrecision, {QS("amountPrecision"), 12}},
|
{Config::amountPrecision, {QS("amountPrecision"), 12}},
|
||||||
{Config::dateFormat, {QS("dateFormat"), "yyyy-MM-dd"}},
|
{Config::dateFormat, {QS("dateFormat"), "yyyy-MM-dd"}},
|
||||||
{Config::timeFormat, {QS("timeFormat"), "HH:mm"}},
|
{Config::timeFormat, {QS("timeFormat"), "HH:mm"}},
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ public:
|
|||||||
// Embedded node (wowlet)
|
// Embedded node (wowlet)
|
||||||
runLocalNode,
|
runLocalNode,
|
||||||
pruneBlockchain,
|
pruneBlockchain,
|
||||||
|
wownerodPath,
|
||||||
|
|
||||||
// Network -> Proxy
|
// Network -> Proxy
|
||||||
proxy,
|
proxy,
|
||||||
|
|||||||
Reference in New Issue
Block a user