diff --git a/configure.ac b/configure.ac index af230c35..11a9a311 100644 --- a/configure.ac +++ b/configure.ac @@ -63,38 +63,6 @@ AC_ARG_ENABLE([ipv6], [use_ipv6=$enableval], [use_ipv6=yes]) -dnl enable qt support -AC_ARG_WITH([qt], - [AS_HELP_STRING([--with-qt], - [enable qt (default is yes)])], - [use_qt=$withval], - [use_qt=auto]) -AC_DEFUN([BITCOIN_QT_FAIL],[ - if test "x$use_qt" = "xauto"; then - AC_MSG_WARN([$1; bitcoin-qt frontend will not be built]) - use_qt=no - else - AC_MSG_ERROR([$1]) - fi -]) -AC_DEFUN([BITCOIN_QT_CHECK],[ - if test "x$use_qt" != "xno"; then - true - $1 - else - true - $2 - fi -]) -AC_DEFUN([BITCOIN_QT_PATH_PROGS],[ - BITCOIN_QT_CHECK([ - AC_PATH_PROGS($1,$2,$3,$4) - if test "x$$1" = "x"; then - BITCOIN_QT_FAIL([$1 not found]) - fi - ]) -]) - AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]), [use_tests=$enableval], @@ -116,12 +84,6 @@ AC_ARG_WITH([qrencode], [use_qr=$withval], [use_qr=auto]) -AC_ARG_WITH([qtdbus], - [AS_HELP_STRING([--with-qtdbus], - [enable DBus support (default is yes if qt is enabled and QtDBus is found)])], - [use_dbus=$withval], - [use_dbus=auto]) - AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--enable-hardening], [attempt to harden the resulting executables (default is yes)])], @@ -140,10 +102,6 @@ AC_ARG_ENABLE([lcov], [use_lcov=yes], [use_lcov=no]) -AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], []) -AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], []) -AC_ARG_WITH([qt-bindir],[AS_HELP_STRING([--with-qt-bindir=BIN_DIR],[specify qt bin path])], [qt_bin_path=$withval], []) -AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], []) AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) @@ -168,13 +126,7 @@ AC_PATH_PROG(LCOV, lcov) AC_PATH_PROG(JAVA, java) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) -BITCOIN_QT_PATH_PROGS([MOC], [moc-qt4 moc4 moc],, $qt_bin_path:$PATH) -BITCOIN_QT_PATH_PROGS([UIC], [uic-qt4 uic4 uic],, $qt_bin_path:$PATH) -BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt4 rcc4 rcc],, $qt_bin_path:$PATH) -BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt4 lrelease4 lrelease],, $qt_bin_path:$PATH) -BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],, $protoc_bin_path:$PATH) AC_PATH_PROG(CCACHE,ccache) -AC_PATH_PROGS([LUPDATE], [lupdate-qt4 lupdate4 lupdate],, $qt_bin_path:$PATH) AC_PATH_PROG(XGETTEXT,xgettext) AC_PATH_PROG(HEXDUMP,hexdump) PKG_PROG_PKG_CONFIG @@ -239,7 +191,7 @@ case $host in AC_CHECK_PROG([PORT],port, port) if test x$PORT = xport; then dnl add default macports paths - CPPFLAGS="$CPPFLAGS -I/opt/local/include -I/opt/local/include/db48" + CPPFLAGS="$CPPFLAGS -isystem /opt/local/include -I/opt/local/include/db48" LIBS="$LIBS -L/opt/local/lib -L/opt/local/lib/db48" fi @@ -254,12 +206,6 @@ case $host in fi fi - BITCOIN_QT_CHECK([ - MOC_DEFS="-DQ_OS_MAC" - base_frameworks="-framework Foundation -framework ApplicationServices -framework AppKit" - AX_CHECK_LINK_FLAG([[$base_frameworks]],[LIBS="$LIBS $base_frameworks"],[AC_MSG_ERROR(could not find base frameworks)]) - ]) - CPPFLAGS="$CPPFLAGS -DMAC_OSX" TESTDEFS="-DBOOST_TEST_DYN_LINK" ;; @@ -452,6 +398,8 @@ if test x$boost_sleep != xyes; then AC_MSG_ERROR(No working boost sleep implementation found) fi +BITCOIN_QT_INIT + if test x$use_pkgconfig = xyes; then if test x$PKG_CONFIG == x; then @@ -464,23 +412,10 @@ if test x$use_pkgconfig = xyes; then [ PKG_CHECK_MODULES([SSL], [libssl], [INCLUDES="$INCLUDES $SSL_CFLAGS"; LIBS="$LIBS $SSL_LIBS"], [AC_MSG_ERROR(openssl not found.)]) PKG_CHECK_MODULES([CRYPTO], [libcrypto], [INCLUDES="$INCLUDES $CRYPTO_CFLAGS"; LIBS="$LIBS $CRYPTO_LIBS"], [AC_MSG_ERROR(libcrypto not found.)]) - - BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT], [QtCore QtGui QtNetwork], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes],[ - have_qt=no - BITCOIN_QT_FAIL([Qt dependencies not found]) - ]) - if test x$use_tests = xyes; then - PKG_CHECK_MODULES([QT_TEST], [QtTest], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) - fi - if test x$use_dbus != xno; then - PKG_CHECK_MODULES([QT_DBUS], [QtDBus], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) - fi - if test x$use_qr != xno; then - PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no]) - fi - PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [AC_MSG_ERROR(libprotobuf not found.)]) - ]) + BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])]) + if test x$use_qr != xno; then + BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) + fi ] ) else @@ -490,82 +425,19 @@ else AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],, AC_MSG_ERROR(libssl missing)) - BITCOIN_QT_CHECK([ - TEMP_LIBS="$LIBS" - LIBS= - if test x$qt_lib_path != x; then - QT_LIBS="$QT_LIBS -L$qt_lib_path" - LIBS="$QT_LIBS" - fi - if test x$qt_plugin_path != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs" - LIBS="$QT_LIBS" - fi - - if test x$TARGET_OS == xwindows; then - AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found)) - fi - ]) - - #TODO: These are only needed when they're linked directly to parent libs. It really has nothing to do with windows. - #Instead, check for missing functions in parent libs and assume static if they're absent. - if test x$TARGET_OS == xwindows; then - BITCOIN_QT_CHECK(AC_CHECK_LIB([qcncodecs],[main],,BITCOIN_QT_FAIL(libqcncodecs not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([qjpcodecs],[main],,BITCOIN_QT_FAIL(libqjpcodecs not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([qkrcodecs],[main],,BITCOIN_QT_FAIL(libqkrcodecs not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([qtwcodecs],[main],,BITCOIN_QT_FAIL(libqtwcodecs not found))) - fi - - BITCOIN_QT_CHECK(AC_CHECK_LIB([QtCore] ,[main],,BITCOIN_QT_FAIL(libQtCore not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([QtGui] ,[main],,BITCOIN_QT_FAIL(libQtGui not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([QtNetwork],[main],,BITCOIN_QT_FAIL(libQtNetwork not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],,BITCOIN_QT_FAIL(libprotobuf not found))) - - BITCOIN_QT_CHECK([ - QT_LIBS="$LIBS" - LIBS="$TEMP_LIBS" - - TEMP_CPPFLAGS="$CPPFLAGS" - if test x$qt_include_path != x; then - QT_INCLUDES="-I$qt_include_path -I$qt_include_path/QtCore -I$qt_include_path/QtGui -I$qt_include_path/QtNetwork -I$qt_include_path/QtTest -I$qt_include_path/QtDBus" - CPPFLAGS="$CPPFLAGS $QT_INCLUDES" - fi - ]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITCOIN_QT_FAIL(QtCore headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITCOIN_QT_FAIL(QtGui headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITCOIN_QT_FAIL(QtNetwork headers missing))]) - - BITCOIN_QT_CHECK([ - if test x$use_tests = xyes; then - TEMP_LIBS="$LIBS" - LIBS= - if test x$qt_lib_path != x; then - LIBS="-L$qt_lib_path" - fi - AC_CHECK_LIB([QtTest], [main],, have_qt_test=no) - AC_CHECK_HEADER([QTest],, have_qt_test=no) - QT_TEST_LIBS="$LIBS" - LIBS="$TEMP_LIBS" - fi - if test x$use_dbus != xno; then - TEMP_LIBS="$LIBS" - LIBS= - if test x$qt_lib_path != x; then - LIBS="-L$qt_lib_path" - fi - AC_CHECK_LIB([QtDBus], [main],, have_qt_dbus=no) - AC_CHECK_HEADER([QtDBus],, have_qt_dbus=no) - QT_DBUS_LIBS="$LIBS" - LIBS="$TEMP_LIBS" - fi - CPPFLAGS="$TEMP_CPPFLAGS" - if test x$use_qr != xno; then - AC_CHECK_LIB([qrencode], [main],, [have_qrencode=no]) - AC_CHECK_HEADER([qrencode.h],, have_qrencode=no) - fi - ]) + BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],,BITCOIN_QT_FAIL(libprotobuf not found))) + if test x$use_qr != xno; then + BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],, [have_qrencode=no])]) + BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) + fi fi +BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) + +dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus +BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4]) + + if test x$use_ipv6 = xyes; then dnl Check for ipv6 build requirements AC_MSG_CHECKING(for IPV6 build support) @@ -613,10 +485,6 @@ if test x$enable_wallet != xno; then else AC_MSG_RESULT(no) - - if test "x$use_qt" != "xno"; then - AC_MSG_ERROR([Cannot currently build Qt GUI with wallet disabled. Use --without-qt.]) - fi fi dnl enable ipv6 support @@ -662,46 +530,15 @@ else fi fi -dnl enable qt support -AC_MSG_CHECKING([if qt should be enabled]) -BITCOIN_QT_CHECK([ - use_qt=yes - BUILD_QT=qt - if test x$use_tests = xyes; then - if test x$have_qt_test = xno; then - AC_MSG_ERROR("libQtTest not found. Use --disable-tests or --without-qt.") - fi - fi - if test x$have_qt_dbus = xno; then - if test x$use_dbus = xyes; then - AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.") - fi - use_dbus=no - fi - if test x$XGETTEXT == x; then - AC_MSG_WARN("xgettext is required to update qt translations") - fi - if test x$LUPDATE == x; then - AC_MSG_WARN("lupdate is required to update qt translations") - fi -],[ - use_qt=no -]) - -AC_MSG_RESULT($use_qt) - dnl these are only used when qt is enabled -if test x$use_qt = xyes; then - +if test x$bitcoin_enable_qt != xno; then + BUILD_QT=qt dnl enable dbus support AC_MSG_CHECKING([if dbus should be enabled]) - if test x$use_dbus != xno; then - use_dbus=yes + if test x$bitcoin_enable_qt_dbus != xno; then AC_DEFINE([USE_DBUS],[1],[Define if dbus support should be compiled in]) - else - use_dbus=no fi - AC_MSG_RESULT($use_dbus) + AC_MSG_RESULT($bitcoin_enable_qt_dbus) dnl enable qr support AC_MSG_CHECKING([if qr should be enabled]) @@ -720,8 +557,18 @@ if test x$use_qt = xyes; then fi fi - if test x$use_tests$have_qt_test = xyesyes; then + if test x$XGETTEXT == x; then + AC_MSG_WARN("xgettext is required to update qt translations") + fi + + if test x$use_tests = xyes; then BUILD_TEST_QT="test" + if test x$bitcoin_enable_qt_test != xyes; then + AC_MSG_ERROR("QT Test lib not found. Use --disable-tests or --without-qt.") + fi + fi + if test x$enable_wallet == xno; then + AC_MSG_ERROR([Cannot currently build Qt GUI with wallet disabled. Use --without-qt.]) fi fi @@ -756,17 +603,10 @@ AC_SUBST(USE_QRCODE) AC_SUBST(USE_IPV6) AC_SUBST(INCLUDES) AC_SUBST(BOOST_LIBS) -AC_SUBST(MOC_DEFS) -AC_SUBST(QT_INCLUDES) -AC_SUBST(QT_TEST_LIBS) -AC_SUBST(QT_LIBS) -AC_SUBST(QT_DBUS_LIBS) -AC_SUBST(QT_DBUS_INCLUDES) -AC_SUBST(QT_TEST_INCLUDES) AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) -AC_SUBST(BUILD_QT) AC_SUBST(BUILD_TEST) +AC_SUBST(BUILD_QT) AC_SUBST(BUILD_TEST_QT) AC_CONFIG_FILES([Makefile src/Makefile src/test/Makefile src/qt/Makefile src/qt/test/Makefile share/setup.nsi share/qt/Info.plist]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) diff --git a/qa/rpc-tests/send.sh b/qa/rpc-tests/send.sh new file mode 100755 index 00000000..fdfb1867 --- /dev/null +++ b/qa/rpc-tests/send.sh @@ -0,0 +1,14 @@ +#!/bin/bash +TIMEOUT=10 +SIGNAL=HUP +if [ $# -eq 0 ]; then + echo -e "Usage:\t$0 " + echo -e "\tRuns and wait ${TIMEOUT} seconds or until SIG${SIGNAL} is received." + echo -e "\tReturns: 0 if SIG${SIGNAL} is received, 1 otherwise." + exit 0 +fi +trap '[[ ${PID} ]] && kill ${PID}' ${SIGNAL} +"$@" +sleep ${TIMEOUT} & PID=$! +wait ${PID} && exit 1 +exit 0 diff --git a/qa/rpc-tests/util.sh b/qa/rpc-tests/util.sh index e4e39537..fed7d325 100644 --- a/qa/rpc-tests/util.sh +++ b/qa/rpc-tests/util.sh @@ -23,6 +23,7 @@ function CreateDataDir { echo "rpcuser=rt" >> $CONF echo "rpcpassword=rt" >> $CONF echo "rpcwait=1" >> $CONF + echo "walletnotify=killall -HUP `basename ${SENDANDWAIT}`" >> $CONF shift while (( "$#" )); do echo $1 >> $CONF @@ -59,7 +60,7 @@ function Send { to=$2 amount=$3 address=$(Address $to) - txid=$( $CLI $from sendtoaddress $address $amount ) + txid=$( ${SENDANDWAIT} $CLI $from sendtoaddress $address $amount ) } # Use: Unspent @@ -80,7 +81,7 @@ function CreateTxn1 { # Use: SendRawTxn function SendRawTxn { - $CLI $1 sendrawtransaction $2 + ${SENDANDWAIT} $CLI $1 sendrawtransaction $2 } # Use: GetBlocks diff --git a/qa/rpc-tests/wallet.sh b/qa/rpc-tests/wallet.sh index 118809a2..8d5a6cdc 100755 --- a/qa/rpc-tests/wallet.sh +++ b/qa/rpc-tests/wallet.sh @@ -12,6 +12,7 @@ BITCOIND=${1}/bitcoind CLI=${1}/bitcoin-cli DIR="${BASH_SOURCE%/*}" +SENDANDWAIT="${DIR}/send.sh" if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi . "$DIR/util.sh" diff --git a/src/Makefile.include b/src/Makefile.include index 13cffd29..b9e6c262 100644 --- a/src/Makefile.include +++ b/src/Makefile.include @@ -32,23 +32,23 @@ $(LIBBITCOINQT): ui_%.h: %.ui @test -d $(abs_builddir)/$(@D) || $(MKDIR_P) $(abs_builddir)/$(@D) - @test -f $(UIC) && $(UIC) -o $(abs_builddir)/$@ $(abs_srcdir)/$< || echo error: could not build $(abs_builddir)/$@ + @test -f $(UIC) && QT_SELECT=$(QT_SELECT) $(UIC) -o $(abs_builddir)/$@ $(abs_srcdir)/$< || echo error: could not build $(abs_builddir)/$@ $(SED) -i.bak -e '/^\*\*.*Created:/d' $(abs_builddir)/$@ && rm $(abs_builddir)/$@.bak $(SED) -i.bak -e '/^\*\*.*by:/d' $(abs_builddir)/$@ && rm $(abs_builddir)/$@.bak %.moc: %.cpp - $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $< + QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $< $(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm $@.bak $(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm $@.bak moc_%.cpp: %.h - $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $< + QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $< $(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm $@.bak $(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm $@.bak %.qm: %.ts @test -d $(abs_builddir)/$(@D) || $(MKDIR_P) $(abs_builddir)/$(@D) - @test -f $(LRELEASE) && $(LRELEASE) $(abs_srcdir)/$< -qm $(abs_builddir)/$@ || \ + @test -f $(LRELEASE) && QT_SELECT=$(QT_SELECT) $(LRELEASE) $(abs_srcdir)/$< -qm $(abs_builddir)/$@ || \ echo error: could not build $(abs_builddir)/$@ %.pb.cc %.pb.h: %.proto diff --git a/src/m4/bitcoin_qt.m4 b/src/m4/bitcoin_qt.m4 new file mode 100644 index 00000000..91c399ee --- /dev/null +++ b/src/m4/bitcoin_qt.m4 @@ -0,0 +1,380 @@ +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 "x$bitcoin_qt_want_version" = "xauto" && test x$bitcoin_qt_force != xyes; then + if test x$bitcoin_enable_qt != xno; then + AC_MSG_WARN([$1; bitcoin-qt frontend will not be built]) + fi + bitcoin_enable_qt=no + else + AC_MSG_ERROR([$1]) + fi +]) + +AC_DEFUN([BITCOIN_QT_CHECK],[ + if test "x$bitcoin_enable_qt" != "xno" && test x$bitcoin_qt_want_version != xno; then + true + $1 + else + true + $2 + fi +]) + +dnl BITCOIN_QT_PATH_PROGS([FOO], [foo foo2], [/path/to/search/first], [continue if missing]) +dnl Helper for finding the path of programs needed for QT. +dnl Inputs: $1: Variable to be set +dnl Inputs: $2: List of programs to search for +dnl Inputs: $3: Look for $2 here before $PATH +dnl Inputs: $4: If "yes", don't fail if $2 is not found. +dnl Output: $1 is set to the path of $2 if found. $2 are searched in order. +AC_DEFUN([BITCOIN_QT_PATH_PROGS],[ + BITCOIN_QT_CHECK([ + if test "x$3" != "x"; then + AC_PATH_PROGS($1,$2,,$3) + else + AC_PATH_PROGS($1,$2) + fi + if test "x$$1" = "x" && test "x$4" != "xyes"; then + BITCOIN_QT_FAIL([$1 not found]) + fi + ]) +]) + +dnl Initialize qt input. +dnl This must be called before any other BITCOIN_QT* macros to ensure that +dnl input variables are set correctly. +dnl CAUTION: Do not use this inside of a conditional. +AC_DEFUN([BITCOIN_QT_INIT],[ + dnl enable qt support + AC_ARG_WITH([qt], + [AS_HELP_STRING([--with-qt], + [with qt (no|qt4|qt5|auto. default is auto, qt4 tried first.)])], + [ + bitcoin_qt_want_version=$withval + if test x$bitcoin_qt_want_version = xyes; then + bitcoin_qt_force=yes + bitcoin_qt_want_version=auto + fi + ], + [bitcoin_qt_want_version=auto]) + + AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], []) + AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], []) + AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], []) + AC_ARG_WITH([qt-bindir],[AS_HELP_STRING([--with-qt-bindir=BIN_DIR],[specify qt bin path])], [qt_bin_path=$withval], []) + + AC_ARG_WITH([qtdbus], + [AS_HELP_STRING([--with-qtdbus], + [enable DBus support (default is yes if qt is enabled and QtDBus is found)])], + [use_dbus=$withval], + [use_dbus=auto]) +]) + +dnl Find the appropriate version of Qt libraries and includes. +dnl Inputs: $1: Whether or not pkg-config should be used. yes|no. Default: yes. +dnl Inputs: $2: If $1 is "yes" and --with-qt=auto, which qt version should be +dnl tried first. +dnl Outputs: See _BITCOIN_QT_FIND_LIBS_* +dnl Outputs: Sets variables for all qt-related tools. +dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test +AC_DEFUN([BITCOIN_QT_CONFIGURE],[ + use_pkgconfig=$1 + + if test x$use_pkgconfig == x; then + use_pkgconfig=yes + fi + + if test x$use_pkgconfig = xyes; then + if test x$PKG_CONFIG == x; then + AC_MSG_ERROR(pkg-config not found.) + fi + BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG([$2])]) + else + BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG]) + fi + + BITCOIN_QT_PATH_PROGS([MOC], [moc-qt${bitcoin_qt_got_major_vers} moc${bitcoin_qt_got_major_vers} moc], $qt_bin_path) + BITCOIN_QT_PATH_PROGS([UIC], [uic-qt${bitcoin_qt_got_major_vers} uic${bitcoin_qt_got_major_vers} uic], $qt_bin_path) + BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt${bitcoin_qt_got_major_vers} rcc${bitcoin_qt_got_major_vers} rcc], $qt_bin_path) + BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt${bitcoin_qt_got_major_vers} lrelease${bitcoin_qt_got_major_vers} lrelease], $qt_bin_path) + BITCOIN_QT_PATH_PROGS([LUPDATE], [lupdate-qt${bitcoin_qt_got_major_vers} lupdate${bitcoin_qt_got_major_vers} lupdate],$qt_bin_path, yes) + + case $host in + *darwin*) + BITCOIN_QT_CHECK([ + MOC_DEFS="-DQ_OS_MAC" + base_frameworks="-framework Foundation -framework ApplicationServices -framework AppKit" + AX_CHECK_LINK_FLAG([[$base_frameworks]],[QT_LIBS="$QT_LIBS $base_frameworks"],[AC_MSG_ERROR(could not find base frameworks)]) + AC_SUBST(MOC_DEFS) + ]) + ;; + esac + + + dnl enable qt support + AC_MSG_CHECKING(if QT should be enabled) + BITCOIN_QT_CHECK([ + bitcoin_enable_qt=yes + bitcoin_enable_qt_test=yes + if test x$have_qt_test = xno; then + bitcoin_enable_qt_test=no + fi + bitcoin_enable_qt_dbus=yes + if test x$have_qt_dbus = xno; then + bitcoin_enable_qt_dbus=no + if test x$use_dbus = xyes; then + AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.") + fi + fi + if test x$LUPDATE == x; then + AC_MSG_WARN("lupdate is required to update qt translations") + fi + ],[ + bitcoin_enable_qt=no + ]) + AC_MSG_RESULT([$bitcoin_enable_qt (Qt${bitcoin_qt_got_major_vers})]) + + AC_SUBST(QT_INCLUDES) + AC_SUBST(QT_LIBS) + AC_SUBST(QT_DBUS_INCLUDES) + AC_SUBST(QT_DBUS_LIBS) + AC_SUBST(QT_TEST_INCLUDES) + AC_SUBST(QT_TEST_LIBS) + AC_SUBST(QT_SELECT, qt${bitcoin_qt_got_major_vers}) +]) + +dnl All macros below are internal and should _not_ be used from the main +dnl configure.ac. +dnl ---- + +dnl Internal. Check if the included version of QT is Qt5. +dnl Requires: INCLUDES must be populated as necessary. +dnl Output: bitcoin_cv_qt5=yes|no +AC_DEFUN([_BITCOIN_QT_CHECK_QT5],[ + AC_CACHE_CHECK(for QT 5, bitcoin_cv_qt5,[ + AC_TRY_COMPILE( + [#include ], + [ + #if QT_VERSION < 0x050000 + choke me + #else + return 0; + #endif + ], + bitcoin_cv_qt5=yes, + bitcoin_cv_qt5=no) +])]) + +dnl Internal. Check if the linked version of QT was built as static libs. +dnl Requires: Qt5. This check cannot determine if Qt4 is static. +dnl Requires: INCLUDES and LIBS must be populated as necessary. +dnl Output: bitcoin_cv_static_qt=yes|no +dnl Output: Defines QT_STATICPLUGIN if plugins are static. +AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ + AC_CACHE_CHECK(for static QT, bitcoin_cv_static_qt,[ + AC_TRY_COMPILE( + [#include ], + [ + #if defined(QT_STATIC) + return 0; + #else + choke me + #endif + ], + [bitcoin_cv_static_qt=yes], + [bitcoin_cv_static_qt=no]) + ]) + if test xbitcoin_cv_static_qt = xyes; then + AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol for static QT plugins]) + fi +]) + +dnl Internal. Check if the link-requirements for static plugins are met. +dnl Requires: INCLUDES and LIBS must be populated as necessary. +dnl Inputs: $1: A series of Q_IMPORT_PLUGIN(). +dnl Inputs: $2: The libraries that resolve $1. +dnl Output: QT_LIBS is prepended or configure exits. +AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[ + AC_MSG_CHECKING(for static QT plugins: $2) + CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS" + LIBS="$2 $QT_LIBS $LIBS" + AC_TRY_LINK([ + #define QT_STATICPLUGIN + #include + $1], + [return 0;], + [AC_MSG_RESULT(yes); QT_LIBS="$2 $QT_LIBS"], + [AC_MSG_RESULT(no)]; BITCOIN_QT_FAIL(Could not resolve: $2)) + LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS" +]) + +dnl Internal. Find Qt libraries using pkg-config. +dnl Inputs: bitcoin_qt_want_version (from --with-qt=). The version to check +dnl first. +dnl Inputs: $1: If bitcoin_qt_want_version is "auto", check for this version +dnl first. +dnl Outputs: All necessary QT_* variables are set. +dnl Outputs: bitcoin_qt_got_major_vers is set to "4" or "5". +dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. +AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[ + m4_ifdef([PKG_CHECK_MODULES],[ + auto_priority_version=$1 + if test x$auto_priority_version == x; then + auto_priority_version=qt5 + fi + if test x$bitcoin_qt_want_version == xqt5 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt5 ); then + QT_LIB_PREFIX=Qt5 + bitcoin_qt_got_major_vers=5 + else + QT_LIB_PREFIX=Qt + bitcoin_qt_got_major_vers=4 + fi + qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets" + qt4_modules="QtCore QtGui QtNetwork" + BITCOIN_QT_CHECK([ + if test x$bitcoin_qt_want_version == xqt5 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt5 ); then + PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes],[have_qt=no]) + elif test x$bitcoin_qt_want_version == xqt4 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt4 ); then + PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes], [have_qt=no]) + fi + + dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other. + if test x$have_qt == xno && test x$bitcoin_qt_want_version == xauto; then + if test x$auto_priority_version = x$qt5; then + PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no]) + else + PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt5; bitcoin_qt_got_major_vers=5], [have_qt=no]) + fi + fi + if test x$have_qt != xyes; then + have_qt=no + BITCOIN_QT_FAIL([Qt dependencies not found]) + fi + ]) + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_TEST], [${QT_LIB_PREFIX}Test], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) + if test x$use_dbus != xno; then + PKG_CHECK_MODULES([QT_DBUS], [${QT_LIB_PREFIX}DBus], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) + fi + ]) + ]) + true; dnl +]) + +dnl Internal. Find Qt libraries without using pkg-config. Version is deduced +dnl from the discovered headers. +dnl Inputs: bitcoin_qt_want_version (from --with-qt=). The version to use. +dnl If "auto", the version will be discovered by _BITCOIN_QT_CHECK_QT5. +dnl Outputs: All necessary QT_* variables are set. +dnl Outputs: bitcoin_qt_got_major_vers is set to "4" or "5". +dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. +AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[ + TEMP_CPPFLAGS="$CPPFLAGS" + TEMP_LIBS="$LIBS" + BITCOIN_QT_CHECK([ + if test x$qt_include_path != x; then + QT_INCLUDES="-I$qt_include_path -I$qt_include_path/QtCore -I$qt_include_path/QtGui -I$qt_include_path/QtWidgets -I$qt_include_path/QtNetwork -I$qt_include_path/QtTest -I$qt_include_path/QtDBus" + CPPFLAGS="$QT_INCLUDES $CPPFLAGS" + fi + ]) + + BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITCOIN_QT_FAIL(QtCore headers missing))]) + BITCOIN_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITCOIN_QT_FAIL(QtGui headers missing))]) + BITCOIN_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITCOIN_QT_FAIL(QtNetwork headers missing))]) + + BITCOIN_QT_CHECK([ + if test x$bitcoin_qt_want_version = xauto; then + _BITCOIN_QT_CHECK_QT5 + fi + if test x$bitcoin_cv_qt5 == xyes || test x$bitcoin_qt_want_version = xqt5; then + QT_LIB_PREFIX=Qt5 + bitcoin_qt_got_major_vers=5 + else + QT_LIB_PREFIX=Qt + bitcoin_qt_got_major_vers=4 + fi + ]) + + BITCOIN_QT_CHECK([ + LIBS= + if test x$qt_lib_path != x; then + LIBS="$LIBS -L$qt_lib_path" + fi + if test x$qt_plugin_path != x; then + LIBS="$LIBS -L$qt_plugin_path/accessible" + if test x$bitcoin_qt_got_major_vers == x5; then + LIBS="$LIBS -L$qt_plugin_path/platforms" + else + LIBS="$LIBS -L$qt_plugin_path/codecs" + fi + fi + + if test x$TARGET_OS == xwindows; then + AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found)) + fi + ]) + + BITCOIN_QT_CHECK(AC_CHECK_LIB([z] ,[main],,BITCOIN_QT_FAIL(zlib not found))) + BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXCore not found))) + BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXGui not found))) + BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Network],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXNetwork not found))) + if test x$bitcoin_qt_got_major_vers == x5; then + BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Widgets],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXWidgets not found))) + fi + QT_LIBS="$LIBS" + LIBS="$TEMP_LIBS" + + dnl This is ugly and complicated. Yuck. Works as follows: + dnl We can't discern whether Qt4 builds are static or not. For Qt5, we can + dnl check a header to find out. When Qt is built statically, some plugins must + dnl be linked into the final binary as well. These plugins have changed between + dnl Qt4 and Qt5. With Qt5, languages moved into core and the WindowsIntegration + dnl plugin was added. Since we can't tell if Qt4 is static or not, it is + dnl assumed for all non-pkg-config builds. + dnl _BITCOIN_QT_CHECK_STATIC_PLUGINS does a quick link-check and appends the + dnl results to QT_LIBS. + BITCOIN_QT_CHECK([ + if test x$bitcoin_qt_got_major_vers == x5; then + _BITCOIN_QT_IS_STATIC + if test x$bitcoin_cv_static_qt == xyes; then + AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) + _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) + if test x$TARGET_OS == xwindows; then + _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) + fi + fi + else + AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) + _BITCOIN_QT_CHECK_STATIC_PLUGINS([ + Q_IMPORT_PLUGIN(qcncodecs) + Q_IMPORT_PLUGIN(qjpcodecs) + Q_IMPORT_PLUGIN(qtwcodecs) + Q_IMPORT_PLUGIN(qkrcodecs) + Q_IMPORT_PLUGIN(AccessibleFactory)], + [-lqcncodecs -lqjpcodecs -lqtwcodecs -lqkrcodecs -lqtaccessiblewidgets]) + fi + ]) + + BITCOIN_QT_CHECK([ + LIBS= + if test x$qt_lib_path != x; then + LIBS="-L$qt_lib_path" + fi + AC_CHECK_LIB([${QT_LIB_PREFIX}Test], [main],, have_qt_test=no) + AC_CHECK_HEADER([QTest],, have_qt_test=no) + QT_TEST_LIBS="$LIBS" + if test x$use_dbus != xno; then + LIBS= + if test x$qt_lib_path != x; then + LIBS="-L$qt_lib_path" + fi + AC_CHECK_LIB([${QT_LIB_PREFIX}DBus], [main],, have_qt_dbus=no) + AC_CHECK_HEADER([QtDBus],, have_qt_dbus=no) + QT_DBUS_LIBS="$LIBS" + fi + ]) + CPPFLAGS="$TEMP_CPPFLAGS" + LIBS="$TEMP_LIBS" +]) + diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am index 863274e8..abd8a9f1 100644 --- a/src/qt/Makefile.am +++ b/src/qt/Makefile.am @@ -220,10 +220,10 @@ bitcoinstrings.cpp: FORCE translate: bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" - @$(LUPDATE) $^ -locations relative -no-obsolete -ts locale/bitcoin_en.ts + @QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts locale/bitcoin_en.ts $(QT_QRC_CPP): $(QT_QRC) $(QT_QM) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H) - @cd $(abs_srcdir); test -f $(RCC) && $(RCC) -name bitcoin -o $(abs_builddir)/$@ $< || \ + @cd $(abs_srcdir); test -f $(RCC) && QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin -o $(abs_builddir)/$@ $< || \ echo error: could not build $@ $(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm $@.bak $(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm $@.bak diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index d78f6fab..794d12f6 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "bitcoin-config.h" #include "bitcoingui.h" #include "clientmodel.h" @@ -30,19 +31,22 @@ #include #include -#if QT_VERSION < 0x050000 -#include -#endif - -#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) -#define _BITCOIN_QT_PLUGINS_INCLUDED -#define __INSURE__ +#if defined(QT_STATICPLUGIN) #include +#if QT_VERSION < 0x050000 Q_IMPORT_PLUGIN(qcncodecs) Q_IMPORT_PLUGIN(qjpcodecs) Q_IMPORT_PLUGIN(qtwcodecs) Q_IMPORT_PLUGIN(qkrcodecs) Q_IMPORT_PLUGIN(qtaccessiblewidgets) +#else +Q_IMPORT_PLUGIN(AccessibleFactory) +Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); +#endif +#endif + +#if QT_VERSION < 0x050000 +#include #endif // Declare meta types used for QMetaObject::invokeMethod diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 1cef397d..38a029db 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -14,18 +14,18 @@ #include #include #include - -#ifdef Q_OS_MAC -#include "macnotificationhandler.h" - -#include -#endif - #ifdef USE_DBUS #include - #include #endif +// Include ApplicationServices.h after QtDbus to avoid redefinition of check(). +// This affects at least OSX 10.6. See /usr/include/AssertMacros.h for details. +// Note: This could also be worked around using: +// #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#ifdef Q_OS_MAC +#include +#include "macnotificationhandler.h" +#endif // https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128 diff --git a/src/qt/test/Makefile.am b/src/qt/test/Makefile.am index cb687470..01505243 100644 --- a/src/qt/test/Makefile.am +++ b/src/qt/test/Makefile.am @@ -18,7 +18,7 @@ test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) $(QT_TEST_INCLUDES) test_bitcoin_qt_SOURCES = test_main.cpp uritests.cpp paymentservertests.cpp $(TEST_QT_H) nodist_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP) test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) \ - $(LIBMEMENV) $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) \ + $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) CLEANFILES = $(BUILT_SOURCES) *.gcda *.gcno diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index ae584706..ad0dfd98 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -1,3 +1,4 @@ +#include "bitcoin-config.h" #include "paymentservertests.h" #include "uritests.h" @@ -5,6 +6,14 @@ #include #include +#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000 +#include +Q_IMPORT_PLUGIN(qcncodecs) +Q_IMPORT_PLUGIN(qjpcodecs) +Q_IMPORT_PLUGIN(qtwcodecs) +Q_IMPORT_PLUGIN(qkrcodecs) +#endif + // This is all you need to run all the tests int main(int argc, char *argv[]) {