From adcb89539a61eb05c4f020d817aa7992f5fbb824 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:29:40 +0000 Subject: [PATCH 1/6] Revert "build, qt: Do not install *.prl files" This reverts commit 1155978d8f3fcc1cebf357302b933b834f9c9465. --- depends/packages/qt.mk | 2 +- depends/patches/qt/qt.pro | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 5608e5f07387d..99511362b7892 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -288,5 +288,5 @@ endef define $(package)_postprocess_cmds rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \ - rm -f lib/lib*.la + rm -f lib/lib*.la lib/*.prl plugins/*/*.prl endef diff --git a/depends/patches/qt/qt.pro b/depends/patches/qt/qt.pro index 8f2e900a840fb..6d8b7fdb6a2ca 100644 --- a/depends/patches/qt/qt.pro +++ b/depends/patches/qt/qt.pro @@ -3,10 +3,6 @@ cache(, super) !QTDIR_build: cache(CONFIG, add, $$list(QTDIR_build)) -prl = no_install_prl -CONFIG += $$prl -cache(CONFIG, add stash, prl) - TEMPLATE = subdirs SUBDIRS = qtbase qttools qttranslations From 26093770e8daab4394e49315e527b591f166f722 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 19 Jan 2024 18:45:27 +0000 Subject: [PATCH 2/6] fixup! build: Generate `share/toolchain.cmake` in depends --- depends/Makefile | 1 + depends/toolchain.cmake.in | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/depends/Makefile b/depends/Makefile index cb84c480c9484..13ce840fac5aa 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -266,6 +266,7 @@ $(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_ -e 's|@host_arch@|$(host_arch)|' \ -e 's|@CC@|$(host_CC)|' \ -e 's|@CXX@|$(host_CXX)|' \ + -e 's|@OSX_SDK@|$(OSX_SDK)|' \ -e 's|@AR@|$(host_AR)|' \ -e 's|@RANLIB@|$(host_RANLIB)|' \ -e 's|@STRIP@|$(host_STRIP)|' \ diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in index 26a9818b35711..7193c172868a1 100644 --- a/depends/toolchain.cmake.in +++ b/depends/toolchain.cmake.in @@ -91,8 +91,16 @@ set(PKG_CONFIG_PATH "@depends_prefix@/lib/pkgconfig") set(PKG_CONFIG_LIBDIR "${PKG_CONFIG_PATH}") set(QT_TRANSLATIONS_DIR "@depends_prefix@/translations") +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_HOST_APPLE) + # The find_package(Qt ...) function internally uses find_library() + # calls for all dependencies to ensure their availability. + # In turn, the find_library() inspects the well-known locations + # on the file system; therefore, a hint is required. + set(CMAKE_FRAMEWORK_PATH "@OSX_SDK@/System/Library/Frameworks") +endif() + if(NOT WITH_GUI AND "@no_qt@" STREQUAL "1") - set(WITH_GUI "no" CACHE STRING "") + set(WITH_GUI OFF CACHE STRING "") endif() if(NOT WITH_QRENCODE AND "@no_qr@" STREQUAL "1") From b342887e0acc46947d5ce2e2e313c3abfc3bf624 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 26 Jan 2024 19:23:43 +0000 Subject: [PATCH 3/6] cmake: Build `bitcoin-qt` executable --- CMakeLists.txt | 3 + cmake/optional_qt.cmake | 46 +++++++++++ depends/packages/qt.mk | 9 ++- src/CMakeLists.txt | 5 ++ src/qt/CMakeLists.txt | 172 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 cmake/optional_qt.cmake create mode 100644 src/qt/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ba48df5f04ef..9f5597dfbe8fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -236,6 +236,8 @@ else() unset(debug_flags) endif() +include(cmake/optional_qt.cmake) + include(cmake/optional.cmake) # Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review. @@ -342,6 +344,7 @@ message("Wallet support:") message(" SQLite, descriptor wallets .......... ${WITH_SQLITE}") message(" Berkeley DB, legacy wallets ......... ${WITH_BDB}") message("Optional packages:") +message(" GUI ................................. ${WITH_GUI}") message(" NAT-PMP ............................. ${WITH_NATPMP}") message(" UPnP ................................ ${WITH_MINIUPNPC}") message(" ZeroMQ .............................. ${WITH_ZMQ}") diff --git a/cmake/optional_qt.cmake b/cmake/optional_qt.cmake new file mode 100644 index 0000000000000..bf46f8413b13b --- /dev/null +++ b/cmake/optional_qt.cmake @@ -0,0 +1,46 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +set(WITH_GUI "AUTO" CACHE STRING "Build GUI ([AUTO], Qt5, OFF)") +set(with_gui_values AUTO Qt5 OFF) +if(NOT WITH_GUI IN_LIST with_gui_values) + message(FATAL_ERROR "WITH_GUI value is \"${WITH_GUI}\", but must be one of \"AUTO\", \"Qt5\" or \"OFF\".") +endif() + +if(WITH_GUI) + set(QT_NO_CREATE_VERSIONLESS_FUNCTIONS ON) + set(QT_NO_CREATE_VERSIONLESS_TARGETS ON) + + if(BREW_COMMAND) + execute_process( + COMMAND ${BREW_COMMAND} --prefix qt@5 + OUTPUT_VARIABLE qt5_brew_prefix + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + + if(WITH_GUI STREQUAL "AUTO") + # The PATH_SUFFIXES option is required on OpenBSD systems. + find_package(QT NAMES Qt5 + COMPONENTS Core + HINTS ${qt5_brew_prefix} + PATH_SUFFIXES Qt5 + ) + if(QT_FOUND) + set(WITH_GUI Qt${QT_VERSION_MAJOR}) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + enable_language(OBJCXX) + set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_OBJCXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_OBJCXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + set(CMAKE_OBJCXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") + endif() + else() + message(WARNING "Qt not found, disabling.\n" + "To skip this warning check, use \"-DWITH_GUI=OFF\".\n") + set(WITH_GUI OFF) + endif() + endif() +endif() diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 99511362b7892..ffa2e66a84607 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -280,13 +280,14 @@ define $(package)_build_cmds $(MAKE) endef +# TODO: Investigate whether specific targets can be used here to minimize the amount of files/components installed. define $(package)_stage_cmds - $(MAKE) -C qtbase/src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && \ - $(MAKE) -C qttools/src/linguist INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_linguist_tools))) && \ + $(MAKE) -C qtbase INSTALL_ROOT=$($(package)_staging_dir) install && \ + $(MAKE) -C qttools INSTALL_ROOT=$($(package)_staging_dir) install && \ $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets endef define $(package)_postprocess_cmds - rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \ - rm -f lib/lib*.la lib/*.prl plugins/*/*.prl + rm -rf doc/ native/lib/ && \ + rm -f lib/lib*.la endef diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 087cf4b641b19..44b83f83002ad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -327,6 +327,11 @@ if(BUILD_UTIL) endif() +if(WITH_GUI) + add_subdirectory(qt) +endif() + + add_subdirectory(test/util) if(BUILD_BENCH) add_subdirectory(bench) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt new file mode 100644 index 0000000000000..8af0a65ccc158 --- /dev/null +++ b/src/qt/CMakeLists.txt @@ -0,0 +1,172 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +# See: +# - https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html +# - https://doc.qt.io/qt-5/cmake-manual.html + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOUIC_SEARCH_PATHS forms) + +set(qt_minimum_required_version 5.11.3) + +set(qt_components Core Gui Widgets Network LinguistTools) + +if(CMAKE_CROSSCOMPILING) + # The find_package(Qt ...) function internally uses find_library() + # calls for all dependencies to ensure their availability. + # In turn, the find_library() inspects the well-known locations + # on the file system; therefore, it must be able to find + # platform-specific system libraries, for example: + # /usr/x86_64-w64-mingw32/lib/libm.a or /usr/arm-linux-gnueabihf/lib/libm.a. + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) +endif() + +find_package(Qt5 ${qt_minimum_required_version} REQUIRED + COMPONENTS ${qt_components} + HINTS ${qt5_brew_prefix} + PATH_SUFFIXES Qt5 # Required on OpenBSD systems. +) +unset(qt_components) +message(STATUS "Found Qt: ${Qt5_DIR} (found suitable version \"${Qt5_VERSION}\", minimum required is \"${qt_minimum_required_version}\")") +unset(qt_minimum_required_version) + +# TODO: The file(GLOB ...) command should be replaced with an explicit +# file list. Such a change must be synced with the corresponding change +# to https://github.com/bitcoin-core/bitcoin-maintainer-tools/blob/main/update-translations.py +file(GLOB ts_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} locale/*.ts) +set_source_files_properties(${ts_files} PROPERTIES OUTPUT_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/locale) +qt5_add_translation(qm_files ${ts_files}) + +configure_file(bitcoin_locale.qrc bitcoin_locale.qrc COPYONLY) + +add_library(bitcoinqt STATIC EXCLUDE_FROM_ALL + bantablemodel.cpp + bitcoin.cpp + bitcoinaddressvalidator.cpp + bitcoinamountfield.cpp + bitcoingui.cpp + bitcoinunits.cpp + clientmodel.cpp + csvmodelwriter.cpp + guiutil.cpp + initexecutor.cpp + intro.cpp + modaloverlay.cpp + networkstyle.cpp + notificator.cpp + optionsdialog.cpp + optionsmodel.cpp + peertablemodel.cpp + peertablesortproxy.cpp + platformstyle.cpp + qvalidatedlineedit.cpp + qvaluecombobox.cpp + rpcconsole.cpp + splashscreen.cpp + trafficgraphwidget.cpp + utilitydialog.cpp + $<$:winshutdownmonitor.cpp> + $<$:macdockiconhandler.mm> + $<$:macnotificationhandler.mm> + $<$:macos_appnap.mm> + bitcoin.qrc + ${CMAKE_CURRENT_BINARY_DIR}/bitcoin_locale.qrc +) +target_compile_definitions(bitcoinqt + PUBLIC + QT_NO_KEYWORDS + QT_USE_QSTRINGBUILDER +) +target_include_directories(bitcoinqt + PUBLIC + $ +) +target_link_libraries(bitcoinqt + PUBLIC + Qt5::Widgets + PRIVATE + core_interface + bitcoin_cli + leveldb + Boost::headers + $ + $ + $<$:-framework\ AppKit> + $<$:shlwapi> +) + +if(ENABLE_WALLET) + target_sources(bitcoinqt + PRIVATE + addressbookpage.cpp + addresstablemodel.cpp + askpassphrasedialog.cpp + coincontroldialog.cpp + coincontroltreewidget.cpp + createwalletdialog.cpp + editaddressdialog.cpp + openuridialog.cpp + overviewpage.cpp + paymentserver.cpp + psbtoperationsdialog.cpp + qrimagewidget.cpp + receivecoinsdialog.cpp + receiverequestdialog.cpp + recentrequeststablemodel.cpp + sendcoinsdialog.cpp + sendcoinsentry.cpp + signverifymessagedialog.cpp + transactiondesc.cpp + transactiondescdialog.cpp + transactionfilterproxy.cpp + transactionoverviewwidget.cpp + transactionrecord.cpp + transactiontablemodel.cpp + transactionview.cpp + walletcontroller.cpp + walletframe.cpp + walletmodel.cpp + walletmodeltransaction.cpp + walletview.cpp + ) + target_link_libraries(bitcoinqt + PRIVATE + bitcoin_wallet + Qt5::Network + ) +endif() + +if(CMAKE_CROSSCOMPILING) + target_compile_definitions(bitcoinqt PRIVATE QT_STATICPLUGIN) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND TARGET Qt5::QXcbIntegrationPlugin) + target_compile_definitions(bitcoinqt PRIVATE QT_QPA_PLATFORM_XCB) + elseif(WIN32 AND TARGET Qt5::QWindowsIntegrationPlugin AND TARGET Qt5::QWindowsVistaStylePlugin) + target_compile_definitions(bitcoinqt PRIVATE QT_QPA_PLATFORM_WINDOWS) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND TARGET Qt5::QCocoaIntegrationPlugin AND TARGET Qt5::QMacStylePlugin) + target_compile_definitions(bitcoinqt PRIVATE QT_QPA_PLATFORM_COCOA) + endif() +endif() + +add_executable(bitcoin-qt + main.cpp + ../init/bitcoin-qt.cpp +) + +target_link_libraries(bitcoin-qt + core_interface + bitcoinqt + bitcoin_node +) + +if(WIN32) + set_target_properties(bitcoin-qt PROPERTIES WIN32_EXECUTABLE TRUE) +endif() + +install(TARGETS bitcoin-qt + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT GUI +) From 923d88368f4837bcc2d105475338432d55c23659 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:23:45 +0000 Subject: [PATCH 4/6] msvc: Fix building with vcpkg's Qt packages See: https://stackoverflow.com/questions/4845198/fatal-error-no-target-architecture-in-visual-studio --- src/qt/winshutdownmonitor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/winshutdownmonitor.h b/src/qt/winshutdownmonitor.h index 78f287637f324..060d8546e3921 100644 --- a/src/qt/winshutdownmonitor.h +++ b/src/qt/winshutdownmonitor.h @@ -10,7 +10,7 @@ #include #include -#include // for HWND +#include #include From de62901d6f027e1684f2d8420230eb3d88dd5fcb Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:06:05 +0000 Subject: [PATCH 5/6] fixup! cmake: Add vcpkg manifest file --- vcpkg.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vcpkg.json b/vcpkg.json index bc2f10faad0fb..2917412320821 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -11,6 +11,8 @@ "libevent", "miniupnpc", "sqlite3", + "qt5-base", + "qt5-tools", "zeromq" ] } From 7f4babc752c6dc2027020e68891b6546e0fe8178 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:05:28 +0000 Subject: [PATCH 6/6] fixup! ci: Test CMake edge cases --- .github/workflows/cmake.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 1683e46d1e3fc..e944457605f33 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -259,17 +259,17 @@ jobs: packages: 'clang-14 g++-multilib' c_compiler: 'clang-14 -m32' cxx_compiler: 'clang++-14 -m32' - depends_options: 'NO_QT=1' + depends_options: '' configure_options: '-DWERROR=ON' - name: 'MinGW-w64' triplet: 'x86_64-w64-mingw32' packages: 'g++-mingw-w64-x86-64-posix' - depends_options: 'NO_QT=1' + depends_options: '' exe_extension: '.exe' - name: 'MinGW-w64, debug' triplet: 'x86_64-w64-mingw32' packages: 'g++-mingw-w64-x86-64-posix' - depends_options: 'NO_QT=1 DEBUG=1' + depends_options: 'DEBUG=1' configure_options: '-DCMAKE_BUILD_TYPE=Debug' cache_suffix: '-debug' exe_extension: '.exe' @@ -392,6 +392,9 @@ jobs: # to avoid linker errors when using vcpkg in the manifest mode. # See: https://github.com/bitcoin/bitcoin/pull/28934 Add-Content -Path "$env:VCPKG_ROOT\triplets\x64-windows-static.cmake" -Value "set(VCPKG_PLATFORM_TOOLSET_VERSION $env:VCToolsVersion)" + # Skip debug configuration to speed up build and minimize cache size. + Add-Content -Path "$env:VCPKG_ROOT\triplets\x64-windows.cmake" -Value "set(VCPKG_BUILD_TYPE release)" + Add-Content -Path "$env:VCPKG_ROOT\triplets\x64-windows-static.cmake" -Value "set(VCPKG_BUILD_TYPE release)" - name: Restore vcpkg binary cache uses: actions/cache/restore@v3 @@ -453,7 +456,7 @@ jobs: env: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 run: | - brew install ccache cmake pkg-config boost libevent berkeley-db@4 libnatpmp miniupnpc zeromq tree + brew install ccache cmake pkg-config boost libevent berkeley-db@4 qt@5 libnatpmp miniupnpc zeromq tree echo "CCACHE_DIR=${{ runner.temp }}/ccache" >> "$GITHUB_ENV" - name: CMake version