From af9103eb75182f51a987e7c35fa3eae61c58d010 Mon Sep 17 00:00:00 2001
From: James O'Beirne <james.obeirne@gmail.com>
Date: Wed, 15 Nov 2017 20:26:02 -0800
Subject: [PATCH 1/2] [build] Add a script for installing db4

Instead of maintaining not-easily-tested instructions for building BerkeleyDB
in doc/build-unix.md, package the installation as a script in contrib/. This
allows shared usage from a number of contexts, e.g. Docker.

Thanks to @jonasschnelli, @laanwj for feedback.
---
 Makefile.am            |  1 +
 contrib/install_db4.sh | 87 ++++++++++++++++++++++++++++++++++++++++++
 doc/build-openbsd.md   | 27 ++++---------
 doc/build-unix.md      | 31 ++++-----------
 4 files changed, 103 insertions(+), 43 deletions(-)
 create mode 100755 contrib/install_db4.sh

diff --git a/Makefile.am b/Makefile.am
index a7092bb33..9b791cc0e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,7 @@ 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/install_db4.sh \
 	       $(top_srcdir)/contrib/rpm
 DIST_SHARE = \
   $(top_srcdir)/share/genbuild.sh \
diff --git a/contrib/install_db4.sh b/contrib/install_db4.sh
new file mode 100755
index 000000000..1d33e8d3b
--- /dev/null
+++ b/contrib/install_db4.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+# Install libdb4.8 (Berkeley DB).
+
+set -e
+
+if [ -z "${1}" ]; then
+  echo "Usage: ./install_db4.sh <base-dir> [<extra-bdb-configure-flag> ...]"
+  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 bitcoin repository."
+  exit 1
+fi
+
+expand_path() {
+  echo "$(cd "${1}" && pwd -P)"
+}
+
+BDB_PREFIX="$(expand_path ${1})/db4"; shift;
+BDB_EXTRA_CONFIGURE_FLAGS="${@}"
+BDB_VERSION='db-4.8.30.NC'
+BDB_HASH='12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef'
+BDB_URL="https://download.oracle.com/berkeley-db/${BDB_VERSION}.tar.gz"
+
+check_exists() {
+  which "$1" >/dev/null 2>&1
+}
+
+sha256_check() {
+  # Args: <sha256_hash> <filename>
+  #
+  if check_exists sha256sum; then
+    echo "${1}  ${2}" | sha256sum -c
+  elif check_exists sha256; then
+    echo "${1}  ${2}" | sha256 -c
+  else
+    echo "${1}  ${2}" | shasum -a 256 -c
+  fi
+}
+
+http_get() {
+  # Args: <url> <filename> <sha256_hash>
+  #
+  # 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 "${1}" -o "${2}"
+  else
+    wget --no-check-certificate "${1}" -O "${2}"
+  fi
+
+  sha256_check "${3}" "${2}"
+}
+
+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 when building on OS X to make the build work with Xcode.
+#
+if [ "$(uname)" = "Darwin" ]; then
+  BDB_OSX_ATOMIC_PATCH_URL='https://raw.githubusercontent.com/narkoleptik/os-x-berkeleydb-patch/0007e2846ae3fc9757849f5277018f4179ad17ef/atomic.patch'
+  BDB_OSX_ATOMIC_PATCH_HASH='ba0e2b4f53e9cb0ec58f60a979b53b8567b4565f0384886196f1fc1ef111d151'
+
+  http_get "${BDB_OSX_ATOMIC_PATCH_URL}" atomic.patch "${BDB_OSX_ATOMIC_PATCH_HASH}"
+  patch -p1 < atomic.patch
+fi
+
+cd build_unix/
+
+"${BDB_PREFIX}/${BDB_VERSION}/dist/configure" \
+  --enable-cxx --disable-shared --with-pic --prefix="${BDB_PREFIX}" \
+  "${BDB_EXTRA_CONFIGURE_FLAGS}"
+
+make install
+
+echo
+echo "db4 build complete."
+echo
+echo 'When compiling bitcoind, run `./configure` in the following way:'
+echo
+echo "  export BDB_PREFIX='${BDB_PREFIX}'"
+echo '  ./configure LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" ...'
diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md
index 760bb69b1..cd1d217b4 100644
--- a/doc/build-openbsd.md
+++ b/doc/build-openbsd.md
@@ -38,28 +38,17 @@ The default C++ compiler that comes with OpenBSD 6.2 is g++ 4.2.1. This version
 
 BerkeleyDB is only necessary for the wallet functionality. To skip this, pass `--disable-wallet` to `./configure`.
 
