# src/CMakeLists.txt # Defines all build targets: libraries and executables. # ═══════════════════════════════════════════════════════════════════════════════ # 1. Hash9 cryptographic primitives (pure C) # ═══════════════════════════════════════════════════════════════════════════════ add_library(hash9_crypto STATIC blake.c groestl.c jh.c keccak.c skein.c aes_helper.c bmw.c cubehash.c echo.c fugue.c hamsi.c hamsi_helper.c luffa.c shavite.c simd.c ) target_include_directories(hash9_crypto PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") set_target_properties(hash9_crypto PROPERTIES LINKER_LANGUAGE C) # Hash9 C files have colliding static symbols (IV512, DECL_STATE, etc.) — skip unity set_target_properties(hash9_crypto PROPERTIES UNITY_BUILD OFF) # ═══════════════════════════════════════════════════════════════════════════════ # 2. JSON library (header-only nlohmann/json via json_compat.h shim) # ═══════════════════════════════════════════════════════════════════════════════ add_library(json_compat INTERFACE) target_include_directories(json_compat INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/json") # ═══════════════════════════════════════════════════════════════════════════════ # 3. Common core library (shared between daemon, Qt, and tests) # # EXCLUDES init.cpp, wallet.cpp (QT_GUI-conditional), noui.cpp (target-specific) # ═══════════════════════════════════════════════════════════════════════════════ set(CORE_SOURCES addrman.cpp bootstrap.cpp checkpointpublisher.cpp checkpoints.cpp crypter.cpp hdwallet.cpp crypto_ecdh.cpp crypto_ecdsa.cpp db.cpp key.cpp keystore.cpp main.cpp miner.cpp net.cpp net_bootstrap.cpp netbase.cpp protocol.cpp script.cpp sync.cpp util.cpp version.cpp walletdb.cpp kernel.cpp pbkdf2.cpp scrypt.cpp smessage.cpp syncmanager.cpp chaindb_migrate.cpp tor_embed_hooks.cpp rest.cpp trianglesrpc.cpp rpcdump.cpp rpcnet.cpp rpcmining.cpp rpcwallet.cpp rpcblockchain.cpp rpcrawtransaction.cpp rpcsmessage.cpp zmqpublishnotifier.cpp txdb-base.cpp txdb-factory.cpp txdb-leveldb.cpp utxosnapshot.cpp snapshotnet.cpp lz4/lz4.c tor/onion_v3.cpp tor/tor_process.cpp tor/tor_embedded.cpp i2p/i2p_embedded.cpp ) # Scrypt assembly — platform-specific if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64") enable_language(ASM) list(APPEND CORE_SOURCES scrypt-x86_64.S) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i[3-6]86|x86") enable_language(ASM) list(APPEND CORE_SOURCES scrypt-x86.S) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64") enable_language(ASM) list(APPEND CORE_SOURCES scrypt-arm.S) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM") enable_language(ASM) list(APPEND CORE_SOURCES scrypt-arm.S) endif() # RocksDB chain database backend (always built; see top-level CMakeLists.txt # for the rationale — RocksDB also backs the smessage store). list(APPEND CORE_SOURCES txdb-rocksdb.cpp) # Modernization: SQLite wallet DB backend + Berkeley→SQLite migration. # Built unconditionally; selection happens at runtime via -walletdb. list(APPEND CORE_SOURCES walletdb-factory.cpp walletdb-sqlite.cpp walletdb-recover.cpp walletmigrate.cpp ) add_library(triangles_common OBJECT ${CORE_SOURCES}) target_include_directories(triangles_common PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/json" "${CMAKE_CURRENT_SOURCE_DIR}/tor" "${CMAKE_CURRENT_SOURCE_DIR}/i2p" "${CMAKE_BINARY_DIR}/generated" # for build.h ) target_compile_definitions(triangles_common PUBLIC HAVE_BUILD_INFO) target_link_libraries(triangles_common PUBLIC hash9_crypto json_compat leveldb_bundled OpenSSL::SSL OpenSSL::Crypto BerkeleyDB::BerkeleyDB Libevent::Libevent ZLIB::ZLIB Threads::Threads SQLite::SQLite3 ) # Optional: UPnP if(USE_UPNP) target_compile_definitions(triangles_common PUBLIC USE_UPNP=1 STATICLIB MINIUPNP_STATICLIB) target_link_libraries(triangles_common PUBLIC Miniupnpc::Miniupnpc) if(WIN32) target_link_libraries(triangles_common PUBLIC iphlpapi) endif() endif() # Optional: IPv6 if(USE_IPV6) target_compile_definitions(triangles_common PUBLIC USE_IPV6=1) endif() # Optional: ZMQ if(USE_ZMQ) target_compile_definitions(triangles_common PUBLIC ENABLE_ZMQ) target_link_libraries(triangles_common PUBLIC PkgConfig::ZMQ) endif() # libsecp256k1 (mandatory) — ECDH / ECDSA replacement for OpenSSL EC. # Provided by add_subdirectory(src/secp256k1) in the top-level CMakeLists. target_link_libraries(triangles_common PUBLIC secp256k1) # RocksDB (mandatory) if(TARGET RocksDB::rocksdb) target_link_libraries(triangles_common PUBLIC RocksDB::rocksdb) elseif(TARGET PkgConfig::RocksDB) target_link_libraries(triangles_common PUBLIC PkgConfig::RocksDB) endif() # Optional: Embedded Tor if(USE_TOR_EMBEDDED) if(TOR_SOURCE_ROOT STREQUAL "") set(TOR_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/tor/tor-src") endif() target_compile_definitions(triangles_common PUBLIC ENABLE_TOR_EMBEDDED) target_include_directories(triangles_common PUBLIC "${TOR_SOURCE_ROOT}/src/feature/api") target_link_directories(triangles_common PUBLIC "${TOR_SOURCE_ROOT}") # libtor.a has circular deps with libevent/openssl/zlib # OpenSSL and zlib already linked via imported targets above, so only add # libevent and compression libs that libtor needs but aren't yet linked. # --start-group / --end-group resolves circular references between libtor # and its dependencies. # Use --allow-multiple-definition because libtor.a may pull in static # OpenSSL objects that duplicate the DLL import lib already linked above. # These GNU ld options are not supported on macOS (which uses lld) — # guard with NOT APPLE so the build still works on macOS. # On macOS, the libevent/openssl/zlib install paths are not on the # default linker search path. Pull them in from the standard # homebrew locations so -levent / -lssl / -lssl etc. resolve. if(APPLE) target_link_directories(triangles_common PUBLIC /opt/homebrew/opt/libevent/lib /opt/homebrew/opt/openssl@3/lib /opt/homebrew/opt/zlib/lib ) endif() if(NOT APPLE) target_link_libraries(triangles_common PUBLIC -Wl,--allow-multiple-definition -Wl,--start-group ) endif() target_link_libraries(triangles_common PUBLIC -ltor -levent -levent_core -levent_extra -levent_openssl -lssl -lcrypto -lz -llzma -lzstd ) if(NOT APPLE) target_link_libraries(triangles_common PUBLIC -Wl,--end-group ) endif() if(WIN32) target_link_libraries(triangles_common PUBLIC iphlpapi shlwapi crypt32) endif() endif() # Optional: Embedded I2P (i2pd) if(USE_I2P_EMBEDDED) if(I2P_SOURCE_ROOT STREQUAL "") set(I2P_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/i2p/i2pd-src") endif() if(NOT EXISTS "${I2P_SOURCE_ROOT}/libi2pd/Crypto.h") message(FATAL_ERROR "USE_I2P_EMBEDDED=ON but i2pd source not found at ${I2P_SOURCE_ROOT}.\n" "Run: git submodule update --init --recursive\n" "Or set -DI2P_SOURCE_ROOT=/path/to/i2pd") endif() target_compile_definitions(triangles_common PUBLIC ENABLE_I2P_EMBEDDED) target_include_directories(triangles_common PUBLIC "${I2P_SOURCE_ROOT}" "${I2P_SOURCE_ROOT}/libi2pd" "${I2P_SOURCE_ROOT}/libi2pd_client" "${I2P_SOURCE_ROOT}/i18n" ) # i2pd builds as two static libraries: libi2pd.a (core router) and # libi2pd_client.a (SAM, SOCKS, tunnels, client context). Both are needed. # i2pd's own Makefile.mingw links by full static .a paths rather than # -l flags because MinGW's linker is single-pass and CMake imported # targets (Boost::) may not exist on MSYS2. We follow the same pattern: # link the archives, then their Boost/zlib deps as full paths, then # the archives again to resolve the second-pass references. target_link_libraries(triangles_common PUBLIC "${I2P_SOURCE_ROOT}/libi2pdclient.a" "${I2P_SOURCE_ROOT}/libi2pd.a" "${I2P_SOURCE_ROOT}/libi2pdlang.a" ) if(WIN32) # MinGW/MSYS2: Boost:: CMake imported targets are unreliable here. # Use find_library to locate the actual .a/.dll files. Some Boost # libs (e.g. boost_system) are header-only in newer versions and # won't have a .a file at all — that's fine, we skip them. if(NOT MINGW_PREFIX) if(DEFINED ENV{MINGW_PREFIX}) set(MINGW_PREFIX "$ENV{MINGW_PREFIX}") else() set(MINGW_PREFIX "/mingw64") endif() endif() find_library(I2P_BOOST_FS NAMES boost_filesystem-mt boost_filesystem libboost_filesystem-mt HINTS "${MINGW_PREFIX}/lib") find_library(I2P_BOOST_PO NAMES boost_program_options-mt boost_program_options libboost_program_options-mt HINTS "${MINGW_PREFIX}/lib") find_library(I2P_BOOST_SYS NAMES boost_system-mt boost_system libboost_system-mt HINTS "${MINGW_PREFIX}/lib") find_library(I2P_SSL NAMES ssl libssl HINTS "${MINGW_PREFIX}/lib") find_library(I2P_CRYPTO NAMES crypto libcrypto HINTS "${MINGW_PREFIX}/lib") find_library(I2P_Z NAMES z libz zlib HINTS "${MINGW_PREFIX}/lib") set(I2P_WIN_LIBS "") foreach(lib I2P_BOOST_FS I2P_BOOST_PO I2P_BOOST_SYS I2P_SSL I2P_CRYPTO I2P_Z) if(${lib}) list(APPEND I2P_WIN_LIBS "${${lib}}") message(STATUS " I2P link: ${lib} = ${${lib}}") else() message(STATUS " I2P link: ${lib} = (not found, header-only?)") endif() endforeach() target_link_libraries(triangles_common PUBLIC ${I2P_WIN_LIBS} -Wl,--allow-multiple-definition) else() target_link_libraries(triangles_common PUBLIC Boost::program_options Boost::thread Boost::chrono OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB ) if(TARGET Boost::filesystem) target_link_libraries(triangles_common PUBLIC Boost::filesystem) endif() if(TARGET Boost::system) target_link_libraries(triangles_common PUBLIC Boost::system) endif() endif() # Second pass: list archives again so linker resolves i2pd→Boost refs # that were unsatisfied in the first left-to-right pass. target_link_libraries(triangles_common PUBLIC "${I2P_SOURCE_ROOT}/libi2pd.a" "${I2P_SOURCE_ROOT}/libi2pdclient.a" ) endif() # Platform-specific libraries if(WIN32) target_link_libraries(triangles_common PUBLIC ws2_32 shlwapi mswsock ole32 oleaut32 uuid gdi32 crypt32) elseif(APPLE) target_link_libraries(triangles_common PUBLIC "-framework Foundation" "-framework ApplicationServices" "-framework AppKit") else() # Linux target_link_libraries(triangles_common PUBLIC rt dl) endif() add_dependencies(triangles_common generate_build_info build_leveldb) # ── Precompiled header (heavy STL + Boost + OpenSSL includes, C++ only) ── target_precompile_headers(triangles_common PRIVATE "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" "$<$:>" ) # ═══════════════════════════════════════════════════════════════════════════════ # 4. Headless daemon (trianglesd) # ═══════════════════════════════════════════════════════════════════════════════ if(BUILD_DAEMON) add_executable(trianglesd noui.cpp init.cpp wallet.cpp ) # No QT_GUI define — daemon gets the #if !defined(QT_GUI) code paths target_link_libraries(trianglesd PRIVATE triangles_common) target_precompile_headers(trianglesd REUSE_FROM triangles_common) if(WIN32) set_target_properties(trianglesd PROPERTIES SUFFIX ".exe") endif() endif() # ═══════════════════════════════════════════════════════════════════════════════ # 4b. JSON-RPC client (triangles-cli) # # Self-contained: only links univalue + boost::asio + boost::program_options # + boost::filesystem + OpenSSL (for base64 / future TLS). Does NOT link # triangles_common, wallet, or net — keeps the binary small. # ═══════════════════════════════════════════════════════════════════════════════ if(BUILD_CLI) add_executable(triangles-cli triangles-cli.cpp ) # No Boost dependency: uses raw POSIX/Winsock sockets for HTTP. Only links # the json_compat header-only shim and the platform's native socket lib # (Winsock ws2_32 on Windows; libc on POSIX). Keeps the binary small and # avoids per-platform Boost linking pain (MSYS2 uses versioned -mt- names; # Homebrew doesn't ship the boost_system CMake config). target_link_libraries(triangles-cli PRIVATE json_compat ) if(WIN32) set_target_properties(triangles-cli PROPERTIES SUFFIX ".exe") target_link_libraries(triangles-cli PRIVATE ws2_32) endif() if(MSVC) set_target_properties(triangles-cli PROPERTIES VS_WINRT_COMPONENT "console" ) endif() endif() # ═══════════════════════════════════════════════════════════════════════════════ # 5. Qt5 GUI wallet (triangles-qt) # ═══════════════════════════════════════════════════════════════════════════════ if(BUILD_QT) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/qt/forms" "${CMAKE_CURRENT_SOURCE_DIR}/qt/plugins/mrichtexteditor" ) # ui_interface.h is a hand-written header (Bitcoin convention), NOT a Qt # Designer file. Disable AutoUic globally and run UIC manually for real .ui files. set(CMAKE_AUTOUIC OFF) # Collect all .ui files and run UIC on them explicitly file(GLOB_RECURSE UI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/qt/forms/*.ui" "${CMAKE_CURRENT_SOURCE_DIR}/qt/plugins/mrichtexteditor/*.ui" ) qt5_wrap_ui(UI_HEADERS ${UI_FILES}) set(QT_SOURCES qt/triangles.cpp qt/trianglesgui.cpp qt/transactiontablemodel.cpp qt/addresstablemodel.cpp qt/optionsdialog.cpp qt/sendcoinsdialog.cpp qt/coincontroldialog.cpp qt/coincontroltreewidget.cpp qt/addressbookpage.cpp qt/aboutdialog.cpp qt/introdialog.cpp qt/editaddressdialog.cpp qt/trianglesaddressvalidator.cpp qt/clientmodel.cpp qt/guiutil.cpp qt/transactionrecord.cpp qt/optionsmodel.cpp qt/monitoreddatamapper.cpp qt/transactiondesc.cpp qt/transactiondescdialog.cpp qt/trianglesstrings.cpp qt/trianglesamountfield.cpp qt/transactionfilterproxy.cpp qt/transactionview.cpp qt/walletmodel.cpp qt/overviewpage.cpp qt/csvmodelwriter.cpp qt/sendcoinsentry.cpp qt/qvalidatedlineedit.cpp qt/trianglesunits.cpp qt/qvaluecombobox.cpp qt/askpassphrasedialog.cpp qt/hdseeddialog.cpp qt/outlinedlabel.cpp qt/notificator.cpp qt/qtipcserver.cpp qt/rpcconsole.cpp qt/messagepage.cpp qt/dialog_move_handler.cpp qt/signmessagepage.cpp qt/verifymessagepage.cpp qt/messagemodel.cpp qt/sendmessagesdialog.cpp qt/sendmessagesentry.cpp qt/qvalidatedtextedit.cpp qt/plugins/mrichtexteditor/mrichtextedit.cpp ) set(QT_RESOURCES qt/triangles.qrc) set(QT_FORMS qt/forms/coincontroldialog.ui qt/forms/sendcoinsdialog.ui qt/forms/addressbookpage.ui qt/forms/aboutdialog.ui qt/forms/editaddressdialog.ui qt/forms/transactiondescdialog.ui qt/forms/overviewpage.ui qt/forms/sendcoinsentry.ui qt/forms/askpassphrasedialog.ui qt/forms/rpcconsole.ui qt/forms/optionsdialog.ui qt/forms/messagepage.ui qt/forms/sendmessagesentry.ui qt/forms/sendmessagesdialog.ui qt/plugins/mrichtexteditor/mrichtextedit.ui qt/forms/mainwindow.ui qt/forms/signmessagepage.ui qt/forms/verifymessagepage.ui qt/forms/transactionspage.ui ) # Optional QR code dialog if(USE_QRCODE) list(APPEND QT_SOURCES qt/qrcodedialog.cpp) list(APPEND QT_FORMS qt/forms/qrcodedialog.ui) endif() # macOS Objective-C++ sources if(APPLE) list(APPEND QT_SOURCES qt/macdockiconhandler.mm qt/macnotificationhandler.mm ) endif() add_executable(triangles-qt WIN32 MACOSX_BUNDLE ${QT_SOURCES} ${QT_RESOURCES} ${QT_FORMS} ${UI_HEADERS} # Per-target: compiled with QT_GUI define init.cpp wallet.cpp noui.cpp ) target_compile_definitions(triangles-qt PRIVATE QT_GUI QT_DISABLE_DEPRECATED_BEFORE=0 ) target_include_directories(triangles-qt PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/qt" "${CMAKE_CURRENT_SOURCE_DIR}/qt/plugins/mrichtexteditor" "${CMAKE_CURRENT_BINARY_DIR}" ) target_link_libraries(triangles-qt PRIVATE triangles_common Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Network ) # Optional: D-Bus notifications (Linux) if(USE_DBUS) target_compile_definitions(triangles-qt PRIVATE USE_DBUS) target_link_libraries(triangles-qt PRIVATE Qt5::DBus) endif() # Optional: QR code if(USE_QRCODE) target_compile_definitions(triangles-qt PRIVATE USE_QRCODE) target_link_libraries(triangles-qt PRIVATE QRencode::QRencode) endif() # Windows resource file (.rc with version info and icon) if(WIN32) target_sources(triangles-qt PRIVATE qt/res/triangles-qt.rc) # Ensure RC compiler can find clientversion.h if(MINGW) set_source_files_properties(qt/res/triangles-qt.rc PROPERTIES COMPILE_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR}" ) endif() endif() # macOS bundle settings if(APPLE) set_target_properties(triangles-qt PROPERTIES OUTPUT_NAME "Triangles-Qt" MACOSX_BUNDLE_ICON_FILE triangles.icns MACOSX_BUNDLE_BUNDLE_NAME "Triangles-Qt" MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}" MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}" ) set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/qt/res/icons/triangles.icns" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" ) target_sources(triangles-qt PRIVATE qt/res/icons/triangles.icns) endif() # Translations (optional — requires LinguistTools) if(TARGET Qt5::lrelease) file(GLOB TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/qt/locale/triangles_*.ts") if(TS_FILES) set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/qt/locale" ) qt5_add_translation(QM_FILES ${TS_FILES}) target_sources(triangles-qt PRIVATE ${QM_FILES}) endif() endif() endif() # ═══════════════════════════════════════════════════════════════════════════════ # 6. Unit tests (test_triangles) # ═══════════════════════════════════════════════════════════════════════════════ if(BUILD_TESTS) enable_testing() file(GLOB TEST_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/test/*.cpp") # Exclude miner_tests.cpp (never ported from Bitcoin) list(FILTER TEST_SOURCES EXCLUDE REGEX "miner_tests\\.cpp$") # Exclude the standalone chaindb test driver — it gets its own target # because it needs to run without the TestingSetup global fixture. list(FILTER TEST_SOURCES EXCLUDE REGEX "chaindb_equivalence_tests_main\\.cpp$") # These two are standalone test drivers: each #defines its own # BOOST_TEST_MODULE and redefines the wallet/UI globals, and each has # a dedicated executable + add_test below. They must NOT also be # globbed into test_triangles, or the duplicate module/main and global # symbols only link by virtue of -Wl,--allow-multiple-definition (which # silently drops duplicates and can run their suites under the wrong # global fixture). Excluding them keeps each standalone module isolated. list(FILTER TEST_SOURCES EXCLUDE REGEX "chaindb_runtime_tests\\.cpp$") list(FILTER TEST_SOURCES EXCLUDE REGEX "snapshotnet_tests\\.cpp$") add_executable(test_triangles ${TEST_SOURCES} # Per-target: wallet without QT_GUI, noui for noui_connect() wallet.cpp noui.cpp ) # No init.cpp — test_triangles.cpp provides its own StartShutdown() stub target_compile_definitions(test_triangles PRIVATE "TEST_DATA_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test/data" ) target_include_directories(test_triangles PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/test" ) target_link_libraries(test_triangles PRIVATE triangles_common Boost::unit_test_framework ) add_test(NAME triangles_unit_tests COMMAND test_triangles --log_level=test_suite) # ── Standalone chaindb equivalence tests ───────────────────────────────── # Runs without the TestingSetup global fixture (which would otherwise # open the real chain DB and lock it for the process). Sets a fresh # temp -datadir via its own global fixture, then runs the # chaindb_equivalence_tests suite. add_executable(test_chaindb_equivalence "${CMAKE_CURRENT_SOURCE_DIR}/test/chaindb_equivalence_tests_main.cpp" # wallet.cpp provides the CWallet symbols that triangles_common # (txdb-rocksdb, net, etc.) references, even though the chaindb # tests themselves don't use the wallet. wallet.cpp ) target_include_directories(test_chaindb_equivalence PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/test" "${CMAKE_CURRENT_SOURCE_DIR}/leveldb/include" ) target_link_libraries(test_chaindb_equivalence PRIVATE triangles_common Boost::unit_test_framework ) add_test(NAME chaindb_equivalence_tests COMMAND test_chaindb_equivalence --log_level=test_suite) # ── Standalone snapshotnet P2P tests ──────────────────────────────────── # Same rationale as test_chaindb_equivalence: snapshotnet needs filesystem # and threading globals and its own tmp datadir fixture, which would # conflict with test_triangles' heavy TestingSetup. Runs independently. add_executable(test_snapshotnet "${CMAKE_CURRENT_SOURCE_DIR}/test/snapshotnet_tests.cpp" wallet.cpp ) target_include_directories(test_snapshotnet PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/test" "${CMAKE_CURRENT_SOURCE_DIR}/leveldb/include" ) target_link_libraries(test_snapshotnet PRIVATE triangles_common Boost::unit_test_framework ) add_test(NAME snapshotnet_tests COMMAND test_snapshotnet --log_level=test_suite) # ── Standalone chaindb runtime tests (CRocksTxDB wrapper layer) ───────── # Exercises MakeChainDB / WipeChainDataDir / IsRocksDbChainBackend and # the CRocksTxDB write/read/batch/iterator wrapper — the same code path # the daemon uses when launched with `-chaindb=rocksdb`. The # chaindb_equivalence_tests (above) only verify the byte-copy migration # via the raw leveldb/rocksdb APIs; this one verifies the wrapper class. add_executable(test_chaindb_runtime "${CMAKE_CURRENT_SOURCE_DIR}/test/chaindb_runtime_tests.cpp" wallet.cpp ) target_include_directories(test_chaindb_runtime PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/test" "${CMAKE_CURRENT_SOURCE_DIR}/leveldb/include" ) target_link_libraries(test_chaindb_runtime PRIVATE triangles_common Boost::unit_test_framework ) add_test(NAME chaindb_runtime_tests COMMAND test_chaindb_runtime --log_level=test_suite) endif()