diff --git a/build-aux/m4/dogecoin_find_bdb53.m4 b/build-aux/m4/dogecoin_find_bdb53.m4 index c04c43463..47792f6f4 100644 --- a/build-aux/m4/dogecoin_find_bdb53.m4 +++ b/build-aux/m4/dogecoin_find_bdb53.m4 @@ -1,66 +1,80 @@ +dnl Copyright (c) 2013-2017 The Bitcoin Core developers +dnl Copyright (c) 2021 The Dogecoin Core developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. + AC_DEFUN([BITCOIN_FIND_BDB53],[ - AC_MSG_CHECKING([for Berkeley DB C++ headers]) - BDB_CPPFLAGS= - BDB_LIBS= - bdbpath=X - bdb53path=X - bdbdirlist= - for _vn in 5.3 53 5 ''; do - for _pfx in b lib ''; do - bdbdirlist="$bdbdirlist ${_pfx}db${_vn}" + AC_ARG_VAR([BDB_CFLAGS], [C compiler flags for BerkeleyDB, bypasses autodetection]) + AC_ARG_VAR([BDB_LIBS], [Linker flags for BerkeleyDB, bypasses autodetection]) + + if test "$BDB_CFLAGS" = ""; then + AC_MSG_CHECKING([for Berkeley DB C++ headers]) + BDB_CPPFLAGS= + BDB_LIBS= + bdbpath=X + bdb53path=X + bdbdirlist= + for _vn in 5.3 53 5 ''; do + for _pfx in b lib ''; do + bdbdirlist="$bdbdirlist ${_pfx}db${_vn}" + done done - done - for searchpath in $bdbdirlist ''; do - test -n "${searchpath}" && searchpath="${searchpath}/" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include <${searchpath}db_cxx.h> - ]],[[ - #if !((DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 3) || DB_VERSION_MAJOR > 5) - #error "failed to find bdb 5.3+" - #endif - ]])],[ - if test "x$bdbpath" = "xX"; then - bdbpath="${searchpath}" - fi - ],[ - continue - ]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include <${searchpath}db_cxx.h> - ]],[[ - #if !(DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR == 3) - #error "failed to find bdb 5.3" - #endif - ]])],[ - bdb53path="${searchpath}" - break - ],[]) - done - if test "x$bdbpath" = "xX"; then - AC_MSG_RESULT([no]) - AC_MSG_ERROR([libdb_cxx headers missing, Dogecoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) - elif test "x$bdb53path" = "xX"; then - BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx) - AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[ - AC_MSG_WARN([Found Berkeley DB other than 5.3; wallets opened by this build will not be portable!]) - ],[ - AC_MSG_ERROR([Found Berkeley DB other than 5.3, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)]) - ]) + for searchpath in $bdbdirlist ''; do + test -n "${searchpath}" && searchpath="${searchpath}/" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <${searchpath}db_cxx.h> + ]],[[ + #if !((DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 3) || DB_VERSION_MAJOR > 5) + #error "failed to find bdb 5.3+" + #endif + ]])],[ + if test "x$bdbpath" = "xX"; then + bdbpath="${searchpath}" + fi + ],[ + continue + ]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <${searchpath}db_cxx.h> + ]],[[ + #if !(DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR == 3) + #error "failed to find bdb 5.3" + #endif + ]])],[ + bdb53path="${searchpath}" + break + ],[]) + done + if test "x$bdbpath" = "xX"; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([libdb_cxx headers missing, Dogecoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + elif test "x$bdb53path" = "xX"; then + BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx) + AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 5.3])],[ + AC_MSG_WARN([Found Berkeley DB other than 5.3; wallets opened by this build will not be portable!]) + ],[ + AC_MSG_ERROR([Found Berkeley DB other than 5.3, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)]) + ]) + else + BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb53path}],db_cxx) + bdbpath="${bdb53path}" + fi else - BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb53path}],db_cxx) - bdbpath="${bdb53path}" + BDB_CPPFLAGS=${BDB_CFLAGS} fi AC_SUBST(BDB_CPPFLAGS) - - # TODO: Ideally this could find the library version and make sure it matches the headers being used - for searchlib in db_cxx-5.3 db_cxx; do - AC_CHECK_LIB([$searchlib],[main],[ - BDB_LIBS="-l${searchlib}" - break - ]) - done - if test "x$BDB_LIBS" = "x"; then - AC_MSG_ERROR([libdb_cxx missing, Dogecoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + + if test "$BDB_LIBS" = ""; then + # TODO: Ideally this could find the library version and make sure it matches the headers being used + for searchlib in db_cxx-5.3 db_cxx; do + AC_CHECK_LIB([$searchlib],[main],[ + BDB_LIBS="-l${searchlib}" + break + ]) + done + if test "x$BDB_LIBS" = "x"; then + AC_MSG_ERROR([libdb_cxx missing, Dogecoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + fi fi AC_SUBST(BDB_LIBS) ]) diff --git a/contrib/install_db5.sh b/contrib/install_db5.sh new file mode 100755 index 000000000..c993ed680 --- /dev/null +++ b/contrib/install_db5.sh @@ -0,0 +1,260 @@ +#!/bin/sh +# Copyright (c) 2017-2021 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Install libdb5.3 (Berkeley DB). + +export LC_ALL=C +set -e + +if [ -z "${1}" ]; then + echo "Usage: $0 [ ...]" + echo + echo "Must specify a single argument: the directory in which db5 will be built." + echo "This is probably \`pwd\` if you're at the root of the dogecoin repository." + exit 1 +fi + +expand_path() { + cd "${1}" && pwd -P +} + +BDB_PREFIX="$(expand_path "${1}")/db5"; shift; +BDB_VERSION='db-5.3.28.NC' +BDB_HASH='76a25560d9e52a198d37a31440fd07632b5f1f8f9f2b6d5438f4bc3e7c9013ef' +BDB_URL="https://download.oracle.com/berkeley-db/${BDB_VERSION}.tar.gz" + +check_exists() { + command -v "$1" >/dev/null +} + +sha256_check() { + # Args: + # + if check_exists sha256sum; then + echo "${1} ${2}" | sha256sum -c + elif check_exists sha256; then + if [ "$(uname)" = "FreeBSD" ]; then + sha256 -c "${1}" "${2}" + else + echo "${1} ${2}" | sha256 -c + fi + else + echo "${1} ${2}" | shasum -a 256 -c + fi +} + +http_get() { + # Args: + # + # It's acceptable that we don't require SSL here because we manually verify + # content hashes below. + # + if [ -f "${2}" ]; then + echo "File ${2} already exists; not downloading again" + elif check_exists curl; then + curl --insecure --retry 5 "${1}" -o "${2}" + elif check_exists wget; then + wget --no-check-certificate "${1}" -O "${2}" + else + echo "Simple transfer utilities 'curl' and 'wget' not found. Please install one of them and try again." + exit 1 + fi + + sha256_check "${3}" "${2}" +} + +# Ensure the commands we use exist on the system +if ! check_exists patch; then + echo "Command-line tool 'patch' not found. Install patch and try again." + exit 1 +fi + +mkdir -p "${BDB_PREFIX}" +http_get "${BDB_URL}" "${BDB_VERSION}.tar.gz" "${BDB_HASH}" +tar -xzvf ${BDB_VERSION}.tar.gz -C "$BDB_PREFIX" +cd "${BDB_PREFIX}/${BDB_VERSION}/" + +# Apply a patch necessary when building with clang and c++11 (see https://community.oracle.com/thread/3952592) +patch --ignore-whitespace -p1 << 'EOF' +commit 3311d68f11d1697565401eee6efc85c34f022ea7 +Author: fanquake +Date: Mon Aug 17 20:03:56 2020 +0800 + + Fix C++11 compatibility + +diff --git a/src/dbinc/atomic.h b/src/dbinc/atomic.h +index 0034dcc..7c11d4a 100644 +--- a/src/dbinc/atomic.h ++++ b/src/dbinc/atomic.h +@@ -70,7 +70,7 @@ typedef struct { + * These have no memory barriers; the caller must include them when necessary. + */ + #define atomic_read(p) ((p)->value) +-#define atomic_init(p, val) ((p)->value = (val)) ++#define atomic_init_db(p, val) ((p)->value = (val)) + + #ifdef HAVE_ATOMIC_SUPPORT + +@@ -144,7 +144,7 @@ typedef LONG volatile *interlocked_val; + #define atomic_inc(env, p) __atomic_inc(p) + #define atomic_dec(env, p) __atomic_dec(p) + #define atomic_compare_exchange(env, p, o, n) \ +- __atomic_compare_exchange((p), (o), (n)) ++ __atomic_compare_exchange_db((p), (o), (n)) + static inline int __atomic_inc(db_atomic_t *p) + { + int temp; +@@ -176,7 +176,7 @@ static inline int __atomic_dec(db_atomic_t *p) + * http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html + * which configure could be changed to use. + */ +-static inline int __atomic_compare_exchange( ++static inline int __atomic_compare_exchange_db( + db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval) + { + atomic_value_t was; +@@ -206,7 +206,7 @@ static inline int __atomic_compare_exchange( + #define atomic_dec(env, p) (--(p)->value) + #define atomic_compare_exchange(env, p, oldval, newval) \ + (DB_ASSERT(env, atomic_read(p) == (oldval)), \ +- atomic_init(p, (newval)), 1) ++ atomic_init_db(p, (newval)), 1) + #else + #define atomic_inc(env, p) __atomic_inc(env, p) + #define atomic_dec(env, p) __atomic_dec(env, p) +diff --git a/src/mp/mp_fget.c b/src/mp/mp_fget.c +index 5fdee5a..0b75f57 100644 +--- a/src/mp/mp_fget.c ++++ b/src/mp/mp_fget.c +@@ -617,7 +617,7 @@ alloc: /* Allocate a new buffer header and data space. */ + + /* Initialize enough so we can call __memp_bhfree. */ + alloc_bhp->flags = 0; +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + #ifdef DIAGNOSTIC + if ((uintptr_t)alloc_bhp->buf & (sizeof(size_t) - 1)) { + __db_errx(env, +@@ -911,7 +911,7 @@ alloc: /* Allocate a new buffer header and data space. */ + MVCC_MPROTECT(bhp->buf, mfp->stat.st_pagesize, + PROT_READ); + +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + MUTEX_LOCK(env, alloc_bhp->mtx_buf); + alloc_bhp->priority = bhp->priority; + alloc_bhp->pgno = bhp->pgno; +diff --git a/src/mp/mp_mvcc.c b/src/mp/mp_mvcc.c +index 34467d2..f05aa0c 100644 +--- a/src/mp/mp_mvcc.c ++++ b/src/mp/mp_mvcc.c +@@ -276,7 +276,7 @@ __memp_bh_freeze(dbmp, infop, hp, bhp, need_frozenp) + #else + memcpy(frozen_bhp, bhp, SSZA(BH, buf)); + #endif +- atomic_init(&frozen_bhp->ref, 0); ++ atomic_init_db(&frozen_bhp->ref, 0); + if (mutex != MUTEX_INVALID) + frozen_bhp->mtx_buf = mutex; + else if ((ret = __mutex_alloc(env, MTX_MPOOL_BH, +@@ -428,7 +428,7 @@ __memp_bh_thaw(dbmp, infop, hp, frozen_bhp, alloc_bhp) + #endif + alloc_bhp->mtx_buf = mutex; + MUTEX_LOCK(env, alloc_bhp->mtx_buf); +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + F_CLR(alloc_bhp, BH_FROZEN); + } + +diff --git a/src/mp/mp_region.c b/src/mp/mp_region.c +index e6cece9..ddbe906 100644 +--- a/src/mp/mp_region.c ++++ b/src/mp/mp_region.c +@@ -224,7 +224,7 @@ __memp_init(env, dbmp, reginfo_off, htab_buckets, max_nreg) + MTX_MPOOL_FILE_BUCKET, 0, &htab[i].mtx_hash)) != 0) + return (ret); + SH_TAILQ_INIT(&htab[i].hash_bucket); +- atomic_init(&htab[i].hash_page_dirty, 0); ++ atomic_init_db(&htab[i].hash_page_dirty, 0); + } + + /* +@@ -269,7 +269,7 @@ __memp_init(env, dbmp, reginfo_off, htab_buckets, max_nreg) + hp->mtx_hash = (mtx_base == MUTEX_INVALID) ? MUTEX_INVALID : + mtx_base + i; + SH_TAILQ_INIT(&hp->hash_bucket); +- atomic_init(&hp->hash_page_dirty, 0); ++ atomic_init_db(&hp->hash_page_dirty, 0); + #ifdef HAVE_STATISTICS + hp->hash_io_wait = 0; + hp->hash_frozen = hp->hash_thawed = hp->hash_frozen_freed = 0; +diff --git a/src/mutex/mut_method.c b/src/mutex/mut_method.c +index 2588763..5c6d516 100644 +--- a/src/mutex/mut_method.c ++++ b/src/mutex/mut_method.c +@@ -426,7 +426,7 @@ atomic_compare_exchange(env, v, oldval, newval) + MUTEX_LOCK(env, mtx); + ret = atomic_read(v) == oldval; + if (ret) +- atomic_init(v, newval); ++ atomic_init_db(v, newval); + MUTEX_UNLOCK(env, mtx); + + return (ret); +diff --git a/src/mutex/mut_tas.c b/src/mutex/mut_tas.c +index f3922e0..e40fcdf 100644 +--- a/src/mutex/mut_tas.c ++++ b/src/mutex/mut_tas.c +@@ -46,7 +46,7 @@ __db_tas_mutex_init(env, mutex, flags) + + #ifdef HAVE_SHARED_LATCHES + if (F_ISSET(mutexp, DB_MUTEX_SHARED)) +- atomic_init(&mutexp->sharecount, 0); ++ atomic_init_db(&mutexp->sharecount, 0); + else + #endif + if (MUTEX_INIT(&mutexp->tas)) { +@@ -486,7 +486,7 @@ __db_tas_mutex_unlock(env, mutex) + F_CLR(mutexp, DB_MUTEX_LOCKED); + /* Flush flag update before zeroing count */ + MEMBAR_EXIT(); +- atomic_init(&mutexp->sharecount, 0); ++ atomic_init_db(&mutexp->sharecount, 0); + } else { + DB_ASSERT(env, sharecount > 0); + MEMBAR_EXIT(); +EOF + +# The packaged config.guess and config.sub are ancient (2009) and can cause build issues. +# Replace them with modern versions. +# See https://github.com/bitcoin/bitcoin/issues/16064 +CONFIG_GUESS_URL='https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=4550d2f15b3a7ce2451c1f29500b9339430c877f' +CONFIG_GUESS_HASH='c8f530e01840719871748a8071113435bdfdf75b74c57e78e47898edea8754ae' +CONFIG_SUB_URL='https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=4550d2f15b3a7ce2451c1f29500b9339430c877f' +CONFIG_SUB_HASH='3969f7d5f6967ccc6f792401b8ef3916a1d1b1d0f0de5a4e354c95addb8b800e' + +rm -f "dist/config.guess" +rm -f "dist/config.sub" + +http_get "${CONFIG_GUESS_URL}" dist/config.guess "${CONFIG_GUESS_HASH}" +http_get "${CONFIG_SUB_URL}" dist/config.sub "${CONFIG_SUB_HASH}" + +cd build_unix/ + +"${BDB_PREFIX}/${BDB_VERSION}/dist/configure" \ + --enable-cxx --disable-shared --disable-replication --with-pic --prefix="${BDB_PREFIX}" \ + "${@}" + +make install + +echo +echo "db5 build complete." +echo +# shellcheck disable=SC2016 +echo 'When compiling dogecoind, run `./configure` in the following way:' +echo +echo " export BDB_PREFIX='${BDB_PREFIX}'" +# shellcheck disable=SC2016 +echo ' ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-5.3" BDB_CFLAGS="-I${BDB_PREFIX}/include" ...' diff --git a/doc/build-unix.md b/doc/build-unix.md index 746e99ea6..48a92c545 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -106,39 +106,24 @@ Create `dogecoin-qt`, the core wallet GUI. ``` #### Wallet -BerkeleyDB is required for wallet functionality and use the `wallet.dat` file. +BerkeleyDB is required for wallet functionality and use of the `wallet.dat` file. -By default, **Dogecoin Core expect BerkeleyDB 5.3**. +By default, **Dogecoin Core expects BerkeleyDB 5.3**. You can use a different version by specifying `--with-incompatible-bdb` flag. -If no package is available for your distribution in optional dependencies, you can build BerkeleyDB from source : -```bash -# Install script for BerkeleyDB 5.3 +If you have to build it yourself, you can +use [the installation script included in contrib/](/contrib/install_db5.sh) +like so: -# BerkeleyDB installation directory -BDB_PREFIX=$(pwd)/bdb -mkdir $BDB_PREFIX - -# Fetch the source and verify shasum -wget 'http://download.oracle.com/berkeley-db/db-5.3.28.NC.tar.gz' -echo '76a25560d9e52a198d37a31440fd07632b5f1f8f9f2b6d5438f4bc3e7c9013ef db-5.3.28.NC.tar.gz' | sha256sum -c - -# Extract sources -tar -xzvf db-5.3.28.NC.tar.gz -cd db-5.3.28.NC/build_unix/ - -# Apply patch (see https://gist.github.com/danieldk/5700533) -sed -i 's/__atomic_compare_exchange/__atomic_compare_exchange_db/g' ../src/dbinc/atomic.h - -# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime -../dist/configure --prefix=$BDB_PREFIX --enable-cxx --disable-shared --with-pic -make install +```shell +./contrib/install_db5.sh `pwd` ``` -Then use `LDFLAGS` and `CPPFLAGS` during configuration to link the database : -```bash -./configure LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" -``` +from the root of the repository. + +Otherwise, you can build Dogecoin Core from self-compiled [depends](/depends/README.md). + +**Note**: You only need Berkeley DB if the wallet is enabled (see [*Disable-wallet mode*](#disable-wallet-mode)). #### Disable-wallet mode When the intention is to run only a P2P node without a wallet, Dogecoin may be compiled in