diff --git a/arcanist/linter/CppCheckLinter.php b/arcanist/linter/CppCheckLinter.php index 1c6730001..791c2dc44 100644 --- a/arcanist/linter/CppCheckLinter.php +++ b/arcanist/linter/CppCheckLinter.php @@ -1,266 +1,266 @@ [messages]> to whitelist. */ const CPPCHECK_IGNORED_WARNINGS = array( "src/arith_uint256.h" => array( "Class 'arith_uint256' has a constructor with 1 argument that is not explicit.", "Class 'base_uint < 256 >' has a constructor with 1 argument that is not explicit.", "Class 'base_uint' has a constructor with 1 argument that is not explicit.", ), "src/bench/prevector.cpp" => array( // Remove this once this false positive is fixed in cppcheck "syntax error", ), "src/coins.h" => array( "Class 'CCoinsViewBacked' has a constructor with 1 argument that is not explicit.", "Class 'CCoinsViewCache' has a constructor with 1 argument that is not explicit.", "Class 'CCoinsViewCursor' has a constructor with 1 argument that is not explicit.", ), "src/cuckoocache.h" => array( "Struct 'KeyOnly' has a constructor with 1 argument that is not explicit.", ), "src/net.h" => array( "Class 'CNetMessage' has a constructor with 1 argument that is not explicit.", ), "src/net_processing.cpp" => array( "Same iterator is used with different containers 'mapOrphanTransactions' and 'itPrev.second'.", ), "src/policy/feerate.h" => array( "Class 'CFeeRate' has a constructor with 1 argument that is not explicit.", ), "src/prevector.h" => array( "Class 'const_iterator' has a constructor with 1 argument that is not explicit.", "Class 'const_reverse_iterator' has a constructor with 1 argument that is not explicit.", "Class 'iterator' has a constructor with 1 argument that is not explicit.", "Class 'reverse_iterator' has a constructor with 1 argument that is not explicit.", ), "src/primitives/block.h" => array( "Class 'CBlock' has a constructor with 1 argument that is not explicit.", ), "src/primitives/transaction.h" => array( "Class 'CTransaction' has a constructor with 1 argument that is not explicit.", ), "src/protocol.h" => array( "Class 'CMessageHeader' has a constructor with 1 argument that is not explicit.", ), "src/qt/guiutil.h" => array( "Class 'ItemDelegate' has a constructor with 1 argument that is not explicit.", ), "src/rpc/util.h" => array( "Struct 'RPCResults' has a constructor with 1 argument that is not explicit.", "Struct 'UniValueType' has a constructor with 1 argument that is not explicit.", ), "src/script/descriptor.cpp" => array( "Class 'AddressDescriptor' has a constructor with 1 argument that is not explicit.", "Class 'ComboDescriptor' has a constructor with 1 argument that is not explicit.", "Class 'ConstPubkeyProvider' has a constructor with 1 argument that is not explicit.", "Class 'PKDescriptor' has a constructor with 1 argument that is not explicit.", "Class 'PKHDescriptor' has a constructor with 1 argument that is not explicit.", "Class 'RawDescriptor' has a constructor with 1 argument that is not explicit.", "Class 'SHDescriptor' has a constructor with 1 argument that is not explicit.", "Class 'WPKHDescriptor' has a constructor with 1 argument that is not explicit.", "Class 'WSHDescriptor' has a constructor with 1 argument that is not explicit.", ), "src/script/script.h" => array( "Class 'CScript' has a constructor with 1 argument that is not explicit.", ), "src/script/standard.h" => array( "Class 'CScriptID' has a constructor with 1 argument that is not explicit.", ), "src/support/allocators/secure.h" => array( "Struct 'secure_allocator < char >' has a constructor with 1 argument that is not explicit.", "Struct 'secure_allocator < RNGState >' has a constructor with 1 argument that is not explicit.", "Struct 'secure_allocator < unsigned char >' has a constructor with 1 argument that is not explicit.", ), "src/support/allocators/zeroafterfree.h" => array( "Struct 'zero_after_free_allocator < char >' has a constructor with 1 argument that is not explicit.", ), "src/test/checkqueue_tests.cpp" => array( "Struct 'FailingCheck' has a constructor with 1 argument that is not explicit.", "Struct 'MemoryCheck' has a constructor with 1 argument that is not explicit.", "Struct 'UniqueCheck' has a constructor with 1 argument that is not explicit.", ), "src/test/cuckoocache_tests.cpp" => array( "Struct 'KeyType' has a constructor with 1 argument that is not explicit.", "Struct 'TestMapElement' has a constructor with 1 argument that is not explicit." ), "src/test/prevector_tests.cpp" => array( // Remove this once this false positive is fixed in cppcheck "syntax error", ), "src/wallet/db.h" => array( "Class 'BerkeleyEnvironment' has a constructor with 1 argument that is not explicit.", ), ); // phpcs:enable const CPPCHECK_OPTIONS = array( '-j2', '--enable=all', '--language=c++', - '--std=c++14', + '--std=c++17', ); const CPPCHECK_DEFINITIONS = array( '-D__cplusplus', '-DCLIENT_VERSION_BUILD', '-DCLIENT_VERSION_IS_RELEASE', '-DCLIENT_VERSION_MAJOR', '-DCLIENT_VERSION_MINOR', '-DCLIENT_VERSION_REVISION', '-DCOPYRIGHT_YEAR', '-DDEBUG', ); public function getInfoName() { return 'cppcheck'; } public function getInfoURI() { return 'http://cppcheck.sourceforge.net'; } public function getInfoDescription() { return pht( 'Use `%s` to perform static analysis on C/C++ code.', 'cppcheck'); } public function getLinterName() { return 'lint-cppcheck'; } public function getLinterConfigurationName() { return 'lint-cppcheck'; } public function getDefaultBinary() { return 'cppcheck'; } public function getVersion() { list($stdout) = execx('%C --version', $this->getExecutableCommand()); $matches = array(); $regex = '/^Cppcheck (?P\d+\.\d+)$/'; if (preg_match($regex, $stdout, $matches)) { return $matches['version']; } return false; } public function getInstallInstructions() { return pht( 'Install Cppcheck using `%s` or similar.', 'apt-get install cppcheck'); } protected function getDefaultFlags() { return array_merge( self::CPPCHECK_OPTIONS, self::CPPCHECK_DEFINITIONS ); } protected function getMandatoryFlags() { return array( '--quiet', '--inline-suppr', '--xml', '--xml-version=2', ); } public function shouldExpectCommandErrors() { return false; } private function isWhitelisted($path, $errorId, $errorDescription) { return array_key_exists($path, self::CPPCHECK_IGNORED_WARNINGS) && in_array($errorDescription, self::CPPCHECK_IGNORED_WARNINGS[$path]); } private function isCheckEnabled($errorId) { return in_array($errorId, self::CPPCHECK_ENABLED_CHECKS); } private function isCheckDisabled($errorId) { return in_array($errorId, self::CPPCHECK_DISABLED_CHECKS); } protected function parseLinterOutput($path, $err, $stdout, $stderr) { $dom = new DOMDocument(); $ok = @$dom->loadXML($stderr); if (!$ok) { return false; } $errors = $dom->getElementsByTagName('error'); $messages = array(); foreach ($errors as $error) { foreach ($error->getElementsByTagName('location') as $location) { $errorPath = Filesystem::readablePath( $location->getAttribute('file'), $this->getProjectRoot()); $errorId = $error->getAttribute('id'); $errorDescription = $error->getAttribute('msg'); /* * Only raise errors related to the actual source file. * This prevents from printing tons of duplicates. */ if ($errorPath !== $path || $this->isWhitelisted( $errorPath, $errorId, $errorDescription)) { continue; } // For errors, we work on a blacklist basis. // For advices and warnings, we work on a whitelist basis. $is_error = $error->getAttribute('severity') == 'error'; if ($is_error && $this->isCheckDisabled($errorId)) { continue; } else if (!$is_error && !$this->isCheckEnabled($errorId)) { continue; } $message = new ArcanistLintMessage(); $message->setPath($errorPath); $message->setLine($location->getAttribute('line')); $message->setCode('CPPCHECK'); $message->setName($errorId); $message->setDescription($errorDescription); if ($is_error) { $message->setSeverity(ArcanistLintSeverity::SEVERITY_ERROR); } elseif ($error->getAttribute('inconclusive')) { $message->setSeverity(ArcanistLintSeverity::SEVERITY_ADVICE); } else { $message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING); } $messages[] = $message; } } return $messages; } } diff --git a/doc/build-osx.md b/doc/build-osx.md index c115f859a..50455ce20 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -1,99 +1,99 @@ macOS Build Instructions and Notes ==================================== The commands in this guide should be executed in a Terminal application. The built-in one is located in `/Applications/Utilities/Terminal.app`. Preparation ----------- 1. Install Xcode from the app store if you don't have it already (it's a dependency for qt5) 2. Install the macOS command line tools: `xcode-select --install` When the popup appears, click `Install`. 3. Install [Homebrew](https://brew.sh). Dependencies ---------------------- Install dependencies: brew install berkeley-db boost cmake jemalloc libevent librsvg miniupnpc ninja openssl protobuf python qrencode qt zeromq See [dependencies.md](dependencies.md) for a complete overview. If you want to build the disk image with `ninja osx-dmg` (.dmg / optional), you need RSVG: brew install librsvg Build Bitcoin ABC ----------------- -Before you start building, please make sure that your compiler supports C++14. +Before you start building, please make sure that your compiler supports C++17. 1. Clone the Bitcoin ABC source code and cd into `bitcoin-abc` git clone https://github.com/Bitcoin-ABC/bitcoin-abc.git cd bitcoin-abc 2. Build Bitcoin ABC: Configure and build the headless Bitcoin ABC binaries as well as the GUI. You can disable the GUI build by passing `-DBUILD_BITCOIN_QT=OFF` to cmake. It is recommended to create a build directory to build out-of-tree. mkdir build cd build cmake -GNinja .. ninja 3. It is recommended to build and run the unit tests: ninja check 4. You can also create a .dmg that contains the .app bundle (optional): ninja osx-dmg Disable-wallet mode -------------------- When the intention is to run only a P2P node without a wallet, Bitcoin ABC may be compiled in disable-wallet mode with: cmake -GNinja .. -DBUILD_BITCOIN_WALLET=OFF Mining is also possible in disable-wallet mode using the `getblocktemplate` RPC call. Running ------- Bitcoin ABC is now available at `./src/bitcoind` Before running, it's recommended that you create an RPC configuration file: echo -e "rpcuser=bitcoinrpc\nrpcpassword=$(xxd -l 16 -p /dev/urandom)" > "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" The first time you run bitcoind, it will start downloading the blockchain. This process could take many hours, or even days on slower than average systems. You can monitor the download process by looking at the debug.log file: tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log Other commands: ------- ./src/bitcoind -daemon # Starts the bitcoin daemon. ./src/bitcoin-cli --help # Outputs a list of command-line options. ./src/bitcoin-cli help # Outputs a list of RPC commands when the daemon is running. Notes ----- * Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714) diff --git a/doc/build-unix.md b/doc/build-unix.md index 132b2c708..ea7943bb3 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -1,326 +1,326 @@ UNIX BUILD NOTES ==================== Some notes on how to build Bitcoin ABC in Unix. To Build --------------------- -Before you start building, please make sure that your compiler supports C++14. +Before you start building, please make sure that your compiler supports C++17. It is recommended to create a build directory to build out-of-tree. ```bash mkdir build cd build cmake -GNinja .. ninja ninja install # optional ``` This will build bitcoin-qt as well. Dependencies --------------------- *Note: Bitcoin ABC provides a [Docker image with all the dependencies preinstalled](#build-using-a-docker-container).* These dependencies are required: Library | Purpose | Description ------------|------------------|---------------------- libssl | Crypto | Random Number Generation, Elliptic Curve Cryptography libboost | Utility | Library for threading, data structures, etc libevent | Networking | OS independent asynchronous networking Optional dependencies: Library | Purpose | Description ------------|------------------|---------------------- miniupnpc | UPnP Support | Firewall-jumping support libdb | Berkeley DB | Wallet storage (only needed when wallet enabled) jemalloc | Memory allocator | Library to enhance the memory allocation and improve performances qt | GUI | GUI toolkit (only needed when GUI enabled) protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when BIP70 enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure) libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.1.5) For the versions used, see [dependencies.md](dependencies.md) Memory Requirements -------------------- C++ compilers are memory-hungry. It is recommended to have at least 1.5 GB of memory available when compiling Bitcoin ABC. On systems with less, gcc can be tuned to conserve memory with additional CXXFLAGS: cmake -GNinja .. -DCXXFLAGS="--param ggc-min-expand=1 --param ggc-min-heapsize=32768" Dependency Build Instructions: Ubuntu & Debian ---------------------------------------------- Build requirements: sudo apt-get install bsdmainutils build-essential libssl-dev libevent-dev ninja-build python3 **Installing cmake:** On Debian Buster (10), `cmake` should be installed from the backports repository: echo "deb http://deb.debian.org/debian buster-backports main" | sudo tee -a /etc/apt/sources.list sudo apt-get update sudo apt-get -t buster-backports install cmake On Ubuntu 20.04 and later: sudo apt-get install cmake On previous Ubuntu versions, the `cmake` package is too old and needs to be installed from the Kitware APT repository: sudo apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - Add the repository corresponding to your version (see [instructions from Kitware](https://apt.kitware.com)). For Ubuntu Bionic (18.04): sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' Then update the package list and install `cmake`: sudo apt update sudo apt install cmake Now, you can either build from self-compiled [depends](/depends/README.md) or install the required dependencies with the following instructions. Options when installing required Boost library files: 1. On at least Ubuntu 16.04+ and Debian 9+ there are generic names for the individual boost development packages, so the following can be used to only install necessary parts of boost: sudo apt-get install libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev 2. If that doesn't work, you can install all boost development packages with: sudo apt-get install libboost-all-dev BerkeleyDB 5.3 or later is required for the wallet. This can be installed with: sudo apt-get install libdb-dev libdb++-dev See the section "Disable-wallet mode" to build Bitcoin ABC without wallet. Minipupnc dependencies (can be disabled by passing `-DENABLE_UPNP=OFF` on the cmake command line): sudo apt-get install libminiupnpc-dev ZMQ dependencies (provides ZMQ API, can be disabled by passing `-DBUILD_BITCOIN_ZMQ=OFF` on the cmake command line): sudo apt-get install libzmq3-dev jemalloc dependencies (provides the jemalloc library, can be disabled by passing `-DUSE_JEMALLOC=OFF` on the cmake command line): sudo apt-get install libjemalloc-dev Dependencies for the GUI: Ubuntu & Debian ----------------------------------------- If you want to build bitcoin-qt, make sure that the required packages for Qt development are installed. Qt 5 is necessary to build the GUI. To build without GUI pass `-DBUILD_BITCOIN_QT=OFF` on the cmake command line. To build with Qt 5 you need the following: sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode dependencies (can be disabled by passing `-DENABLE_QRCODE=OFF` on the cmake command line): sudo apt-get install libqrencode-dev Dependency Build Instructions: Fedora ------------------------------------- Build requirements: sudo dnf install boost-devel cmake gcc-c++ libdb-cxx-devel libdb-devel libevent-devel ninja-build openssl-devel python3 Minipupnc dependencies (can be disabled by passing `-DENABLE_UPNP=OFF` on the cmake command line): sudo dnf install miniupnpc-devel ZMQ dependencies (can be disabled by passing `-DBUILD_BITCOIN_ZMQ=OFF` on the cmake command line): sudo dnf install zeromq-devel To build with Qt 5 you need the following: sudo dnf install qt5-qttools-devel qt5-qtbase-devel protobuf-devel libqrencode dependencies (can be disabled by passing `-DENABLE_QRCODE=OFF`): sudo dnf install qrencode-devel Notes ----- The release is built with GCC and then "strip bitcoind" to strip the debug symbols, which reduces the executable size by about 90%. miniupnpc --------- [miniupnpc](https://miniupnp.tuxfamily.org) may be used for UPnP port mapping. It can be downloaded from [here]( https://miniupnp.tuxfamily.org/files/). UPnP support is compiled in and turned off by default. See the cmake options for upnp behavior desired: ENABLE_UPNP Enable UPnP support (miniupnp required, default ON) START_WITH_UPNP UPnP support turned on by default at runtime (default OFF) Boost ----- For documentation on building Boost look at their official documentation: http://www.boost.org/build/doc/html/bbv2/installation.html Security -------- To help make your Bitcoin ABC installation more secure by making certain attacks impossible to exploit even if a vulnerability is found, binaries are hardened by default. This can be disabled by passing `-DENABLE_HARDENING=OFF`. Hardening enables the following features: * _Position Independent Executable_: Build position independent code to take advantage of Address Space Layout Randomization offered by some kernels. Attackers who can cause execution of code at an arbitrary memory location are thwarted if they don't know where anything useful is located. The stack and heap are randomly located by default, but this allows the code section to be randomly located as well. On an AMD64 processor where a library was not compiled with -fPIC, this will cause an error such as: "relocation R_X86_64_32 against `......' can not be used when making a shared object;" To test that you have built PIE executable, install scanelf, part of paxutils, and use: scanelf -e ./bitcoin The output should contain: TYPE ET_DYN * _Non-executable Stack_: If the stack is executable then trivial stack-based buffer overflow exploits are possible if vulnerable buffers are found. By default, Bitcoin ABC should be built with a non-executable stack, but if one of the libraries it uses asks for an executable stack or someone makes a mistake and uses a compiler extension which requires an executable stack, it will silently build an executable without the non-executable stack protection. To verify that the stack is non-executable after compiling use: scanelf -e ./bitcoin The output should contain: STK/REL/PTL RW- R-- RW- The `STK RW-` means that the stack is readable and writeable but not executable. Disable-wallet mode -------------------- When the intention is to run only a P2P node without a wallet, Bitcoin ABC may be compiled in disable-wallet mode by passing `-DBUILD_BITCOIN_WALLET=OFF` on the cmake command line. Mining is also possible in disable-wallet mode using the `getblocktemplate` RPC call. Additional cmake options -------------------------- A list of the cmake options and their current value can be displayed. From the build subdirectory (see above), run `cmake -LH ..`. Setup and Build Example: Arch Linux ----------------------------------- This example lists the steps necessary to setup and build a command line only, non-wallet distribution of the latest changes on Arch Linux: pacman -S base-devel boost cmake git libevent ninja python git clone https://github.com/Bitcoin-ABC/bitcoin-abc.git cd bitcoin-abc/ mkdir build cd build cmake -GNinja .. -DBUILD_BITCOIN_WALLET=OFF -DBUILD_BITCOIN_QT=OFF -DENABLE_UPNP=OFF -DBUILD_BITCOIN_ZMQ=OFF -DUSE_JEMALLOC=OFF ninja ARM Cross-compilation ------------------- These steps can be performed on, for example, a Debian VM. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different. Make sure you install all the build requirements mentioned above. Then, install the toolchain and some additional dependencies: sudo apt-get install autoconf automake curl g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf gperf pkg-config To build executables for ARM: cd depends make build-linux-arm cd .. mkdir build cd build cmake -GNinja .. -DCMAKE_TOOLCHAIN_FILE=../cmake/platforms/LinuxARM.cmake -DENABLE_GLIBC_BACK_COMPAT=ON -DENABLE_STATIC_LIBSTDCXX=ON ninja For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory. Build using a Docker container ------------------------------- Bitcoin ABC provides a [Docker image](https://hub.docker.com/r/bitcoinabc/bitcoin-abc-dev) with all the dependencies pre-installed, based on Debian. If the dependencies cannot be installed on your system but it can run a Docker container, this image can be pulled and used for the build. *Note: The image has all the dependencies and can weight a few gigabytes.* To get the latest image (current master): ```shell docker pull bitcoinabc/bitcoin-abc-dev ``` It is also possible to use a release version. Example for 0.22.4: ```shell docker pull bitcoinabc/bitcoin-abc-dev:0.22.4 ``` Running the container will start a `bash` shell at the project root: ```shell # On the host docker run -it bitcoinabc/bitcoin-abc-dev # Start the build in the container mkdir build cd build cmake -GNinja .. ninja ``` It is possible to bind the project to a local directory on the host machine. First create an empty volume on the host: ```shell # On the host mkdir bitcoin-abc-volume docker volume create \ --driver local \ --opt type=none \ --opt device=${PWD}/bitcoin-abc-volume \ --opt o=bind \ bitcoin-abc-volume ``` Then start the container with the volume bound to `/bitcoin-abc`: ```shell docker run -it -v bitcoin-abc-volume:/bitcoin-abc bitcoinabc/bitcoin-abc-dev ``` diff --git a/doc/build-windows.md b/doc/build-windows.md index 1b9248f8b..b9e2b3bdc 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -1,156 +1,156 @@ WINDOWS BUILD NOTES ==================== Below are some notes on how to build Bitcoin ABC for Windows. The options known to work for building Bitcoin ABC on Windows are: * On Linux, using the [Mingw-w64](https://mingw-w64.org/doku.php) cross compiler tool chain. Debian Buster is recommended and is the platform used to build the Bitcoin ABC Windows release binaries. * On Windows, using [Windows Subsystem for Linux (WSL)](https://msdn.microsoft.com/commandline/wsl/about) and the Mingw-w64 cross compiler tool chain. Other options which may work, but which have not been extensively tested are (please contribute instructions): * On Windows, using a POSIX compatibility layer application such as [cygwin](http://www.cygwin.com/) or [msys2](http://www.msys2.org/). * On Windows, using a native compiler tool chain such as [Visual Studio](https://www.visualstudio.com). -In any case please make sure that the compiler supports C++14. +In any case please make sure that the compiler supports C++17. Installing Windows Subsystem for Linux --------------------------------------- With Windows 10, Microsoft has released a new feature named the [Windows Subsystem for Linux (WSL)](https://msdn.microsoft.com/commandline/wsl/about). This feature allows you to run a bash shell directly on Windows in an Ubuntu-based environment. Within this environment you can cross compile for Windows without the need for a separate Linux VM or server. Note that while WSL can be installed with other Linux variants, such as OpenSUSE, the following instructions have only been tested with Ubuntu Bionic. This feature is not supported in versions of Windows prior to Windows 10 or on Windows Server SKUs. In addition, it is available [only for 64-bit versions of Windows](https://msdn.microsoft.com/en-us/commandline/wsl/install_guide). Full instructions to install WSL are available on the above link. To install WSL on Windows 10 with Fall Creators Update installed (version >= 16215.0) do the following: 1. Enable the Windows Subsystem for Linux feature * Open the Windows Features dialog (`OptionalFeatures.exe`) * Enable 'Windows Subsystem for Linux' * Click 'OK' and restart if necessary 2. Install Ubuntu * Open Microsoft Store and search for Ubuntu or use [this link](https://www.microsoft.com/store/productId/9NBLGGH4MSV6) * Click Install 3. Complete Installation * Open a cmd prompt and type "Ubuntu" * Create a new UNIX user account (this is a separate account from your Windows account) After the bash shell is active, you can follow the instructions below, starting with the "Cross-compilation" section. Compiling the 64-bit version is recommended, but it is possible to compile the 32-bit version. Cross-compilation for Ubuntu and Windows Subsystem for Linux ------------------------------------------------------------ At the time of writing the Windows Subsystem for Linux installs Ubuntu Bionic 18.04. The steps below can be performed on Ubuntu (including in a VM) or WSL. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different. First, install the general dependencies: sudo apt update sudo apt upgrade sudo apt install autoconf automake build-essential bsdmainutils curl git libboost-all-dev libevent-dec libssl-dev libtool ninja-build pkg-config python3 The cmake version packaged with Ubuntu Bionic is too old for building Building Bitcoin ABC. To install the latest version: sudo apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' sudo apt update sudo apt install cmake A host toolchain (`build-essential`) is necessary because some dependency packages (such as `protobuf`) need to build host utilities that are used in the build process. See also: [dependencies.md](dependencies.md). ## Building for 64-bit Windows The first step is to install the mingw-w64 cross-compilation tool chain. Due to different Ubuntu packages for each distribution and problems with the Xenial packages the steps for each are different. Common steps to install mingw32 cross compiler tool chain: sudo apt install g++-mingw-w64-x86-64 Ubuntu Xenial 16.04 and Windows Subsystem for Linux [1](#footnote1),[2](#footnote2): sudo apt install software-properties-common sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu artful universe" sudo apt update sudo apt upgrade sudo update-alternatives --config x86_64-w64-mingw32-g++ # Set the default mingw32 g++ compiler option to posix. sudo update-alternatives --config x86_64-w64-mingw32-gcc # Set the default mingw32 gcc compiler option to posix. Ubuntu Artful 17.10 [2](#footnote2) and later, including Ubuntu Bionic on WSL: sudo update-alternatives --config x86_64-w64-mingw32-g++ # Set the default mingw32 g++ compiler option to posix. sudo update-alternatives --config x86_64-w64-mingw32-gcc # Set the default mingw32 gcc compiler option to posix. Once the toolchain is installed the build steps are common: Note that for WSL the Bitcoin ABC source path MUST be somewhere in the default mount file system, for example /usr/src/bitcoin-abc, AND not under /mnt/d/. This means you cannot use a directory that is located directly on the host Windows file system to perform the build. Acquire the source in the usual way: git clone https://github.com/Bitcoin-ABC/bitcoin-abc.git Once the source code is ready the build steps are below: PATH=$(echo "$PATH" | sed -e 's/:\/mnt.*//g') # strip out problematic Windows %PATH% imported var cd depends make build-win64 cd .. mkdir build cd build cmake -GNinja .. -DCMAKE_TOOLCHAIN_FILE=../cmake/platforms/Win64.cmake -DBUILD_BITCOIN_SEEDER=OFF # seeder not supported in Windows yet ninja ## Depends system For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory. Installation ------------- After building using the Windows subsystem it can be useful to copy the compiled executables to a directory on the Windows drive in the same directory structure as they appear in the release `.zip` archive. This can be done in the following way. This will install to `c:\workspace\bitcoin-abc`, for example: cmake -GNinja .. -DCMAKE_TOOLCHAIN_FILE=../cmake/platforms/Win64.cmake -DBUILD_BITCOIN_SEEDER=OFF -DCMAKE_INSTALL_PREFIX=/mnt/c/workspace/bitcoin-abc ninja install Footnotes --------- 1: There is currently a bug in the 64 bit Mingw-w64 cross compiler packaged for WSL/Ubuntu Xenial 16.04 that causes two of the bitcoin executables to crash shortly after start up. The bug is related to the -fstack-protector-all g++ compiler flag which is used to mitigate buffer overflows. Installing the Mingw-w64 packages from the Ubuntu 17.10 distribution solves the issue, however, this is not an officially supported approach and it's only recommended if you are prepared to reinstall WSL/Ubuntu should something break. 2: Starting from Ubuntu Xenial 16.04, the Mingw-w64 packages install two different compiler options to allow a choice between either posix or win32 threads. The default option is win32 threads which is the more efficient since it will result in binary code that links directly with the Windows kernel32.lib. Unfortunately, the headers required to support win32 threads conflict with some of the classes in the C++11 standard library, in particular std::mutex. It's not possible to build the Bitcoin ABC code using the win32 version of the Mingw-w64 cross compilers (at least not without modifying headers in the Bitcoin ABC source code). diff --git a/doc/dependencies.md b/doc/dependencies.md index 8a50e5623..86a02d740 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -1,49 +1,49 @@ Dependencies ============ These are the dependencies currently used by Bitcoin ABC. You can find instructions for installing them in the [`build-*.md`](../INSTALL.md) file for your platform. | Dependency | Version used | Minimum required | CVEs | Shared | [Bundled Qt library](https://doc.qt.io/qt-5/configure-options.html) | | --- | --- | --- | --- | --- | --- | | Berkeley DB | [5.3.28](http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 5.3 | No | | | | Boost | [1.70.0](https://www.boost.org/users/download/) | 1.59.0 | No | | | -| Clang | | [3.4](https://releases.llvm.org/download.html) (C++14 support) | | | | +| Clang | | [5](https://releases.llvm.org/download.html) (C++17 support) | | | | | CMake | | [3.16](https://cmake.org/download/) | | | | | Expat | [2.2.7](https://libexpat.github.io/) | | No | Yes | | | fontconfig | [2.12.6](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | | FreeType | [2.7.1](http://download.savannah.gnu.org/releases/freetype) | | No | | | -| GCC | | [5.0](https://gcc.gnu.org/) (C++14 support) | | | | +| GCC | | [7](https://gcc.gnu.org/) (C++17 support) | | | | | HarfBuzz-NG | | | | | | | jemalloc | [5.2.1](https://github.com/jemalloc/jemalloc/releases) | 3.6.0 | | | | | libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | 2.0.22 | No | | | | libpng | | | | | Yes | | librsvg | | | | | | | MiniUPnPc | [2.0.20180203](https://miniupnp.tuxfamily.org/files) | 1.9 | No | | | | Ninja | | [1.5.1](https://github.com/ninja-build/ninja/releases) | | | | | OpenSSL | [1.0.1k](https://www.openssl.org/source) | | Yes | | | | PCRE | | | | | Yes | | protobuf | [2.6.1](https://github.com/google/protobuf/releases) | | No | | | | Python (tests) | | [3.5](https://www.python.org/downloads) | | | | | qrencode | [3.4.4](https://fukuchi.org/works/qrencode) | | No | | | | Qt | [5.9.7](https://download.qt.io/official_releases/qt/) | 5.9.5 | No | | | | XCB | | | | | Yes (Linux only) | | xkbcommon | | | | | Yes (Linux only) | | ZeroMQ | [4.3.1](https://github.com/zeromq/libzmq/releases) | 4.1.5 | No | | | | zlib | [1.2.11](http://zlib.net/) | | | | No | Controlling dependencies ------------------------ Some dependencies are not needed in all configurations. The following are some factors that affect the dependency list. #### Options passed to `cmake` * MiniUPnPc is not needed with `-DENABLE_UPNP=OFF`. * Berkeley DB is not needed with `-DBUILD_BITCOIN_WALLET=OFF`. * protobuf is not needed with `-DENABLE_BIP70=OFF`. * Qt is not needed with `-DBUILD_BITCOIN_QT=OFF`. * qrencode is not needed with `-DENABLE_QRCODE=OFF`. * ZeroMQ is not needed with the `-DBUILD_BITCOIN_ZMQ=OFF`. #### Other * librsvg is only needed if you need to run `ninja osx-dmg` on (cross-compilation to) macOS. diff --git a/doc/release-notes.md b/doc/release-notes.md index e7c5a40ef..f66f5a70a 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,7 +1,9 @@ # Bitcoin ABC 0.22.8 Release Notes Bitcoin ABC version 0.22.8 is now available from: This release includes the following features and fixes: + +- Code updated to conform to the C++17 standard. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3f75517a4..eb2ce4fdd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,712 +1,713 @@ # Copyright (c) 2017 The Bitcoin developers project(bitcoind) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) # Default visibility is hidden on all targets. set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden) # Supported Networks set(NETWORK_COMPATIBILITY "ABC" CACHE STRING "Network that will be supported: BCHA or BCHN") option(BUILD_BITCOIN_WALLET "Activate the wallet functionality" ON) option(BUILD_BITCOIN_ZMQ "Activate the ZeroMQ functionalities" ON) option(BUILD_BITCOIN_CLI "Build bitcoin-cli" ON) option(BUILD_BITCOIN_TX "Build bitcoin-tx" ON) option(BUILD_BITCOIN_QT "Build bitcoin-qt" ON) option(BUILD_BITCOIN_SEEDER "Build bitcoin-seeder" ON) option(BUILD_LIBBITCOINCONSENSUS "Build the bitcoinconsenus shared library" ON) option(ENABLE_BIP70 "Enable BIP70 (payment protocol) support in GUI" ON) option(ENABLE_HARDENING "Harden the executables" ON) option(ENABLE_REDUCE_EXPORTS "Reduce the amount of exported symbols" OFF) option(ENABLE_STATIC_LIBSTDCXX "Statically link libstdc++" OFF) option(ENABLE_GLIBC_BACK_COMPAT "Enable Glibc compatibility features" OFF) option(ENABLE_QRCODE "Enable QR code display" ON) option(ENABLE_UPNP "Enable UPnP support" ON) option(START_WITH_UPNP "Make UPnP the default to map ports" OFF) option(ENABLE_CLANG_TIDY "Enable clang-tidy checks for Bitcoin ABC" OFF) option(ENABLE_PROFILING "Select the profiling tool to use" OFF) option(USE_LD_GOLD "Try to use gold as a linker if available" ON) set(OS_WITH_JEMALLOC_AS_SYSTEM_DEFAULT "Android" "FreeBSD" "NetBSD" ) if(NOT CMAKE_SYSTEM_NAME IN_LIST OS_WITH_JEMALLOC_AS_SYSTEM_DEFAULT) set(USE_JEMALLOC_DEFAULT ON) endif() # FIXME: Building against jemalloc causes the software to segfault on OSX. # See https://github.com/Bitcoin-ABC/bitcoin-abc/issues/401 if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT CMAKE_CROSSCOMPILING) set(USE_JEMALLOC_DEFAULT OFF) endif() option(USE_JEMALLOC "Use jemalloc as an allocation library" ${USE_JEMALLOC_DEFAULT}) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(DEFAULT_ENABLE_DBUS_NOTIFICATIONS ON) endif() option(ENABLE_DBUS_NOTIFICATIONS "Enable DBus desktop notifications. Linux only." ${DEFAULT_ENABLE_DBUS_NOTIFICATIONS}) # If ccache is available, then use it. find_program(CCACHE ccache) if(CCACHE) message(STATUS "Using ccache: ${CCACHE}") set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE}) set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE}) endif(CCACHE) # Disable what we do not need for the native build. include(NativeExecutable) native_add_cmake_flags( "-DBUILD_BITCOIN_WALLET=OFF" "-DBUILD_BITCOIN_QT=OFF" "-DBUILD_BITCOIN_ZMQ=OFF" "-DENABLE_QRCODE=OFF" "-DENABLE_UPNP=OFF" "-DUSE_JEMALLOC=OFF" "-DENABLE_CLANG_TIDY=OFF" "-DENABLE_BIP70=OFF" ) if(ENABLE_CLANG_TIDY) include(ClangTidy) endif() if(ENABLE_SANITIZERS) include(Sanitizers) enable_sanitizers(${ENABLE_SANITIZERS}) endif() include(AddCompilerFlags) if(USE_LD_GOLD) add_linker_flags(-fuse-ld=gold) endif() # Prefer -g3, defaults to -g if unavailable foreach(LANGUAGE C CXX) set(COMPILER_DEBUG_LEVEL -g) check_compiler_flags(G3_IS_SUPPORTED ${LANGUAGE} -g3) if(${G3_IS_SUPPORTED}) set(COMPILER_DEBUG_LEVEL -g3) endif() add_compile_options_to_configuration_for_language(Debug ${LANGUAGE} ${COMPILER_DEBUG_LEVEL}) endforeach() # Define the debugging symbols DEBUG and DEBUG_LOCKORDER when the Debug build # type is selected. add_compile_definitions_to_configuration(Debug DEBUG DEBUG_LOCKORDER) # Add -ftrapv when building in Debug add_compile_options_to_configuration(Debug -ftrapv) # All versions of gcc that we commonly use for building are subject to bug # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90348. To work around that, set # -fstack-reuse=none for all gcc builds. (Only gcc understands this flag) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") add_compiler_flags(-fstack-reuse=none) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") # Ensure that WINDRES_PREPROC is enabled when using windres. list(APPEND CMAKE_RC_FLAGS "-DWINDRES_PREPROC") # Build all static so there is no dll file to distribute. add_linker_flags(-static) add_compile_definitions( # Windows 7 _WIN32_WINNT=0x0601 # Internet Explorer 5.01 (!) _WIN32_IE=0x0501 # Define WIN32_LEAN_AND_MEAN to exclude APIs such as Cryptography, DDE, # RPC, Shell, and Windows Sockets. WIN32_LEAN_AND_MEAN ) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") add_compile_definitions(MAC_OSX OBJC_OLD_DISPATCH_PROTOTYPES=0) add_linker_flags(-Wl,-dead_strip_dylibs) endif() if(ENABLE_REDUCE_EXPORTS) # Default visibility is set by CMAKE__VISIBILITY_PRESET, but this # doesn't tell if the visibility set is effective. # Check if the flag -fvisibility=hidden is supported, as using the hidden # visibility is a requirement to reduce exports. check_compiler_flags(HAS_CXX_FVISIBILITY CXX -fvisibility=hidden) if(NOT HAS_CXX_FVISIBILITY) message(FATAL_ERROR "Cannot set default symbol visibility. Use -DENABLE_REDUCE_EXPORTS=OFF.") endif() # Also hide symbols from static libraries add_linker_flags(-Wl,--exclude-libs,libstdc++) endif() # Enable statically linking libstdc++ if(ENABLE_STATIC_LIBSTDCXX) add_linker_flags(-static-libstdc++) endif() set(CMAKE_POSITION_INDEPENDENT_CODE ON) if(ENABLE_HARDENING) # Enable stack protection add_cxx_compiler_flags(-fstack-protector-all -Wstack-protector) # Enable some buffer overflow checking, except in -O0 builds which # do not support them add_compiler_flags(-U_FORTIFY_SOURCE) add_compile_options($<$>:-D_FORTIFY_SOURCE=2>) # Enable ASLR (these flags are primarily targeting MinGw) add_linker_flags(-Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va) # Make the relocated sections read-only add_linker_flags(-Wl,-z,relro -Wl,-z,now) # CMake provides the POSITION_INDEPENDENT_CODE property to set PIC/PIE. cmake_policy(SET CMP0083 NEW) include(CheckPIESupported) check_pie_supported() if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") # MinGw provides its own libssp for stack smashing protection link_libraries(ssp) endif() endif() if(ENABLE_PROFILING MATCHES "gprof") message(STATUS "Enable profiling with gprof") # -pg is incompatible with -pie. Since hardening and profiling together # doesn't make sense, we simply make them mutually exclusive here. # Additionally, hardened toolchains may force -pie by default, in which # case it needs to be turned off with -no-pie. if(ENABLE_HARDENING) message(FATAL_ERROR "Profiling with gprof requires disabling hardening with -DENABLE_HARDENING=OFF.") endif() add_linker_flags(-no-pie) add_compiler_flags(-pg) add_linker_flags(-pg) endif() # Enable warning add_c_compiler_flags(-Wnested-externs -Wstrict-prototypes) add_compiler_flags( -Wall -Wextra -Wformat -Wvla -Wcast-align -Wunused-parameter -Wmissing-braces -Wthread-safety -Wshadow -Wshadow-field -Wrange-loop-analysis -Wredundant-decls ) add_compiler_flag_group(-Wformat -Wformat-security) add_cxx_compiler_flags( -Wredundant-move ) option(EXTRA_WARNINGS "Enable extra warnings" OFF) if(EXTRA_WARNINGS) add_cxx_compiler_flags(-Wsuggest-override) else() add_compiler_flags(-Wno-unused-parameter) add_compiler_flags(-Wno-implicit-fallthrough) endif() # libtool style configure add_subdirectory(config) # Enable LFS (Large File Support) on targets that don't have it natively. # This should be defined before the libraries are included as leveldb need the # definition to be set. if(NOT HAVE_LARGE_FILE_SUPPORT) add_compile_definitions(_FILE_OFFSET_BITS=64) add_linker_flags(-Wl,--large-address-aware) endif() if(ENABLE_GLIBC_BACK_COMPAT) # Wrap some glibc functions with ours add_linker_flags(-Wl,--wrap=__divmoddi4) add_linker_flags(-Wl,--wrap=log2f) if(NOT HAVE_LARGE_FILE_SUPPORT) add_linker_flags(-Wl,--wrap=fcntl -Wl,--wrap=fcntl64) endif() endif() if(USE_JEMALLOC) # Most of the sanitizers require their instrumented allocation functions to # be fully functional. This is obviously the case for all the memory related # sanitizers (asan, lsan, msan) but not only. if(ENABLE_SANITIZERS) message(WARNING "Jemalloc is incompatible with the sanitizers and has been disabled.") else() find_package(Jemalloc 3.6.0 REQUIRED) link_libraries(Jemalloc::jemalloc) endif() endif() # Make sure that all the global compiler and linker flags are set BEFORE # including the libraries so they apply as needed. # libraries add_subdirectory(crypto) add_subdirectory(leveldb) add_subdirectory(secp256k1) add_subdirectory(univalue) # Find the git root, and returns the full path to the .git/logs/HEAD file if # it exists. function(find_git_head_logs_file RESULT) find_package(Git) if(GIT_FOUND) execute_process( COMMAND "${GIT_EXECUTABLE}" "rev-parse" "--show-toplevel" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE GIT_ROOT RESULT_VARIABLE GIT_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) if(GIT_RESULT EQUAL 0) set(GIT_LOGS_DIR "${GIT_ROOT}/.git/logs") set(GIT_HEAD_LOGS_FILE "${GIT_LOGS_DIR}/HEAD") # If the .git/logs/HEAD does not exist, create it if(NOT EXISTS "${GIT_HEAD_LOGS_FILE}") file(MAKE_DIRECTORY "${GIT_LOGS_DIR}") file(TOUCH "${GIT_HEAD_LOGS_FILE}") endif() set(${RESULT} "${GIT_HEAD_LOGS_FILE}" PARENT_SCOPE) endif() endif() endfunction() find_git_head_logs_file(GIT_HEAD_LOGS_FILE) set(OBJ_DIR "${CMAKE_CURRENT_BINARY_DIR}/obj") file(MAKE_DIRECTORY "${OBJ_DIR}") set(BUILD_HEADER "${OBJ_DIR}/build.h") set(BUILD_HEADER_TMP "${BUILD_HEADER}.tmp") add_custom_command( DEPENDS "${GIT_HEAD_LOGS_FILE}" "${CMAKE_SOURCE_DIR}/share/genbuild.sh" OUTPUT "${BUILD_HEADER}" COMMAND "${CMAKE_SOURCE_DIR}/share/genbuild.sh" "${BUILD_HEADER_TMP}" "${CMAKE_SOURCE_DIR}" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${BUILD_HEADER_TMP}" "${BUILD_HEADER}" COMMAND ${CMAKE_COMMAND} -E remove "${BUILD_HEADER_TMP}" ) # Because the Bitcoin ABc source code is disorganised, we # end up with a bunch of libraries without any apparent # cohesive structure. This is inherited from Bitcoin Core # and reflecting this. # TODO: Improve the structure once cmake is rocking. # Various completely unrelated features shared by all executables. add_library(util chainparamsbase.cpp clientversion.cpp compat/glibcxx_sanity.cpp compat/strnlen.cpp fs.cpp interfaces/handler.cpp logging.cpp random.cpp randomenv.cpp rcu.cpp rpc/request.cpp blockdb.cpp support/cleanse.cpp support/lockedpool.cpp sync.cpp threadinterrupt.cpp uint256.cpp util/asmap.cpp util/bip32.cpp util/bytevectorhash.cpp util/error.cpp util/message.cpp util/moneystr.cpp util/settings.cpp util/spanparsing.cpp util/strencodings.cpp util/string.cpp util/system.cpp util/threadnames.cpp util/time.cpp util/url.cpp # obj/build.h "${BUILD_HEADER}" ) target_compile_definitions(util PUBLIC HAVE_CONFIG_H HAVE_BUILD_INFO) target_include_directories(util PUBLIC . # To access the config/ and obj/ directories ${CMAKE_CURRENT_BINARY_DIR} ) if(ENABLE_GLIBC_BACK_COMPAT) target_sources(util PRIVATE compat/glibc_compat.cpp) endif() # Target specific configs if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_RUNTIME ON) set(Boost_THREADAPI win32) find_package(SHLWAPI REQUIRED) target_link_libraries(util SHLWAPI::shlwapi) find_library(WS2_32_LIBRARY NAMES ws2_32) target_link_libraries(util ${WS2_32_LIBRARY}) target_compile_definitions(util PUBLIC BOOST_THREAD_USE_LIB) endif() target_link_libraries(util univalue crypto) macro(link_event TARGET) non_native_target_link_libraries(${TARGET} Event 2.0.22 ${ARGN}) endmacro() link_event(util event) macro(link_boost TARGET) non_native_target_link_libraries(${TARGET} Boost 1.59 ${ARGN}) endmacro() link_boost(util filesystem thread) # Make sure boost uses std::atomic (it doesn't before 1.63) target_compile_definitions(util PUBLIC BOOST_SP_USE_STD_ATOMIC BOOST_AC_USE_STD_ATOMIC) function(add_network_sources NETWORK_SOURCES) if(${NETWORK_COMPATIBILITY} MATCHES "ABC|BCHA") set(NETWORK_DIR abc) elseif(${NETWORK_COMPATIBILITY} MATCHES "BCHN") set(NETWORK_DIR bchn) else() message(FATAL "${NETWORK_COMPATIBILITY} is not a supported network") endif() list(TRANSFORM ARGN PREPEND "networks/${NETWORK_DIR}/" OUTPUT_VARIABLE NETWORK_SOURCES ) set(NETWORK_SOURCES ${NETWORK_SOURCES} PARENT_SCOPE) endfunction() add_network_sources(NETWORK_SOURCES checkpoints.cpp network.cpp chainparamsconstants.cpp ) # More completely unrelated features shared by all executables. # Because nothing says this is different from util than "common" add_library(common amount.cpp base58.cpp bloom.cpp cashaddr.cpp cashaddrenc.cpp chainparams.cpp chainparamsconstants.cpp config.cpp consensus/merkle.cpp coins.cpp compressor.cpp eventloop.cpp feerate.cpp core_read.cpp core_write.cpp key.cpp key_io.cpp merkleblock.cpp net_permissions.cpp netaddress.cpp netbase.cpp outputtype.cpp policy/policy.cpp primitives/block.cpp protocol.cpp psbt.cpp rpc/rawtransaction_util.cpp rpc/util.cpp scheduler.cpp salteduint256hasher.cpp versionbitsinfo.cpp warnings.cpp ${NETWORK_SOURCES} ) target_link_libraries(common util secp256k1 script) # script library add_library(script script/bitfield.cpp script/descriptor.cpp script/interpreter.cpp script/script.cpp script/script_error.cpp script/sigencoding.cpp script/sign.cpp script/signingprovider.cpp script/standard.cpp ) target_link_libraries(script common) # libbitcoinconsensus add_library(bitcoinconsensus arith_uint256.cpp hash.cpp primitives/transaction.cpp pubkey.cpp uint256.cpp util/strencodings.cpp consensus/tx_check.cpp ) target_link_libraries(bitcoinconsensus script) include(InstallationHelper) if(BUILD_LIBBITCOINCONSENSUS) target_compile_definitions(bitcoinconsensus PUBLIC BUILD_BITCOIN_INTERNAL HAVE_CONSENSUS_LIB ) install_shared_library(bitcoinconsensus script/bitcoinconsensus.cpp PUBLIC_HEADER script/bitcoinconsensus.h ) endif() # Bitcoin server facilities add_library(server addrdb.cpp addrman.cpp avalanche/peermanager.cpp avalanche/processor.cpp avalanche/proof.cpp avalanche/proofbuilder.cpp banman.cpp blockencodings.cpp blockfilter.cpp blockindex.cpp chain.cpp checkpoints.cpp config.cpp consensus/activation.cpp consensus/tx_verify.cpp dbwrapper.cpp flatfile.cpp httprpc.cpp httpserver.cpp index/base.cpp index/blockfilterindex.cpp index/txindex.cpp init.cpp interfaces/chain.cpp interfaces/node.cpp miner.cpp minerfund.cpp net.cpp net_processing.cpp node/coin.cpp node/coinstats.cpp node/context.cpp node/psbt.cpp node/transaction.cpp noui.cpp policy/fees.cpp policy/settings.cpp pow/aserti32d.cpp pow/daa.cpp pow/eda.cpp pow/grasberg.cpp pow/pow.cpp rest.cpp rpc/abc.cpp rpc/avalanche.cpp rpc/blockchain.cpp rpc/command.cpp rpc/mining.cpp rpc/misc.cpp rpc/net.cpp rpc/rawtransaction.cpp rpc/server.cpp script/scriptcache.cpp script/sigcache.cpp shutdown.cpp timedata.cpp torcontrol.cpp txdb.cpp txmempool.cpp ui_interface.cpp validation.cpp validationinterface.cpp versionbits.cpp ) target_include_directories(server PRIVATE leveldb/helpers/memenv) target_link_libraries(server bitcoinconsensus leveldb memenv ) link_event(server event) if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Windows") link_event(server pthreads) endif() if(ENABLE_UPNP) find_package(MiniUPnPc 1.9 REQUIRED) target_link_libraries(server MiniUPnPc::miniupnpc) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") # TODO: check if we are really using a static library. Assume this is # the one from the depends for now since the native windows build is not # supported. target_compile_definitions(server PUBLIC -DSTATICLIB PUBLIC -DMINIUPNP_STATICLIB ) endif() endif() # Test suites. add_subdirectory(test) add_subdirectory(avalanche/test) add_subdirectory(pow/test) # Benchmark suite. add_subdirectory(bench) include(BinaryTest) include(WindowsVersionInfo) # Wallet if(BUILD_BITCOIN_WALLET) add_subdirectory(wallet) target_link_libraries(server wallet) # bitcoin-wallet add_executable(bitcoin-wallet bitcoin-wallet.cpp) generate_windows_version_info(bitcoin-wallet DESCRIPTION "CLI tool for ${PACKAGE_NAME} wallets" ) target_link_libraries(bitcoin-wallet wallet-tool common util) add_to_symbols_check(bitcoin-wallet) add_to_security_check(bitcoin-wallet) install_target(bitcoin-wallet) install_manpages(bitcoin-wallet) else() target_sources(server PRIVATE dummywallet.cpp) endif() # ZeroMQ if(BUILD_BITCOIN_ZMQ) add_subdirectory(zmq) target_link_libraries(server zmq) endif() # RPC client support add_library(rpcclient compat/stdin.cpp rpc/client.cpp ) target_link_libraries(rpcclient univalue util) # bitcoin-seeder if(BUILD_BITCOIN_SEEDER) add_subdirectory(seeder) endif() # bitcoin-cli if(BUILD_BITCOIN_CLI) add_executable(bitcoin-cli bitcoin-cli.cpp) generate_windows_version_info(bitcoin-cli DESCRIPTION "JSON-RPC client for ${PACKAGE_NAME}" ) target_link_libraries(bitcoin-cli common rpcclient) link_event(bitcoin-cli event) add_to_symbols_check(bitcoin-cli) add_to_security_check(bitcoin-cli) install_target(bitcoin-cli) install_manpages(bitcoin-cli) endif() # bitcoin-tx if(BUILD_BITCOIN_TX) add_executable(bitcoin-tx bitcoin-tx.cpp) generate_windows_version_info(bitcoin-tx DESCRIPTION "CLI Bitcoin transaction editor utility" ) target_link_libraries(bitcoin-tx bitcoinconsensus) add_to_symbols_check(bitcoin-tx) add_to_security_check(bitcoin-tx) install_target(bitcoin-tx) install_manpages(bitcoin-tx) endif() # bitcoind add_executable(bitcoind bitcoind.cpp) target_link_libraries(bitcoind server) generate_windows_version_info(bitcoind DESCRIPTION "Bitcoin node with a JSON-RPC server" ) add_to_symbols_check(bitcoind) add_to_security_check(bitcoind) install_target(bitcoind) install_manpages(bitcoind) # Bitcoin-qt if(BUILD_BITCOIN_QT) add_subdirectory(qt) endif() diff --git a/src/compat/assumptions.h b/src/compat/assumptions.h index dd9e2dabb..a5b6c49ed 100644 --- a/src/compat/assumptions.h +++ b/src/compat/assumptions.h @@ -1,105 +1,105 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // Compile-time verification of assumptions we make. #ifndef BITCOIN_COMPAT_ASSUMPTIONS_H #define BITCOIN_COMPAT_ASSUMPTIONS_H #include #include #include #include // Assumption: We assume that the macro NDEBUG is not defined. // Example(s): We use assert(...) extensively with the assumption of it never // being a noop at runtime. #if defined(NDEBUG) #error "Bitcoin cannot be compiled without assertions." #endif -// Assumption: We assume a C++14 (ISO/IEC 14882:2014) compiler (minimum +// Assumption: We assume a C++17 (ISO/IEC 14882:2017) compiler (minimum // requirement). // Example(s): We use std::make_unique() through the codebase. // Note: MSVC does not report the expected __cplusplus value due to // legacy reasons. #if !defined(_MSC_VER) // N3936* ยง16.8 [cpp.predefined]/p1:: // "The name __cplusplus is defined to the value 201402L when compiling a C++ // translation unit." -static_assert(__cplusplus >= 201402L, "C++14 standard assumed"); +static_assert(__cplusplus >= 201703L, "C++17 standard assumed"); #endif // Assumption: We assume the floating-point types to fulfill the requirements of // IEC 559 (IEEE 754) standard. // Example(s): Floating-point division by zero in ConnectBlock, // CreateTransaction // and EstimateMedianVal. static_assert(std::numeric_limits::is_iec559, "IEEE 754 float assumed"); static_assert(std::numeric_limits::is_iec559, "IEEE 754 double assumed"); // Assumption: We assume floating-point widths. // Example(s): Type punning in serialization code // (ser_{float,double}_to_uint{32,64}). static_assert(sizeof(float) == 4, "32-bit float assumed"); static_assert(sizeof(double) == 8, "64-bit double assumed"); // Assumption: We assume integer widths. // Example(s): GetSizeOfCompactSize and WriteCompactSize in the serialization // code. static_assert(sizeof(short) == 2, "16-bit short assumed"); static_assert(sizeof(int) == 4, "32-bit int assumed"); // Assumption: We assume 8-bit bytes, because 32-bit int and 16-bit short are // assumed. static_assert(CHAR_BIT == 8, "8-bit bytes assumed"); // Assumption: We assume uint8_t is an alias of unsigned char. // char, unsigned char, and std::byte (C++17) are the only "byte types" // according to the C++ Standard. "byte type" means a type that can be used to // observe an object's value representation. We use uint8_t everywhere to see // bytes, so we have to ensure that uint8_t is an alias to a "byte type". // http://eel.is/c++draft/basic.types // http://eel.is/c++draft/basic.memobj#def:byte // http://eel.is/c++draft/expr.sizeof#1 // http://eel.is/c++draft/cstdint#syn static_assert(std::is_same::value, "uint8_t is an alias of unsigned char"); // Assumption: We assume size_t to be 32-bit or 64-bit. // Example(s): size_t assumed to be at least 32-bit in // ecdsa_signature_parse_der_lax(...). // size_t assumed to be 32-bit or 64-bit in MallocUsage(...). static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t assumed to be 32-bit or 64-bit"); static_assert(sizeof(size_t) == sizeof(void *), "Sizes of size_t and void* assumed to be equal"); // Some important things we are NOT assuming (non-exhaustive list): // * We are NOT assuming a specific value for std::endian::native. // * We are NOT assuming a specific value for std::locale("").name(). // * We are NOT assuming a specific value for // std::numeric_limits::is_signed. /** * /!\ C++ right shift signedness handling is implementation defined. It is * defined as an arithmetic on all the platform we support, but this * may not be the case on other platforms. * * NB: C++20 defines signed right shift as being arithmetic shifts, so in * practice, we should see all platforms converge toward that behavior if * they haven't already. */ static_assert((int64_t(-1) >> 1) == int64_t(-1), "Arithmetic right shift assumed"); /** * /!\ C++ Does not guarantee 2-complement, but it implementation defined. All * the platform we support use 2-complement. */ static_assert((int64_t(-10) & 0xffff) == 0xfff6, "2-complement assumed"); #endif // BITCOIN_COMPAT_ASSUMPTIONS_H diff --git a/src/span.h b/src/span.h index 77a578ab9..3ad629405 100644 --- a/src/span.h +++ b/src/span.h @@ -1,106 +1,130 @@ // Copyright (c) 2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SPAN_H #define BITCOIN_SPAN_H #include #include #include #include /** A Span is an object that can refer to a contiguous sequence of objects. * * It implements a subset of C++20's std::span. */ template class Span { C *m_data; std::ptrdiff_t m_size; public: constexpr Span() noexcept : m_data(nullptr), m_size(0) {} constexpr Span(C *data, std::ptrdiff_t size) noexcept : m_data(data), m_size(size) {} constexpr Span(C *data, C *end) noexcept : m_data(data), m_size(end - data) {} + /** Implicit conversion of spans between compatible types. + * + * Specifically, if a pointer to an array of type O can be implicitly + * converted to a pointer to an array of type C, then permit implicit + * conversion of Span to Span. This matches the behavior of the + * corresponding C++20 std::span constructor. + * + * For example this means that a Span can be converted into a Span. + */ + template ::value, int>::type = 0> + constexpr Span(const Span &other) noexcept + : m_data(other.m_data), m_size(other.m_size) {} + + /** Default copy constructor. */ + constexpr Span(const Span &) noexcept = default; + + /** Default assignment operator. */ + Span &operator=(const Span &other) noexcept = default; + constexpr C *data() const noexcept { return m_data; } constexpr C *begin() const noexcept { return m_data; } constexpr C *end() const noexcept { return m_data + m_size; } constexpr C &front() const noexcept { return m_data[0]; } constexpr C &back() const noexcept { return m_data[m_size - 1]; } constexpr std::ptrdiff_t size() const noexcept { return m_size; } constexpr C &operator[](std::ptrdiff_t pos) const noexcept { return m_data[pos]; } constexpr Span subspan(std::ptrdiff_t offset) const noexcept { return Span(m_data + offset, m_size - offset); } constexpr Span subspan(std::ptrdiff_t offset, std::ptrdiff_t count) const noexcept { return Span(m_data + offset, count); } constexpr Span first(std::ptrdiff_t count) const noexcept { return Span(m_data, count); } constexpr Span last(std::ptrdiff_t count) const noexcept { return Span(m_data + m_size - count, count); } friend constexpr bool operator==(const Span &a, const Span &b) noexcept { return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); } friend constexpr bool operator!=(const Span &a, const Span &b) noexcept { return !(a == b); } friend constexpr bool operator<(const Span &a, const Span &b) noexcept { return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); } friend constexpr bool operator<=(const Span &a, const Span &b) noexcept { return !(b < a); } friend constexpr bool operator>(const Span &a, const Span &b) noexcept { return (b < a); } friend constexpr bool operator>=(const Span &a, const Span &b) noexcept { return !(a < b); } + + template friend class Span; }; /** Create a span to a container exposing data() and size(). * * This correctly deals with constness: the returned Span's element type will be * whatever data() returns a pointer to. If either the passed container is * const, or its element type is const, the resulting span will have a const * element type. * * std::span will have a constructor that implements this functionality * directly. */ template constexpr Span MakeSpan(A (&a)[N]) { return Span(a, N); } template constexpr Span< typename std::remove_pointer().data())>::type> MakeSpan(V &v) { return Span< typename std::remove_pointer().data())>::type>( v.data(), v.size()); } /** Pop the last element off a span, and return a reference to that element. */ template T &SpanPopBack(Span &span) { size_t size = span.size(); assert(size > 0); T &back = span[size - 1]; span = Span(span.data(), size - 1); return back; } #endif // BITCOIN_SPAN_H