diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a5e64ce4a4..7bf8eb0701 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,222 +1,227 @@ Contributing to Bitcoin ABC =========================== The Bitcoin ABC project welcomes contributors! This guide is intended to help developers contribute effectively to Bitcoin ABC. Communicating with Developers ----------------------------- To get in contact with ABC developers, we monitor a telegram supergroup. The intent of this group is specifically to facilitate development of Bitcoin-ABC, and to welcome people who wish to participate. https://t.me/joinchat/HCYr50mxRWjA2uLqii-psw Acceptable use of this supergroup includes the following: * Introducing yourself to other ABC developers. * Getting help with your development environment. * Discussing how to complete a patch. It is not for: * Market discussion * Non-constructive criticism Bitcoin ABC Development Philosophy ---------------------------------- Bitcoin ABC aims for fast iteration and continuous integration. This means that there should be quick turnaround for patches to be proposed, reviewed, and committed. Changes should not sit in a queue for long. Here are some tips to help keep the development working as intended. These are guidelines for the normal and expected development process. Developers can use their judgement to deviate from these guidelines when they have a good reason to do so. - Keep each change small and self-contained. - Reach out for a 1-on-1 review so things move quickly. - Land the Diff quickly after it is accepted. - Don't amend changes after the Diff accepted, new Diff for another fix. - Review Diffs from other developers as quickly as possible. - Large changes should be broken into logical chunks that are easy to review, and keep the code in a functional state. - Do not mix moving stuff around with changing stuff. Do changes with renames on their own. - Sometimes you want to replace one subsystem by another implementation, in which case it is not possible to do things incrementally. In such cases, you keep both implementations in the codebase for a while, as described [here](https://www.gamasutra.com/view/news/128325/Opinion_Parallel_Implementations.php) - There are no "development" branches, all Diffs apply to the master branch, and should always improve it (no regressions). - Don't break the build, it is important to keep master green as much as possible. If a Diff is landed, and breaks the build, fix it quickly. If it cannot be fixed quickly, it should be reverted, and re-applied later when it no longer breaks the build. - As soon as you see a bug, you fix it. Do not continue on. Fixing the bug becomes the top priority, more important than completing other tasks. - Automate as much as possible, and spend time on things only humans can do. Here are some handy links for development practices aligned with Bitcoin ABC: - [Developer Notes](doc/developer-notes.md) - [Statement of Bitcoin ABC Values and Visions](https://www.yours.org/content/bitcoin-abc---our-values-and-vision-a282afaade7c) - [How to Do Code Reviews Like a Human - Part 1](https://mtlynch.io/human-code-reviews-1/) - [How to Do Code Reviews Like a Human - Part 2](https://mtlynch.io/human-code-reviews-2/) - [Large Diffs Are Hurting Your Ability To Ship](https://medium.com/@kurtisnusbaum/large-diffs-are-hurting-your-ability-to-ship-e0b2b41e8acf) - [Stacked Diffs: Keeping Phabricator Diffs Small](https://medium.com/@kurtisnusbaum/stacked-diffs-keeping-phabricator-diffs-small-d9964f4dcfa6) - [Parallel Implementations](https://www.gamasutra.com/view/news/128325/Opinion_Parallel_Implementations.php) - [The Pragmatic Programmer: From Journeyman to Master](https://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X) - [Advantages of monolithic version control](https://danluu.com/monorepo/) - [The importance of fixing bugs immediately](https://youtu.be/E2MIpi8pIvY?t=16m0s) - [Slow Deployment Causes Meetings](https://www.facebook.com/notes/kent-beck/slow-deployment-causes-meetings/1055427371156793/) - [Good Work, Great Work, and Right Work](https://forum.dlang.org/post/q7u6g1$94p$1@digitalmars.com) - [Accelerate: The Science of Lean Software and DevOps](https://www.amazon.com/Accelerate-Software-Performing-Technology-Organizations/dp/1942788339) Getting set up with the Bitcoin ABC Repository ---------------------------------------------- 1. Create an account at https://reviews.bitcoinabc.org/ 2. Install Git and Arcanist on your machine Git documentation can be found at: https://git-scm.com/ Arcanist documentation can be found at: https://secure.phabricator.com/book/phabricator/article/arcanist_quick_start/ And: https://secure.phabricator.com/book/phabricator/article/arcanist/ To install these packages on Debian or Ubuntu, type: `sudo apt-get install git arcanist` 3. If you do not already have an SSH key set up, follow these steps: Type: `ssh-keygen -t rsa -b 4096 -C "your_email@example.com"` Enter a file in which to save the key (/home/*username*/.ssh/id_rsa): [Press enter] 4. Upload your SSH public key to reviews.bitcoinabc.org - Go to: `https://reviews.bitcoinabc.org/settings/user/*username*/page/ssh/` - Under "SSH Key Actions", Select "Upload Public Key" Paste contents from: `/home/*username*/.ssh/id_rsa.pub` 5. Clone the repository and install Arcanist certificate: ``` git clone ssh://vcs@reviews.bitcoinabc.org:2221/source/bitcoin-abc.git cd bitcoin-abc arc install-certificate ``` Note: Arcanist tooling will tend to fail if your remote origin is set to something other than the above. A common mistake is to clone from Github and then forget to update your remotes. Follow instructions provided by `arc install-certificate` to provide your API token. 6. Code formatting tools During submission of patches, arcanist will automatically run `arc lint` to enforce Bitcoin ABC code formatting standards, and often suggests changes. If code formatting tools do not install automatically on your system, you -will have to install clang-format-8, autopep8, flake8, phpcs and shellcheck. +will have to install clang-format-8, clang-tidy (version >=8), autopep8, flake8, +phpcs and shellcheck. -To install clang-format-8 on Ubuntu (>= 18.04+updates) or Debian (>= 10): +To install clang-format-8 and clang-tidy on Ubuntu (>= 18.04+updates) or Debian (>= 10): ``` -sudo apt-get install clang-format-8 +sudo apt-get install clang-format-8 clang-tidy-8 clang-tools-8 ``` -To install clang-format-8 on OSX (requires npm): + +If not available in the distribution, `clang-format-8` and `clang-tidy` can be +installed from https://releases.llvm.org/download.html or https://apt.llvm.org. + +For example, for macOS: ``` -npm install -g clang-format@1.2.4 +curl http://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-apple-darwin.tar.xz | tar -xJv +ln -s $PWD/clang+llvm-8.0.0-x86_64-apple-darwin/bin/clang-format /usr/local/bin/clang-format +ln -s $PWD/clang+llvm-8.0.0-x86_64-apple-darwin/bin/clang-tidy /usr/local/bin/clang-tidy ``` -If not available in the distribution, clang-format-8 can be installed from -https://releases.llvm.org/download.html or https://apt.llvm.org To install autopep8, flake8 and phpcs on Ubuntu: ``` sudo apt-get install python-autopep8 flake8 php-codesniffer shellcheck ``` Working with The Bitcoin ABC Repository --------------------------------------- A typical workflow would be: - Create a topic branch in Git for your changes git checkout -b 'my-topic-branch' - Make your changes, and commit them git commit -a -m 'my-commit' - Create a differential with Arcanist arc diff You should add suggested reviewers and a test plan to the commit message. Note that Arcanist is set up to look only at the most-recent commit message, So all you changes for this Diff should be in one Git commit. - For large changes, break them into several Diffs, as described in this [guide](https://medium.com/@kurtisnusbaum/stacked-diffs-keeping-phabricator-diffs-small-d9964f4dcfa6). You can also include "Depends on Dxxx" in the Arcanist message to indicate dependence on other Diffs. - Log into Phabricator to see review and feedback. - Make changes as suggested by the reviewers. You can simply edit the files with my-topic-branch checked out, and then type `arc diff`. Arcanist will give you the option to add uncommited changes. Or, alternatively, you can commit the changes using `git commit -a --am` to add them to the last commit, or squash multiple commits by typing `git rebase -i master`. If you squash, make sure the commit message has the information needed for arcanist (such as the Diff number, reviewers, etc.). - Update your Diff by typing `arc diff` again. - When reviewers approve your Diff, it should be listed as "ready to Land" in Phabricator. When you want to commit your diff to the repository, check out type my-topic-branch in git, then type `arc land`. You have now successfully committed a change to the Bitcoin ABC repository. - When reviewing a Diff, apply the changeset on your local by using `arc patch D{NNNN}` - You will likely be re-writing git histories multiple times, which causes timestamp changes that require re-building a significant number of files. It's highly recommended to install `ccache` (re-run cmake if you install it later), as this will help cut your re-build times from several minutes to under a minute, in many cases. What to work on --------------- If you are looking for a useful task to contribute to the project, a good place to start is the list of tasks at https://reviews.bitcoinabc.org/maniphest/ You could also try [backporting](doc/backporting.md) some code from Bitcoin Core. Copyright --------- By contributing to this repository, you agree to license your work under the MIT license unless specified otherwise in `contrib/debian/copyright` or at the top of the file itself. Any work contributed where you are not the original author must contain its license header with the original author(s) and source. Disclosure Policy ----------------- See [DISCLOSURE_POLICY](DISCLOSURE_POLICY.md). diff --git a/cmake/modules/ClangTidy.cmake b/cmake/modules/ClangTidy.cmake new file mode 100644 index 0000000000..e514ba623d --- /dev/null +++ b/cmake/modules/ClangTidy.cmake @@ -0,0 +1,34 @@ +if(NOT CLANG_TIDY_EXE) + include(DoOrFail) + find_program_or_fail(CLANG_TIDY_EXE clang-tidy clang-tidy-10 clang-tidy-9 clang-tidy-8) + + execute_process( + COMMAND "${CLANG_TIDY_EXE}" -version + RESULT_VARIABLE CLANG_TIDY_VERSION_RESULT + OUTPUT_VARIABLE CLANG_TIDY_VERSION_OUTPUT + ) + + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" CLANG_TIDY_VERSION "${CLANG_TIDY_VERSION_OUTPUT}") + if("${CLANG_TIDY_VERSION}" VERSION_LESS "8.0.0") + message(FATAL_ERROR "clang-tidy version >= 8 is required") + endif() + + message(STATUS "Using clang-tidy: ${CLANG_TIDY_EXE} (version ${CLANG_TIDY_VERSION})") +endif() + +set(CLANG_TIDY_ARGS "${CLANG_TIDY_EXE}" -fix) + +set(CMAKE_C_CLANG_TIDY ${CLANG_TIDY_ARGS}) +set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_ARGS}) + +# This is useful to run clang-tidy manually: +# clang-tidy -checks= -p compile_commands.json +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Disable for a single target +macro(target_disable_clang_tidy TARGET) + set_target_properties(${TARGET} PROPERTIES + C_CLANG_TIDY "" + CXX_CLANG_TIDY "" + ) +endmacro() diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 32f6b915fe..f687b043c8 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,183 +1,185 @@ --- name: "bitcoin-abc-linux" enable_cache: true distro: "debian" suites: - "buster" architectures: - "amd64" multiarch: - "i386" packages: - "autoconf" - "automake" - "binutils-aarch64-linux-gnu" - "binutils-arm-linux-gnueabihf" - "binutils-gold" - "bsdmainutils" - "build-essential" - "ca-certificates" - "cmake" - "curl" - "faketime" - "g++-aarch64-linux-gnu" - "g++-arm-linux-gnueabihf" - "gcc-aarch64-linux-gnu" - "gcc-arm-linux-gnueabihf" - "git" - "gperf" - "lib32stdc++-8-dev" - "libc6-dev:i386" - "libtool" - "ninja-build" - "pkg-config" - "python3" # FIXME: these dependencies are only required to make CMake happy when building # native tools. They can be removed when the `NativeExecutable.cmake` gets # improved to avoid requiring all the bitcoin-abc dependencies. - "libboost-all-dev" - "libevent-dev" - "libssl-dev" remotes: - "url": "https://github.com/Bitcoin-ABC/bitcoin-abc.git" "dir": "bitcoin" files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" # CMake toolchain file name differ from host name declare -A CMAKE_TOOLCHAIN_FILE CMAKE_TOOLCHAIN_FILE[i686-pc-linux-gnu]=Linux32.cmake CMAKE_TOOLCHAIN_FILE[x86_64-linux-gnu]=Linux64.cmake CMAKE_TOOLCHAIN_FILE[arm-linux-gnueabihf]=LinuxARM.cmake CMAKE_TOOLCHAIN_FILE[aarch64-linux-gnu]=LinuxAArch64.cmake INSTALL_COMPONENTS="bitcoind bitcoin-qt bitcoin-seeder" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="date ar ranlib nm" HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" HOST_LDFLAGS=-static-libstdc++ export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export GZIP="-9n" export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} export BASE_CACHE=${GBUILD_PACKAGE_CACHE} mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } # Faketime for depends so intermediate results are comparable export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} cd bitcoin SOURCEDIR=`pwd` BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} mkdir -p source_package pushd source_package cmake -GNinja .. \ -DBUILD_BITCOIN_WALLET=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DBUILD_BITCOIN_SEEDER=OFF \ -DBUILD_BITCOIN_CLI=OFF \ -DBUILD_BITCOIN_TX=OFF \ -DBUILD_BITCOIN_QT=OFF \ -DBUILD_LIBBITCOINCONSENSUS=OFF \ + -DENABLE_CLANG_TIDY=OFF \ -DENABLE_QRCODE=OFF \ -DENABLE_UPNP=OFF ninja package_source SOURCEDIST=`echo bitcoin-abc-*.tar.gz` mv ${SOURCEDIST} .. popd DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` # Correct tar file order mkdir -p temp pushd temp tar xf ../$SOURCEDIST find bitcoin-abc-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} mkdir -p distsrc-${i} cd distsrc-${i} INSTALLPATH=`pwd`/installed/${DISTNAME} mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST cmake -GNinja .. \ -DCMAKE_TOOLCHAIN_FILE=${SOURCEDIR}/cmake/platforms/${CMAKE_TOOLCHAIN_FILE[${i}]} \ -DCLIENT_VERSION_IS_RELEASE=ON \ + -DENABLE_CLANG_TIDY=OFF \ -DENABLE_REDUCE_EXPORTS=ON \ -DENABLE_STATIC_LIBSTDCXX=ON \ -DENABLE_GLIBC_BACK_COMPAT=ON \ -DCMAKE_INSTALL_PREFIX=${INSTALLPATH} \ -DCCACHE=OFF ninja ninja check-security ninja check-symbols for _component in ${INSTALL_COMPONENTS}; do cmake -DCOMPONENT=${_component} -P cmake_install.cmake done cd installed find ${DISTNAME}/bin -type f -executable -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \; find ${DISTNAME}/lib -type f -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \; find ${DISTNAME} -not -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz find ${DISTNAME} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz cd ../../ rm -rf distsrc-${i} done mkdir -p $OUTDIR/src mv $SOURCEDIST $OUTDIR/src diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index f2f0f045a4..77eda95906 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,203 +1,205 @@ --- name: "bitcoin-abc-osx" enable_cache: true distro: "debian" suites: - "buster" architectures: - "amd64" packages: - "autoconf" - "automake" - "bsdmainutils" - "ca-certificates" - "cmake" - "curl" - "faketime" - "fonts-tuffy" - "g++" - "git" - "imagemagick" - "libbz2-dev" - "libcap-dev" - "librsvg2-bin" - "libtiff-tools" - "libtinfo5" - "libtool" - "libz-dev" - "ninja-build" - "pkg-config" - "python3" - "python3-dev" - "python3-setuptools" # FIXME: these dependencies are only required to make CMake happy when building # native tools. They can be removed when the `NativeExecutable.cmake` gets # improved to avoid requiring all the bitcoin-abc dependencies. - "libboost-all-dev" - "libevent-dev" - "libssl-dev" remotes: - "url": "https://github.com/Bitcoin-ABC/bitcoin-abc.git" "dir": "bitcoin" files: - "MacOSX10.11.sdk.tar.gz" script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin14" # CMake toolchain file name differ from host name declare -A CMAKE_TOOLCHAIN_FILE CMAKE_TOOLCHAIN_FILE[x86_64-apple-darwin14]=OSX.cmake INSTALL_COMPONENTS="bitcoind bitcoin-qt bitcoin-seeder" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export GZIP="-9n" export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} export BASE_CACHE=${GBUILD_PACKAGE_CACHE} mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi export ZERO_AR_DATE=1 function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } # Faketime for depends so intermediate results are comparable export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} cd bitcoin SOURCEDIR=`pwd` BASEPREFIX=`pwd`/depends mkdir -p ${BASEPREFIX}/SDKs tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} mkdir -p source_package pushd source_package cmake -GNinja .. \ -DBUILD_BITCOIN_WALLET=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DBUILD_BITCOIN_SEEDER=OFF \ -DBUILD_BITCOIN_CLI=OFF \ -DBUILD_BITCOIN_TX=OFF \ -DBUILD_BITCOIN_QT=OFF \ -DBUILD_LIBBITCOINCONSENSUS=OFF \ + -DENABLE_CLANG_TIDY=OFF \ -DENABLE_QRCODE=OFF \ -DENABLE_UPNP=OFF ninja package_source SOURCEDIST=`echo bitcoin-abc-*.tar.gz` mv ${SOURCEDIST} .. popd DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` # Correct tar file order mkdir -p temp pushd temp tar xf ../$SOURCEDIST find bitcoin-abc-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} mkdir -p distsrc-${i} cd distsrc-${i} INSTALLPATH=`pwd`/installed/${DISTNAME} mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST cmake -GNinja .. \ -DCMAKE_TOOLCHAIN_FILE=${SOURCEDIR}/cmake/platforms/${CMAKE_TOOLCHAIN_FILE[${i}]} \ -DCLIENT_VERSION_IS_RELEASE=ON \ + -DENABLE_CLANG_TIDY=OFF \ -DENABLE_REDUCE_EXPORTS=ON \ -DCMAKE_INSTALL_PREFIX=${INSTALLPATH} \ -DCCACHE=OFF \ -DGENISOIMAGE_EXECUTABLE="${WRAP_DIR}/genisoimage" ninja for _component in ${INSTALL_COMPONENTS}; do cmake -DCOMPONENT=${_component} -P cmake_install.cmake done export PYTHONPATH="${BASEPREFIX}/${i}/native/lib/python3/dist-packages:${PYTHONPATH}" ninja osx-deploydir OSX_VOLNAME="$(cat osx_volname)" mkdir -p unsigned-app-${i} cp osx_volname unsigned-app-${i}/ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i} cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i} cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i} cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff mv dist unsigned-app-${i} pushd unsigned-app-${i} find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz popd ninja osx-dmg ${WRAP_DIR}/dmg dmg "${OSX_VOLNAME}.dmg" ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg cd installed # The install/strip target should do exactly that. However there is a bug in # in the Buster CMake version that causes strip to be called with the wrong # parameters when an Apple strip tool is used. This is fixed starting with # CMake versions >= 3.14, see: # https://gitlab.kitware.com/cmake/cmake/merge_requests/2892 find -path "*.app*" -type f -executable -exec mv {} ${DISTNAME}/bin/bitcoin-qt \; find ${DISTNAME}/bin -type f -executable -exec ${i}-strip -u -r {} \; find ${DISTNAME}/lib -type f -executable -exec ${i}-strip -x {} \; find ${DISTNAME} -not -path "*.app*" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz cd ../../ done mkdir -p $OUTDIR/src mv $SOURCEDIST $OUTDIR/src mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-osx64.tar.gz diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 0e8af01ab8..0fdf51c99c 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,215 +1,217 @@ --- name: "bitcoin-abc-win" enable_cache: true distro: "debian" suites: - "buster" architectures: - "amd64" packages: - "autoconf" - "automake" - "bsdmainutils" - "ca-certificates" - "cmake" - "curl" - "faketime" - "g++" - "g++-mingw-w64" - "git" - "libtool" - "ninja-build" - "mingw-w64" - "nsis" - "pkg-config" - "python3" - "zip" # FIXME: these dependencies are only required to make CMake happy when building # native tools. They can be removed when the `NativeExecutable.cmake` gets # improved to avoid requiring all the bitcoin-abc dependencies. - "libboost-all-dev" - "libevent-dev" - "libssl-dev" remotes: - "url": "https://github.com/Bitcoin-ABC/bitcoin-abc.git" "dir": "bitcoin" files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-w64-mingw32 x86_64-w64-mingw32" # CMake toolchain file name differ from host name declare -A CMAKE_TOOLCHAIN_FILE CMAKE_TOOLCHAIN_FILE[i686-w64-mingw32]=Win32.cmake CMAKE_TOOLCHAIN_FILE[x86_64-w64-mingw32]=Win64.cmake INSTALL_COMPONENTS="bitcoind bitcoin-qt" FAKETIME_HOST_PROGS="ar ranlib nm windres strip objcopy" FAKETIME_PROGS="date makensis zip" HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export GZIP="-9n" export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} export BASE_CACHE=${GBUILD_PACKAGE_CACHE} mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } function create_per-host_linker_wrapper { # This is only needed for trusty, as the mingw linker leaks a few bytes of # heap, causing non-determinism. See discussion in https://github.com/bitcoin/bitcoin/pull/6900 for i in $HOSTS; do mkdir -p ${WRAP_DIR}/${i} for prog in collect2; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}/${prog} REAL=$(${i}-gcc -print-prog-name=${prog}) echo "export MALLOC_PERTURB_=255" >> ${WRAP_DIR}/${i}/${prog} echo "${REAL} \$@" >> $WRAP_DIR/${i}/${prog} chmod +x ${WRAP_DIR}/${i}/${prog} done for prog in gcc g++; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog}-posix | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "export COMPILER_PATH=${WRAP_DIR}/${i}" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } # Faketime for depends so intermediate results are comparable export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" create_per-host_linker_wrapper "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} cd bitcoin SOURCEDIR=`pwd` BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_linker_wrapper "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} mkdir -p source_package pushd source_package cmake -GNinja .. \ -DBUILD_BITCOIN_WALLET=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DBUILD_BITCOIN_SEEDER=OFF \ -DBUILD_BITCOIN_CLI=OFF \ -DBUILD_BITCOIN_TX=OFF \ -DBUILD_BITCOIN_QT=OFF \ -DBUILD_LIBBITCOINCONSENSUS=OFF \ + -DENABLE_CLANG_TIDY=OFF \ -DENABLE_QRCODE=OFF \ -DENABLE_UPNP=OFF ninja package_source SOURCEDIST=`echo bitcoin-abc-*.tar.gz` mv ${SOURCEDIST} .. popd DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` # Correct tar file order mkdir -p temp pushd temp tar xf ../$SOURCEDIST find bitcoin-abc-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST mkdir -p $OUTDIR/src cp ../$SOURCEDIST $OUTDIR/src popd # Allow extra cmake option to be specified for each host declare -A CMAKE_EXTRA_OPTIONS CMAKE_EXTRA_OPTIONS[i686-w64-mingw32]="-DCPACK_PACKAGE_FILE_NAME=${DISTNAME}-win32-setup-unsigned" CMAKE_EXTRA_OPTIONS[x86_64-w64-mingw32]="-DCPACK_PACKAGE_FILE_NAME=${DISTNAME}-win64-setup-unsigned" ORIGPATH="$PATH" # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${WRAP_DIR}:${ORIGPATH} mkdir -p distsrc-${i} cd distsrc-${i} INSTALLPATH=`pwd`/installed/${DISTNAME} mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST cmake -GNinja .. \ -DCMAKE_TOOLCHAIN_FILE=${SOURCEDIR}/cmake/platforms/${CMAKE_TOOLCHAIN_FILE[${i}]} \ -DCLIENT_VERSION_IS_RELEASE=ON \ + -DENABLE_CLANG_TIDY=OFF \ -DENABLE_REDUCE_EXPORTS=ON \ -DBUILD_BITCOIN_SEEDER=OFF \ -DCPACK_STRIP_FILES=ON \ -DCMAKE_INSTALL_PREFIX=${INSTALLPATH} \ -DCCACHE=OFF \ ${CMAKE_EXTRA_OPTIONS[${i}]} ninja ninja check-security for _component in ${INSTALL_COMPONENTS}; do cmake -DCOMPONENT=${_component} -P cmake_install.cmake done ninja package cp -f bitcoin-abc-*-setup-unsigned.exe ${OUTDIR}/ cd installed mkdir -p ${DISTNAME}/lib mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/ find ${DISTNAME}/bin -type f -executable -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; find ${DISTNAME}/lib -type f -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; find ${DISTNAME} -not -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip find ${DISTNAME} -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}-debug.zip cd ../../ rm -rf distsrc-${i} done cd $OUTDIR find . -name "*-setup-unsigned.exe" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.zip ${OUTDIR}/${DISTNAME}-win64-debug.zip mv ${OUTDIR}/${DISTNAME}-i686-*-debug.zip ${OUTDIR}/${DISTNAME}-win32-debug.zip mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip mv ${OUTDIR}/${DISTNAME}-i686-*.zip ${OUTDIR}/${DISTNAME}-win32.zip diff --git a/contrib/teamcity/build_cmake.sh b/contrib/teamcity/build_cmake.sh index 7a239795b2..68d50db658 100755 --- a/contrib/teamcity/build_cmake.sh +++ b/contrib/teamcity/build_cmake.sh @@ -1,20 +1,20 @@ #!/usr/bin/env bash export LC_ALL=C set -euxo pipefail : "${TOPLEVEL:=$(git rev-parse --show-toplevel)}" : "${BUILD_DIR:=${TOPLEVEL}/build}" # Default to nothing : "${CMAKE_FLAGS:=}" cd ${BUILD_DIR} git clean -xffd read -a CMAKE_FLAGS <<< "${CMAKE_FLAGS}" -cmake -GNinja .. "${CMAKE_FLAGS[@]}" +cmake -GNinja .. -DENABLE_CLANG_TIDY=OFF "${CMAKE_FLAGS[@]}" # Run build ninja diff --git a/src/.clang-tidy b/src/.clang-tidy new file mode 100644 index 0000000000..ad48a9ab03 --- /dev/null +++ b/src/.clang-tidy @@ -0,0 +1,2 @@ +Checks: -*,boost-use-to-string +FormatStyle: file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index faa3dc32b1..7e58ed6079 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,573 +1,580 @@ # Copyright (c) 2017 The Bitcoin developers project(bitcoind) set(CMAKE_CXX_STANDARD 14) # Default visibility is hidden on all targets. set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden) option(BUILD_BITCOIN_WALLET "Activate the wallet functionality" ON) option(BUILD_BITCOIN_ZMQ "Activate the ZeroMQ functionalities" ON) option(BUILD_BITCOIN_SEEDER "Build bitcoin-seeder" 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_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(ENABLE_NOTIFICATIONS "Enable desktop notifications" ON) option(ENABLE_WERROR "Promote some compiler warnings to errors" OFF) option(START_WITH_UPNP "Make UPnP the default to map ports" OFF) +option(ENABLE_CLANG_TIDY "Enable clang-tidy checks for Bitcoin ABC" ON) # 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" + # Forward the current setting for clang-tidy + "-DENABLE_CLANG_TIDY=${ENABLE_CLANG_TIDY}" ) +if(ENABLE_CLANG_TIDY) + include(ClangTidy) +endif() + # Allow usage of sanitizers by setting ECM_ENABLE_SANITIZERS if(ENABLE_SANITIZERS) set(ECM_ENABLE_SANITIZERS ${ENABLE_SANITIZERS}) find_package(ECM NO_MODULE) if(ECM_MODULE_PATH) list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) include(ECMEnableSanitizers) else() message(FATAL_ERROR "ECM is required to enable the sanitizers (https://api.kde.org/ecm/manual/ecm.7.html). Try installing 'extra-cmake-modules' package." ) endif() endif() include(AddCompilerFlags) # Prefer -g3, defaults to -g if unavailable foreach(LANGUAGE C CXX) set(COMPILER_DEBUG_LEVEL -g) check_compiler_flag(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) add_compiler_flags(-fstack-reuse=none) # Ensure that WINDRES_PREPROC is enabled when using windres. 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) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") add_compile_definitions(MAC_OSX OBJC_OLD_DISPATCH_PROTOTYPES=0) 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_flag(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,ALL) 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 add_compiler_flags(-U_FORTIFY_SOURCE -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. # Unfortunately setting the -pie linker flag this way require CMake >= 3.14, # which is not widely distributed at the time of writing. # FIXME: remove the fallback case when cmake >= 3.14 get enforced. if(POLICY CMP0083) cmake_policy(SET CMP0083 NEW) include(CheckPIESupported) check_pie_supported() elseif(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Windows") add_linker_flags(-pie) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") # MinGw provides its own libssp for stack smashing protection link_libraries(ssp) endif() endif() # Enable warning add_c_compiler_flags(-Wnested-externs -Wstrict-prototypes) add_compiler_flags( -Wall -Wextra -Wformat -Wvla -Wformat-security -Wcast-align -Wunused-parameter -Wmissing-braces -Wthread-safety-analysis -Wshadow -Wrange-loop-analysis -Wredundant-decls -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() if(ENABLE_WERROR) add_compiler_flags( -Werror=vla -Werror=thread-safety-analysis ) endif() # Create a target for OpenSSL include(BrewHelper) find_brew_prefix(OPENSSL_ROOT_DIR openssl) find_package(OpenSSL REQUIRED) # libtool style configure add_subdirectory(config) # 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 ) 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/glibc_sanity.cpp compat/glibcxx_sanity.cpp compat/strnlen.cpp fs.cpp logging.cpp random.cpp rcu.cpp rpc/protocol.cpp rpc/util.cpp support/cleanse.cpp support/lockedpool.cpp sync.cpp threadinterrupt.cpp uint256.cpp util/system.cpp util/moneystr.cpp util/strencodings.cpp util/time.cpp util/bytevectorhash.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) # glibc absorbed clock_gettime in 2.17. librt (its previous location) is # safe to link in anyway for back-compat. find_library(RT_LIBRARY rt) target_link_libraries(util ${RT_LIBRARY}) # 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() target_sources(util PRIVATE compat/glibc_compat.cpp) endif() # Enable LFS (Large File Support) on targets that don't have it natively. if(NOT HAVE_LARGE_FILE_SUPPORT) add_compiler_flags(-D_FILE_OFFSET_BITS=64) add_linker_flags(-Wl,--large-address-aware) endif() # Target specific configs if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(Boost_USE_STATIC_LIBS ON) set(Boost_THREADAPI win32) find_package(SHLWAPI REQUIRED) target_link_libraries(util ${SHLWAPI_LIBRARY}) target_include_directories(util PUBLIC ${SHLWAPI_INCLUDE_DIR}) 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() # Boost packages set(BOOST_PACKAGES_REQUIRED chrono filesystem thread) function(prepend var prefix) set(listVar "") foreach(f ${ARGN}) list(APPEND listVar "${prefix}${f}") endforeach(f) set(${var} "${listVar}" PARENT_SCOPE) endfunction(prepend) prepend(BOOST_LIBRARIES "Boost::" ${BOOST_PACKAGES_REQUIRED}) find_package(Boost 1.58 REQUIRED ${BOOST_PACKAGES_REQUIRED}) target_link_libraries(util univalue crypto ${BOOST_LIBRARIES}) # 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) # 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 cashaddr.cpp cashaddrenc.cpp chainparams.cpp config.cpp consensus/merkle.cpp coins.cpp compressor.cpp feerate.cpp globals.cpp core_read.cpp core_write.cpp key.cpp key_io.cpp keystore.cpp netaddress.cpp netbase.cpp primitives/block.cpp protocol.cpp scheduler.cpp versionbitsinfo.cpp warnings.cpp ) target_link_libraries(common util secp256k1) # script library add_library(script script/bitfield.cpp script/descriptor.cpp script/interpreter.cpp script/ismine.cpp script/script.cpp script/script_error.cpp script/sigencoding.cpp script/sign.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 ) 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.cpp banman.cpp bloom.cpp blockencodings.cpp blockfilter.cpp chain.cpp checkpoints.cpp config.cpp consensus/activation.cpp consensus/tx_verify.cpp dbwrapper.cpp flatfile.cpp globals.cpp httprpc.cpp httpserver.cpp index/base.cpp index/txindex.cpp init.cpp interfaces/chain.cpp interfaces/handler.cpp interfaces/node.cpp merkleblock.cpp miner.cpp net.cpp net_processing.cpp noui.cpp outputtype.cpp policy/fees.cpp policy/policy.cpp pow.cpp rest.cpp rpc/abc.cpp rpc/blockchain.cpp rpc/command.cpp rpc/jsonrpcrequest.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 ) # This require libevent find_package(Event REQUIRED) target_include_directories(server PRIVATE leveldb/helpers/memenv) target_link_libraries(server Event bitcoinconsensus leveldb memenv ) if(ENABLE_UPNP) target_include_directories(server PUBLIC ${MINIUPNPC_INCLUDE_DIR}) target_link_libraries(server ${MINIUPNPC_LIBRARY}) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") find_library(IPHLPAPI_LIBRARY NAMES iphlpapi) if(NOT IPHLPAPI_LIBRARY) message(FATAL_ERROR "Lib iphlpapi is missing") endif() target_link_libraries(server ${IPHLPAPI_LIBRARY}) target_compile_definitions(server PUBLIC -DSTATICLIB PUBLIC -DMINIUPNP_STATICLIB ) endif() endif() # Test suite. add_subdirectory(test) # Benchmark suite. add_subdirectory(bench) # Wallet if(BUILD_BITCOIN_WALLET) add_subdirectory(wallet) target_link_libraries(server wallet) # There is a circular dependency between wallet and server, see: # https://github.com/bitcoin/bitcoin/pull/14437#discussion_r226237048 target_link_libraries(wallet server) 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 rpc/client.cpp) target_link_libraries(rpcclient univalue util) # bitcoin-seeder if(BUILD_BITCOIN_SEEDER) add_subdirectory(seeder) endif() include(BinaryTest) # bitcoin-cli if(BUILD_BITCOIN_CLI) add_executable(bitcoin-cli bitcoin-cli.cpp) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") target_sources(bitcoin-cli PRIVATE bitcoin-cli-res.rc) endif() target_link_libraries(bitcoin-cli common rpcclient Event) add_to_symbols_check(bitcoin-cli) add_to_security_check(bitcoin-cli) install_target(bitcoin-cli) endif() # bitcoin-tx if(BUILD_BITCOIN_TX) add_executable(bitcoin-tx bitcoin-tx.cpp) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") target_sources(bitcoin-tx PRIVATE bitcoin-tx-res.rc) endif() target_link_libraries(bitcoin-tx bitcoinconsensus) add_to_symbols_check(bitcoin-tx) add_to_security_check(bitcoin-tx) install_target(bitcoin-tx) endif() # bitcoind add_executable(bitcoind bitcoind.cpp) target_link_libraries(bitcoind server) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") target_sources(bitcoind PRIVATE bitcoind-res.rc) endif() add_to_symbols_check(bitcoind) add_to_security_check(bitcoind) install_target(bitcoind) # Bitcoin-qt if(BUILD_BITCOIN_QT) add_subdirectory(qt) endif() diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index bbda783359..f8f9851220 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -1,583 +1,589 @@ # Copyright (c) 2018 The Bitcoin developers project(bitcoin-qt) # This ensure that AUTOMOC doesn't run on generated files. cmake_policy(SET CMP0071 OLD) include(BrewHelper) find_brew_prefix(QT5_PREFIX qt5) set(QT_REQUIRED_COMPONENTS Core Widgets Network Test) if(ENABLE_NOTIFICATIONS) list(APPEND QT_REQUIRED_COMPONENTS DBus) endif() find_package(Qt5 5.5.1 COMPONENTS ${QT_REQUIRED_COMPONENTS} REQUIRED HINTS "${QT5_PREFIX}") # Localisation add_subdirectory(locale) add_custom_command(OUTPUT temp_bitcoin_locale.qrc COMMAND cmake ARGS -E copy "${CMAKE_CURRENT_SOURCE_DIR}/bitcoin_locale.qrc" temp_bitcoin_locale.qrc MAIN_DEPENDENCY bitcoin_locale.qrc VERBATIM ) add_custom_command(OUTPUT qrc_bitcoin_locale.cpp COMMAND Qt5::rcc ARGS temp_bitcoin_locale.qrc -name bitcoin_locale -o qrc_bitcoin_locale.cpp MAIN_DEPENDENCY temp_bitcoin_locale.qrc DEPENDS locales VERBATIM ) # UI elements # qt5_wrap_ui() generates the files in the CMAKE_CURRENT_BINARY_DIR. As there # is no option to change the output directory, moving the files to the forms # subdirectory requires to override the variable. It is reset to its actual # value after the call so it does not impact the other sections of this # CMakeLists.txt file. set(SAVE_CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/forms") qt5_wrap_ui(UI_GENERATED_HEADERS forms/addressbookpage.ui forms/askpassphrasedialog.ui forms/coincontroldialog.ui forms/editaddressdialog.ui forms/helpmessagedialog.ui forms/intro.ui forms/modaloverlay.ui forms/openuridialog.ui forms/optionsdialog.ui forms/overviewpage.ui forms/receivecoinsdialog.ui forms/receiverequestdialog.ui forms/debugwindow.ui forms/sendcoinsdialog.ui forms/sendcoinsentry.ui forms/signverifymessagedialog.ui forms/transactiondescdialog.ui ) set(CMAKE_CURRENT_BINARY_DIR ${SAVE_CMAKE_CURRENT_BINARY_DIR}) # Qt MOC set(CMAKE_AUTOMOC ON) # Handle qrc resources qt5_add_resources(QRC_BITCOIN_CPP bitcoin.qrc) add_library(bitcoin-qt-base bantablemodel.cpp bitcoin.cpp bitcoinaddressvalidator.cpp bitcoinamountfield.cpp bitcoingui.cpp bitcoinunits.cpp clientmodel.cpp csvmodelwriter.cpp guiutil.cpp intro.cpp modaloverlay.cpp networkstyle.cpp notificator.cpp optionsdialog.cpp optionsmodel.cpp peertablemodel.cpp platformstyle.cpp qvalidatedlineedit.cpp qvaluecombobox.cpp rpcconsole.cpp splashscreen.cpp trafficgraphwidget.cpp utilitydialog.cpp # Handle ui files ${UI_GENERATED_HEADERS} # Translations ${BITCOIN_QM_FILES} # Handle qrc files ${QRC_BITCOIN_CPP} qrc_bitcoin_locale.cpp ) # Add the minimal integration plugin, and other plugins according to the target # platform. set(QT_PLUGIN_COMPONENTS QMinimalIntegrationPlugin) set(QT_PLUGIN_PLATFORM_DEFINITIONS -DQT_QPA_PLATFORM_MINIMAL=1) # Linux support if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") list(APPEND QT_PLUGIN_COMPONENTS QXcbIntegrationPlugin) list(APPEND QT_PLUGIN_PLATFORM_DEFINITIONS -DQT_QPA_PLATFORM_XCB=1) endif() # Windows support if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") list(APPEND QT_PLUGIN_COMPONENTS QWindowsIntegrationPlugin) list(APPEND QT_PLUGIN_PLATFORM_DEFINITIONS -DQT_QPA_PLATFORM_WINDOWS=1) target_sources(bitcoin-qt-base PRIVATE winshutdownmonitor.cpp) endif() # OSX support if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") list(APPEND QT_PLUGIN_COMPONENTS QCocoaIntegrationPlugin) list(APPEND QT_PLUGIN_PLATFORM_DEFINITIONS -DQT_QPA_PLATFORM_COCOA=1) target_sources(bitcoin-qt-base PRIVATE macdockiconhandler.mm macnotificationhandler.mm ) set_property(TARGET bitcoin-qt-base PROPERTY AUTOMOC_MOC_OPTIONS "-DQ_OS_MAC") target_link_libraries(bitcoin-qt-base "-framework Foundation" "-framework ApplicationServices" "-framework AppKit" ) endif() # Find out more about Qt. This is similar to # http://code.qt.io/cgit/qt/qtwebkit.git/tree/Source/cmake/OptionsQt.cmake get_target_property(QT_CORE_TYPE Qt5::Core TYPE) if(QT_CORE_TYPE MATCHES STATIC) set(QT_STATIC_BUILD ON) endif() # Determine the Qt libraries directory from the QT5::Core library location get_target_property(QT_CORE_LIB_LOCATION Qt5::Core LOCATION) get_filename_component(QT5_LIB_DIR "${QT_CORE_LIB_LOCATION}" DIRECTORY) set(STATIC_DEPENDENCIES_CMAKE_FILE "${CMAKE_BINARY_DIR}/QtStaticDependencies.cmake") if(EXISTS ${STATIC_DEPENDENCIES_CMAKE_FILE}) file(REMOVE ${STATIC_DEPENDENCIES_CMAKE_FILE}) endif() set(CONVERT_PRL_PATH "${CONTRIB_PATH}/qt/convert-prl-libs-to-cmake.pl") macro(CONVERT_PRL_LIBS_TO_CMAKE _qt_component) if(TARGET Qt5::${_qt_component}) get_target_property(_lib_location Qt5::${_qt_component} LOCATION) execute_process(COMMAND ${PERL_EXECUTABLE} "${CONVERT_PRL_PATH}" --lib "${_lib_location}" --qt_lib_install_dir "${QT5_LIB_DIR}" --out "${STATIC_DEPENDENCIES_CMAKE_FILE}" --component "${_qt_component}" --compiler "${CMAKE_CXX_COMPILER_ID}" ) endif() endmacro() if(QT_STATIC_BUILD) list(APPEND QT_REQUIRED_COMPONENTS ${QT_PLUGIN_COMPONENTS}) foreach(qt_module ${QT_REQUIRED_COMPONENTS}) CONVERT_PRL_LIBS_TO_CMAKE(${qt_module}) endforeach() # HACK: We must explicitly add LIB path of the Qt installation # to correctly find qtpcre link_directories("${QT5_LIB_DIR}") # Now that we generated the dependencies, import them. set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CONVERT_PRL_PATH}") if(NOT EXISTS ${STATIC_DEPENDENCIES_CMAKE_FILE}) message(FATAL_ERROR "Unable to find ${STATIC_DEPENDENCIES_CMAKE_FILE}") endif() include(${STATIC_DEPENDENCIES_CMAKE_FILE}) list(REMOVE_DUPLICATES STATIC_LIB_DEPENDENCIES) # According to Qt documentation (https://doc.qt.io/qt-5/plugins-howto.html): # "Plugins can be linked statically into your application. # If you build the static version of Qt, this is the only option for # including Qt's predefined plugins." # So if the Qt build is static, the plugins should also be static and we # need to define QT_STATICPLUGIN to tell the code to import . target_compile_definitions(bitcoin-qt-base PUBLIC -DQT_STATICPLUGIN=1) # Add the platform plugin definition if required # Setting this definition tells the code what is the target for Q_IMPORT_PLUGIN(). foreach(qt_platform_definition ${QT_PLUGIN_PLATFORM_DEFINITIONS}) target_compile_definitions(bitcoin-qt-base PUBLIC "${qt_platform_definition}") endforeach() # Link the required plugins foreach(qt_plugin ${QT_PLUGIN_COMPONENTS}) target_link_libraries(bitcoin-qt-base Qt5::${qt_plugin}) endforeach() endif() target_link_libraries(bitcoin-qt-base server rpcclient Qt5::Widgets Qt5::Network ) if(ENABLE_NOTIFICATIONS) target_link_libraries(bitcoin-qt-base Qt5::DBus) endif() if(ENABLE_BIP70) # Do protobuf codegen find_package(Protobuf REQUIRED) protobuf_generate_cpp(PROTOBUF_SOURCES PROTOBUF_HEADERS paymentrequest.proto) add_library(bitcoin-qt-protobuf OBJECT # Protobuf codegen ${PROTOBUF_HEADERS} ${PROTOBUF_SOURCES} ) target_include_directories(bitcoin-qt-protobuf PUBLIC ${Protobuf_INCLUDE_DIRS}) target_link_libraries(bitcoin-qt-protobuf ${Protobuf_LIBRARIES}) - + + # Don't run clang-tidy on generated files + if(ENABLE_CLANG_TIDY) + include(ClangTidy) + target_disable_clang_tidy(bitcoin-qt-protobuf) + endif() + target_link_libraries(bitcoin-qt-base OpenSSL::SSL bitcoin-qt-protobuf ) endif() # Wallet if(BUILD_BITCOIN_WALLET) # Automoc option. set(AUTOMOC_MOC_OPTIONS -DENABLE_WALLET=1) # Add wallet functionality to bitcoin-qt target_sources(bitcoin-qt-base PRIVATE addressbookpage.cpp addresstablemodel.cpp askpassphrasedialog.cpp coincontroldialog.cpp coincontroltreewidget.cpp editaddressdialog.cpp openuridialog.cpp overviewpage.cpp paymentserver.cpp receivecoinsdialog.cpp receiverequestdialog.cpp recentrequeststablemodel.cpp sendcoinsdialog.cpp sendcoinsentry.cpp signverifymessagedialog.cpp transactiondesc.cpp transactiondescdialog.cpp transactionfilterproxy.cpp transactionrecord.cpp transactiontablemodel.cpp transactionview.cpp walletcontroller.cpp walletframe.cpp walletmodel.cpp walletmodeltransaction.cpp walletview.cpp ) # Add BIP70 functionality to bitcoin-qt if(ENABLE_BIP70) target_sources(bitcoin-qt-base PRIVATE paymentrequestplus.cpp ) endif() target_link_libraries(bitcoin-qt-base wallet) if(ENABLE_QRCODE) target_include_directories(bitcoin-qt-base PUBLIC ${QRENCODE_INCLUDE_DIR}) target_link_libraries(bitcoin-qt-base ${QRENCODE_LIBRARY}) endif() endif() # The executable add_executable(bitcoin-qt WIN32 main.cpp) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") target_sources(bitcoin-qt PRIVATE res/bitcoin-qt-res.rc) endif() target_link_libraries(bitcoin-qt bitcoin-qt-base) include(BinaryTest) add_to_symbols_check(bitcoin-qt) add_to_security_check(bitcoin-qt) include(InstallationHelper) install_target(bitcoin-qt) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(BITCOINQT_BUNDLE_ICON "res/icons/bitcoin.icns") get_filename_component(BITCOINQT_BUNDLE_ICON_NAME "${BITCOINQT_BUNDLE_ICON}" NAME ) set(INFO_PLIST_STRINGS_FILE "Base.lproj/InfoPlist.strings") set(INFO_PLIST_STRINGS_PATH "${CMAKE_CURRENT_BINARY_DIR}/${INFO_PLIST_STRINGS_FILE}") file(WRITE "${INFO_PLIST_STRINGS_PATH}" "{ CFBundleDisplayName = \"${PACKAGE_NAME}\"; CFBundleName = \"${PACKAGE_NAME}\"; }" ) set(EMPTY_LPROJ_FILE "${CMAKE_CURRENT_BINARY_DIR}/empty.lproj") file(TOUCH "${EMPTY_LPROJ_FILE}") target_sources(bitcoin-qt PRIVATE "${BITCOINQT_BUNDLE_ICON}" "${INFO_PLIST_STRINGS_PATH}" "${EMPTY_LPROJ_FILE}" ) string(JOIN ";" BITCOINQT_BUNDLE_RESOURCES "${BITCOINQT_BUNDLE_ICON}" "${EMPTY_LPROJ_FILE}" ) set(BITCOIN_QT_OSX_BUNDLE_NAME "BitcoinABC-Qt") set_target_properties(bitcoin-qt PROPERTIES MACOSX_BUNDLE ON OUTPUT_NAME "${BITCOIN_QT_OSX_BUNDLE_NAME}" MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/share/qt/Info.plist.cmake.in" MACOSX_BUNDLE_BUNDLE_NAME "${BITCOIN_QT_OSX_BUNDLE_NAME}" MACOSX_BUNDLE_BUNDLE_VERSION "${bitcoin-abc_VERSION}" MACOSX_BUNDLE_GUI_IDENTIFIER "org.bitcoinabc.${BITCOIN_QT_OSX_BUNDLE_NAME}" MACOSX_BUNDLE_ICON_FILE "${BITCOINQT_BUNDLE_ICON_NAME}" MACOSX_BUNDLE_INFO_STRING "${bitcoin-abc_VERSION}, Copyright © 2009-${COPYRIGHT_YEAR} ${COPYRIGHT_HOLDERS_FINAL}" MACOSX_BUNDLE_LONG_VERSION_STRING "${bitcoin-abc_VERSION}" MACOSX_BUNDLE_SHORT_VERSION_STRING "${bitcoin-abc_VERSION}" RESOURCE "${BITCOINQT_BUNDLE_RESOURCES}" ) # The InfoPlist.strings files should be located in a resource subdirectory. # This is not supported by the RESOURCE property and require the use of the # MACOSX_PACKAGE_LOCATION property instead. The RESOURCE documentation has # an example demonstrating this behavior (see the appres.txt file): # https://cmake.org/cmake/help/latest/prop_tgt/RESOURCE.html set_source_files_properties( "${INFO_PLIST_STRINGS_PATH}" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/${INFO_PLIST_STRINGS_FILE}" ) # Create a stripped version of the application bundle to be used in the DMG. # Since the LOCATION property and the BundleUtilities package are deprecated # by cmake, only generator expressions can be used to determine the path to # the bundle and its executable. However the generator expressions are # solved at build time, making them unusable to do path computation at # configuration time. # The paths here are then hard-coded, which is safe since the structure of # an application bundle is well-known and specified by Apple. Note that this # will only work for building MacOS application bundle as the IOS structure # is slightly different. set(STRIPPED_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/stripped/${BITCOIN_QT_OSX_BUNDLE_NAME}.app") add_custom_command( OUTPUT "${STRIPPED_BUNDLE}" COMMAND ${CMAKE_COMMAND} -E copy_directory "$" "${STRIPPED_BUNDLE}" COMMAND ${CMAKE_STRIP} -u -r "${STRIPPED_BUNDLE}/Contents/MacOS/${BITCOIN_QT_OSX_BUNDLE_NAME}" DEPENDS bitcoin-qt ) include(DoOrFail) find_program_or_fail(CMAKE_INSTALL_NAME_TOOL "install_name_tool") find_program_or_fail(CMAKE_OTOOL "otool") set(QT_INSTALLER_SUPPORTED_LANGUAGES "da" "de" "es" "hu" "ru" "uk" "zh_CN" "zh_TW" ) string(JOIN "," QT_LOCALES ${QT_INSTALLER_SUPPORTED_LANGUAGES}) get_target_property(QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) execute_process( COMMAND "${QMAKE_EXECUTABLE}" -query QT_INSTALL_TRANSLATIONS OUTPUT_VARIABLE QT_TRANSLATION_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) function(get_qt_translation_dir QT_TRANSLATION_DIR) foreach(_locale ${ARGN}) find_path(_qt_translation_dir "qt_${_locale}.qm" HINTS "${QT_TRANSLATION_DIR}" PATH_SUFFIXES "translations" ) # Ensure that all the translation files are found, and are located # in the same directory. if(NOT _qt_translation_dir OR (_qt_translation_dir_previous AND (NOT _qt_translation_dir_previous STREQUAL _qt_translation_dir))) return() endif() set(_qt_translation_dir_previous _qt_translation_dir) endforeach() set(QT_TRANSLATION_DIR ${_qt_translation_dir} PARENT_SCOPE) endfunction() get_qt_translation_dir(QT_TRANSLATION_DIR ${QT_INSTALLER_SUPPORTED_LANGUAGES}) if(NOT QT_TRANSLATION_DIR) message(FATAL_ERROR "Qt translation files are not found") endif() set(MACDEPLOY_DIR "${CMAKE_SOURCE_DIR}/contrib/macdeploy") set(MACDEPLOYQTPLUS "${MACDEPLOY_DIR}/macdeployqtplus") set(DMG_DIST "${CMAKE_BINARY_DIR}/dist") add_custom_command( OUTPUT "${DMG_DIST}" COMMAND "INSTALLNAMETOOL=${CMAKE_INSTALL_NAME_TOOL}" "OTOOL=${CMAKE_OTOOL}" "STRIP=${CMAKE_STRIP}" "${PYTHON_EXECUTABLE}" "${MACDEPLOYQTPLUS}" "${STRIPPED_BUNDLE}" -translations-dir "${QT_TRANSLATION_DIR}" -add-qt-tr "${QT_LOCALES}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" DEPENDS "${STRIPPED_BUNDLE}" ) # Building the DMG background image requires several steps: # 1/ The SVG file must be edited to display the package name # 2/ The SVG file should be transformed into a couple PNG files, on for # low resolution screens and one for high resolution screens. # 3/ The PNG files must be transformed into a multi-resolution TIFF file. # The names are not set arbitrarily, they follow Apple's guidelines for # resolution independent bitmap images (see `man tiffutil`). set(BACKGROUND_SVG "background.svg") configure_file( "${CMAKE_SOURCE_DIR}/contrib/macdeploy/background.svg.cmake.in" "${BACKGROUND_SVG}" ) include(ImageHelper) set(BACKGROUND_PNG_LOWRES "${CMAKE_CURRENT_BINARY_DIR}/background_temp.png") set(BACKGROUND_PNG_HIRES "${CMAKE_CURRENT_BINARY_DIR}/background_temp@2x.png") set(BACKGROUND_TIFF_LOWRES "${CMAKE_CURRENT_BINARY_DIR}/background_temp.tiff") set(BACKGROUND_TIFF_HIRES "${CMAKE_CURRENT_BINARY_DIR}/background_temp@2x.tiff") set(BACKGROUND_TIFF_NAME "background.tiff") set(BACKGROUND_TIFF_MULTIRES "${CMAKE_BINARY_DIR}/${BACKGROUND_TIFF_NAME}") convert_svg_to_png("${BACKGROUND_SVG}" "${BACKGROUND_PNG_LOWRES}" 36) convert_svg_to_png("${BACKGROUND_SVG}" "${BACKGROUND_PNG_HIRES}" 72) convert_png_to_tiff("${BACKGROUND_PNG_LOWRES}" "${BACKGROUND_TIFF_LOWRES}") convert_png_to_tiff("${BACKGROUND_PNG_HIRES}" "${BACKGROUND_TIFF_HIRES}") cat_multi_resolution_tiff("${BACKGROUND_TIFF_MULTIRES}" "${BACKGROUND_TIFF_LOWRES}" "${BACKGROUND_TIFF_HIRES}") set(BACKGROUND_DIST_DIR "${DMG_DIST}/.background") set(BACKGROUND_DIST_TIFF "${BACKGROUND_DIST_DIR}/${BACKGROUND_TIFF_NAME}") add_custom_command( OUTPUT "${BACKGROUND_DIST_TIFF}" COMMAND ${CMAKE_COMMAND} -E make_directory "${BACKGROUND_DIST_DIR}" COMMAND ${CMAKE_COMMAND} -E copy "${BACKGROUND_TIFF_MULTIRES}" "${BACKGROUND_DIST_TIFF}" DEPENDS "${BACKGROUND_TIFF_MULTIRES}" "${DMG_DIST}" ) string(REPLACE " " "-" OSX_VOLNAME "${PACKAGE_NAME}") file(WRITE "${CMAKE_BINARY_DIR}/osx_volname" "${OSX_VOLNAME}") set(DMG_DSSTORE "${DMG_DIST}/.DS_Store") set(GEN_DSSTORE "${MACDEPLOY_DIR}/custom_dsstore.py") add_custom_command( OUTPUT "${DMG_DSSTORE}" COMMAND "${PYTHON_EXECUTABLE}" "${GEN_DSSTORE}" "${DMG_DSSTORE}" "${OSX_VOLNAME}" DEPENDS "${GEN_DSSTORE}" "${DMG_DIST}" ) set(OSX_APPLICATION_DIR "Applications") set(OSX_APPLICATION_SYMLINK "${DMG_DIST}/${OSX_APPLICATION_DIR}") add_custom_command( OUTPUT "${OSX_APPLICATION_SYMLINK}" COMMAND ${CMAKE_COMMAND} -E create_symlink "/${OSX_APPLICATION_DIR}" "${OSX_APPLICATION_SYMLINK}" DEPENDS "${DMG_DIST}" ) add_custom_target(osx-deploydir DEPENDS "${OSX_APPLICATION_SYMLINK}" "${DMG_DSSTORE}" "${BACKGROUND_DIST_TIFF}" ) if(CMAKE_CROSSCOMPILING) find_program_or_fail(GENISOIMAGE_EXECUTABLE genisoimage) add_custom_target(osx-dmg COMMAND "${GENISOIMAGE_EXECUTABLE}" -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -apple -o "${OSX_VOLNAME}.dmg" "${DMG_DIST}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" ) add_dependencies(osx-dmg osx-deploydir) else() add_custom_target(osx-dmg COMMAND "${PYTHON_EXECUTABLE}" "${MACDEPLOYQTPLUS}" "${STRIPPED_BUNDLE}" -translations-dir "${QT_TRANSLATION_DIR}" -add-qt-tr "${QT_LOCALES}" -dmg -fancy "${MACDEPLOY_DIR}/fancy.plist" -volname "${OSX_VOLNAME}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" DEPENDS "${STRIPPED_BUNDLE}" "${BACKGROUND_TIFF_MULTIRES}" ) endif() endif() # Test tests add_subdirectory(test)