diff --git a/.travis.yml b/.travis.yml index 03df07ca9..ed05a6211 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,87 +1,87 @@ group: deprecated-2017Q2 sudo: required dist: trusty os: linux language: generic addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-7 cache: directories: - depends/built - depends/sdk-sources - $HOME/.ccache env: global: - MAKEJOBS=-j3 - RUN_TESTS=false - CHECK_DOC=0 - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID - CCACHE_SIZE=100M - CCACHE_TEMPDIR=/tmp/.ccache-temp - CCACHE_COMPRESS=1 - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - SDK_URL=https://bitcoincore.org/depends-sources/sdks - PYTHON_DEBUG=1 - WINEDEBUG=fixme-all - MATRIX_EVAL="CC=gcc && CXX=g++" matrix: # 32-bit + dash - HOST=i686-pc-linux-gnu PACKAGES="g++-7-multilib bc python3-zmq" DEP_OPTS="NO_QT=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" # bitcoind - HOST=x86_64-unknown-linux-gnu PACKAGES="bc python3-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" # No wallet - HOST=x86_64-unknown-linux-gnu PACKAGES="python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" # Cross-Mac - HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" OSX_SDK=10.11 GOAL="deploy" before_install: - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g") - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/pyenv/d' | tr "\n" ":" | sed "s|::|:|g") - eval "${MATRIX_EVAL}" install: - if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi - if [ -n "$DPKG_ADD_ARCH" ]; then sudo dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 50 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 50 before_script: - unset CC; unset CXX - eval "${MATRIX_EVAL}" - export CC; export CXX - COMPILERS="CC=$CC CXX=$CXX" - if [ "$HOST" = "x86_64-apple-darwin11" ]; then unset CC; unset CXX; COMPILERS=""; fi - if [ "$HOST" = "i686-pc-linux-gnu" ]; then sudo ln -s /usr/include/asm-generic /usr/include/asm ; fi - if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/check-doc.py; fi - mkdir -p depends/SDKs depends/sdk-sources - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS script: - if [ "$RUN_TESTS" = "true" -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then while read LINE; do travis_retry gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys $LINE; done < contrib/verify-commits/trusted-keys; fi - if [ "$RUN_TESTS" = "true" -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then git fetch --unshallow; fi - if [ "$RUN_TESTS" = "true" -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then contrib/verify-commits/verify-commits.sh; fi - export TRAVIS_COMMIT_LOG=`git log --format=fuller -1` - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST - BITCOIN_CONFIG_ALL="$COMPILERS --disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE - set -e - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - mkdir build && cd build - ../configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make distdir VERSION=$HOST - cd bitcoin-abc-$HOST - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS check VERBOSE=1; fi - - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.py --coverage; fi + - if [ "$RUN_TESTS" = "true" ]; then test/pull-tester/rpc-tests.py --coverage; fi - set +e after_script: - echo $TRAVIS_COMMIT_RANGE - echo $TRAVIS_COMMIT_LOG diff --git a/Makefile.am b/Makefile.am index 91c35329f..ab44b0125 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,242 +1,242 @@ # Copyright (c) 2013-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src if ENABLE_MAN SUBDIRS += doc/man endif export PYTHONPATH .PHONY: deploy FORCE GZIP_ENV="-9n" if BUILD_BITCOIN_LIBS pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libbitcoinconsensus.pc endif BITCOIND_BIN=$(top_builddir)/src/$(BITCOIN_DAEMON_NAME)$(EXEEXT) BITCOIN_QT_BIN=$(top_builddir)/src/qt/$(BITCOIN_GUI_NAME)$(EXEEXT) BITCOIN_CLI_BIN=$(top_builddir)/src/$(BITCOIN_CLI_NAME)$(EXEEXT) BITCOIN_SEEDER_BIN=$(top_builddir)/src/$(BITCOIN_SEEDER_NAME)$(EXEEXT) BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) empty := space := $(empty) $(empty) OSX_APP=BitcoinABC-Qt.app OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) OSX_DMG = $(OSX_VOLNAME).dmg OSX_BACKGROUND_SVG=background.svg OSX_BACKGROUND_IMAGE=background.tiff OSX_BACKGROUND_IMAGE_DPIS=36 72 OSX_DSSTORE_GEN=$(top_srcdir)/contrib/macdeploy/custom_dsstore.py OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) DIST_CONTRIB = $(top_srcdir)/contrib/bitcoin-cli.bash-completion \ $(top_srcdir)/contrib/bitcoin-tx.bash-completion \ $(top_srcdir)/contrib/bitcoind.bash-completion \ $(top_srcdir)/contrib/init \ $(top_srcdir)/contrib/rpm BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ $(top_srcdir)/contrib/devtools/security-check.py WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-header.bmp \ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp \ $(top_srcdir)/doc/README_windows.txt OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_SVG) \ $(OSX_DSSTORE_GEN) \ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh COVERAGE_INFO = baseline_filtered_combined.info baseline.info \ leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \ baseline_filtered.info rpc_test.info rpc_test_filtered.info \ leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info dist-hook: -$(GIT) archive --format=tar HEAD -- src/clientversion.cpp | $(AMTAR) -C $(top_distdir) -xf - $(BITCOIN_WIN_INSTALLER): all-recursive $(MKDIR_P) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIND_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_QT_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_CLI_BIN) $(top_builddir)/release @test -f $(MAKENSIS) && $(MAKENSIS) -V2 $(top_builddir)/share/setup.nsi || \ echo error: could not build $@ @echo built $@ $(if $(findstring src/,$(MAKECMDGOALS)),$(MAKECMDGOALS), none): FORCE $(MAKE) -C src $(patsubst src/%,%,$@) $(OSX_APP)/Contents/PkgInfo: $(MKDIR_P) $(@D) @echo "APPL????" > $@ $(OSX_APP)/Contents/Resources/empty.lproj: $(MKDIR_P) $(@D) @touch $@ $(OSX_APP)/Contents/Info.plist: $(OSX_PLIST) $(MKDIR_P) $(@D) $(INSTALL_DATA) $< $@ $(OSX_APP)/Contents/Resources/bitcoin.icns: $(OSX_INSTALLER_ICONS) $(MKDIR_P) $(@D) $(INSTALL_DATA) $< $@ $(OSX_APP)/Contents/MacOS/BitcoinABC-Qt: $(BITCOIN_QT_BIN) $(MKDIR_P) $(@D) STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $< $@ $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings: $(MKDIR_P) $(@D) echo '{ CFBundleDisplayName = "$(PACKAGE_NAME)"; CFBundleName = "$(PACKAGE_NAME)"; }' > $@ OSX_APP_BUILT=$(OSX_APP)/Contents/PkgInfo $(OSX_APP)/Contents/Resources/empty.lproj \ $(OSX_APP)/Contents/Resources/bitcoin.icns $(OSX_APP)/Contents/Info.plist \ $(OSX_APP)/Contents/MacOS/BitcoinABC-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings osx_volname: echo $(OSX_VOLNAME) >$@ if BUILD_DARWIN $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) $(OSX_BACKGROUND_IMAGE) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2 -volname $(OSX_VOLNAME) $(OSX_BACKGROUND_IMAGE).png: contrib/macdeploy/$(OSX_BACKGROUND_SVG) sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d 36 -p 36 -o $@ $(OSX_BACKGROUND_IMAGE)@2x.png: contrib/macdeploy/$(OSX_BACKGROUND_SVG) sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d 72 -p 72 -o $@ $(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE).png $(OSX_BACKGROUND_IMAGE)@2x.png tiffutil -cathidpicheck $^ -out $@ deploydir: $(OSX_DMG) else APP_DIST_DIR=$(top_builddir)/dist APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE) $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications $(APP_DIST_DIR)/Applications: @rm -f $@ @cd $(@D); $(LN_S) /Applications $(@F) $(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/BitcoinABC-Qt $(OSX_DMG): $(APP_DIST_EXTRAS) $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -apple -o $@ dist dpi%.$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_SVG) sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d $* -p $* | $(IMAGEMAGICK_CONVERT) - $@ OSX_BACKGROUND_IMAGE_DPIFILES := $(foreach dpi,$(OSX_BACKGROUND_IMAGE_DPIS),dpi$(dpi).$(OSX_BACKGROUND_IMAGE)) $(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIFILES) $(MKDIR_P) $(@D) $(TIFFCP) -c none $(OSX_BACKGROUND_IMAGE_DPIFILES) $@ $(APP_DIST_DIR)/.DS_Store: $(OSX_DSSTORE_GEN) $(PYTHON) $< "$@" "$(OSX_VOLNAME)" $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/BitcoinABC-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2 deploydir: $(APP_DIST_EXTRAS) endif if TARGET_DARWIN appbundle: $(OSX_APP_BUILT) deploy: $(OSX_DMG) endif if TARGET_WINDOWS deploy: $(BITCOIN_WIN_INSTALLER) endif $(BITCOIN_QT_BIN): FORCE $(MAKE) -C src qt/$(@F) $(BITCOIND_BIN): FORCE $(MAKE) -C src $(@F) $(BITCOIN_CLI_BIN): FORCE $(MAKE) -C src $(@F) $(BITCOIN_SEEDER_BIN): FORCE $(MAKE) -C src $(@F) if USE_LCOV baseline.info: $(LCOV) -c -i -d $(abs_builddir)/src -o $@ baseline_filtered.info: baseline.info $(LCOV) -r $< "/usr/include/*" -o $@ leveldb_baseline.info: baseline_filtered.info $(LCOV) -c -i -d $(abs_builddir)/src/leveldb -b $(abs_builddir)/src/leveldb -o $@ leveldb_baseline_filtered.info: leveldb_baseline.info $(LCOV) -r $< "/usr/include/*" -o $@ baseline_filtered_combined.info: leveldb_baseline_filtered.info baseline_filtered.info $(LCOV) -a leveldb_baseline_filtered.info -a baseline_filtered.info -o $@ test_bitcoin.info: baseline_filtered_combined.info $(MAKE) -C src/ check $(LCOV) -c -d $(abs_builddir)/src -t test_bitcoin -o $@ $(LCOV) -z -d $(abs_builddir)/src $(LCOV) -z -d $(abs_builddir)/src/leveldb test_bitcoin_filtered.info: test_bitcoin.info $(LCOV) -r $< "/usr/include/*" -o $@ rpc_test.info: test_bitcoin_filtered.info - -@TIMEOUT=15 python qa/pull-tester/rpc-tests.py $(EXTENDED_RPC_TESTS) + -@TIMEOUT=15 python test/pull-tester/rpc-tests.py $(EXTENDED_RPC_TESTS) $(LCOV) -c -d $(abs_builddir)/src --t rpc-tests -o $@ $(LCOV) -z -d $(abs_builddir)/src $(LCOV) -z -d $(abs_builddir)/src/leveldb rpc_test_filtered.info: rpc_test.info $(LCOV) -r $< "/usr/include/*" -o $@ test_bitcoin_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -o $@ total_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info rpc_test_filtered.info $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -a rpc_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt test_bitcoin.coverage/.dirstamp: test_bitcoin_coverage.info $(GENHTML) -s $< -o $(@D) @touch $@ total.coverage/.dirstamp: total_coverage.info $(GENHTML) -s $< -o $(@D) @touch $@ cov: test_bitcoin.coverage/.dirstamp total.coverage/.dirstamp endif dist_noinst_SCRIPTS = autogen.sh -EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_CONTRIB) $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) +EXTRA_DIST = $(top_srcdir)/share/genbuild.sh test/pull-tester/rpc-tests.py test/rpc-tests $(DIST_CONTRIB) $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) .INTERMEDIATE: $(COVERAGE_INFO) DISTCHECK_CONFIGURE_FLAGS = --enable-man clean-local: - rm -rf coverage_percent.txt test_bitcoin.coverage/ total.coverage/ qa/tmp/ cache/ $(OSX_APP) - rm -rf qa/pull-tester/__pycache__ + rm -rf coverage_percent.txt test_bitcoin.coverage/ total.coverage/ test/tmp/ cache/ $(OSX_APP) + rm -rf test/pull-tester/__pycache__ diff --git a/README.md b/README.md index 0d0c2ec25..1faa1c7cb 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,32 @@ Bitcoin ABC =========== https://bitcoinabc.org What is Bitcoin? ---------------- Bitcoin is an experimental digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. What is Bitcoin ABC? -------------------- Bitcoin ABC is the name of open source software which enables the use of Bitcoin. It is designed to facilite a hard fork to increase Bitcoin's block size limit. "ABC" stands for "Adjustable Blocksize Cap". Bitcoin ABC is a fork of the [Bitcoin Core](https://bitcoincore.org) software project. License ------- Bitcoin ABC is released under the terms of the MIT license. See [COPYING](COPYING) for more information or see https://opensource.org/licenses/MIT. Development Process ------------------- -This Github repository contains only source code of releases. - -Bitcoin ABC development takes place at https://reviews.bitcoinabc.org/ - -You can clone the active development version from here: - - https://reviews.bitcoinabc.org/source/bitcoin-abc.git +Please see [CONTRIBUTING](CONTRIBUTING.md) diff --git a/configure.ac b/configure.ac index d5a72b0d6..a8348f347 100644 --- a/configure.ac +++ b/configure.ac @@ -1,1320 +1,1320 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 16) define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2017) define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin]]) AC_INIT([Bitcoin ABC],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/Bitcoin-ABC/bitcoin-abc/issues],[bitcoin-abc],[https://bitcoinabc.org/]) AC_CONFIG_SRCDIR([src/validation.cpp]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) BITCOIN_DAEMON_NAME=bitcoind BITCOIN_GUI_NAME=bitcoin-qt BITCOIN_CLI_NAME=bitcoin-cli BITCOIN_TX_NAME=bitcoin-tx BITCOIN_SEEDER_NAME=bitcoin-seeder AC_CANONICAL_HOST AH_TOP([#ifndef BITCOIN_BITCOIN_CONFIG_H]) AH_TOP([#define BITCOIN_BITCOIN_CONFIG_H]) AH_BOTTOM([#endif // BITCOIN_BITCOIN_CONFIG_H]) dnl faketime breaks configure and is only needed for make. Disable it here. unset FAKETIME dnl Automake init set-up and checks AM_INIT_AUTOMAKE([no-define subdir-objects foreign]) dnl faketime messes with timestamps and causes configure to be re-run. dnl --disable-maintainer-mode can be used to bypass this. AM_MAINTAINER_MODE([enable]) dnl make the compilation flags quiet unless V=1 is used m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) dnl Compiler checks (here before libtool). if test "x${CXXFLAGS+set}" = "xset"; then CXXFLAGS_overridden=yes else CXXFLAGS_overridden=no fi AC_PROG_CXX dnl By default, libtool for mingw refuses to link static libs into a dll for dnl fear of mixing pic/non-pic objects, and import/export complications. Since dnl we have those under control, re-enable that functionality. case $host in *mingw*) lt_cv_deplibs_check_method="pass_all" ;; esac dnl Require C++11 compiler (no GNU extensions) AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory], [nodefault]) dnl Check if -latomic is required for CHECK_ATOMIC dnl Unless the user specified OBJCXX, force it to be the same as CXX. This ensures dnl that we get the same -std flags for both. m4_ifdef([AC_PROG_OBJCXX],[ if test "x${OBJCXX+set}" = "x"; then OBJCXX="${CXX}" fi AC_PROG_OBJCXX ]) dnl Libtool init checks. LT_INIT([pic-only]) dnl Check/return PATH for base programs. AC_PATH_TOOL(AR, ar) AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) dnl Python 3.x is supported from 3.4 on (see https://github.com/bitcoin/bitcoin/issues/7893) AC_PATH_PROGS([PYTHON], [python3.6 python3.5 python3.4 python3 python2.7 python2 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) AC_PATH_PROG(XGETTEXT,xgettext) AC_PATH_PROG(HEXDUMP,hexdump) AC_PATH_TOOL(READELF, readelf) AC_PATH_TOOL(CPPFILT, c++filt) AC_PATH_TOOL(OBJCOPY, objcopy) AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) # Enable wallet AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], [disable wallet (enabled by default)])], [enable_wallet=$enableval], [enable_wallet=yes]) AC_ARG_WITH([miniupnpc], [AS_HELP_STRING([--with-miniupnpc], [enable UPNP (default is yes if libminiupnpc is found)])], [use_upnp=$withval], [use_upnp=auto]) AC_ARG_ENABLE([upnp-default], [AS_HELP_STRING([--enable-upnp-default], [if UPNP is enabled, turn it on at startup (default is no)])], [use_upnp_default=$enableval], [use_upnp_default=no]) AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]), [use_tests=$enableval], [use_tests=yes]) AC_ARG_ENABLE(gui-tests, AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]), [use_gui_tests=$enableval], [use_gui_tests=$use_tests]) AC_ARG_ENABLE(bench, AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]), [use_bench=$enableval], [use_bench=yes]) AC_ARG_ENABLE([extended-rpc-tests], AS_HELP_STRING([--enable-extended-rpc-tests],[enable expensive RPC tests when using lcov (default no)]), [use_extended_rpc_tests=$enableval], [use_extended_rpc_tests=no]) AC_ARG_WITH([qrencode], [AS_HELP_STRING([--with-qrencode], [enable QR code support (default is yes if qt is enabled and libqrencode is found)])], [use_qr=$withval], [use_qr=auto]) AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--disable-hardening], [do not attempt to harden the resulting executables (default is to harden)])], [use_hardening=$enableval], [use_hardening=yes]) AC_ARG_ENABLE([reduce-exports], [AS_HELP_STRING([--enable-reduce-exports], [attempt to reduce exported symbols in the resulting executables (default is no)])], [use_reduce_exports=$enableval], [use_reduce_exports=no]) AC_ARG_ENABLE([ccache], [AS_HELP_STRING([--disable-ccache], [do not use ccache for building (default is to use if found)])], [use_ccache=$enableval], [use_ccache=auto]) AC_ARG_ENABLE([lcov], [AS_HELP_STRING([--enable-lcov], [enable lcov testing (default is no)])], [use_lcov=yes], [use_lcov=no]) AC_ARG_ENABLE([glibc-back-compat], [AS_HELP_STRING([--enable-glibc-back-compat], [enable backwards compatibility with glibc])], [use_glibc_compat=$enableval], [use_glibc_compat=no]) AC_ARG_WITH([system-univalue], [AS_HELP_STRING([--with-system-univalue], [Build with system UniValue (default is no)])], [system_univalue=$withval], [system_univalue=no] ) AC_ARG_ENABLE([zmq], [AS_HELP_STRING([--disable-zmq], [disable ZMQ notifications])], [use_zmq=$enableval], [use_zmq=yes]) AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) AC_ARG_ENABLE(man, [AS_HELP_STRING([--disable-man], [do not install man pages (default is to install)])],, enable_man=yes) AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no) # Enable debug AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [use debug compiler flags and macros (default is no)])], [enable_debug=$enableval], [enable_debug=no]) # Enable ASAN AC_ARG_ENABLE([asan], [AS_HELP_STRING([--enable-asan], [enable address sanitizer compiler flags (implies --enable-debug, default is no)])], [enable_asan=$enableval], [enable_asan=no]) # Enable TSAN AC_ARG_ENABLE([tsan], [AS_HELP_STRING([--enable-tsan], [enable thread sanitizer compiler flags; requires 64-bit target architecture (implies --enable-debug, default is no)])], [enable_tsan=$enableval], [enable_tsan=no]) # Enable UBSAN AC_ARG_ENABLE([ubsan], [AS_HELP_STRING([--enable-ubsan], [enable undefined behavior sanitizer compiler flags (implies --enable-debug, default is no)])], [enable_ubsan=$enableval], [enable_ubsan=no]) # Turn warnings into errors AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], [Treat certain compiler warnings as errors (default is no)])], [enable_werror=$enableval], [enable_werror=no]) AC_LANG_PUSH([C++]) AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) if test "x$enable_asan" = xyes; then enable_debug=yes asan_failed=no AX_CHECK_COMPILE_FLAG([-fsanitize=address], [CXXFLAGS="$CXXFLAGS -fsanitize=address"], [asan_failed=yes]) AX_CHECK_LINK_FLAG([-fsanitize=address], [LDFLAGS="$LDFLAGS -fsanitize=address"], [asan_failed=yes]) AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer"], [asan_failed=yes]) if test "x$asan_failed" = xyes; then AC_MSG_ERROR("ASAN is not supported") fi fi if test "x$enable_tsan" = xyes; then enable_debug=yes tsan_failed=no AX_CHECK_COMPILE_FLAG([-fsanitize=thread], [CXXFLAGS="$CXXFLAGS -fsanitize=thread"], [tsan_failed=yes]) AX_CHECK_LINK_FLAG([-fsanitize=thread], [LDFLAGS="$LDFLAGS -fsanitize=thread"], [tsan_failed=yes]) AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer"], [tsan_failed=yes]) if test "x$tsan_failed" = xyes; then AC_MSG_ERROR("TSAN is not supported") fi fi if test "x$enable_ubsan" = xyes; then enable_debug=yes ubsan_failed=no AX_CHECK_COMPILE_FLAG([-fsanitize=undefined], [CXXFLAGS="$CXXFLAGS -fsanitize=undefined"], [ubsan_failed=yes]) AX_CHECK_LINK_FLAG([-fsanitize=undefined], [LDFLAGS="$LDFLAGS -fsanitize=undefined"], [ubsan_failed=yes]) AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer"], [ubsan_failed=yes]) if test "x$ubsan_failed" = xyes; then AC_MSG_ERROR("UBSAN is not supported") fi fi if test "x$enable_debug" = xyes; then CPPFLAGS="$CPPFLAGS -DDEBUG -DDEBUG_LOCKORDER" if test "x$GCC" = xyes; then CFLAGS="$CFLAGS -g3 -O0" fi if test "x$GXX" = xyes; then CXXFLAGS="$CXXFLAGS -g3 -O0" fi fi ERROR_CXXFLAGS= if test "x$enable_werror" = "xyes"; then if test "x$CXXFLAG_WERROR" = "x"; then AC_MSG_ERROR("enable-werror set but -Werror is not usable") fi AX_CHECK_COMPILE_FLAG([-Werror=vla],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=vla"],,[[$CXXFLAG_WERROR]]) fi if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wall],[CXXFLAGS="$CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wextra],[CXXFLAGS="$CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wvla],[CXXFLAGS="$CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all ## unknown options if any other warning is produced. Test the -Wfoo case, and ## set the -Wno-foo case if it works. AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[CXXFLAGS="$CXXFLAGS -Wno-unused-parameter"],,[[$CXXFLAG_WERROR]]) # Check for optional instruction set support. Enabling these does _not_ imply that all code will # be compiled with them, rather that specific objects/libs may use them after checking for runtime # compatibility. AX_CHECK_COMPILE_FLAG([-msse4.2],[[enable_sse42=yes; SSE42_CXXFLAGS="-msse4.2"]],,[[$CXXFLAG_WERROR]]) fi CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" AC_ARG_WITH([utils], [AS_HELP_STRING([--with-utils], [build bitcoin-cli bitcoin-tx (default=yes)])], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], [build libraries (default=yes)])], [build_bitcoin_libs=$withval], [build_bitcoin_libs=yes]) AC_ARG_WITH([daemon], [AS_HELP_STRING([--with-daemon], [build bitcoind daemon (default=yes)])], [build_bitcoind=$withval], [build_bitcoind=yes]) AC_ARG_WITH([seeder], [AS_HELP_STRING([--with-seeder], [build seeder (default=yes)])], [build_bitcoin_seeder=$withval], [build_bitcoin_seeder=yes]) use_pkgconfig=yes case $host in *mingw*) #pkgconfig does more harm than good with MinGW use_pkgconfig=no TARGET_OS=windows AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([kernel32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([winspool], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([shell32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([ole32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([rpcrt4], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([advapi32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([ws2_32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([mswsock], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([shlwapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(lib missing)) # -static is interpreted by libtool, where it has a different meaning. # In libtool-speak, it's -all-static. AX_CHECK_LINK_FLAG([[-static]],[LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"]) AC_PATH_PROG([MAKENSIS], [makensis], none) if test x$MAKENSIS = xnone; then AC_MSG_WARN("makensis not found. Cannot create installer.") fi AC_PATH_TOOL(WINDRES, windres, none) if test x$WINDRES = xnone; then AC_MSG_ERROR("windres not found") fi CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB" LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" if test "x$CXXFLAGS_overridden" = "xno"; then CXXFLAGS="$CXXFLAGS -w" fi case $host in i?86-*) WINDOWS_BITS=32 ;; x86_64-*) WINDOWS_BITS=64 ;; *) AC_MSG_ERROR("Could not determine win32/win64 for installer") ;; esac AC_SUBST(WINDOWS_BITS) dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against. dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override dnl its command here, with the predeps/postdeps removed, and -static inserted. Postdeps are dnl also overridden to prevent their insertion later. dnl This should only affect dll's. archive_cmds_CXX="\$CC -shared \$libobjs \$deplibs \$compiler_flags -static -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib" postdeps_CXX= ;; *darwin*) TARGET_OS=darwin LEVELDB_TARGET_FLAGS="-DOS_MACOSX" if test x$cross_compiling != xyes; then BUILD_OS=darwin AC_CHECK_PROG([PORT],port, port) if test x$PORT = xport; then dnl add default macports paths CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" LIBS="$LIBS -L/opt/local/lib" if test -d /opt/local/include/db48; then CPPFLAGS="$CPPFLAGS -I/opt/local/include/db48" LIBS="$LIBS -L/opt/local/lib/db48" fi fi AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_CHECK_PROG([BREW],brew, brew) if test x$BREW = xbrew; then dnl These Homebrew packages may be keg-only, meaning that they won't be found dnl in expected paths because they may conflict with system files. Ask dnl Homebrew where each one is located, then adjust paths accordingly. dnl It's safe to add these paths even if the functionality is disabled by dnl the user (--without-wallet or --without-gui for example). openssl_prefix=`$BREW --prefix openssl 2>/dev/null` bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null` qt5_prefix=`$BREW --prefix qt5 2>/dev/null` if test x$openssl_prefix != x; then PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" export PKG_CONFIG_PATH fi if test x$bdb_prefix != x; then CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include" LIBS="$LIBS -L$bdb_prefix/lib" fi if test x$qt5_prefix != x; then PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" export PKG_CONFIG_PATH fi fi else case $build_os in *darwin*) BUILD_OS=darwin ;; *) AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) dnl libtool will try to strip the static lib, which is a problem for dnl cross-builds because strip attempts to call a hard-coded ld, dnl which may not exist in the path. Stripping the .a is not dnl necessary, so just disable it. old_striplib= ;; esac fi AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"]) CPPFLAGS="$CPPFLAGS -DMAC_OSX" OBJCXXFLAGS="$CXXFLAGS" ;; *linux*) TARGET_OS=linux LEVELDB_TARGET_FLAGS="-DOS_LINUX" ;; *freebsd*) LEVELDB_TARGET_FLAGS="-DOS_FREEBSD" ;; *openbsd*) LEVELDB_TARGET_FLAGS="-DOS_OPENBSD" ;; *) OTHER_OS=`echo ${host_os} | awk '{print toupper($0)}'` AC_MSG_WARN([Guessing LevelDB OS as OS_${OTHER_OS}, please check whether this is correct, if not add an entry to configure.ac.]) LEVELDB_TARGET_FLAGS="-DOS_${OTHER_OS}" ;; esac if test x$use_pkgconfig = xyes; then m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) m4_ifdef([PKG_PROG_PKG_CONFIG], [ PKG_PROG_PKG_CONFIG if test x"$PKG_CONFIG" = "x"; then AC_MSG_ERROR(pkg-config not found.) fi ]) fi if test x$use_extended_rpc_tests != xno; then AC_SUBST(EXTENDED_RPC_TESTS, -extended) fi if test x$use_lcov = xyes; then if test x$LCOV = x; then AC_MSG_ERROR("lcov testing requested but lcov not found") fi if test x$GCOV = x; then AC_MSG_ERROR("lcov testing requested but gcov not found") fi if test x$PYTHON = x; then AC_MSG_ERROR("lcov testing requested but python not found") fi if test x$GENHTML = x; then AC_MSG_ERROR("lcov testing requested but genhtml not found") fi LCOV="$LCOV --gcov-tool=$GCOV" AX_CHECK_LINK_FLAG([[--coverage]], [LDFLAGS="$LDFLAGS --coverage"], [AC_MSG_ERROR("lcov testing requested but --coverage linker flag does not work")]) AX_CHECK_COMPILE_FLAG([--coverage],[CXXFLAGS="$CXXFLAGS --coverage"], [AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")]) fi dnl Check for endianness AC_C_BIGENDIAN dnl Check for pthread compile/link requirements AX_PTHREAD # The following macro will add the necessary defines to bitcoin-config.h, but # they also need to be passed down to any subprojects. Pull the results out of # the cache and add them to CPPFLAGS. AC_SYS_LARGEFILE # detect POSIX or GNU variant of strerror_r AC_FUNC_STRERROR_R if test x$ac_cv_sys_file_offset_bits != x && test x$ac_cv_sys_file_offset_bits != xno && test x$ac_cv_sys_file_offset_bits != xunknown; then CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits" fi if test x$ac_cv_sys_large_files != x && test x$ac_cv_sys_large_files != xno && test x$ac_cv_sys_large_files != xunknown; then CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=$ac_cv_sys_large_files" fi AX_CHECK_LINK_FLAG([[-Wl,--large-address-aware]], [LDFLAGS="$LDFLAGS -Wl,--large-address-aware"]) AX_GCC_FUNC_ATTRIBUTE([visibility]) AX_GCC_FUNC_ATTRIBUTE([dllexport]) AX_GCC_FUNC_ATTRIBUTE([dllimport]) if test x$use_glibc_compat != xno; then #glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link #in anyway for back-compat. AC_CHECK_LIB([rt],[clock_gettime],, AC_MSG_ERROR(lib missing)) #__fdelt_chk's params and return type have changed from long unsigned int to long int. # See which one is present here. AC_MSG_CHECKING(__fdelt_chk type) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef _FORTIFY_SOURCE #undef _FORTIFY_SOURCE #endif #define _FORTIFY_SOURCE 2 #include extern "C" long unsigned int __fdelt_warn(long unsigned int);]],[[]])], [ fdelt_type="long unsigned int"], [ fdelt_type="long int"]) AC_MSG_RESULT($fdelt_type) AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk]) else AC_SEARCH_LIBS([clock_gettime],[rt]) fi if test x$TARGET_OS != xwindows; then # All windows code is PIC, forcing it on just adds useless compile warnings AX_CHECK_COMPILE_FLAG([-fPIC],[PIC_FLAGS="-fPIC"]) fi if test x$use_hardening != xno; then AX_CHECK_COMPILE_FLAG([-Wstack-protector],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wstack-protector"]) AX_CHECK_COMPILE_FLAG([-fstack-protector-all],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-protector-all"]) AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[ AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[ HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -U_FORTIFY_SOURCE" ]) HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2" ]) AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"]) AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"]) AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"]) AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"]) AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"]) if test x$TARGET_OS != xwindows; then AX_CHECK_COMPILE_FLAG([-fPIE],[PIE_FLAGS="-fPIE"]) AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"]) fi case $host in *mingw*) AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(lib missing)) ;; esac fi dnl this flag screws up non-darwin gcc even when the check fails. special-case it. if test x$TARGET_OS = xdarwin; then AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) fi AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) AC_CHECK_DECLS([strnlen]) # Check for daemon(3), unrelated to --with-daemon (although used by it) AC_CHECK_DECLS([daemon]) AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,, [#if HAVE_ENDIAN_H #include #elif HAVE_SYS_ENDIAN_H #include #endif]) AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,, [#if HAVE_BYTESWAP_H #include #endif]) AC_CHECK_DECLS([__builtin_clz, __builtin_clzl, __builtin_clzll]) dnl Check for MSG_NOSIGNAL AC_MSG_CHECKING(for MSG_NOSIGNAL) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ int f = MSG_NOSIGNAL; ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MSG_NOSIGNAL, 1,[Define this symbol if you have MSG_NOSIGNAL]) ], [ AC_MSG_RESULT(no)] ) dnl Check for mallopt(M_ARENA_MAX) (to set glibc arenas) AC_MSG_CHECKING(for mallopt M_ARENA_MAX) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ mallopt(M_ARENA_MAX, 1); ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MALLOPT_ARENA_MAX, 1,[Define this symbol if you have mallopt with M_ARENA_MAX]) ], [ AC_MSG_RESULT(no)] ) AC_MSG_CHECKING([for visibility attribute]) AC_LINK_IFELSE([AC_LANG_SOURCE([ int foo_def( void ) __attribute__((visibility("default"))); int main(){} ])], [ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE,1,[Define if the visibility attribute is supported.]) AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) if test x$use_reduce_exports = xyes; then AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.]) fi ] ) # Check for different ways of gathering OS randomness AC_MSG_CHECKING(for Linux getrandom syscall) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include #include ]], [[ syscall(SYS_getrandom, nullptr, 32, 0); ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYS_GETRANDOM, 1,[Define this symbol if the Linux getrandom system call is available]) ], [ AC_MSG_RESULT(no)] ) AC_MSG_CHECKING(for getentropy) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ getentropy(nullptr, 32) ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GETENTROPY, 1,[Define this symbol if the BSD getentropy system call is available]) ], [ AC_MSG_RESULT(no)] ) AC_MSG_CHECKING(for sysctl KERN_ARND) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[ static const int name[2] = {CTL_KERN, KERN_ARND}; sysctl(name, 2, nullptr, nullptr, nullptr, 0); ]])], [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSCTL_ARND, 1,[Define this symbol if the BSD sysctl(KERN_ARND) is available]) ], [ AC_MSG_RESULT(no)] ) # Check for reduced exports if test x$use_reduce_exports = xyes; then AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi LEVELDB_CPPFLAGS= LIBLEVELDB= LIBMEMENV= AM_CONDITIONAL([EMBEDDED_LEVELDB],[true]) AC_SUBST(LEVELDB_CPPFLAGS) AC_SUBST(LIBLEVELDB) AC_SUBST(LIBMEMENV) if test x$enable_wallet != xno; then dnl Check for libdb_cxx only if wallet enabled BITCOIN_FIND_BDB48 fi dnl Check for libminiupnpc (optional) if test x$use_upnp != xno; then AC_CHECK_HEADERS( [miniupnpc/miniwget.h miniupnpc/miniupnpc.h miniupnpc/upnpcommands.h miniupnpc/upnperrors.h], [AC_CHECK_LIB([miniupnpc], [main],[MINIUPNPC_LIBS=-lminiupnpc], [have_miniupnpc=no])], [have_miniupnpc=no] ) fi BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt5]) if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$build_bitcoin_seeder$use_tests$use_bench = xnononononono; then use_boost=no else use_boost=yes fi if test x$use_boost = xyes; then dnl Minimum required Boost version define(MINIMUM_REQUIRED_BOOST, 1.55.0) dnl Check for boost libs AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) AX_BOOST_SYSTEM AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS AX_BOOST_THREAD AX_BOOST_CHRONO if test x$use_reduce_exports = xyes; then AC_MSG_CHECKING([for working boost reduced exports]) TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS" AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ @%:@include ]], [[ #if BOOST_VERSION >= 104900 // Everything is okay #else # error Boost version is too old #endif ]])],[ AC_MSG_RESULT(yes) ],[ AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.]) ]) CPPFLAGS="$TEMP_CPPFLAGS" fi fi if test x$use_reduce_exports = xyes; then CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS" AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"]) fi if test x$use_tests = xyes; then if test x$HEXDUMP = x; then AC_MSG_ERROR(hexdump is required for tests) fi if test x$use_boost = xyes; then AX_BOOST_UNIT_TEST_FRAMEWORK dnl Determine if -DBOOST_TEST_DYN_LINK is needed AC_MSG_CHECKING([for dynamic linked boost test]) TEMP_LIBS="$LIBS" LIBS="$LIBS $BOOST_LDFLAGS $BOOST_UNIT_TEST_FRAMEWORK_LIB" TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_LINK_IFELSE([AC_LANG_SOURCE([ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN #include ])], [AC_MSG_RESULT(yes)] [TESTDEFS="$TESTDEFS -DBOOST_TEST_DYN_LINK"], [AC_MSG_RESULT(no)]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" fi fi if test x$use_boost = xyes; then BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" dnl If boost (prior to 1.57) was built without c++11, it emulated scoped enums dnl using c++98 constructs. Unfortunately, this implementation detail leaked into dnl the abi. This was fixed in 1.57. dnl When building against that installed version using c++11, the headers pick up dnl on the native c++11 scoped enum support and enable it, however it will fail to dnl link. This can be worked around by disabling c++11 scoped enums if linking will dnl fail. dnl BOOST_NO_SCOPED_ENUMS was changed to BOOST_NO_CXX11_SCOPED_ENUMS in 1.51. TEMP_LIBS="$LIBS" LIBS="$BOOST_LIBS $LIBS" TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_MSG_CHECKING([for mismatched boost c++11 scoped enums]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include "boost/config.hpp" #include "boost/version.hpp" #if !defined(BOOST_NO_SCOPED_ENUMS) && !defined(BOOST_NO_CXX11_SCOPED_ENUMS) && BOOST_VERSION < 105700 #define BOOST_NO_SCOPED_ENUMS #define BOOST_NO_CXX11_SCOPED_ENUMS #define CHECK #endif #include "boost/filesystem.hpp" ]],[[ #if defined(CHECK) boost::filesystem::copy_file("foo", "bar"); #else choke; #endif ]])], [AC_MSG_RESULT(mismatched); BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS"], [AC_MSG_RESULT(ok)]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if dnl a working version is available, else fall back to sleep. sleep was removed dnl after 1.56. dnl If neither is available, abort. TEMP_LIBS="$LIBS" LIBS="$BOOST_LIBS $LIBS" TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include ]],[[ #if BOOST_VERSION >= 105000 && (!defined(BOOST_HAS_NANOSLEEP) || BOOST_VERSION >= 105200) boost::this_thread::sleep_for(boost::chrono::milliseconds(0)); #else choke me #endif ]])], [boost_sleep=yes; AC_DEFINE(HAVE_WORKING_BOOST_SLEEP_FOR, 1, [Define this symbol if boost sleep_for works])], [boost_sleep=no]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" if test x$boost_sleep != xyes; then TEMP_LIBS="$LIBS" LIBS="$BOOST_LIBS $LIBS" TEMP_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]],[[ #if BOOST_VERSION <= 105600 boost::this_thread::sleep(boost::posix_time::milliseconds(0)); #else choke me #endif ]])], [boost_sleep=yes; AC_DEFINE(HAVE_WORKING_BOOST_SLEEP, 1, [Define this symbol if boost sleep works])], [boost_sleep=no]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" fi if test x$boost_sleep != xyes; then AC_MSG_ERROR(No working boost sleep implementation found.) fi fi if test x$use_pkgconfig = xyes; then : dnl m4_ifdef( [PKG_CHECK_MODULES], [ PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto 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 if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)]) if test x$TARGET_OS != xwindows; then PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)]) fi fi if test "x$use_zmq" = "xyes"; then PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) use_zmq=no]) else AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) fi ] ) else AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),) AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing)) if test x$TARGET_OS != xwindows; then AC_CHECK_LIB([event_pthreads],[main],EVENT_PTHREADS_LIBS=-levent_pthreads,AC_MSG_ERROR(libevent_pthreads missing)) fi fi if test "x$use_zmq" = "xyes"; then AC_CHECK_HEADER([zmq.h], [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], [AC_MSG_WARN([zmq.h not found, disabling zmq support]) use_zmq=no AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) AC_CHECK_LIB([zmq],[zmq_ctx_shutdown],ZMQ_LIBS=-lzmq, [AC_MSG_WARN([libzmq >= 4.0 not found, disabling zmq support]) use_zmq=no AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) else AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) fi if test "x$use_zmq" = "xyes"; then dnl Assume libzmq was built for static linking case $host in *mingw*) ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" ;; esac fi BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) fi fi save_CXXFLAGS="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${CRYPTO_CFLAGS} ${SSL_CFLAGS}" AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT #include ]) CXXFLAGS="${save_CXXFLAGS}" dnl univalue check need_bundled_univalue=yes if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then need_bundled_univalue=no else if test x$system_univalue != xno ; then found_univalue=no if test x$use_pkgconfig = xyes; then : #NOP m4_ifdef( [PKG_CHECK_MODULES], [ PKG_CHECK_MODULES([UNIVALUE],[libunivalue],[found_univalue=yes],[true]) ] ) else AC_CHECK_HEADER([univalue.h],[ AC_CHECK_LIB([univalue], [main],[ UNIVALUE_LIBS=-lunivalue found_univalue=yes ],[true]) ],[true]) fi if test x$found_univalue = xyes ; then system_univalue=yes need_bundled_univalue=no elif test x$system_univalue = xyes ; then AC_MSG_ERROR([univalue not found]) else system_univalue=no fi fi if test x$need_bundled_univalue = xyes ; then UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' UNIVALUE_LIBS='univalue/libunivalue.la' fi fi AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) AC_SUBST(UNIVALUE_CFLAGS) AC_SUBST(UNIVALUE_LIBS) BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) AC_MSG_CHECKING([whether to build bitcoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) AC_MSG_CHECKING([whether to build bitcoin-seeder]) AM_CONDITIONAL([BUILD_BITCOIN_SEEDER], [test x$build_bitcoin_seeder = xyes]) AC_MSG_RESULT($build_bitcoin_seeder) AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)]) AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) AC_MSG_RESULT($build_bitcoin_utils) AC_MSG_CHECKING([whether to build libraries]) AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes]) if test x$build_bitcoin_libs = xyes; then AC_DEFINE(HAVE_CONSENSUS_LIB, 1, [Define this symbol if the consensus lib has been built]) AC_CONFIG_FILES([libbitcoinconsensus.pc:libbitcoinconsensus.pc.in]) fi AC_MSG_RESULT($build_bitcoin_libs) AC_LANG_POP if test "x$use_ccache" != "xno"; then AC_MSG_CHECKING(if ccache should be used) if test x$CCACHE = x; then if test "x$use_ccache" = "xyes"; then AC_MSG_ERROR([ccache not found.]); else use_ccache=no fi else use_ccache=yes CC="$ac_cv_path_CCACHE $CC" CXX="$ac_cv_path_CCACHE $CXX" fi AC_MSG_RESULT($use_ccache) fi if test "x$use_ccache" = "xyes"; then AX_CHECK_PREPROC_FLAG([-Qunused-arguments],[CPPFLAGS="-Qunused-arguments $CPPFLAGS"]) fi dnl enable wallet AC_MSG_CHECKING([if wallet should be enabled]) if test x$enable_wallet != xno; then AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED([ENABLE_WALLET],[1],[Define to 1 to enable wallet functions]) else AC_MSG_RESULT(no) fi dnl enable upnp support AC_MSG_CHECKING([whether to build with support for UPnP]) if test x$have_miniupnpc = xno; then if test x$use_upnp = xyes; then AC_MSG_ERROR("UPnP requested but cannot be built. use --without-miniupnpc") fi AC_MSG_RESULT(no) else if test x$use_upnp != xno; then AC_MSG_RESULT(yes) AC_MSG_CHECKING([whether to build with UPnP enabled by default]) use_upnp=yes upnp_setting=0 if test x$use_upnp_default != xno; then use_upnp_default=yes upnp_setting=1 fi AC_MSG_RESULT($use_upnp_default) AC_DEFINE_UNQUOTED([USE_UPNP],[$upnp_setting],[UPnP support not compiled if undefined, otherwise value (0 or 1) determines default state]) if test x$TARGET_OS = xwindows; then MINIUPNPC_CPPFLAGS="-DSTATICLIB -DMINIUPNP_STATICLIB" fi else AC_MSG_RESULT(no) fi fi dnl these are only used when qt is enabled BUILD_TEST_QT="" if test x$bitcoin_enable_qt != xno; then dnl enable dbus support AC_MSG_CHECKING([whether to build GUI with support for D-Bus]) if test x$bitcoin_enable_qt_dbus != xno; then AC_DEFINE([USE_DBUS],[1],[Define if dbus support should be compiled in]) fi AC_MSG_RESULT($bitcoin_enable_qt_dbus) dnl enable qr support AC_MSG_CHECKING([whether to build GUI with support for QR codes]) if test x$have_qrencode = xno; then if test x$use_qr = xyes; then AC_MSG_ERROR("QR support requested but cannot be built. use --without-qrencode") fi AC_MSG_RESULT(no) else if test x$use_qr != xno; then AC_MSG_RESULT(yes) AC_DEFINE([USE_QRCODE],[1],[Define if QR support should be compiled in]) use_qr=yes else AC_MSG_RESULT(no) fi fi if test x$XGETTEXT = x; then AC_MSG_WARN("xgettext is required to update qt translations") fi AC_MSG_CHECKING([whether to build test_bitcoin-qt]) if test x$use_gui_tests$bitcoin_enable_qt_test = xyesyes; then AC_MSG_RESULT([yes]) BUILD_TEST_QT="yes" else AC_MSG_RESULT([no]) fi fi AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) AC_MSG_CHECKING([whether to build test_bitcoin]) if test x$use_tests = xyes; then AC_MSG_RESULT([yes]) BUILD_TEST="yes" else AC_MSG_RESULT([no]) BUILD_TEST="" fi AC_MSG_CHECKING([whether to reduce exports]) if test x$use_reduce_exports = xyes; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnononononono; then AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-seeder --with-gui --enable-bench or --enable-tests]) fi AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin]) AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes]) AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes]) AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes]) AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) AM_CONDITIONAL([ENABLE_SSE42],[test x$enable_sse42 = xyes]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) AC_DEFINE(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION, [Build revision]) AC_DEFINE(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD, [Version Build]) AC_DEFINE(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE, [Version is release]) AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Copyright year]) AC_DEFINE(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS", [Copyright holder(s) before %s replacement]) AC_DEFINE(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION", [Replacement for %s in copyright holders string]) define(_COPYRIGHT_HOLDERS_FINAL, [patsubst(_COPYRIGHT_HOLDERS, [%s], [_COPYRIGHT_HOLDERS_SUBSTITUTION])]) AC_DEFINE(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL", [Copyright holder(s)]) AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR) AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR) AC_SUBST(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION) AC_SUBST(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD) AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE) AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) AC_SUBST(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS") AC_SUBST(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION") AC_SUBST(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL") AC_SUBST(BITCOIN_DAEMON_NAME) AC_SUBST(BITCOIN_GUI_NAME) AC_SUBST(BITCOIN_CLI_NAME) AC_SUBST(BITCOIN_TX_NAME) AC_SUBST(BITCOIN_SEEDER_NAME) AC_SUBST(RELDFLAGS) AC_SUBST(ERROR_CXXFLAGS) AC_SUBST(HARDENED_CXXFLAGS) AC_SUBST(HARDENED_CPPFLAGS) AC_SUBST(HARDENED_LDFLAGS) AC_SUBST(PIC_FLAGS) AC_SUBST(PIE_FLAGS) AC_SUBST(SSE42_CXXFLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) AC_SUBST(USE_UPNP) AC_SUBST(USE_QRCODE) AC_SUBST(BOOST_LIBS) AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) AC_SUBST(CRYPTO_LIBS) AC_SUBST(SSL_LIBS) AC_SUBST(EVENT_LIBS) AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) -AC_CONFIG_FILES([qa/pull-tester/tests_config.ini],[chmod +x qa/pull-tester/tests_config.ini]) +AC_CONFIG_FILES([test/pull-tester/tests_config.ini],[chmod +x test/pull-tester/tests_config.ini]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) -AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) +AC_CONFIG_LINKS([test/pull-tester/rpc-tests.py:test/pull-tester/rpc-tests.py]) dnl boost's m4 checks do something really nasty: they export these vars. As a dnl result, they leak into secp256k1's configure and crazy things happen. dnl Until this is fixed upstream and we've synced, we'll just un-export them. CPPFLAGS_TEMP="$CPPFLAGS" unset CPPFLAGS CPPFLAGS="$CPPFLAGS_TEMP" LDFLAGS_TEMP="$LDFLAGS" unset LDFLAGS LDFLAGS="$LDFLAGS_TEMP" LIBS_TEMP="$LIBS" unset LIBS LIBS="$LIBS_TEMP" PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" unset PKG_CONFIG_PATH PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP" PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR" unset PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP" if test x$need_bundled_univalue = xyes; then AC_CONFIG_SUBDIRS([src/univalue]) fi ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery" AC_CONFIG_SUBDIRS([src/secp256k1]) AC_OUTPUT dnl Taken from https://wiki.debian.org/RpathIssue case $host in *-*-linux-gnu) AC_MSG_RESULT([Fixing libtool for -rpath problems.]) sed < libtool > libtool-2 \ 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_IS_A_FOOL__ "/' mv libtool-2 libtool chmod 755 libtool ;; esac dnl Replace the BUILDDIR path with the correct Windows path if compiling on Native Windows case ${OS} in *Windows*) - sed 's/BUILDDIR="\/\([[a-z]]\)/BUILDDIR="\1:/' qa/pull-tester/tests_config.py > qa/pull-tester/tests_config-2.py - mv qa/pull-tester/tests_config-2.py qa/pull-tester/tests_config.py + sed 's/BUILDDIR="\/\([[a-z]]\)/BUILDDIR="\1:/' test/pull-tester/tests_config.py > test/pull-tester/tests_config-2.py + mv test/pull-tester/tests_config-2.py test/pull-tester/tests_config.py ;; esac echo echo "Options used to compile and link:" echo " with wallet = $enable_wallet" echo " with gui / qt = $bitcoin_enable_qt" if test x$bitcoin_enable_qt != xno; then echo " qt version = $bitcoin_qt_got_major_vers" echo " with qr = $use_qr" fi echo " with zmq = $use_zmq" echo " with test = $use_tests" echo " with bench = $use_bench" echo " with upnp = $use_upnp" echo " debug enabled = $enable_debug" echo " werror = $enable_werror" echo echo " sanitizers " echo " asan = $enable_asan" echo " tsan = $enable_tsan" echo " ubsan = $enable_ubsan" echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" echo echo " CC = $CC" echo " CFLAGS = $CFLAGS" echo " CPPFLAGS = $CPPFLAGS" echo " CXX = $CXX" echo " CXXFLAGS = $CXXFLAGS" echo " LDFLAGS = $LDFLAGS" echo diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py index 41a334380..5e967ae5d 100755 --- a/contrib/devtools/copyright_header.py +++ b/contrib/devtools/copyright_header.py @@ -1,613 +1,664 @@ #!/usr/bin/env python3 # Copyright (c) 2016 The Bitcoin Core developers # Copyright (c) 2017 The Bitcoin developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import re import fnmatch import sys import subprocess import datetime import os ################################################################################ # file filtering ################################################################################ EXCLUDE = [ # libsecp256k1: 'src/secp256k1/include/secp256k1.h', 'src/secp256k1/include/secp256k1_ecdh.h', 'src/secp256k1/include/secp256k1_recovery.h', 'src/secp256k1/include/secp256k1_schnorr.h', 'src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c', 'src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h', 'src/secp256k1/src/java/org_bitcoin_Secp256k1Context.c', 'src/secp256k1/src/java/org_bitcoin_Secp256k1Context.h', # auto generated: 'src/univalue/lib/univalue_escapes.h', 'src/qt/bitcoinstrings.cpp', 'src/chainparamsseeds.h', # other external copyrights: 'src/tinyformat.h', 'src/leveldb/util/env_win.cc', 'src/crypto/ctaes/bench.c', - 'qa/rpc-tests/test_framework/bignum.py', + 'test/rpc-tests/test_framework/bignum.py', # python init: '*__init__.py', ] -EXCLUDE_COMPILED = re.compile('|'.join([fnmatch.translate(m) for m in EXCLUDE])) +EXCLUDE_COMPILED = re.compile( + '|'.join([fnmatch.translate(m) for m in EXCLUDE])) INCLUDE = ['*.h', '*.cpp', '*.cc', '*.c', '*.py'] -INCLUDE_COMPILED = re.compile('|'.join([fnmatch.translate(m) for m in INCLUDE])) +INCLUDE_COMPILED = re.compile( + '|'.join([fnmatch.translate(m) for m in INCLUDE])) + def applies_to_file(filename): return ((EXCLUDE_COMPILED.match(filename) is None) and (INCLUDE_COMPILED.match(filename) is not None)) ################################################################################ # obtain list of files in repo according to INCLUDE and EXCLUDE ################################################################################ + GIT_LS_CMD = 'git ls-files' + def call_git_ls(): out = subprocess.check_output(GIT_LS_CMD.split(' ')) return [f for f in out.decode("utf-8").split('\n') if f != ''] + def get_filenames_to_examine(): filenames = call_git_ls() return sorted([filename for filename in filenames if applies_to_file(filename)]) ################################################################################ # define and compile regexes for the patterns we are looking for ################################################################################ COPYRIGHT_WITH_C = 'Copyright \(c\)' COPYRIGHT_WITHOUT_C = 'Copyright' ANY_COPYRIGHT_STYLE = '(%s|%s)' % (COPYRIGHT_WITH_C, COPYRIGHT_WITHOUT_C) YEAR = "20[0-9][0-9]" YEAR_RANGE = '(%s)(-%s)?' % (YEAR, YEAR) YEAR_LIST = '(%s)(, %s)+' % (YEAR, YEAR) ANY_YEAR_STYLE = '(%s|%s)' % (YEAR_RANGE, YEAR_LIST) ANY_COPYRIGHT_STYLE_OR_YEAR_STYLE = ("%s %s" % (ANY_COPYRIGHT_STYLE, ANY_YEAR_STYLE)) ANY_COPYRIGHT_COMPILED = re.compile(ANY_COPYRIGHT_STYLE_OR_YEAR_STYLE) + def compile_copyright_regex(copyright_style, year_style, name): return re.compile('%s %s %s' % (copyright_style, year_style, name)) + EXPECTED_HOLDER_NAMES = [ "Satoshi Nakamoto\n", "The Bitcoin Core developers\n", "The Bitcoin Core developers \n", "Bitcoin Core Developers\n", "the Bitcoin Core developers\n", "The Bitcoin developers\n", "The LevelDB Authors\. All rights reserved\.\n", "BitPay Inc\.\n", "BitPay, Inc\.\n", "University of Illinois at Urbana-Champaign\.\n", "MarcoFalke\n", "Pieter Wuille\n", "Pieter Wuille +\*\n", "Pieter Wuille, Gregory Maxwell +\*\n", "Pieter Wuille, Andrew Poelstra +\*\n", "Andrew Poelstra +\*\n", "Wladimir J. van der Laan\n", "Jeff Garzik\n", "Diederik Huys, Pieter Wuille +\*\n", "Thomas Daede, Cory Fields +\*\n", "Jan-Klaas Kollhof\n", "Sam Rushing\n", "ArtForz -- public domain half-a-node\n", "Amaury SÉCHET\n", "Jeremy Rubin\n", ] DOMINANT_STYLE_COMPILED = {} YEAR_LIST_STYLE_COMPILED = {} WITHOUT_C_STYLE_COMPILED = {} for holder_name in EXPECTED_HOLDER_NAMES: DOMINANT_STYLE_COMPILED[holder_name] = ( compile_copyright_regex(COPYRIGHT_WITH_C, YEAR_RANGE, holder_name)) YEAR_LIST_STYLE_COMPILED[holder_name] = ( compile_copyright_regex(COPYRIGHT_WITH_C, YEAR_LIST, holder_name)) WITHOUT_C_STYLE_COMPILED[holder_name] = ( compile_copyright_regex(COPYRIGHT_WITHOUT_C, ANY_YEAR_STYLE, holder_name)) ################################################################################ # search file contents for copyright message of particular category ################################################################################ + def get_count_of_copyrights_of_any_style_any_holder(contents): return len(ANY_COPYRIGHT_COMPILED.findall(contents)) + def file_has_dominant_style_copyright_for_holder(contents, holder_name): match = DOMINANT_STYLE_COMPILED[holder_name].search(contents) return match is not None + def file_has_year_list_style_copyright_for_holder(contents, holder_name): match = YEAR_LIST_STYLE_COMPILED[holder_name].search(contents) return match is not None + def file_has_without_c_style_copyright_for_holder(contents, holder_name): match = WITHOUT_C_STYLE_COMPILED[holder_name].search(contents) return match is not None ################################################################################ # get file info ################################################################################ + def read_file(filename): return open(os.path.abspath(filename), 'r').read() + def gather_file_info(filename): info = {} info['filename'] = filename c = read_file(filename) info['contents'] = c info['all_copyrights'] = get_count_of_copyrights_of_any_style_any_holder(c) info['classified_copyrights'] = 0 info['dominant_style'] = {} info['year_list_style'] = {} info['without_c_style'] = {} for holder_name in EXPECTED_HOLDER_NAMES: has_dominant_style = ( file_has_dominant_style_copyright_for_holder(c, holder_name)) has_year_list_style = ( file_has_year_list_style_copyright_for_holder(c, holder_name)) has_without_c_style = ( file_has_without_c_style_copyright_for_holder(c, holder_name)) info['dominant_style'][holder_name] = has_dominant_style info['year_list_style'][holder_name] = has_year_list_style info['without_c_style'][holder_name] = has_without_c_style if has_dominant_style or has_year_list_style or has_without_c_style: info['classified_copyrights'] = info['classified_copyrights'] + 1 return info ################################################################################ # report execution ################################################################################ + SEPARATOR = '-'.join(['' for _ in range(80)]) + def print_filenames(filenames, verbose): if not verbose: return for filename in filenames: print("\t%s" % filename) + def print_report(file_infos, verbose): print(SEPARATOR) examined = [i['filename'] for i in file_infos] print("%d files examined according to INCLUDE and EXCLUDE fnmatch rules" % len(examined)) print_filenames(examined, verbose) print(SEPARATOR) print('') zero_copyrights = [i['filename'] for i in file_infos if i['all_copyrights'] == 0] print("%4d with zero copyrights" % len(zero_copyrights)) print_filenames(zero_copyrights, verbose) one_copyright = [i['filename'] for i in file_infos if i['all_copyrights'] == 1] print("%4d with one copyright" % len(one_copyright)) print_filenames(one_copyright, verbose) two_copyrights = [i['filename'] for i in file_infos if i['all_copyrights'] == 2] print("%4d with two copyrights" % len(two_copyrights)) print_filenames(two_copyrights, verbose) three_copyrights = [i['filename'] for i in file_infos if i['all_copyrights'] == 3] print("%4d with three copyrights" % len(three_copyrights)) print_filenames(three_copyrights, verbose) four_or_more_copyrights = [i['filename'] for i in file_infos if i['all_copyrights'] >= 4] print("%4d with four or more copyrights" % len(four_or_more_copyrights)) print_filenames(four_or_more_copyrights, verbose) print('') print(SEPARATOR) print('Copyrights with dominant style:\ne.g. "Copyright (c)" and ' '"" or "-":\n') for holder_name in EXPECTED_HOLDER_NAMES: dominant_style = [i['filename'] for i in file_infos if i['dominant_style'][holder_name]] if len(dominant_style) > 0: print("%4d with '%s'" % (len(dominant_style), holder_name.replace('\n', '\\n'))) print_filenames(dominant_style, verbose) print('') print(SEPARATOR) print('Copyrights with year list style:\ne.g. "Copyright (c)" and ' '", , ...":\n') for holder_name in EXPECTED_HOLDER_NAMES: year_list_style = [i['filename'] for i in file_infos if i['year_list_style'][holder_name]] if len(year_list_style) > 0: print("%4d with '%s'" % (len(year_list_style), holder_name.replace('\n', '\\n'))) print_filenames(year_list_style, verbose) print('') print(SEPARATOR) print('Copyrights with no "(c)" style:\ne.g. "Copyright" and "" or ' '"-":\n') for holder_name in EXPECTED_HOLDER_NAMES: without_c_style = [i['filename'] for i in file_infos if i['without_c_style'][holder_name]] if len(without_c_style) > 0: print("%4d with '%s'" % (len(without_c_style), holder_name.replace('\n', '\\n'))) print_filenames(without_c_style, verbose) print('') print(SEPARATOR) unclassified_copyrights = [i['filename'] for i in file_infos if i['classified_copyrights'] < i['all_copyrights']] print("%d with unexpected copyright holder names" % len(unclassified_copyrights)) print_filenames(unclassified_copyrights, verbose) print(SEPARATOR) + def exec_report(base_directory, verbose): original_cwd = os.getcwd() os.chdir(base_directory) filenames = get_filenames_to_examine() file_infos = [gather_file_info(f) for f in filenames] print_report(file_infos, verbose) os.chdir(original_cwd) ################################################################################ # report cmd ################################################################################ + REPORT_USAGE = """ Produces a report of all copyright header notices found inside the source files of a repository. Usage: $ ./copyright_header.py report [verbose] Arguments: - The base directory of a bitcoin source code repository. [verbose] - Includes a list of every file of each subcategory in the report. """ + def report_cmd(argv): if len(argv) == 2: sys.exit(REPORT_USAGE) - + base_directory = argv[2] if not os.path.exists(base_directory): sys.exit("*** bad : %s" % base_directory) if len(argv) == 3: verbose = False elif argv[3] == 'verbose': verbose = True else: sys.exit("*** unknown argument: %s" % argv[2]) exec_report(base_directory, verbose) ################################################################################ # query git for year of last change ################################################################################ + GIT_LOG_CMD = "git log --pretty=format:%%ai %s" + def call_git_log(filename): out = subprocess.check_output((GIT_LOG_CMD % filename).split(' ')) return out.decode("utf-8").split('\n') + def get_git_change_years(filename): git_log_lines = call_git_log(filename) if len(git_log_lines) == 0: return [datetime.date.today().year] # timestamp is in ISO 8601 format. e.g. "2016-09-05 14:25:32 -0600" return [line.split(' ')[0].split('-')[0] for line in git_log_lines] + def get_most_recent_git_change_year(filename): return max(get_git_change_years(filename)) ################################################################################ # read and write to file ################################################################################ + def read_file_lines(filename): f = open(os.path.abspath(filename), 'r') file_lines = f.readlines() f.close() return file_lines + def write_file_lines(filename, file_lines): f = open(os.path.abspath(filename), 'w') f.write(''.join(file_lines)) f.close() ################################################################################ # update header years execution ################################################################################ + COPYRIGHT = 'Copyright \(c\)' YEAR = "20[0-9][0-9]" YEAR_RANGE = '(%s)(-%s)?' % (YEAR, YEAR) HOLDER = 'The Bitcoin developers' -UPDATEABLE_LINE_COMPILED = re.compile(' '.join([COPYRIGHT, YEAR_RANGE, HOLDER])) +UPDATEABLE_LINE_COMPILED = re.compile( + ' '.join([COPYRIGHT, YEAR_RANGE, HOLDER])) + def get_updatable_copyright_line(file_lines): index = 0 for line in file_lines: if UPDATEABLE_LINE_COMPILED.search(line) is not None: return index, line index = index + 1 return None, None + def parse_year_range(year_range): year_split = year_range.split('-') start_year = year_split[0] if len(year_split) == 1: return start_year, start_year return start_year, year_split[1] + def year_range_to_str(start_year, end_year): if start_year == end_year: return start_year return "%s-%s" % (start_year, end_year) + def create_updated_copyright_line(line, last_git_change_year): copyright_splitter = 'Copyright (c) ' copyright_split = line.split(copyright_splitter) # Preserve characters on line that are ahead of the start of the copyright # notice - they are part of the comment block and vary from file-to-file. before_copyright = copyright_split[0] after_copyright = copyright_split[1] space_split = after_copyright.split(' ') year_range = space_split[0] start_year, end_year = parse_year_range(year_range) if end_year == last_git_change_year: return line return (before_copyright + copyright_splitter + year_range_to_str(start_year, last_git_change_year) + ' ' + ' '.join(space_split[1:])) + def update_updatable_copyright(filename): file_lines = read_file_lines(filename) index, line = get_updatable_copyright_line(file_lines) if not line: print_file_action_message(filename, "No updatable copyright.") return last_git_change_year = get_most_recent_git_change_year(filename) new_line = create_updated_copyright_line(line, last_git_change_year) if line == new_line: print_file_action_message(filename, "Copyright up-to-date.") return file_lines[index] = new_line write_file_lines(filename, file_lines) print_file_action_message(filename, "Copyright updated! -> %s" % last_git_change_year) + def exec_update_header_year(base_directory): original_cwd = os.getcwd() os.chdir(base_directory) for filename in get_filenames_to_examine(): update_updatable_copyright(filename) os.chdir(original_cwd) ################################################################################ # update cmd ################################################################################ + UPDATE_USAGE = """ Updates all the copyright headers of "The Bitcoin developers" which were changed in a year more recent than is listed. For example: // Copyright (c) - The Bitcoin developers will be updated to: // Copyright (c) - The Bitcoin developers where is obtained from the 'git log' history. This subcommand also handles copyright headers that have only a single year. In those cases: // Copyright (c) The Bitcoin developers will be updated to: // Copyright (c) - The Bitcoin developers where the update is appropriate. Usage: $ ./copyright_header.py update Arguments: - The base directory of a bitcoin source code repository. """ + def print_file_action_message(filename, action): print("%-52s %s" % (filename, action)) + def update_cmd(argv): if len(argv) != 3: sys.exit(UPDATE_USAGE) - + base_directory = argv[2] if not os.path.exists(base_directory): sys.exit("*** bad base_directory: %s" % base_directory) exec_update_header_year(base_directory) ################################################################################ # inserted copyright header format ################################################################################ + def get_header_lines(header, start_year, end_year): lines = header.split('\n')[1:-1] lines[0] = lines[0] % year_range_to_str(start_year, end_year) return [line + '\n' for line in lines] + CPP_HEADER = ''' // Copyright (c) %s The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' + def get_cpp_header_lines_to_insert(start_year, end_year): return reversed(get_header_lines(CPP_HEADER, start_year, end_year)) + PYTHON_HEADER = ''' # Copyright (c) %s The Bitcoin developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' + def get_python_header_lines_to_insert(start_year, end_year): return reversed(get_header_lines(PYTHON_HEADER, start_year, end_year)) ################################################################################ # query git for year of last change ################################################################################ + def get_git_change_year_range(filename): years = get_git_change_years(filename) return min(years), max(years) ################################################################################ # check for existing core copyright ################################################################################ + def file_already_has_bitcoin_copyright(file_lines): index, _ = get_updatable_copyright_line(file_lines) return index != None ################################################################################ # insert header execution ################################################################################ + def file_has_hashbang(file_lines): if len(file_lines) < 1: return False if len(file_lines[0]) <= 2: return False return file_lines[0][:2] == '#!' + def insert_python_header(filename, file_lines, start_year, end_year): if file_has_hashbang(file_lines): - insert_idx = 1 + insert_idx = 1 else: insert_idx = 0 header_lines = get_python_header_lines_to_insert(start_year, end_year) for line in header_lines: file_lines.insert(insert_idx, line) write_file_lines(filename, file_lines) + def insert_cpp_header(filename, file_lines, start_year, end_year): header_lines = get_cpp_header_lines_to_insert(start_year, end_year) for line in header_lines: file_lines.insert(0, line) write_file_lines(filename, file_lines) + def exec_insert_header(filename, style): file_lines = read_file_lines(filename) if file_already_has_bitcoin_copyright(file_lines): sys.exit('*** %s already has a copyright by The Bitcoin developers' % (filename)) start_year, end_year = get_git_change_year_range(filename) if style == 'python': insert_python_header(filename, file_lines, start_year, end_year) else: insert_cpp_header(filename, file_lines, start_year, end_year) ################################################################################ # insert cmd ################################################################################ + INSERT_USAGE = """ Inserts a copyright header for "The Bitcoin developers" at the top of the file in either Python or C++ style as determined by the file extension. If the file is a Python file and it has a '#!' starting the first line, the header is inserted in the line below it. The copyright dates will be set to be: "-" where is according to the 'git log' history. If is equal to , the date will be set to be: "" If the file already has a copyright for "The Bitcoin developers", the script will exit. Usage: $ ./copyright_header.py insert Arguments: - A source file in the bitcoin repository. """ + def insert_cmd(argv): if len(argv) != 3: sys.exit(INSERT_USAGE) filename = argv[2] if not os.path.isfile(filename): sys.exit("*** bad filename: %s" % filename) _, extension = os.path.splitext(filename) if extension not in ['.h', '.cpp', '.cc', '.c', '.py']: sys.exit("*** cannot insert for file extension %s" % extension) - - if extension == '.py': + + if extension == '.py': style = 'python' else: style = 'cpp' exec_insert_header(filename, style) - + ################################################################################ # UI ################################################################################ + USAGE = """ copyright_header.py - utilities for managing copyright headers of 'The Bitcoin developers' in repository source files. Usage: $ ./copyright_header Subcommands: report update insert To see subcommand usage, run them without arguments. """ SUBCOMMANDS = ['report', 'update', 'insert'] if __name__ == "__main__": if len(sys.argv) == 1: sys.exit(USAGE) subcommand = sys.argv[1] if subcommand not in SUBCOMMANDS: sys.exit(USAGE) if subcommand == 'report': report_cmd(sys.argv) elif subcommand == 'update': update_cmd(sys.argv) elif subcommand == 'insert': insert_cmd(sys.argv) diff --git a/contrib/rpm/bitcoin.spec b/contrib/rpm/bitcoin.spec index 86d82db6a..5b9782ff8 100644 --- a/contrib/rpm/bitcoin.spec +++ b/contrib/rpm/bitcoin.spec @@ -1,440 +1,440 @@ %define bdbv 4.8.30 %global selinux_variants mls strict targeted %if 0%{?_no_gui:1} %define _buildqt 0 %define buildargs --with-gui=no %else %define _buildqt 1 %if 0%{?_use_qt4} %define buildargs --with-qrencode --with-gui=qt4 %else %define buildargs --with-qrencode --with-gui=qt5 %endif %endif Name: bitcoin Version: 0.12.0 Release: 2%{?dist} Summary: Peer to Peer Cryptographic Currency Group: Applications/System License: MIT URL: https://bitcoin.org/ Source0: https://bitcoin.org/bin/bitcoin-core-%{version}/bitcoin-%{version}.tar.gz Source1: http://download.oracle.com/berkeley-db/db-%{bdbv}.NC.tar.gz Source10: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/examples/bitcoin.conf #man pages Source20: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/doc/man/bitcoind.1 Source21: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/doc/man/bitcoin-cli.1 Source22: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/doc/man/bitcoin-qt.1 #selinux Source30: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.te # Source31 - what about bitcoin-tx and bench_bitcoin ??? Source31: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.fc Source32: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.if Source100: https://upload.wikimedia.org/wikipedia/commons/4/46/Bitcoin.svg %if 0%{?_use_libressl:1} BuildRequires: libressl-devel %else BuildRequires: openssl-devel %endif BuildRequires: boost-devel BuildRequires: miniupnpc-devel BuildRequires: autoconf automake libtool BuildRequires: libevent-devel Patch0: bitcoin-0.12.0-libressl.patch %description Bitcoin is a digital cryptographic currency that uses peer-to-peer technology to operate with no central authority or banks; managing transactions and the issuing of bitcoins is carried out collectively by the network. %if %{_buildqt} %package core Summary: Peer to Peer Cryptographic Currency Group: Applications/System Obsoletes: %{name} < %{version}-%{release} Provides: %{name} = %{version}-%{release} %if 0%{?_use_qt4} BuildRequires: qt-devel %else BuildRequires: qt5-qtbase-devel # for /usr/bin/lrelease-qt5 BuildRequires: qt5-linguist %endif BuildRequires: protobuf-devel BuildRequires: qrencode-devel BuildRequires: %{_bindir}/desktop-file-validate # for icon generation from SVG BuildRequires: %{_bindir}/inkscape BuildRequires: %{_bindir}/convert %description core Bitcoin is a digital cryptographic currency that uses peer-to-peer technology to operate with no central authority or banks; managing transactions and the issuing of bitcoins is carried out collectively by the network. This package contains the Qt based graphical client and node. If you are looking to run a Bitcoin wallet, this is probably the package you want. %endif %package libs Summary: Bitcoin shared libraries Group: System Environment/Libraries %description libs This package provides the bitcoinconsensus shared libraries. These libraries may be used by third party software to provide consensus verification functionality. Unless you know need this package, you probably do not. %package devel Summary: Development files for bitcoin Group: Development/Libraries Requires: %{name}-libs = %{version}-%{release} %description devel This package contains the header files and static library for the bitcoinconsensus shared library. If you are developing or compiling software that wants to link against that library, then you need this package installed. Most people do not need this package installed. %package server Summary: The bitcoin daemon Group: System Environment/Daemons Requires: bitcoin-utils = %{version}-%{release} Requires: selinux-policy policycoreutils-python Requires(pre): shadow-utils Requires(post): %{_sbindir}/semodule %{_sbindir}/restorecon %{_sbindir}/fixfiles %{_sbindir}/sestatus Requires(postun): %{_sbindir}/semodule %{_sbindir}/restorecon %{_sbindir}/fixfiles %{_sbindir}/sestatus BuildRequires: systemd BuildRequires: checkpolicy BuildRequires: %{_datadir}/selinux/devel/Makefile %description server This package provides a stand-alone bitcoin-core daemon. For most users, this package is only needed if they need a full-node without the graphical client. Some third party wallet software will want this package to provide the actual bitcoin-core node they use to connect to the network. If you use the graphical bitcoin-core client then you almost certainly do not need this package. %package utils Summary: Bitcoin utilities Group: Applications/System %description utils This package provides several command line utilities for interacting with a bitcoin-core daemon. The bitcoin-cli utility allows you to communicate and control a bitcoin daemon over RPC, the bitcoin-tx utility allows you to create a custom transaction, and the bench_bitcoin utility can be used to perform some benchmarks. This package contains utilities needed by the bitcoin-server package. %prep %setup -q %patch0 -p1 -b .libressl cp -p %{SOURCE10} ./bitcoin.conf.example tar -zxf %{SOURCE1} cp -p db-%{bdbv}.NC/LICENSE ./db-%{bdbv}.NC-LICENSE mkdir db4 SELinux cp -p %{SOURCE30} %{SOURCE31} %{SOURCE32} SELinux/ %build CWD=`pwd` cd db-%{bdbv}.NC/build_unix/ ../dist/configure --enable-cxx --disable-shared --with-pic --prefix=${CWD}/db4 make install cd ../.. ./autogen.sh %configure LDFLAGS="-L${CWD}/db4/lib/" CPPFLAGS="-I${CWD}/db4/include/" --with-miniupnpc --enable-glibc-back-compat %{buildargs} make %{?_smp_mflags} pushd SELinux for selinuxvariant in %{selinux_variants}; do make NAME=${selinuxvariant} -f %{_datadir}/selinux/devel/Makefile mv bitcoin.pp bitcoin.pp.${selinuxvariant} make NAME=${selinuxvariant} -f %{_datadir}/selinux/devel/Makefile clean done popd %install make install DESTDIR=%{buildroot} mkdir -p -m755 %{buildroot}%{_sbindir} mv %{buildroot}%{_bindir}/bitcoind %{buildroot}%{_sbindir}/bitcoind # systemd stuff mkdir -p %{buildroot}%{_tmpfilesdir} cat < %{buildroot}%{_tmpfilesdir}/bitcoin.conf d /run/bitcoind 0750 bitcoin bitcoin - EOF touch -a -m -t 201504280000 %{buildroot}%{_tmpfilesdir}/bitcoin.conf mkdir -p %{buildroot}%{_sysconfdir}/sysconfig cat < %{buildroot}%{_sysconfdir}/sysconfig/bitcoin # Provide options to the bitcoin daemon here, for example # OPTIONS="-testnet -disable-wallet" OPTIONS="" # System service defaults. # Don't change these unless you know what you're doing. CONFIG_FILE="%{_sysconfdir}/bitcoin/bitcoin.conf" DATA_DIR="%{_localstatedir}/lib/bitcoin" PID_FILE="/run/bitcoind/bitcoind.pid" EOF touch -a -m -t 201504280000 %{buildroot}%{_sysconfdir}/sysconfig/bitcoin mkdir -p %{buildroot}%{_unitdir} cat < %{buildroot}%{_unitdir}/bitcoin.service [Unit] Description=Bitcoin daemon After=syslog.target network.target [Service] Type=forking ExecStart=%{_sbindir}/bitcoind -daemon -conf=\${CONFIG_FILE} -datadir=\${DATA_DIR} -pid=\${PID_FILE} \$OPTIONS EnvironmentFile=%{_sysconfdir}/sysconfig/bitcoin User=bitcoin Group=bitcoin Restart=on-failure PrivateTmp=true TimeoutStopSec=120 TimeoutStartSec=60 StartLimitInterval=240 StartLimitBurst=5 [Install] WantedBy=multi-user.target EOF touch -a -m -t 201504280000 %{buildroot}%{_unitdir}/bitcoin.service #end systemd stuff mkdir %{buildroot}%{_sysconfdir}/bitcoin mkdir -p %{buildroot}%{_localstatedir}/lib/bitcoin #SELinux for selinuxvariant in %{selinux_variants}; do install -d %{buildroot}%{_datadir}/selinux/${selinuxvariant} install -p -m 644 SELinux/bitcoin.pp.${selinuxvariant} %{buildroot}%{_datadir}/selinux/${selinuxvariant}/bitcoin.pp done %if %{_buildqt} # qt icons install -D -p share/pixmaps/bitcoin.ico %{buildroot}%{_datadir}/pixmaps/bitcoin.ico install -p share/pixmaps/nsis-header.bmp %{buildroot}%{_datadir}/pixmaps/ install -p share/pixmaps/nsis-wizard.bmp %{buildroot}%{_datadir}/pixmaps/ install -p %{SOURCE100} %{buildroot}%{_datadir}/pixmaps/bitcoin.svg %{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin16.png -w16 -h16 %{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin32.png -w32 -h32 %{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin64.png -w64 -h64 %{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin128.png -w128 -h128 %{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin256.png -w256 -h256 %{_bindir}/convert -resize 16x16 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin16.xpm %{_bindir}/convert -resize 32x32 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin32.xpm %{_bindir}/convert -resize 64x64 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin64.xpm %{_bindir}/convert -resize 128x128 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin128.xpm %{_bindir}/convert %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin256.xpm touch %{buildroot}%{_datadir}/pixmaps/*.png -r %{SOURCE100} touch %{buildroot}%{_datadir}/pixmaps/*.xpm -r %{SOURCE100} # Desktop File - change the touch timestamp if modifying mkdir -p %{buildroot}%{_datadir}/applications cat < %{buildroot}%{_datadir}/applications/bitcoin-core.desktop [Desktop Entry] Encoding=UTF-8 Name=Bitcoin Comment=Bitcoin P2P Cryptocurrency Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi Exec=bitcoin-qt %u Terminal=false Type=Application Icon=bitcoin128 MimeType=x-scheme-handler/bitcoincash; Categories=Office;Finance; EOF # change touch date when modifying desktop touch -a -m -t 201511100546 %{buildroot}%{_datadir}/applications/bitcoin-core.desktop %{_bindir}/desktop-file-validate %{buildroot}%{_datadir}/applications/bitcoin-core.desktop # KDE protocol - change the touch timestamp if modifying mkdir -p %{buildroot}%{_datadir}/kde4/services cat < %{buildroot}%{_datadir}/kde4/services/bitcoin-core.protocol [Protocol] exec=bitcoin-qt '%u' protocol=bitcoin input=none output=none helper=true listing= reading=false writing=false makedir=false deleting=false EOF # change touch date when modifying protocol touch -a -m -t 201511100546 %{buildroot}%{_datadir}/kde4/services/bitcoin-core.protocol %endif # man pages install -D -p %{SOURCE20} %{buildroot}%{_mandir}/man1/bitcoind.1 install -p %{SOURCE21} %{buildroot}%{_mandir}/man1/bitcoin-cli.1 %if %{_buildqt} install -p %{SOURCE22} %{buildroot}%{_mandir}/man1/bitcoin-qt.1 %endif # nuke these, we do extensive testing of binaries in %%check before packaging rm -f %{buildroot}%{_bindir}/test_* %check make check pushd src srcdir=. test/bitcoin-util-test.py popd -qa/pull-tester/rpc-tests.py -extended +test/pull-tester/rpc-tests.py -extended %post libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig %pre server getent group bitcoin >/dev/null || groupadd -r bitcoin getent passwd bitcoin >/dev/null || useradd -r -g bitcoin -d /var/lib/bitcoin -s /sbin/nologin \ -c "Bitcoin wallet server" bitcoin exit 0 %post server %systemd_post bitcoin.service # SELinux if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then for selinuxvariant in %{selinux_variants}; do %{_sbindir}/semodule -s ${selinuxvariant} -i %{_datadir}/selinux/${selinuxvariant}/bitcoin.pp &> /dev/null || : done %{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 8332 %{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 8333 %{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 18332 %{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 18333 %{_sbindir}/fixfiles -R bitcoin-server restore &> /dev/null || : %{_sbindir}/restorecon -R %{_localstatedir}/lib/bitcoin || : fi %posttrans server %{_bindir}/systemd-tmpfiles --create %preun server %systemd_preun bitcoin.service %postun server %systemd_postun bitcoin.service # SELinux if [ $1 -eq 0 ]; then if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then %{_sbindir}/semanage port -d -p tcp 8332 %{_sbindir}/semanage port -d -p tcp 8333 %{_sbindir}/semanage port -d -p tcp 18332 %{_sbindir}/semanage port -d -p tcp 18333 for selinuxvariant in %{selinux_variants}; do %{_sbindir}/semodule -s ${selinuxvariant} -r bitcoin &> /dev/null || : done %{_sbindir}/fixfiles -R bitcoin-server restore &> /dev/null || : [ -d %{_localstatedir}/lib/bitcoin ] && \ %{_sbindir}/restorecon -R %{_localstatedir}/lib/bitcoin &> /dev/null || : fi fi %clean rm -rf %{buildroot} %if %{_buildqt} %files core %defattr(-,root,root,-) %license COPYING db-%{bdbv}.NC-LICENSE %doc COPYING bitcoin.conf.example doc/README.md doc/bips.md doc/files.md doc/multiwallet-qt.md doc/reduce-traffic.md doc/release-notes.md doc/tor.md %attr(0755,root,root) %{_bindir}/bitcoin-qt %attr(0644,root,root) %{_datadir}/applications/bitcoin-core.desktop %attr(0644,root,root) %{_datadir}/kde4/services/bitcoin-core.protocol %attr(0644,root,root) %{_datadir}/pixmaps/*.ico %attr(0644,root,root) %{_datadir}/pixmaps/*.bmp %attr(0644,root,root) %{_datadir}/pixmaps/*.svg %attr(0644,root,root) %{_datadir}/pixmaps/*.png %attr(0644,root,root) %{_datadir}/pixmaps/*.xpm %attr(0644,root,root) %{_mandir}/man1/bitcoin-qt.1* %endif %files libs %defattr(-,root,root,-) %license COPYING %doc COPYING doc/README.md doc/shared-libraries.md %{_libdir}/lib*.so.* %files devel %defattr(-,root,root,-) %license COPYING %doc COPYING doc/README.md doc/developer-notes.md doc/shared-libraries.md %attr(0644,root,root) %{_includedir}/*.h %{_libdir}/*.so %{_libdir}/*.a %{_libdir}/*.la %attr(0644,root,root) %{_libdir}/pkgconfig/*.pc %files server %defattr(-,root,root,-) %license COPYING db-%{bdbv}.NC-LICENSE %doc COPYING bitcoin.conf.example doc/README.md doc/REST-interface.md doc/bips.md doc/dnsseed-policy.md doc/files.md doc/reduce-traffic.md doc/release-notes.md doc/tor.md %attr(0755,root,root) %{_sbindir}/bitcoind %attr(0644,root,root) %{_tmpfilesdir}/bitcoin.conf %attr(0644,root,root) %{_unitdir}/bitcoin.service %dir %attr(0750,bitcoin,bitcoin) %{_sysconfdir}/bitcoin %dir %attr(0750,bitcoin,bitcoin) %{_localstatedir}/lib/bitcoin %config(noreplace) %attr(0600,root,root) %{_sysconfdir}/sysconfig/bitcoin %attr(0644,root,root) %{_datadir}/selinux/*/*.pp %attr(0644,root,root) %{_mandir}/man1/bitcoind.1* %files utils %defattr(-,root,root,-) %license COPYING %doc COPYING bitcoin.conf.example doc/README.md %attr(0755,root,root) %{_bindir}/bitcoin-cli %attr(0755,root,root) %{_bindir}/bitcoin-tx %attr(0755,root,root) %{_bindir}/bench_bitcoin %attr(0644,root,root) %{_mandir}/man1/bitcoin-cli.1* %changelog * Fri Feb 26 2016 Alice Wonder - 0.12.0-2 - Rename Qt package from bitcoin to bitcoin-core - Make building of the Qt package optional - When building the Qt package, default to Qt5 but allow building - against Qt4 - Only run SELinux stuff in post scripts if it is not set to disabled * Wed Feb 24 2016 Alice Wonder - 0.12.0-1 - Initial spec file for 0.12.0 release # This spec file is written from scratch but a lot of the packaging decisions are directly # based upon the 0.11.2 package spec file from https://www.ringingliberty.com/bitcoin/ diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 3a7e4f73b..ec608cfbd 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -1,497 +1,497 @@ Developer Notes =============== Various coding styles have been used during the history of the codebase, and the result is not very consistent. However, we're now trying to converge to a single style, so please use it in new code. Old code will be converted gradually and you are encouraged to use the provided [clang-format-diff script](/contrib/devtools/README.md#clang-format-diffpy) to clean up the patch automatically before submitting a pull request. - Basic rules specified in [src/.clang-format](/src/.clang-format). - Braces on new lines for namespaces, classes, functions, methods. - Braces on the same line for everything else. - 4 space indentation (no tabs) for every block except namespaces. - No indentation for `public`/`protected`/`private` or for `namespace`. - No extra spaces inside parenthesis; don't do ( this ) - No space after function names; one space after `if`, `for` and `while`. - If an `if` only has a single-statement then-clause, it can appear on the same line as the if, without braces. In every other case, braces are required, and the then and else clauses must appear correctly indented on a new line. - `++i` is preferred over `i++`. Block style example: ```c++ namespace foo { class Class { bool Function(const std::string& s, int n) { // Comment summarising what this section of code does for (int i = 0; i < n; ++i) { // When something fails, return early if (!Something()) return false; ... if (SomethingElse()) { DoMore(); } else { DoLess(); } } // Success return is usually at the end return true; } } } ``` Doxygen comments ----------------- To facilitate the generation of documentation, use doxygen-compatible comment blocks for functions, methods and fields. For example, to describe a function use: ```c++ /** * ... text ... * @param[in] arg1 A description * @param[in] arg2 Another argument description * @pre Precondition for function... */ bool function(int arg1, const char *arg2) ``` A complete list of `@xxx` commands can be found at http://www.stack.nl/~dimitri/doxygen/manual/commands.html. As Doxygen recognizes the comments by the delimiters (`/**` and `*/` in this case), you don't *need* to provide any commands for a comment to be valid; just a description text is fine. To describe a class use the same construct above the class definition: ```c++ /** * Alerts are for notifying old versions if they become too obsolete and * need to upgrade. The message is displayed in the status bar. * @see GetWarnings() */ class CAlert { ``` To describe a member or variable use: ```c++ int var; //!< Detailed description after the member ``` or ```cpp //! Description before the member int var; ``` Also OK: ```c++ /// /// ... text ... /// bool function2(int arg1, const char *arg2) ``` Not OK (used plenty in the current source, but not picked up): ```c++ // // ... text ... // ``` A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html, but if possible use one of the above styles. Development tips and tricks --------------------------- **compiling for debugging** Run configure with the --enable-debug option, then make. Or run configure with CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need. **debug.log** If the code is behaving strangely, take a look in the debug.log file in the data directory; error and debugging messages are written there. The -debug=... command-line option controls debugging; running with just -debug or -debug=1 will turn on all categories (and give you a very large debug.log file). The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt to see it. **testnet and regtest modes** Run with the -testnet option to run with "play bitcoins" on the test network, if you are testing multi-machine code that needs to operate across the internet. If you are testing something that can run on one machine, run with the -regtest option. -In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests +In regression test mode, blocks can be created on-demand; see test/rpc-tests/ for tests that run in -regtest mode. **DEBUG_LOCKORDER** Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks are held, and adds warnings to the debug.log file if inconsistencies are detected. Locking/mutex usage notes ------------------------- The code is multi-threaded, and uses mutexes and the LOCK/TRY_LOCK macros to protect data structures. Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main and then cs_wallet, while thread 2 locks them in the opposite order: result, deadlock as each waits for the other to release its lock) are a problem. Compile with -DDEBUG_LOCKORDER to get lock order inconsistencies reported in the debug.log file. Re-architecting the core code so there are better-defined interfaces between the various components is a goal, with any necessary locking done by the components (e.g. see the self-contained CKeyStore class and its cs_KeyStore lock for example). Threads ------- - ThreadScriptCheck : Verifies block scripts. - ThreadImport : Loads blocks from blk*.dat files or bootstrap.dat. - StartNode : Starts other threads. - ThreadDNSAddressSeed : Loads addresses of peers from the DNS. - ThreadMapPort : Universal plug-and-play startup/shutdown - ThreadSocketHandler : Sends/Receives data from peers on port 8333. - ThreadOpenAddedConnections : Opens network connections to added nodes. - ThreadOpenConnections : Initiates new connections to peers. - ThreadMessageHandler : Higher-level message handling (sending and receiving). - DumpAddresses : Dumps IP addresses of nodes to peers.dat. - ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used in 500ms. - ThreadRPCServer : Remote procedure call handler, listens on port 8332 for connections and services them. - BitcoinMiner : Generates bitcoins (if wallet is enabled). - Shutdown : Does an orderly shutdown of everything. Ignoring IDE/editor files -------------------------- In closed-source environments in which everyone uses the same IDE it is common to add temporary files it produces to the project-wide `.gitignore` file. However, in open source software such as Bitcoin Core, where everyone uses their own editors/IDE/tools, it is less common. Only you know what files your editor produces and this may change from version to version. The canonical way to do this is thus to create your local gitignore. Add this to `~/.gitconfig`: ``` [core] excludesfile = /home/.../.gitignore_global ``` (alternatively, type the command `git config --global core.excludesfile ~/.gitignore_global` on a terminal) Then put your favourite tool's temporary filenames in that file, e.g. ``` # NetBeans nbproject/ ``` Another option is to create a per-repository excludes file `.git/info/exclude`. These are not committed but apply only to one repository. If a set of tools is used by the build system or scripts the repository (for example, lcov) it is perfectly acceptable to add its files to `.gitignore` and commit them. Development guidelines ============================ A few non-style-related recommendations for developers, as well as points to pay attention to for reviewers of Bitcoin Core code. General Bitcoin Core ---------------------- - New features should be exposed on RPC first, then can be made available in the GUI - *Rationale*: RPC allows for better automatic testing. The test suite for the GUI is very limited - Make sure pull requests pass Travis CI before merging - *Rationale*: Makes sure that they pass thorough testing, and that the tester will keep passing on the master branch. Otherwise all new pull requests will start failing the tests, resulting in confusion and mayhem - *Explanation*: If the test suite is to be updated for a change, this has to be done first Wallet ------- - Make sure that no crashes happen with run-time option `-disablewallet`. - *Rationale*: In RPC code that conditionally uses the wallet (such as `validateaddress`) it is easy to forget that global pointer `pwalletMain` - can be NULL. See `qa/rpc-tests/disablewallet.py` for functional tests + can be NULL. See `test/rpc-tests/disablewallet.py` for functional tests exercising the API with `-disablewallet` - Include `db_cxx.h` (BerkeleyDB header) only when `ENABLE_WALLET` is set - *Rationale*: Otherwise compilation of the disable-wallet build will fail in environments without BerkeleyDB General C++ ------------- - Assertions should not have side-effects - *Rationale*: Even though the source code is set to to refuse to compile with assertions disabled, having side-effects in assertions is unexpected and makes the code harder to understand - If you use the `.h`, you must link the `.cpp` - *Rationale*: Include files define the interface for the code in implementation files. Including one but not linking the other is confusing. Please avoid that. Moving functions from the `.h` to the `.cpp` should not result in build errors - Use the RAII (Resource Acquisition Is Initialization) paradigm where possible. For example by using `unique_ptr` for allocations in a function. - *Rationale*: This avoids memory and resource leaks, and ensures exception safety C++ data structures -------------------- - Never use the `std::map []` syntax when reading from a map, but instead use `.find()` - *Rationale*: `[]` does an insert (of the default element) if the item doesn't exist in the map yet. This has resulted in memory leaks in the past, as well as race conditions (expecting read-read behavior). Using `[]` is fine for *writing* to a map - Do not compare an iterator from one data structure with an iterator of another data structure (even if of the same type) - *Rationale*: Behavior is undefined. In C++ parlor this means "may reformat the universe", in practice this has resulted in at least one hard-to-debug crash bug - Watch out for out-of-bounds vector access. `&vch[vch.size()]` is illegal, including `&vch[0]` for an empty vector. Use `vch.data()` and `vch.data() + vch.size()` instead. - Vector bounds checking is only enabled in debug mode. Do not rely on it - Make sure that constructors initialize all fields. If this is skipped for a good reason (i.e., optimization on the critical path), add an explicit comment about this - *Rationale*: Ensure determinism by avoiding accidental use of uninitialized values. Also, static analyzers balk about this. - Use explicitly signed or unsigned `char`s, or even better `uint8_t` and `int8_t`. Do not use bare `char` unless it is to pass to a third-party API. This type can be signed or unsigned depending on the architecture, which can lead to interoperability problems or dangerous conditions such as out-of-bounds array accesses - Prefer explicit constructions over implicit ones that rely on 'magical' C++ behavior - *Rationale*: Easier to understand what is happening, thus easier to spot mistakes, even for those that are not language lawyers Strings and formatting ------------------------ - Be careful of `LogPrint` versus `LogPrintf`. `LogPrint` takes a `category` argument, `LogPrintf` does not. - *Rationale*: Confusion of these can result in runtime exceptions due to formatting mismatch, and it is easy to get wrong because of subtly similar naming - Use `std::string`, avoid C string manipulation functions - *Rationale*: C++ string handling is marginally safer, less scope for buffer overflows and surprises with `\0` characters. Also some C string manipulations tend to act differently depending on platform, or even the user locale - Use `ParseInt32`, `ParseInt64`, `ParseUInt32`, `ParseUInt64`, `ParseDouble` from `utilstrencodings.h` for number parsing - *Rationale*: These functions do overflow checking, and avoid pesky locale issues - For `strprintf`, `LogPrint`, `LogPrintf` formatting characters don't need size specifiers - *Rationale*: Bitcoin Core uses tinyformat, which is type safe. Leave them out to avoid confusion Variable names -------------- The shadowing warning (`-Wshadow`) is enabled by default. It prevents issues rising from using a different variable with the same name. Please name variables so that their names do not shadow variables defined in the source code. E.g. in member initializers, prepend `_` to the argument name shadowing the member name: ```c++ class AddressBookPage { Mode mode; } AddressBookPage::AddressBookPage(Mode _mode) : mode(_mode) ... ``` When using nested cycles, do not name the inner cycle variable the same as in upper cycle etc. Threads and synchronization ---------------------------- - Build and run tests with `-DDEBUG_LOCKORDER` to verify that no potential deadlocks are introduced. As of 0.12, this is defined by default when configuring with `--enable-debug` - When using `LOCK`/`TRY_LOCK` be aware that the lock exists in the context of the current scope, so surround the statement and the code that needs the lock with braces OK: ```c++ { TRY_LOCK(cs_vNodes, lockNodes); ... } ``` Wrong: ```c++ TRY_LOCK(cs_vNodes, lockNodes); { ... } ``` Source code organization -------------------------- - Implementation code should go into the `.cpp` file and not the `.h`, unless necessary due to template usage or when performance due to inlining is critical - *Rationale*: Shorter and simpler header files are easier to read, and reduce compile time - Don't import anything into the global namespace (`using namespace ...`). Use fully specified types such as `std::string`. - *Rationale*: Avoids symbol conflicts GUI ----- - Do not display or manipulate dialogs in model code (classes `*Model`) - *Rationale*: Model classes pass through events and data from the core, they should not interact with the user. That's where View classes come in. The converse also holds: try to not directly access core data structures from Views. Subtrees ---------- Several parts of the repository are subtrees of software maintained elsewhere. Some of these are maintained by active developers of Bitcoin Core, in which case changes should probably go directly upstream without being PRed directly against the project. They will be merged back in the next subtree merge. Others are external projects without a tight relationship with our project. Changes to these should also be sent upstream but bugfixes may also be prudent to PR against Bitcoin Core so that they can be integrated quickly. Cosmetic changes should be purely taken upstream. There is a tool in contrib/devtools/git-subtree-check.sh to check a subtree directory for consistency with its upstream repository. Current subtrees include: - src/leveldb - Upstream at https://github.com/google/leveldb ; Maintained by Google, but open important PRs to Core to avoid delay - src/libsecp256k1 - Upstream at https://github.com/bitcoin-core/secp256k1/ ; actively maintaned by Core contributors. - src/crypto/ctaes - Upstream at https://github.com/bitcoin-core/ctaes ; actively maintained by Core contributors. - src/univalue - Upstream at https://github.com/jgarzik/univalue ; report important PRs to Core to avoid delay. Git and GitHub tips --------------------- - For resolving merge/rebase conflicts, it can be useful to enable diff3 style using `git config merge.conflictstyle diff3`. Instead of <<< yours === theirs >>> you will see <<< yours ||| original === theirs >>> This may make it much clearer what caused the conflict. In this style, you can often just look at what changed between *original* and *theirs*, and mechanically apply that to *yours* (or the other way around). - When reviewing patches which change indentation in C++ files, use `git diff -w` and `git show -w`. This makes the diff algorithm ignore whitespace changes. This feature is also available on github.com, by adding `?w=1` at the end of any URL which shows a diff. - When reviewing patches that change symbol names in many places, use `git diff --word-diff`. This will instead of showing the patch as deleted/added *lines*, show deleted/added *words*. - When reviewing patches that move code around, try using `git diff --patience commit~:old/file.cpp commit:new/file/name.cpp`, and ignoring everything except the moved body of code which should show up as neither `+` or `-` lines. In case it was not a pure move, this may even work when combined with the `-w` or `--word-diff` options described above. - When looking at other's pull requests, it may make sense to add the following section to your `.git/config` file: [remote "upstream-pull"] fetch = +refs/pull/*:refs/remotes/upstream-pull/* url = git@github.com:bitcoin/bitcoin.git This will add an `upstream-pull` remote to your git repository, which can be fetched using `git fetch --all` or `git fetch upstream-pull`. Afterwards, you can use `upstream-pull/NUMBER/head` in arguments to `git show`, `git checkout` and anywhere a commit id would be acceptable to see the changes from pull request NUMBER. diff --git a/qa/README.md b/test/README.md similarity index 59% rename from qa/README.md rename to test/README.md index 225207cc1..717643937 100644 --- a/qa/README.md +++ b/test/README.md @@ -1,87 +1,98 @@ -The [pull-tester](/qa/pull-tester/) folder contains a script to call -multiple tests from the [rpc-tests](/qa/rpc-tests/) folder. +The [pull-tester](/test/pull-tester/) folder contains a script to call +multiple tests from the [rpc-tests](/test/rpc-tests/) folder. Every pull request to the bitcoin repository is built and run through the regression test suite. You can also run all or only individual tests locally. Test dependencies ================= Before running the tests, the following must be installed. Unix ---- The python3-zmq library is required. On Ubuntu or Debian it can be installed via: ``` sudo apt-get install python3-zmq ``` OS X ------ ``` pip3 install pyzmq ``` Running tests ============= You can run any single test by calling - qa/pull-tester/rpc-tests.py + test/pull-tester/rpc-tests.py Or you can run any combination of tests by calling - qa/pull-tester/rpc-tests.py ... + test/pull-tester/rpc-tests.py ... Run the regression test suite with - qa/pull-tester/rpc-tests.py + test/pull-tester/rpc-tests.py Run all possible tests with - qa/pull-tester/rpc-tests.py -extended + test/pull-tester/rpc-tests.py --extended By default, tests will be run in parallel. To specify how many jobs to run, append `-parallel=n` (default n=4). If you want to create a basic coverage report for the rpc test suite, append `--coverage`. Possible options, which apply to each individual test run: ``` -h, --help show this help message and exit --nocleanup Leave bitcoinds and test.* datadir on exit or error --noshutdown Don't stop bitcoinds after the test execution --srcdir=SRCDIR Source directory containing bitcoind/bitcoin-cli - (default: ../../src) + (default: /Users/shammah/repos/bitcoin-abc/src) + --cachedir=CACHEDIR Directory for caching pregenerated datadirs --tmpdir=TMPDIR Root directory for datadirs + -l LOGLEVEL, --loglevel=LOGLEVEL + log events at this level and higher to the console. + Can be set to DEBUG, INFO, WARNING, ERROR or CRITICAL. + Passing --loglevel DEBUG will output all logs to + console. Note that logs at all levels are always + written to the test_framework.log file in the + temporary test directory. --tracerpc Print out all RPC calls as they are made + --portseed=PORT_SEED The seed to use for assigning port numbers (default: + current process id) --coveragedir=COVERAGEDIR Write tested RPC commands into this directory ``` If you set the environment variable `PYTHON_DEBUG=1` you will get some debug -output (example: `PYTHON_DEBUG=1 qa/pull-tester/rpc-tests.py wallet`). +output (example: `PYTHON_DEBUG=1 test/pull-tester/rpc-tests.py wallet`). -A 200-block -regtest blockchain and wallets for four nodes +A 200-block `--regtest` blockchain and wallets for four nodes is created the first time a regression test is run and is stored in the cache/ directory. Each node has 25 mature blocks (25*50=1250 BTC) in its wallet. After the first run, the cache/ blockchain and wallets are copied into a temporary directory and used as the initial test state. If you get into a bad state, you should be able to recover with: ```bash rm -rf cache killall bitcoind ``` Writing tests ============= You are encouraged to write tests for new or existing features. -Further information about the test framework and individual rpc -tests is found in [qa/rpc-tests](/qa/rpc-tests). + +Further information about the test framework and individual RPC +tests is found in [test/rpc-tests](/test/rpc-tests). diff --git a/qa/pull-tester/rpc-tests.py b/test/pull-tester/rpc-tests.py similarity index 96% rename from qa/pull-tester/rpc-tests.py rename to test/pull-tester/rpc-tests.py index 5f5a92c0b..bd1de73f9 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/test/pull-tester/rpc-tests.py @@ -1,426 +1,425 @@ #!/usr/bin/env python3 # Copyright (c) 2014-2016 The Bitcoin Core developers # Copyright (c) 2017 The Bitcoin developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """ rpc-tests.py - run regression test suite This module calls down into individual test cases via subprocess. It will forward all unrecognized arguments onto the individual test scripts. RPC tests are disabled on Windows by default. Use --force to run them anyway. For a description of arguments recognized by test scripts, see -`qa/pull-tester/test_framework/test_framework.py:BitcoinTestFramework.main`. +`test/pull-tester/test_framework/test_framework.py:BitcoinTestFramework.main`. """ import argparse import configparser import os import time import shutil import sys import subprocess import tempfile import re BOLD = ("", "") RED = ("", "") GREEN = ("", "") if os.name == 'posix': # primitive formatting on supported # terminal via ANSI escape sequences: BOLD = ('\033[0m', '\033[1m') RED = ("\033[0m", "\033[31m") GREEN = ("\033[0m", "\033[32m") BASE_SCRIPTS = [ # Longest test should go first, to favor running tests in parallel 'wallet-hd.py', 'walletbackup.py', # vv Tests less than 5m vv 'p2p-fullblocktest.py', 'fundrawtransaction.py', 'p2p-compactblocks.py', # vv Tests less than 2m vv 'wallet.py', 'wallet-accounts.py', 'wallet-dump.py', 'listtransactions.py', # vv Tests less than 60s vv 'sendheaders.py', 'zapwallettxes.py', 'importmulti.py', 'mempool_limit.py', 'merkle_blocks.py', 'receivedby.py', 'abandonconflict.py', 'bip68-112-113-p2p.py', 'rawtransactions.py', 'reindex.py', # vv Tests less than 30s vv 'mempool_resurrect_test.py', 'txn_doublespend.py --mineblock', 'txn_clone.py', 'getchaintips.py', 'rest.py', 'mempool_spendcoinbase.py', 'mempool_reorg.py', 'httpbasics.py', 'multi_rpc.py', 'proxy_test.py', 'signrawtransactions.py', 'disconnect_ban.py', 'decodescript.py', 'blockchain.py', 'disablewallet.py', 'keypool.py', 'p2p-mempool.py', 'prioritise_transaction.py', 'high_priority_transaction.py', 'invalidblockrequest.py', 'invalidtxrequest.py', 'p2p-versionbits-warning.py', 'preciousblock.py', 'importprunedfunds.py', 'signmessages.py', 'nulldummy.py', 'import-rescan.py', 'rpcnamedargs.py', 'listsinceblock.py', 'p2p-leaktests.py', 'abc-cmdline.py', 'abc-p2p-fullblocktest.py', 'abc-rpc.py', 'mempool-accept-txn.py', ] ZMQ_SCRIPTS = [ # ZMQ test can only be run if bitcoin was built with zmq-enabled. # call rpc_tests.py with -nozmq to explicitly exclude these tests. "zmq_test.py"] EXTENDED_SCRIPTS = [ # Longest test should go first, to favor running tests in parallel 'pruning.py', # vv Tests less than 20m vv 'smartfees.py', # vv Tests less than 5m vv 'maxuploadtarget.py', 'mempool_packages.py', # vv Tests less than 2m vv 'bip68-sequence.py', 'getblocktemplate_longpoll.py', 'p2p-timeouts.py', # vv Tests less than 60s vv 'bip9-softforks.py', 'p2p-feefilter.py', 'rpcbind_test.py', # vv Tests less than 30s vv 'bip65-cltv.py', 'bip65-cltv-p2p.py', 'bipdersig-p2p.py', 'bipdersig.py', 'getblocktemplate_proposals.py', 'txn_doublespend.py', 'txn_clone.py --mineblock', 'forknotify.py', 'invalidateblock.py', 'maxblocksinflight.py', 'p2p-acceptblock.py', ] ALL_SCRIPTS = BASE_SCRIPTS + ZMQ_SCRIPTS + EXTENDED_SCRIPTS def main(): # Parse arguments and pass through unrecognised args parser = argparse.ArgumentParser(add_help=False, usage='%(prog)s [rpc-test.py options] [script options] [scripts]', description=__doc__, epilog=''' Help text and arguments for individual test script:''', formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface') parser.add_argument( '--exclude', '-x', help='specify a comma-seperated-list of scripts to exclude. Do not include the .py extension in the name.') parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests') parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).') parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit') parser.add_argument('--jobs', '-j', type=int, default=4, help='how many test scripts to run in parallel. Default=4.') parser.add_argument('--nozmq', action='store_true', help='do not run the zmq tests') args, unknown_args = parser.parse_known_args() # Create a set to store arguments and create the passon string tests = set(arg for arg in unknown_args if arg[:2] != "--") passon_args = [arg for arg in unknown_args if arg[:2] == "--"] # Read config generated by configure. config = configparser.ConfigParser() config.read_file(open(os.path.dirname(__file__) + "/tests_config.ini")) enable_wallet = config["components"].getboolean("ENABLE_WALLET") enable_utils = config["components"].getboolean("ENABLE_UTILS") enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") enable_zmq = config["components"].getboolean( "ENABLE_ZMQ") and not args.nozmq if config["environment"]["EXEEXT"] == ".exe" and not args.force: # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 print( "Tests currently disabled on Windows by default. Use --force option to enable") sys.exit(0) if not (enable_wallet and enable_utils and enable_bitcoind): print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") sys.exit(0) # python3-zmq may not be installed. Handle this gracefully and with some helpful info if enable_zmq: try: import zmq except ImportError: print("ERROR: \"import zmq\" failed. Use -nozmq to run without the ZMQ tests." - "To run zmq tests, see dependency info in /qa/README.md.") + "To run zmq tests, see dependency info in /test/README.md.") raise # Build list of tests if tests: # Individual tests have been specified. Run specified tests that exist # in the ALL_SCRIPTS list. Accept the name with or without .py extension. test_list = [t for t in ALL_SCRIPTS if (t in tests or re.sub(".py$", "", t) in tests)] else: # No individual tests have been specified. Run base tests, and # optionally ZMQ tests and extended tests. test_list = BASE_SCRIPTS if enable_zmq: test_list += ZMQ_SCRIPTS if args.extended: test_list += EXTENDED_SCRIPTS # TODO: BASE_SCRIPTS and EXTENDED_SCRIPTS are sorted by runtime # (for parallel running efficiency). This combined list will is no # longer sorted. # Remove the test cases that the user has explicitly asked to exclude. if args.exclude: for exclude_test in args.exclude.split(','): if exclude_test + ".py" in test_list: test_list.remove(exclude_test + ".py") if not test_list: print("No valid test scripts specified. Check that your test is in one " "of the test lists in rpc-tests.py, or run rpc-tests.py with no arguments to run all tests") sys.exit(0) if args.help: # Print help for rpc-tests.py, then print help of the first script and exit. parser.print_help() subprocess.check_call( - (config["environment"]["SRCDIR"] + '/qa/rpc-tests/' + test_list[0]).split() + ['-h']) + (config["environment"]["SRCDIR"] + '/test/rpc-tests/' + test_list[0]).split() + ['-h']) sys.exit(0) run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], args.jobs, args.coverage, passon_args) def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=False, args=[]): # Set env vars if "BITCOIND" not in os.environ: os.environ["BITCOIND"] = build_dir + '/src/bitcoind' + exeext - tests_dir = src_dir + '/qa/rpc-tests/' - - flags = ["--srcdir=" + src_dir] + args - flags.append("--cachedir={}/qa/cache".format(build_dir)) + tests_dir = src_dir + '/test/rpc-tests/' + flags = ["--srcdir={}".format(src_dir)] + args + flags.append("--cachedir=%s/test/cache" % build_dir) if enable_coverage: coverage = RPCCoverage() flags.append(coverage.flag) print("Initializing coverage directory at {dir}\n".format( dir=coverage.dir)) else: coverage = None if len(test_list) > 1 and jobs > 1: # Populate cache subprocess.check_output([tests_dir + 'create_cache.py'] + flags) # Run Tests all_passed = True time_sum = 0 time0 = time.time() job_queue = RPCTestHandler(jobs, tests_dir, test_list, flags) max_len_name = len(max(test_list, key=len)) results = BOLD[1] + "%s | %s | %s\n\n" % ( "TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] for _ in range(len(test_list)): (name, stdout, stderr, passed, duration) = job_queue.get_next() all_passed = all_passed and passed time_sum += duration print('\n' + BOLD[1] + name + BOLD[0] + ":") print('' if passed else stdout + '\n', end='') print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') print("Pass: {bold}{result}{unbold}, Duration: {duration}s\n".format( bold=BOLD[1], result=passed, unbold=BOLD[0], duration=duration)) result = "{name} | {passed} | {duration}s\n".format(name=name.ljust( max_len_name), passed=str(passed).ljust(6), duration=duration) if passed: results += GREEN[1] + result + GREEN[0] else: results += RED[1] + result + RED[0] results += BOLD[1] + "\n{name} | {passed} | {duration}s (accumulated)".format( name="ALL".ljust(max_len_name), passed=str(all_passed).ljust(6), duration=time_sum) + BOLD[0] print(results) print("\nRuntime: {} s".format(int(time.time() - time0))) if coverage: coverage.report_rpc_coverage() print("Cleaning up coverage data") coverage.cleanup() sys.exit(not all_passed) class RPCTestHandler: """ Trigger the testscrips passed in via the list. """ def __init__(self, num_tests_parallel, tests_dir, test_list=None, flags=None): assert(num_tests_parallel >= 1) self.num_jobs = num_tests_parallel self.tests_dir = tests_dir self.test_list = test_list self.flags = flags self.num_running = 0 # In case there is a graveyard of zombie bitcoinds, we can apply a # pseudorandom offset to hopefully jump over them. # (625 is PORT_RANGE/MAX_NODES) self.portseed_offset = int(time.time() * 1000) % 625 self.jobs = [] def get_next(self): while self.num_running < self.num_jobs and self.test_list: # Add tests self.num_running += 1 t = self.test_list.pop(0) port_seed = ["--portseed={}".format( len(self.test_list) + self.portseed_offset)] log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16) log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) self.jobs.append((t, time.time(), subprocess.Popen((self.tests_dir + t).split() + self.flags + port_seed, universal_newlines=True, stdout=log_stdout, stderr=log_stderr), log_stdout, log_stderr)) if not self.jobs: raise IndexError('pop from empty list') while True: # Return first proc that finishes time.sleep(.5) for j in self.jobs: (name, time0, proc, log_out, log_err) = j if proc.poll() is not None: log_out.seek(0), log_err.seek(0) [stdout, stderr] = [l.read().decode('utf-8') for l in (log_out, log_err)] log_out.close(), log_err.close() passed = stderr == "" and proc.returncode == 0 self.num_running -= 1 self.jobs.remove(j) return name, stdout, stderr, passed, int( time.time() - time0) print('.', end='', flush=True) class RPCCoverage(object): """ Coverage reporting utilities for pull-tester. Coverage calculation works by having each test script subprocess write coverage files into a particular directory. These files contain the RPC commands invoked during testing, as well as a complete listing of RPC commands per `bitcoin-cli help` (`rpc_interface.txt`). After all tests complete, the commands run are combined and diff'd against the complete list to calculate uncovered RPC commands. - See also: qa/rpc-tests/test_framework/coverage.py + See also: test/rpc-tests/test_framework/coverage.py """ def __init__(self): self.dir = tempfile.mkdtemp(prefix="coverage") self.flag = '--coveragedir={}'.format(self.dir) def report_rpc_coverage(self): """ Print out RPC commands that were unexercised by tests. """ uncovered = self._get_uncovered_rpc_commands() if uncovered: print("Uncovered RPC commands:") print("".join((" - {}\n".format(i)) for i in sorted(uncovered))) else: print("All RPC commands covered.") def cleanup(self): return shutil.rmtree(self.dir) def _get_uncovered_rpc_commands(self): """ Return a set of currently untested RPC commands. """ - # This is shared from `qa/rpc-tests/test-framework/coverage.py` + # This is shared from `test/rpc-tests/test-framework/coverage.py` reference_filename = 'rpc_interface.txt' coverage_file_prefix = 'coverage.' coverage_ref_filename = os.path.join(self.dir, reference_filename) coverage_filenames = set() all_cmds = set() covered_cmds = set() if not os.path.isfile(coverage_ref_filename): raise RuntimeError("No coverage reference found") with open(coverage_ref_filename, 'r') as f: all_cmds.update([i.strip() for i in f.readlines()]) for root, dirs, files in os.walk(self.dir): for filename in files: if filename.startswith(coverage_file_prefix): coverage_filenames.add(os.path.join(root, filename)) for filename in coverage_filenames: with open(filename, 'r') as f: covered_cmds.update([i.strip() for i in f.readlines()]) return all_cmds - covered_cmds if __name__ == '__main__': main() diff --git a/qa/pull-tester/tests_config.ini.in b/test/pull-tester/tests_config.ini.in similarity index 100% rename from qa/pull-tester/tests_config.ini.in rename to test/pull-tester/tests_config.ini.in diff --git a/qa/rpc-tests/.gitignore b/test/rpc-tests/.gitignore similarity index 100% rename from qa/rpc-tests/.gitignore rename to test/rpc-tests/.gitignore diff --git a/qa/rpc-tests/README.md b/test/rpc-tests/README.md similarity index 100% rename from qa/rpc-tests/README.md rename to test/rpc-tests/README.md diff --git a/qa/rpc-tests/abandonconflict.py b/test/rpc-tests/abandonconflict.py similarity index 100% rename from qa/rpc-tests/abandonconflict.py rename to test/rpc-tests/abandonconflict.py diff --git a/qa/rpc-tests/abc-cmdline.py b/test/rpc-tests/abc-cmdline.py similarity index 100% rename from qa/rpc-tests/abc-cmdline.py rename to test/rpc-tests/abc-cmdline.py diff --git a/qa/rpc-tests/abc-p2p-fullblocktest.py b/test/rpc-tests/abc-p2p-fullblocktest.py similarity index 100% rename from qa/rpc-tests/abc-p2p-fullblocktest.py rename to test/rpc-tests/abc-p2p-fullblocktest.py diff --git a/qa/rpc-tests/abc-rpc.py b/test/rpc-tests/abc-rpc.py similarity index 100% rename from qa/rpc-tests/abc-rpc.py rename to test/rpc-tests/abc-rpc.py diff --git a/qa/rpc-tests/assumevalid.py b/test/rpc-tests/assumevalid.py similarity index 100% rename from qa/rpc-tests/assumevalid.py rename to test/rpc-tests/assumevalid.py diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/test/rpc-tests/bip65-cltv-p2p.py similarity index 100% rename from qa/rpc-tests/bip65-cltv-p2p.py rename to test/rpc-tests/bip65-cltv-p2p.py diff --git a/qa/rpc-tests/bip65-cltv.py b/test/rpc-tests/bip65-cltv.py similarity index 100% rename from qa/rpc-tests/bip65-cltv.py rename to test/rpc-tests/bip65-cltv.py diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/test/rpc-tests/bip68-112-113-p2p.py similarity index 100% rename from qa/rpc-tests/bip68-112-113-p2p.py rename to test/rpc-tests/bip68-112-113-p2p.py diff --git a/qa/rpc-tests/bip68-sequence.py b/test/rpc-tests/bip68-sequence.py similarity index 100% rename from qa/rpc-tests/bip68-sequence.py rename to test/rpc-tests/bip68-sequence.py diff --git a/qa/rpc-tests/bip9-softforks.py b/test/rpc-tests/bip9-softforks.py similarity index 100% rename from qa/rpc-tests/bip9-softforks.py rename to test/rpc-tests/bip9-softforks.py diff --git a/qa/rpc-tests/bipdersig-p2p.py b/test/rpc-tests/bipdersig-p2p.py similarity index 100% rename from qa/rpc-tests/bipdersig-p2p.py rename to test/rpc-tests/bipdersig-p2p.py diff --git a/qa/rpc-tests/bipdersig.py b/test/rpc-tests/bipdersig.py similarity index 100% rename from qa/rpc-tests/bipdersig.py rename to test/rpc-tests/bipdersig.py diff --git a/qa/rpc-tests/blockchain.py b/test/rpc-tests/blockchain.py similarity index 100% rename from qa/rpc-tests/blockchain.py rename to test/rpc-tests/blockchain.py diff --git a/qa/rpc-tests/create_cache.py b/test/rpc-tests/create_cache.py similarity index 100% rename from qa/rpc-tests/create_cache.py rename to test/rpc-tests/create_cache.py diff --git a/qa/rpc-tests/decodescript.py b/test/rpc-tests/decodescript.py similarity index 100% rename from qa/rpc-tests/decodescript.py rename to test/rpc-tests/decodescript.py diff --git a/qa/rpc-tests/disablewallet.py b/test/rpc-tests/disablewallet.py similarity index 100% rename from qa/rpc-tests/disablewallet.py rename to test/rpc-tests/disablewallet.py diff --git a/qa/rpc-tests/disconnect_ban.py b/test/rpc-tests/disconnect_ban.py similarity index 100% rename from qa/rpc-tests/disconnect_ban.py rename to test/rpc-tests/disconnect_ban.py diff --git a/qa/rpc-tests/forknotify.py b/test/rpc-tests/forknotify.py similarity index 100% rename from qa/rpc-tests/forknotify.py rename to test/rpc-tests/forknotify.py diff --git a/qa/rpc-tests/fundrawtransaction.py b/test/rpc-tests/fundrawtransaction.py similarity index 100% rename from qa/rpc-tests/fundrawtransaction.py rename to test/rpc-tests/fundrawtransaction.py diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/test/rpc-tests/getblocktemplate_longpoll.py similarity index 100% rename from qa/rpc-tests/getblocktemplate_longpoll.py rename to test/rpc-tests/getblocktemplate_longpoll.py diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/test/rpc-tests/getblocktemplate_proposals.py similarity index 100% rename from qa/rpc-tests/getblocktemplate_proposals.py rename to test/rpc-tests/getblocktemplate_proposals.py diff --git a/qa/rpc-tests/getchaintips.py b/test/rpc-tests/getchaintips.py similarity index 100% rename from qa/rpc-tests/getchaintips.py rename to test/rpc-tests/getchaintips.py diff --git a/qa/rpc-tests/high_priority_transaction.py b/test/rpc-tests/high_priority_transaction.py similarity index 100% rename from qa/rpc-tests/high_priority_transaction.py rename to test/rpc-tests/high_priority_transaction.py diff --git a/qa/rpc-tests/httpbasics.py b/test/rpc-tests/httpbasics.py similarity index 100% rename from qa/rpc-tests/httpbasics.py rename to test/rpc-tests/httpbasics.py diff --git a/qa/rpc-tests/import-rescan.py b/test/rpc-tests/import-rescan.py similarity index 100% rename from qa/rpc-tests/import-rescan.py rename to test/rpc-tests/import-rescan.py diff --git a/qa/rpc-tests/importmulti.py b/test/rpc-tests/importmulti.py similarity index 100% rename from qa/rpc-tests/importmulti.py rename to test/rpc-tests/importmulti.py diff --git a/qa/rpc-tests/importprunedfunds.py b/test/rpc-tests/importprunedfunds.py similarity index 100% rename from qa/rpc-tests/importprunedfunds.py rename to test/rpc-tests/importprunedfunds.py diff --git a/qa/rpc-tests/invalidateblock.py b/test/rpc-tests/invalidateblock.py similarity index 100% rename from qa/rpc-tests/invalidateblock.py rename to test/rpc-tests/invalidateblock.py diff --git a/qa/rpc-tests/invalidblockrequest.py b/test/rpc-tests/invalidblockrequest.py similarity index 100% rename from qa/rpc-tests/invalidblockrequest.py rename to test/rpc-tests/invalidblockrequest.py diff --git a/qa/rpc-tests/invalidtxrequest.py b/test/rpc-tests/invalidtxrequest.py similarity index 100% rename from qa/rpc-tests/invalidtxrequest.py rename to test/rpc-tests/invalidtxrequest.py diff --git a/qa/rpc-tests/keypool.py b/test/rpc-tests/keypool.py similarity index 100% rename from qa/rpc-tests/keypool.py rename to test/rpc-tests/keypool.py diff --git a/qa/rpc-tests/listsinceblock.py b/test/rpc-tests/listsinceblock.py similarity index 100% rename from qa/rpc-tests/listsinceblock.py rename to test/rpc-tests/listsinceblock.py diff --git a/qa/rpc-tests/listtransactions.py b/test/rpc-tests/listtransactions.py similarity index 100% rename from qa/rpc-tests/listtransactions.py rename to test/rpc-tests/listtransactions.py diff --git a/qa/rpc-tests/maxblocksinflight.py b/test/rpc-tests/maxblocksinflight.py similarity index 100% rename from qa/rpc-tests/maxblocksinflight.py rename to test/rpc-tests/maxblocksinflight.py diff --git a/qa/rpc-tests/maxuploadtarget.py b/test/rpc-tests/maxuploadtarget.py similarity index 100% rename from qa/rpc-tests/maxuploadtarget.py rename to test/rpc-tests/maxuploadtarget.py diff --git a/qa/rpc-tests/mempool-accept-txn.py b/test/rpc-tests/mempool-accept-txn.py similarity index 100% rename from qa/rpc-tests/mempool-accept-txn.py rename to test/rpc-tests/mempool-accept-txn.py diff --git a/qa/rpc-tests/mempool_limit.py b/test/rpc-tests/mempool_limit.py similarity index 100% rename from qa/rpc-tests/mempool_limit.py rename to test/rpc-tests/mempool_limit.py diff --git a/qa/rpc-tests/mempool_packages.py b/test/rpc-tests/mempool_packages.py similarity index 100% rename from qa/rpc-tests/mempool_packages.py rename to test/rpc-tests/mempool_packages.py diff --git a/qa/rpc-tests/mempool_reorg.py b/test/rpc-tests/mempool_reorg.py similarity index 100% rename from qa/rpc-tests/mempool_reorg.py rename to test/rpc-tests/mempool_reorg.py diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/test/rpc-tests/mempool_resurrect_test.py similarity index 100% rename from qa/rpc-tests/mempool_resurrect_test.py rename to test/rpc-tests/mempool_resurrect_test.py diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/test/rpc-tests/mempool_spendcoinbase.py similarity index 100% rename from qa/rpc-tests/mempool_spendcoinbase.py rename to test/rpc-tests/mempool_spendcoinbase.py diff --git a/qa/rpc-tests/merkle_blocks.py b/test/rpc-tests/merkle_blocks.py similarity index 100% rename from qa/rpc-tests/merkle_blocks.py rename to test/rpc-tests/merkle_blocks.py diff --git a/qa/rpc-tests/multi_rpc.py b/test/rpc-tests/multi_rpc.py similarity index 100% rename from qa/rpc-tests/multi_rpc.py rename to test/rpc-tests/multi_rpc.py diff --git a/qa/rpc-tests/nulldummy.py b/test/rpc-tests/nulldummy.py similarity index 100% rename from qa/rpc-tests/nulldummy.py rename to test/rpc-tests/nulldummy.py diff --git a/qa/rpc-tests/p2p-acceptblock.py b/test/rpc-tests/p2p-acceptblock.py similarity index 100% rename from qa/rpc-tests/p2p-acceptblock.py rename to test/rpc-tests/p2p-acceptblock.py diff --git a/qa/rpc-tests/p2p-compactblocks.py b/test/rpc-tests/p2p-compactblocks.py similarity index 100% rename from qa/rpc-tests/p2p-compactblocks.py rename to test/rpc-tests/p2p-compactblocks.py diff --git a/qa/rpc-tests/p2p-feefilter.py b/test/rpc-tests/p2p-feefilter.py similarity index 100% rename from qa/rpc-tests/p2p-feefilter.py rename to test/rpc-tests/p2p-feefilter.py diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/test/rpc-tests/p2p-fullblocktest.py similarity index 100% rename from qa/rpc-tests/p2p-fullblocktest.py rename to test/rpc-tests/p2p-fullblocktest.py diff --git a/qa/rpc-tests/p2p-leaktests.py b/test/rpc-tests/p2p-leaktests.py similarity index 100% rename from qa/rpc-tests/p2p-leaktests.py rename to test/rpc-tests/p2p-leaktests.py diff --git a/qa/rpc-tests/p2p-mempool.py b/test/rpc-tests/p2p-mempool.py similarity index 100% rename from qa/rpc-tests/p2p-mempool.py rename to test/rpc-tests/p2p-mempool.py diff --git a/qa/rpc-tests/p2p-timeouts.py b/test/rpc-tests/p2p-timeouts.py similarity index 100% rename from qa/rpc-tests/p2p-timeouts.py rename to test/rpc-tests/p2p-timeouts.py diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/test/rpc-tests/p2p-versionbits-warning.py similarity index 100% rename from qa/rpc-tests/p2p-versionbits-warning.py rename to test/rpc-tests/p2p-versionbits-warning.py diff --git a/qa/rpc-tests/preciousblock.py b/test/rpc-tests/preciousblock.py similarity index 100% rename from qa/rpc-tests/preciousblock.py rename to test/rpc-tests/preciousblock.py diff --git a/qa/rpc-tests/prioritise_transaction.py b/test/rpc-tests/prioritise_transaction.py similarity index 100% rename from qa/rpc-tests/prioritise_transaction.py rename to test/rpc-tests/prioritise_transaction.py diff --git a/qa/rpc-tests/proxy_test.py b/test/rpc-tests/proxy_test.py similarity index 100% rename from qa/rpc-tests/proxy_test.py rename to test/rpc-tests/proxy_test.py diff --git a/qa/rpc-tests/pruning.py b/test/rpc-tests/pruning.py similarity index 100% rename from qa/rpc-tests/pruning.py rename to test/rpc-tests/pruning.py diff --git a/qa/rpc-tests/rawtransactions.py b/test/rpc-tests/rawtransactions.py similarity index 100% rename from qa/rpc-tests/rawtransactions.py rename to test/rpc-tests/rawtransactions.py diff --git a/qa/rpc-tests/receivedby.py b/test/rpc-tests/receivedby.py similarity index 100% rename from qa/rpc-tests/receivedby.py rename to test/rpc-tests/receivedby.py diff --git a/qa/rpc-tests/reindex.py b/test/rpc-tests/reindex.py similarity index 100% rename from qa/rpc-tests/reindex.py rename to test/rpc-tests/reindex.py diff --git a/qa/rpc-tests/rest.py b/test/rpc-tests/rest.py similarity index 100% rename from qa/rpc-tests/rest.py rename to test/rpc-tests/rest.py diff --git a/qa/rpc-tests/rpcbind_test.py b/test/rpc-tests/rpcbind_test.py similarity index 100% rename from qa/rpc-tests/rpcbind_test.py rename to test/rpc-tests/rpcbind_test.py diff --git a/qa/rpc-tests/rpcnamedargs.py b/test/rpc-tests/rpcnamedargs.py similarity index 100% rename from qa/rpc-tests/rpcnamedargs.py rename to test/rpc-tests/rpcnamedargs.py diff --git a/qa/rpc-tests/sendheaders.py b/test/rpc-tests/sendheaders.py similarity index 100% rename from qa/rpc-tests/sendheaders.py rename to test/rpc-tests/sendheaders.py diff --git a/qa/rpc-tests/signmessages.py b/test/rpc-tests/signmessages.py similarity index 100% rename from qa/rpc-tests/signmessages.py rename to test/rpc-tests/signmessages.py diff --git a/qa/rpc-tests/signrawtransactions.py b/test/rpc-tests/signrawtransactions.py similarity index 100% rename from qa/rpc-tests/signrawtransactions.py rename to test/rpc-tests/signrawtransactions.py diff --git a/qa/rpc-tests/smartfees.py b/test/rpc-tests/smartfees.py similarity index 100% rename from qa/rpc-tests/smartfees.py rename to test/rpc-tests/smartfees.py diff --git a/qa/rpc-tests/test_framework/__init__.py b/test/rpc-tests/test_framework/__init__.py similarity index 100% rename from qa/rpc-tests/test_framework/__init__.py rename to test/rpc-tests/test_framework/__init__.py diff --git a/qa/rpc-tests/test_framework/address.py b/test/rpc-tests/test_framework/address.py similarity index 100% rename from qa/rpc-tests/test_framework/address.py rename to test/rpc-tests/test_framework/address.py diff --git a/qa/rpc-tests/test_framework/authproxy.py b/test/rpc-tests/test_framework/authproxy.py similarity index 100% rename from qa/rpc-tests/test_framework/authproxy.py rename to test/rpc-tests/test_framework/authproxy.py diff --git a/qa/rpc-tests/test_framework/bignum.py b/test/rpc-tests/test_framework/bignum.py similarity index 100% rename from qa/rpc-tests/test_framework/bignum.py rename to test/rpc-tests/test_framework/bignum.py diff --git a/qa/rpc-tests/test_framework/blockstore.py b/test/rpc-tests/test_framework/blockstore.py similarity index 100% rename from qa/rpc-tests/test_framework/blockstore.py rename to test/rpc-tests/test_framework/blockstore.py diff --git a/qa/rpc-tests/test_framework/blocktools.py b/test/rpc-tests/test_framework/blocktools.py similarity index 100% rename from qa/rpc-tests/test_framework/blocktools.py rename to test/rpc-tests/test_framework/blocktools.py diff --git a/qa/rpc-tests/test_framework/cdefs.py b/test/rpc-tests/test_framework/cdefs.py similarity index 100% rename from qa/rpc-tests/test_framework/cdefs.py rename to test/rpc-tests/test_framework/cdefs.py diff --git a/qa/rpc-tests/test_framework/comptool.py b/test/rpc-tests/test_framework/comptool.py similarity index 100% rename from qa/rpc-tests/test_framework/comptool.py rename to test/rpc-tests/test_framework/comptool.py diff --git a/qa/rpc-tests/test_framework/coverage.py b/test/rpc-tests/test_framework/coverage.py similarity index 100% rename from qa/rpc-tests/test_framework/coverage.py rename to test/rpc-tests/test_framework/coverage.py diff --git a/qa/rpc-tests/test_framework/key.py b/test/rpc-tests/test_framework/key.py similarity index 100% rename from qa/rpc-tests/test_framework/key.py rename to test/rpc-tests/test_framework/key.py diff --git a/qa/rpc-tests/test_framework/mininode.py b/test/rpc-tests/test_framework/mininode.py similarity index 100% rename from qa/rpc-tests/test_framework/mininode.py rename to test/rpc-tests/test_framework/mininode.py diff --git a/qa/rpc-tests/test_framework/netutil.py b/test/rpc-tests/test_framework/netutil.py similarity index 100% rename from qa/rpc-tests/test_framework/netutil.py rename to test/rpc-tests/test_framework/netutil.py diff --git a/qa/rpc-tests/test_framework/outputchecker.py b/test/rpc-tests/test_framework/outputchecker.py similarity index 100% rename from qa/rpc-tests/test_framework/outputchecker.py rename to test/rpc-tests/test_framework/outputchecker.py diff --git a/qa/rpc-tests/test_framework/script.py b/test/rpc-tests/test_framework/script.py similarity index 100% rename from qa/rpc-tests/test_framework/script.py rename to test/rpc-tests/test_framework/script.py diff --git a/qa/rpc-tests/test_framework/siphash.py b/test/rpc-tests/test_framework/siphash.py similarity index 100% rename from qa/rpc-tests/test_framework/siphash.py rename to test/rpc-tests/test_framework/siphash.py diff --git a/qa/rpc-tests/test_framework/socks5.py b/test/rpc-tests/test_framework/socks5.py similarity index 100% rename from qa/rpc-tests/test_framework/socks5.py rename to test/rpc-tests/test_framework/socks5.py diff --git a/qa/rpc-tests/test_framework/test_framework.py b/test/rpc-tests/test_framework/test_framework.py similarity index 100% rename from qa/rpc-tests/test_framework/test_framework.py rename to test/rpc-tests/test_framework/test_framework.py diff --git a/qa/rpc-tests/test_framework/tests/README.md b/test/rpc-tests/test_framework/tests/README.md similarity index 100% rename from qa/rpc-tests/test_framework/tests/README.md rename to test/rpc-tests/test_framework/tests/README.md diff --git a/qa/rpc-tests/test_framework/tests/initialize_direct.py b/test/rpc-tests/test_framework/tests/initialize_direct.py similarity index 100% rename from qa/rpc-tests/test_framework/tests/initialize_direct.py rename to test/rpc-tests/test_framework/tests/initialize_direct.py diff --git a/qa/rpc-tests/test_framework/tests/run_self_tests.sh b/test/rpc-tests/test_framework/tests/run_self_tests.sh similarity index 100% rename from qa/rpc-tests/test_framework/tests/run_self_tests.sh rename to test/rpc-tests/test_framework/tests/run_self_tests.sh diff --git a/qa/rpc-tests/test_framework/tests/simple-initialize-chain.py b/test/rpc-tests/test_framework/tests/simple-initialize-chain.py similarity index 100% rename from qa/rpc-tests/test_framework/tests/simple-initialize-chain.py rename to test/rpc-tests/test_framework/tests/simple-initialize-chain.py diff --git a/qa/rpc-tests/test_framework/util.py b/test/rpc-tests/test_framework/util.py similarity index 100% rename from qa/rpc-tests/test_framework/util.py rename to test/rpc-tests/test_framework/util.py diff --git a/qa/rpc-tests/txn_clone.py b/test/rpc-tests/txn_clone.py similarity index 100% rename from qa/rpc-tests/txn_clone.py rename to test/rpc-tests/txn_clone.py diff --git a/qa/rpc-tests/txn_doublespend.py b/test/rpc-tests/txn_doublespend.py similarity index 100% rename from qa/rpc-tests/txn_doublespend.py rename to test/rpc-tests/txn_doublespend.py diff --git a/qa/rpc-tests/wallet-accounts.py b/test/rpc-tests/wallet-accounts.py similarity index 100% rename from qa/rpc-tests/wallet-accounts.py rename to test/rpc-tests/wallet-accounts.py diff --git a/qa/rpc-tests/wallet-dump.py b/test/rpc-tests/wallet-dump.py similarity index 100% rename from qa/rpc-tests/wallet-dump.py rename to test/rpc-tests/wallet-dump.py diff --git a/qa/rpc-tests/wallet-hd.py b/test/rpc-tests/wallet-hd.py similarity index 100% rename from qa/rpc-tests/wallet-hd.py rename to test/rpc-tests/wallet-hd.py diff --git a/qa/rpc-tests/wallet.py b/test/rpc-tests/wallet.py similarity index 100% rename from qa/rpc-tests/wallet.py rename to test/rpc-tests/wallet.py diff --git a/qa/rpc-tests/walletbackup.py b/test/rpc-tests/walletbackup.py similarity index 100% rename from qa/rpc-tests/walletbackup.py rename to test/rpc-tests/walletbackup.py diff --git a/qa/rpc-tests/zapwallettxes.py b/test/rpc-tests/zapwallettxes.py similarity index 100% rename from qa/rpc-tests/zapwallettxes.py rename to test/rpc-tests/zapwallettxes.py diff --git a/qa/rpc-tests/zmq_test.py b/test/rpc-tests/zmq_test.py similarity index 100% rename from qa/rpc-tests/zmq_test.py rename to test/rpc-tests/zmq_test.py