-See "Berkeley DB" in [build-unix.md](build-unix.md#berkeley-db) for instructions on how to build BerkeleyDB 4.8.
-You cannot use the BerkeleyDB library from ports, for the same reason as boost above (g++/libstd++ incompatibility).
+It is recommended to use Berkeley DB 4.8. You cannot use the BerkeleyDB library
+from ports, for the same reason as boost above (g++/libstd++ incompatibility).
+If you have to build it yourself, you can use [the installation script included
+in contrib/](contrib/install_db4.sh) like so
 
-```bash
-# Pick some path to install BDB to, here we create a directory within the bitcoin directory
-BITCOIN_ROOT=$(pwd)
-BDB_PREFIX="${BITCOIN_ROOT}/db4"
-mkdir -p $BDB_PREFIX
-
-# Fetch the source and verify that it is not tampered with
-curl -o db-4.8.30.NC.tar.gz 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
-echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef  db-4.8.30.NC.tar.gz' | sha256 -c
-# MUST output: (SHA256) db-4.8.30.NC.tar.gz: OK
-tar -xzf db-4.8.30.NC.tar.gz
-
-# Build the library and install to specified prefix
-cd db-4.8.30.NC/build_unix/
-#  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 --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX CC=egcc CXX=eg++ CPP=ecpp
-make install # do NOT use -jX, this is broken
+```shell
+./contrib/install_db4.sh `pwd` CC=egcc CXX=eg++ CPP=ecpp
 ```
 
+from the root of the repository.
+
 ### Resource limits
 
 The standard ulimit restrictions in OpenBSD are very strict:
diff --git a/doc/build-unix.md b/doc/build-unix.md
index 8a102abae..5d3329e2c 100644
--- a/doc/build-unix.md
+++ b/doc/build-unix.md
@@ -165,33 +165,16 @@ turned off by default.  See the configure options for upnp behavior desired:
 
 Berkeley DB
 -----------
-It is recommended to use Berkeley DB 4.8. If you have to build it yourself:
+It is recommended to use Berkeley DB 4.8. If you have to build it yourself,
+you can use [the installation script included in contrib/](contrib/install_db4.sh)
+like so
 
-```bash
-BITCOIN_ROOT=$(pwd)
-
-# Pick some path to install BDB to, here we create a directory within the bitcoin directory
-BDB_PREFIX="${BITCOIN_ROOT}/db4"
-mkdir -p $BDB_PREFIX
-
-# Fetch the source and verify that it is not tampered with
-wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
-echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef  db-4.8.30.NC.tar.gz' | sha256sum -c
-# -> db-4.8.30.NC.tar.gz: OK
-tar -xzvf db-4.8.30.NC.tar.gz
-
-# Build the library and install to our prefix
-cd db-4.8.30.NC/build_unix/
-#  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 --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX
-make install
-
-# Configure Bitcoin Core to use our own-built instance of BDB
-cd $BITCOIN_ROOT
-./autogen.sh
-./configure LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" # (other args...)
+```shell
+./contrib/install_db4.sh `pwd`
 ```
 
+from the root of the repository.
+
 **Note**: You only need Berkeley DB if the wallet is enabled (see the section *Disable-Wallet mode* below).
 
 Boost

From 6e4cdd67b1f2b3927a525ebba843c27ef3c63e1c Mon Sep 17 00:00:00 2001
From: James O'Beirne <james.obeirne@gmail.com>
Date: Wed, 15 Nov 2017 23:36:08 -0800
Subject: [PATCH 2/2] [docs] Add reference to install_db4.sh in OS X build
 instructions

---
 doc/build-osx.md | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/doc/build-osx.md b/doc/build-osx.md
index 836c856a6..6f08562ff 100644
--- a/doc/build-osx.md
+++ b/doc/build-osx.md
@@ -26,6 +26,20 @@ If you want to build the disk image with `make deploy` (.dmg / optional), you ne
 
 NOTE: Building with Qt4 is still supported, however, could result in a broken UI. Building with Qt5 is recommended.
 
+Berkeley DB
+-----------
+It is recommended to use Berkeley DB 4.8. If you have to build it yourself,
+you can use [the installation script included in contrib/](contrib/install_db4.sh)
+like so
+
+```shell
+./contrib/install_db4.sh .
+```
+
+from the root of the repository.
+
+**Note**: You only need Berkeley DB if the wallet is enabled (see the section *Disable-Wallet mode* below).
+
 Build Bitcoin Core
 ------------------------