diff --git a/libbitcoind.patch b/libbitcoind.patch new file mode 100644 index 00000000..e58358ea --- /dev/null +++ b/libbitcoind.patch @@ -0,0 +1,500 @@ +diff --git a/Makefile.am b/Makefile.am +index b51f477..58241df 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -35,6 +35,11 @@ COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ + baseline_filtered.info block_test_filtered.info \ + leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info + ++if ENABLE_DAEMONLIB ++all: ++ $(MAKE) -C src ++endif ++ + dist-hook: + -$(MAKE) -C $(top_distdir)/src/leveldb clean + -$(MAKE) -C $(top_distdir)/src/secp256k1 distclean +diff --git a/configure.ac b/configure.ac +index 9814197..3f25415 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -126,6 +126,12 @@ AC_ARG_ENABLE([reduce-exports], + [use_reduce_exports=$enableval], + [use_reduce_exports=auto]) + ++AC_ARG_ENABLE([daemonlib], ++ [AS_HELP_STRING([--enable-daemonlib], ++ [compile all of bitcoind as a library (default is no)])], ++ [use_daemonlib=$enableval], ++ [use_daemonlib=no]) ++ + AC_ARG_ENABLE([ccache], + [AS_HELP_STRING([--enable-ccache], + [use ccache for building (default is yes if ccache is found)])], +@@ -387,6 +393,9 @@ 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"]) ++ if test x$use_daemonlib = xno; then ++ AX_CHECK_COMPILE_FLAG([-fPIE],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fPIE"]) ++ fi + + AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[ + AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[ +@@ -400,7 +409,7 @@ if test x$use_hardening != xno; then + 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 ++ if test x$TARGET_OS != xwindows -a x$use_daemonlib = xno; then + # All windows code is PIC, forcing it on just adds useless compile warnings + AX_CHECK_COMPILE_FLAG([-fPIE],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fPIE"]) + AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"]) +@@ -418,6 +427,17 @@ if test x$use_hardening != xno; then + OBJCXXFLAGS="$CXXFLAGS" + fi + ++AC_DEFINE([ENABLE_DAEMONLIB],[0],[Enable daemonlib.]) ++AM_CONDITIONAL([ENABLE_DAEMONLIB],[false]) ++if test x$use_daemonlib != xno; then ++ AX_CHECK_COMPILE_FLAG([-fPIC],[DAEMONLIB_CXXFLAGS="$DAEMONLIB_CXXFLAGS -fPIC"]) ++ AC_DEFINE([ENABLE_DAEMONLIB],[1],[Enable daemonlib.]) ++ AM_CONDITIONAL([ENABLE_DAEMONLIB],[true]) ++ CXXFLAGS="$CXXFLAGS $DAEMONLIB_CXXFLAGS" ++ CPPFLAGS="$CPPFLAGS $DAEMONLIB_CPPFLAGS" ++ OBJCXXFLAGS="$CXXFLAGS" ++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"]) +@@ -463,7 +483,7 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([ + ] + ) + +-if test x$use_reduce_exports != xno; then ++if test x$use_reduce_exports != xno -a x$use_daemonlib = xno; then + AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], + [ + if test x$use_reduce_exports = xyes; then +@@ -811,6 +831,13 @@ if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_q + AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests]) + fi + ++AC_MSG_CHECKING([whether to compile as daemonlib]) ++if test x$use_daemonlib != xno; then ++ AC_MSG_RESULT([yes]) ++else ++ AC_MSG_RESULT([no]) ++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]) +diff --git a/doc/build-unix.md b/doc/build-unix.md +index 8ddee3b..c4274a3 100644 +--- a/doc/build-unix.md ++++ b/doc/build-unix.md +@@ -239,3 +239,42 @@ In this case there is no dependency on Berkeley DB 4.8. + Mining is also possible in disable-wallet mode, but only using the `getblocktemplate` RPC + call not `getwork`. + ++Compiling bitcoind as a shared object (`libbitcoind.so`) ++-------------------------------------------------------- ++ ++### Compiling as a library ++ ++``` bash ++# ensure clean up ++$ make clean ++ ++# create configure file ++$ ./autogen.sh ++ ++# configure as a library with -fPIC on all object files ++# use --with-incompatible-bdb if necessary ++# use --prefix=/usr if necessary ++$ ./configure --enable-daemonlib ++ ++# build libbitcoind.so ++$ time make ++... ++real 31m33.128s ++user 16m23.930s ++sys 2m52.310s ++``` ++ ++`--enable-daemonlib` will compile all object files with `-fPIC` (Position ++Independent Code - needed to create a shared object). ++ ++`make` will then compile `./src/libbitcoind.so` (with `-shared -fPIC`), linking ++to all the freshly compiled PIC object files. This will completely ignore ++compiling tests and the QT object files. ++ ++Without `--enable-daemonlib`, the Makefile with compile bitcoind with -fPIE ++(Position Independent for Executable), this allows compiling of bitcoind. ++ ++#### Todo ++ ++- Find a way to compile bitcoind and libbitcoind.so at the same time without ++ recompiling object files each time? Possibly use libtool's .lo/.la. +diff --git a/src/Makefile.am b/src/Makefile.am +index d6ac6e1..4ac63a2 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -31,12 +31,15 @@ LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a + LIBBITCOIN_UNIVALUE=univalue/libbitcoin_univalue.a + LIBBITCOINQT=qt/libbitcoinqt.a + LIBSECP256K1=secp256k1/libsecp256k1.la ++LIBBITCOIND=libbitcoind.so + + $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) + + # Make is not made aware of per-object dependencies to avoid limiting building parallelization + # But to build the less dependent modules first, we manually select their order here: ++ ++if !ENABLE_DAEMONLIB + noinst_LIBRARIES = \ + crypto/libbitcoin_crypto.a \ + libbitcoin_util.a \ +@@ -76,6 +79,7 @@ BITCOIN_CORE_H = \ + amount.h \ + base58.h \ + bloom.h \ ++ bitcoind.h \ + chain.h \ + chainparams.h \ + chainparamsbase.h \ +@@ -152,10 +156,17 @@ JSON_H = \ + json/json_spirit_writer.h \ + json/json_spirit_writer_template.h + ++else ++.PHONY: FORCE ++BITCOIN_INCLUDES += $(BDB_CPPFLAGS) ++endif ++ + obj/build.h: FORCE + @$(MKDIR_P) $(builddir)/obj + @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \ + $(abs_top_srcdir) ++ ++if !ENABLE_DAEMONLIB + libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h + + # server: shared between bitcoind and bitcoin-qt +@@ -165,6 +176,7 @@ libbitcoin_server_a_SOURCES = \ + alert.cpp \ + bloom.cpp \ + chain.cpp \ ++ bitcoind.cpp \ + checkpoints.cpp \ + init.cpp \ + leveldbwrapper.cpp \ +@@ -304,7 +316,7 @@ bitcoind_LDADD = \ + if ENABLE_WALLET + bitcoind_LDADD += libbitcoin_wallet.a + endif +-bitcoind_SOURCES = bitcoind.cpp ++bitcoind_SOURCES = bitcoin-main.cpp + # + + if TARGET_WINDOWS +@@ -380,6 +392,7 @@ if USE_LIBSECP256K1 + libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la + endif + endif ++endif + + CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno + +@@ -405,6 +418,9 @@ clean-local: + @test -f $(PROTOC) + $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $( +-#include +-#include ++#include "bitcoind.h" + + /* Introduction text for doxygen: */ + +@@ -174,13 +164,3 @@ bool AppInit(int argc, char* argv[]) + + return fRet; + } +- +-int main(int argc, char* argv[]) +-{ +- SetupEnvironment(); +- +- // Connect bitcoind signal handlers +- noui_connect(); +- +- return (AppInit(argc, argv) ? 0 : 1); +-} +diff --git a/src/bitcoind.h b/src/bitcoind.h +new file mode 100644 +index 0000000..0e34008 +--- /dev/null ++++ b/src/bitcoind.h +@@ -0,0 +1,25 @@ ++// Copyright (c) 2009-2010 Satoshi Nakamoto ++// Copyright (c) 2009-2013 The Bitcoin developers ++// Distributed under the MIT/X11 software license, see the accompanying ++// file COPYING or http://www.opensource.org/licenses/mit-license.php. ++ ++#ifndef _BITCOIN_BITCOIND ++#define _BITCOIN_BITCOIND 1 ++ ++#include "clientversion.h" ++#include "rpcserver.h" ++#include "init.h" ++#include "main.h" ++#include "noui.h" ++#include "ui_interface.h" ++#include "util.h" ++#include "rpcclient.h" ++ ++#include ++#include ++#include ++ ++extern void DetectShutdownThread(boost::thread_group* threadGroup); ++extern bool AppInit(int argc, char* argv[]); ++ ++#endif +diff --git a/src/init.h b/src/init.h +index f2f7ac6..10abc3a 100644 +--- a/src/init.h ++++ b/src/init.h +@@ -15,7 +15,15 @@ namespace boost + class thread_group; + } // namespace boost + ++#ifdef ENABLE_WALLET ++extern std::string strWalletFile; + extern CWallet* pwalletMain; ++#endif ++ ++#include ++#include ++ ++void ThreadImport(std::vector vImportFiles); + + void StartShutdown(); + bool ShutdownRequested(); +diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h +index 4247920..08c8164 100644 +--- a/src/leveldbwrapper.h ++++ b/src/leveldbwrapper.h +@@ -29,10 +29,9 @@ class CLevelDBBatch + { + friend class CLevelDBWrapper; + +-private: ++public: + leveldb::WriteBatch batch; + +-public: + template + void Write(const K& key, const V& value) + { +@@ -63,7 +62,7 @@ public: + + class CLevelDBWrapper + { +-private: ++public: + //! custom environment this database is using (may be NULL in case of default environment) + leveldb::Env* penv; + +@@ -85,7 +84,6 @@ private: + //! the database itself + leveldb::DB* pdb; + +-public: + CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false); + ~CLevelDBWrapper(); + +diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp +index 8b95373..53f9a5a 100644 +--- a/src/rpcdump.cpp ++++ b/src/rpcdump.cpp +@@ -26,11 +26,11 @@ using namespace std; + + void EnsureWalletIsUnlocked(); + +-std::string static EncodeDumpTime(int64_t nTime) { ++std::string EncodeDumpTime(int64_t nTime) { + return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); + } + +-int64_t static DecodeDumpTime(const std::string &str) { ++int64_t DecodeDumpTime(const std::string &str) { + static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0); + static const std::locale loc(std::locale::classic(), + new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ")); +@@ -43,7 +43,7 @@ int64_t static DecodeDumpTime(const std::string &str) { + return (ptime - epoch).total_seconds(); + } + +-std::string static EncodeDumpString(const std::string &str) { ++std::string EncodeDumpString(const std::string &str) { + std::stringstream ret; + BOOST_FOREACH(unsigned char c, str) { + if (c <= 32 || c >= 128 || c == '%') { +diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp +index d2d14ad..e8abb3d 100644 +--- a/src/rpcwallet.cpp ++++ b/src/rpcwallet.cpp +@@ -4,6 +4,7 @@ + // file COPYING or http://www.opensource.org/licenses/mit-license.php. + + #include "amount.h" ++#include "rpcwallet.h" + #include "base58.h" + #include "core_io.h" + #include "rpcserver.h" +diff --git a/src/rpcwallet.h b/src/rpcwallet.h +new file mode 100644 +index 0000000..2b53241 +--- /dev/null ++++ b/src/rpcwallet.h +@@ -0,0 +1,17 @@ ++// Copyright (c) 2010 Satoshi Nakamoto ++// Copyright (c) 2009-2013 The Bitcoin developers ++// Distributed under the MIT/X11 software license, see the accompanying ++// file COPYING or http://www.opensource.org/licenses/mit-license.php. ++ ++#ifndef _BITCOINRPC_WALLET_H_ ++#define _BITCOINRPC_WALLET_H_ 1 ++ ++#include "wallet.h" ++#include "walletdb.h" ++ ++#include ++ ++CAmount GetAccountBalance(CWalletDB& walletdb, const std::string& strAccount, int nMinDepth, const isminefilter& filter); ++CAmount GetAccountBalance(const std::string& strAccount, int nMinDepth, const isminefilter& filter); ++ ++#endif +diff --git a/src/wallet.h b/src/wallet.h +index 70d274c..604e9e7 100644 +--- a/src/wallet.h ++++ b/src/wallet.h +@@ -105,8 +105,6 @@ public: + class CWallet : public CCryptoKeyStore, public CValidationInterface + { + private: +- bool SelectCoins(const CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; +- + CWalletDB *pwalletdbEncryption; + + //! the current wallet version: clients below this version are not able to load the wallet +@@ -201,6 +199,7 @@ public: + bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } + + void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const; ++ bool SelectCoins(const CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; + bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, CAmount& nValueRet) const; + + bool IsSpent(const uint256& hash, unsigned int n) const; diff --git a/patch-bitcoin.sh b/patch-bitcoin.sh new file mode 100755 index 00000000..c59c1e5b --- /dev/null +++ b/patch-bitcoin.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +dir=$(test -n "$1" && echo "$1" || echo "${HOME}/bitcoin") +cd "$dir" || exit 1 +patch -p1 < libbitcoind.patch