Skip to content

build: Make --with-gui=qt6 configure option available on macOS #25191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ task:
task:
name: 'macOS 12 native [gui, system sqlite only] [no depends]'
brew_install_script:
- brew install boost libevent qt@5 miniupnpc libnatpmp ccache zeromq qrencode libtool automake gnu-getopt
- brew install boost libevent qt@6 miniupnpc libnatpmp ccache zeromq qrencode libtool automake gnu-getopt
<< : *GLOBAL_TASK_TEMPLATE
macos_instance:
# Use latest image, but hardcode version to avoid silent upgrades (and breaks)
Expand Down
101 changes: 66 additions & 35 deletions build-aux/m4/bitcoin_qt.m4
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ dnl file COPYING or http://www.opensource.org/licenses/mit-license.php.
dnl Helper for cases where a qt dependency is not met.
dnl Output: If qt version is auto, set bitcoin_enable_qt to false. Else, exit.
AC_DEFUN([BITCOIN_QT_FAIL],[
if test "$bitcoin_qt_want_version" = "auto" && test "$bitcoin_qt_force" != "yes"; then
if test "$bitcoin_qt_want_version" = "auto"; then
if test "$bitcoin_enable_qt" != "no"; then
AC_MSG_WARN([$1; bitcoin-qt frontend will not be built])
fi
Expand Down Expand Up @@ -53,15 +53,9 @@ dnl CAUTION: Do not use this inside of a conditional.
AC_DEFUN([BITCOIN_QT_INIT],[
dnl enable qt support
AC_ARG_WITH([gui],
[AS_HELP_STRING([--with-gui@<:@=no|qt5|auto@:>@],
[build bitcoin-qt GUI (default=auto)])],
[
bitcoin_qt_want_version=$withval
if test "$bitcoin_qt_want_version" = "yes"; then
bitcoin_qt_force=yes
bitcoin_qt_want_version=auto
fi
],
[AS_HELP_STRING([--with-gui@<:@=no|qt5|qt6|auto@:>@],
[build bitcoin-qt GUI (default=auto), qt6 is supported for Homebrew's Qt 6 on macOS only])],
[bitcoin_qt_want_version=$withval],
[bitcoin_qt_want_version=auto])

AS_IF([test "$with_gui" = "qt5_debug"],
Expand Down Expand Up @@ -106,6 +100,13 @@ dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test
AC_DEFUN([BITCOIN_QT_CONFIGURE],[
qt_version=">= $1"
qt_lib_prefix="Qt5"

if test "$bitcoin_qt_want_version" = "qt6"; then
AS_CASE([$build_os],
[*darwin*], [qt_lib_prefix="Qt6"; qt6_prefix=$($BREW --prefix qt@6 2>/dev/null)],
[AC_MSG_ERROR([qt6 is supported for Homebrew's Qt 6 on macOS only])])
fi

BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS])

dnl This is ugly and complicated. Yuck. Works as follows:
Expand Down Expand Up @@ -220,9 +221,17 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
])
fi

BITCOIN_QT_PATH_PROGS([MOC], [moc-qt5 moc5 moc], $qt_bin_path)
BITCOIN_QT_PATH_PROGS([UIC], [uic-qt5 uic5 uic], $qt_bin_path)
BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt5 rcc5 rcc], $qt_bin_path)
if test "$bitcoin_qt_want_version" = "qt6"; then
qt_bin_path="${qt6_prefix}/bin"
qt_libexec_path="${qt6_prefix}/share/qt/libexec"
RCC_OPTIONS="--compress-algo=zlib"
else
qt_libexec_path="${qt_bin_path}"
fi
AC_SUBST(RCC_OPTIONS)
BITCOIN_QT_PATH_PROGS([MOC], [moc-qt5 moc5 moc], $qt_libexec_path)
BITCOIN_QT_PATH_PROGS([UIC], [uic-qt5 uic5 uic], $qt_libexec_path)
BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt5 rcc5 rcc], $qt_libexec_path)
BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt5 lrelease5 lrelease], $qt_bin_path)
BITCOIN_QT_PATH_PROGS([LUPDATE], [lupdate-qt5 lupdate5 lupdate],$qt_bin_path, yes)
BITCOIN_QT_PATH_PROGS([LCONVERT], [lconvert-qt5 lconvert5 lconvert], $qt_bin_path, yes)
Expand Down Expand Up @@ -371,27 +380,49 @@ dnl
dnl Outputs: All necessary QT_* variables are set.
dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CORE_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CORE_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Core${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_GUI_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_GUI_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_WIDGETS_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_WIDGETS_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_NETWORK_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_NETWORK_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Network${qt_lib_suffix} $qt_version not found])])
])
if test "$bitcoin_qt_want_version" = "qt6"; then
TEMP_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -F${qt6_prefix}/Frameworks"
AX_CHECK_LINK_FLAG([-framework QtCore],
[QT_LIBS="-framework QtCore $QT_LIBS"; QT_INCLUDES="-I${qt6_prefix}/include/QtCore $QT_INCLUDES"],
[AC_MSG_ERROR([could not link against QtCore framework])])
AX_CHECK_LINK_FLAG([-framework QtGui],
[QT_LIBS="-framework QtGui $QT_LIBS"; QT_INCLUDES="-I${qt6_prefix}/include/QtGui $QT_INCLUDES"],
[AC_MSG_ERROR([could not link against QtGui framework])])
AX_CHECK_LINK_FLAG([-framework QtWidgets],
[QT_LIBS="-framework QtWidgets $QT_LIBS"; QT_INCLUDES="-I${qt6_prefix}/include/QtWidgets $QT_INCLUDES"],
[AC_MSG_ERROR([could not link against QtWidgets framework])])
AX_CHECK_LINK_FLAG([-framework QtNetwork],
[QT_LIBS="-framework QtNetwork $QT_LIBS"; QT_INCLUDES="-I${qt6_prefix}/include/QtNetwork $QT_INCLUDES"],
[AC_MSG_ERROR([could not link against QtNetwork framework])])
AX_CHECK_LINK_FLAG([-framework QtTest],
[have_qt_test="yes"; QT_TEST_LIBS="-framework QtTest"; QT_TEST_INCLUDES="-I${qt6_prefix}/include/QtTest"],
[have_qt_test="no"])
LDFLAGS="$TEMP_LDFLAGS"
QT_LIBS="-F${qt6_prefix}/Frameworks $QT_LIBS"
else
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CORE_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CORE_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Core${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_GUI_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_GUI_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_WIDGETS_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_WIDGETS_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_NETWORK_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_NETWORK_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Network${qt_lib_suffix} $qt_version not found])])
])

BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
if test "$use_dbus" != "no"; then
PKG_CHECK_MODULES([QT_DBUS], [${qt_lib_prefix}DBus $qt_version], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no])
fi
])
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
if test "$use_dbus" != "no"; then
PKG_CHECK_MODULES([QT_DBUS], [${qt_lib_prefix}DBus $qt_version], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no])
fi
])
fi
])
3 changes: 2 additions & 1 deletion ci/test/00_setup_env_mac_host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export LC_ALL=C.UTF-8
export HOST=x86_64-apple-darwin
export PIP_PACKAGES="zmq lief"
export GOAL="install"
export BITCOIN_CONFIG="--with-gui --enable-reduce-exports"
export BITCOIN_CONFIG="--with-gui=qt6 --enable-reduce-exports"
export NO_WERROR=1
export CI_OS_NAME="macos"
export NO_DEPENDS=1
export OSX_SDK=""
Expand Down
4 changes: 3 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2003,9 +2003,11 @@ if test "$enable_wallet" != "no"; then
echo " with sqlite = $use_sqlite"
echo " with bdb = $use_bdb"
fi
echo " with gui / qt = $bitcoin_enable_qt"
if test $bitcoin_enable_qt != "no"; then
echo " with gui / qt = $bitcoin_enable_qt, $qt_lib_prefix"
echo " with qr = $use_qr"
else
echo " with gui / qt = $bitcoin_enable_qt"
fi
echo " with zmq = $use_zmq"
if test $enable_fuzz = "no"; then
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,12 @@ translate: $(srcdir)/qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCO
$(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM)
@test -f $(RCC)
@cp -f $< $(@D)/temp_$(<F)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin_locale --format-version 1 $(@D)/temp_$(<F) > $@
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) $(RCC_OPTIONS) --name bitcoin_locale --format-version 1 $(@D)/temp_$(<F) > $@
@rm $(@D)/temp_$(<F)

