f0889d9b70
Three coupled fixes to the test harness (no consensus/runtime code touched): 1. Root CMakeLists never called enable_testing(), so the top-level build/CTestTestfile.cmake was never generated and "cd build && ctest" (exactly what CI runs) discovered ZERO tests. The whole unit suite was silently not gating CI; only the explicitly-invoked equivalence binary ran. Add enable_testing() at the root so ctest finds all four test executables. 2. chaindb_runtime_tests.cpp and snapshotnet_tests.cpp were compiled BOTH into their own standalone executables AND into test_triangles via the test/*.cpp glob. Each #defines its own BOOST_TEST_MODULE and redefines the wallet/UI globals; the link only survived via -Wl,--allow-multiple-definition, which silently drops duplicate module and global symbols and can run those suites under the wrong fixture. Exclude both from the glob (they already have dedicated add_executable + add_test); nothing is lost and isolation is restored. 3. test_triangles TestingSetup opened the PRODUCTION chain DB at the default datadir, so ctest failed (DB lock) on any host running a live daemon and risked touching real chain state. Point -datadir at a fresh temp dir in the fixture (mirrors the standalone DataDirSetup); cleaned up on teardown. After: ctest -N lists 4 tests; ctest runs 100% green even with a live trianglesd holding the default datadir.
700 lines
28 KiB
CMake
700 lines
28 KiB
CMake
# 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
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<string$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<vector$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<map$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<deque$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<algorithm$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<sstream$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<stdexcept$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<cstdint$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<cstring$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<memory$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<functional$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<filesystem$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<fstream$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<thread$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<mutex$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<condition_variable$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<boost/algorithm/string.hpp$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<openssl/sha.h$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<openssl/crypto.h$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<openssl/rand.h$<ANGLE-R>>"
|
|
"$<$<COMPILE_LANGUAGE:CXX>:<openssl/evp.h$<ANGLE-R>>"
|
|
)
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# 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()
|