$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(QT_RES_FONTS) $(QT_RES_ICONS) $(QT_RES_ANIMATION)
@test -f $(RCC)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin --format-version 1 $< > $@
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) $(RCC_OPTIONS) --name bitcoin --format-version 1 $< > $@

CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_bitcoin_locale.qrc

Expand Down
4 changes: 4 additions & 0 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,11 @@ static void RegisterMetaTypes()
qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon");
qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>("interfaces::BlockAndHeaderTipInfo");

#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
qRegisterMetaType<BitcoinUnit>("BitcoinUnit");
#else
qRegisterMetaTypeStreamOperators<BitcoinUnit>("BitcoinUnit");
#endif
}

static QString GetLangTerritory()
Expand Down
15 changes: 9 additions & 6 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <QMouseEvent>
#include <QPluginLoader>
#include <QProgressDialog>
#include <QRegularExpression>
#include <QScreen>
#include <QSettings>
#include <QShortcut>
Expand Down Expand Up @@ -310,11 +311,12 @@ QString getSaveFileName(QWidget *parent, const QString &caption, const QString &
QString result = QDir::toNativeSeparators(QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter));

/* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
QRegularExpression filter_re(".* \\(\\*\\.(.*)[ \\)]");
QString selectedSuffix;
if(filter_re.exactMatch(selectedFilter))
QRegularExpressionMatch m = filter_re.match(selectedFilter);
if(m.hasMatch())
{
selectedSuffix = filter_re.cap(1);
selectedSuffix = m.captured(1);
}

/* Add suffix if needed */
Expand Down Expand Up @@ -358,11 +360,12 @@ QString getOpenFileName(QWidget *parent, const QString &caption, const QString &
if(selectedSuffixOut)
{
/* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
QRegularExpression filter_re(".* \\(\\*\\.(.*)[ \\)]");
QString selectedSuffix;
if(filter_re.exactMatch(selectedFilter))
QRegularExpressionMatch m = filter_re.match(selectedFilter);
if(m.hasMatch())
{
selectedSuffix = filter_re.cap(1);
selectedSuffix = m.captured(1);
}
*selectedSuffixOut = selectedSuffix;
}
Expand Down
2 changes: 1 addition & 1 deletion src/qt/rpcconsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <qt/guiutil.h>
#include <qt/peertablesortproxy.h>
#include <qt/platformstyle.h>
#include <qt/walletmodel.h>
#include <rpc/client.h>
#include <rpc/server.h>
#include <util/strencodings.h>
Expand All @@ -28,6 +27,7 @@
#include <univalue.h>

#ifdef ENABLE_WALLET
#include <qt/walletmodel.h>
#ifdef USE_BDB
#include <wallet/bdb.h>
#endif
Expand Down
5 changes: 2 additions & 3 deletions src/qt/utilitydialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <QCloseEvent>
#include <QLabel>
#include <QMainWindow>
#include <QRegExp>
#include <QRegularExpression>
#include <QTextCursor>
#include <QTextTable>
#include <QVBoxLayout>
Expand All @@ -44,8 +44,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
/// HTML-format the license message from the core
QString licenseInfoHTML = QString::fromStdString(LicenseInfo());
// Make URLs clickable
QRegExp uri("<(.*)>", Qt::CaseSensitive, QRegExp::RegExp2);
uri.setMinimal(true); // use non-greedy matching
QRegularExpression uri("<(.*)>", QRegularExpression::InvertedGreedinessOption);
licenseInfoHTML.replace(uri, "<a href=\"\\1\">\\1</a>");
// Replace newlines with HTML breaks
licenseInfoHTML.replace("\n", "<br>");
Expand Down