From e07507d0958a3687b48551354142e7bc6ffda5e6 Mon Sep 17 00:00:00 2001 From: Michel van Kessel Date: Wed, 23 Feb 2022 15:55:35 +0100 Subject: [PATCH] squash commits --- .github/ISSUE_TEMPLATE.md | 23 + .github/ISSUE_TEMPLATE/bug_report.md | 39 + .github/ISSUE_TEMPLATE/feature_request.md | 20 + .github/ISSUE_TEMPLATE/good_first_issue.md | 22 + .github/PULL_REQUEST_TEMPLATE.md | 41 + .gitignore | 85 +- .travis.yml | 73 - CHANGELOG.md | 21 +- COPYING | 2 +- INSTALL.md | 2 +- Makefile.am | 107 +- autogen.sh | 9 +- build-aux/m4/ax_boost_base.m4 | 252 +- build-aux/m4/ax_boost_chrono.m4 | 11 +- build-aux/m4/ax_boost_filesystem.m4 | 7 +- build-aux/m4/ax_boost_process.m4 | 121 + build-aux/m4/ax_boost_random.m4 | 122 + build-aux/m4/ax_boost_system.m4 | 7 +- build-aux/m4/ax_boost_thread.m4 | 179 +- build-aux/m4/ax_boost_unit_test_framework.m4 | 13 +- build-aux/m4/ax_cxx_compile_stdcxx.m4 | 455 ++- build-aux/m4/ax_pthread.m4 | 228 +- build-aux/m4/bitcoin_qt.m4 | 528 +-- build-aux/m4/bitcoin_runtime_lib.m4 | 42 + build-aux/m4/l_atomic.m4 | 2 +- build-aux/m4/l_socket.m4 | 36 + configure.ac | 1225 ++++-- contrib/builder-keys/README.md | 23 + contrib/builder-keys/keys.txt | 2 + contrib/debian/README.md | 21 - contrib/debian/bitcoin-qt.desktop | 13 - contrib/debian/bitcoin-qt.install | 6 - contrib/debian/bitcoin-qt.lintian-overrides | 2 - contrib/debian/bitcoin-qt.protocol | 11 - contrib/debian/bitcoin-tx.bash-completion | 1 - contrib/debian/bitcoin-tx.install | 1 - contrib/debian/bitcoind.bash-completion | 2 - contrib/debian/bitcoind.examples | 1 - contrib/debian/bitcoind.install | 2 - contrib/debian/bitcoind.lintian-overrides | 2 - contrib/debian/bitcoind.manpages | 3 - contrib/debian/changelog | 459 --- contrib/debian/control | 67 - contrib/debian/copyright | 62 +- contrib/debian/examples/bitcoin.conf | 124 - contrib/debian/gbp.conf | 5 - contrib/debian/manpages/bitcoin-cli.1 | 84 - contrib/debian/manpages/bitcoin-qt.1 | 501 --- contrib/debian/manpages/bitcoin-tx.1 | 107 - contrib/debian/manpages/bitcoin.conf.5 | 19 - contrib/debian/manpages/bitcoind.1 | 480 --- contrib/debian/patches/README | 3 - contrib/debian/patches/series | 1 - contrib/debian/rules | 24 - contrib/debian/source/format | 1 - contrib/debian/watch | 5 - contrib/devtools/README.md | 97 +- contrib/devtools/circular-dependencies.py | 92 + contrib/devtools/clang-format-diff.py | 32 +- contrib/devtools/copyright_header.py | 606 +++ contrib/devtools/gen-manpages.sh | 41 +- contrib/devtools/pixie.py | 323 ++ contrib/devtools/security-check.py | 313 +- contrib/devtools/split-debug.sh.in | 2 +- contrib/devtools/symbol-check.py | 342 +- contrib/devtools/test-security-check.py | 84 +- contrib/devtools/test-symbol-check.py | 194 + .../devtools/test_deterministic_coverage.sh | 151 + contrib/devtools/utils.py | 22 + contrib/devtools/utxo_snapshot.sh | 44 + contrib/filter-lcov.py | 28 + contrib/gitian-build.py | 262 ++ contrib/gitian-build.sh | 388 -- contrib/gitian-descriptors/README.md | 65 - contrib/gitian-descriptors/assign_DISTNAME | 12 + contrib/gitian-descriptors/gitian-linux.yml | 194 +- .../gitian-descriptors/gitian-osx-signer.yml | 36 +- contrib/gitian-descriptors/gitian-osx.yml | 96 +- .../gitian-descriptors/gitian-win-signer.yml | 26 +- contrib/gitian-descriptors/gitian-win.yml | 126 +- contrib/gitian-keys/achow101-key.pgp | 52 - contrib/gitian-keys/aschildbach-key.pgp | Bin 1993 -> 0 bytes contrib/gitian-keys/bluematt-key.pgp | Bin 10324 -> 0 bytes contrib/gitian-keys/btcdrak-key.pgp | Bin 4916 -> 0 bytes contrib/gitian-keys/cdecker-key.pgp | Bin 2230 -> 0 bytes contrib/gitian-keys/centaur1-key.pgp | 30 - contrib/gitian-keys/cfields-key.pgp | 52 - contrib/gitian-keys/devrandom-key.pgp | Bin 2213 -> 0 bytes contrib/gitian-keys/erkmos.pgp | Bin 10205 -> 0 bytes contrib/gitian-keys/fanquake-key.pgp | 63 - contrib/gitian-keys/gavinandresen-key.pgp | Bin 1176 -> 0 bytes contrib/gitian-keys/jl2012-key.pgp | 275 -- contrib/gitian-keys/jonasschnelli-key.pgp | 110 - contrib/gitian-keys/laanwj-key.pgp | 28 - contrib/gitian-keys/luke-jr-key.pgp | Bin 6518 -> 0 bytes contrib/gitian-keys/marcofalke-key.pgp | 69 - contrib/gitian-keys/michagogo-key.pgp | 59 - contrib/gitian-keys/petertodd-key.pgp | 1901 --------- contrib/gitian-keys/prab-key.pgp | 81 - contrib/gitian-keys/sipa-key.pgp | Bin 137597 -> 0 bytes contrib/gitian-keys/tcatm-key.pgp | Bin 1554 -> 0 bytes contrib/gitian-keys/wtogami-key.pgp | 131 - contrib/init/README.md | 18 +- contrib/init/bitcoind.conf | 6 +- contrib/init/bitcoind.init | 4 +- contrib/init/bitcoind.openrc | 13 +- contrib/init/bitcoind.openrcconf | 4 +- contrib/init/bitcoind.service | 82 +- contrib/init/blackmored.conf | 65 + contrib/init/blackmored.init | 67 + contrib/init/blackmored.openrc | 93 + contrib/init/blackmored.openrcconf | 33 + contrib/init/blackmored.service | 82 + contrib/init/org.bitcoin.bitcoind.plist | 1 - contrib/init/org.blackcoin.blackmored.plist | 14 + contrib/install_db4.sh | 106 + contrib/linearize/README.md | 51 +- contrib/linearize/example-linearize.cfg | 58 +- contrib/linearize/linearize-data.py | 559 +-- contrib/linearize/linearize-hashes.py | 227 +- contrib/macdeploy/README.md | 123 +- contrib/macdeploy/detached-sig-apply.sh | 39 +- contrib/macdeploy/detached-sig-create.sh | 42 +- contrib/macdeploy/gen-sdk | 94 + contrib/macdeploy/macdeployqtplus | 692 +--- .../message-capture/message-capture-docs.md | 25 + .../message-capture/message-capture-parser.py | 214 + contrib/qos/README.md | 6 +- contrib/qos/tc.sh | 35 +- contrib/rpm/README.md | 185 - contrib/rpm/bitcoin-0.12.0-libressl.patch | 24 - contrib/rpm/bitcoin.fc | 8 - contrib/rpm/bitcoin.if | 157 - contrib/rpm/bitcoin.spec | 444 --- contrib/rpm/bitcoin.te | 81 - contrib/seeds/.gitignore | 1 + contrib/seeds/nodes_main.txt | 67 +- contrib/seeds/nodes_test.txt | 10 +- contrib/shell/git-utils.bash | 14 + contrib/shell/realpath.bash | 71 + contrib/spendfrom/spendfrom.py | 2 +- contrib/testgen/gen_key_io_test_vectors.py | 190 + contrib/tidy_datadir.sh | 62 - contrib/valgrind.supp | 185 + .../allow-incorrect-sha512-commits | 2 + .../allow-unclean-merge-commits | 4 + .../verify-commits/trusted-sha512-root-commit | 1 + contrib/verify-commits/verify-commits.py | 165 + contrib/verify-commits/verify-commits.sh | 62 - contrib/windeploy/detached-sig-create.sh | 35 + contrib/windeploy/win-codesign.cert | 42 + contrib/zmq/zmq_sub.py | 116 +- depends/Makefile | 94 +- depends/README.md | 35 +- depends/SDKs/.gitignore | 1 + depends/builders/darwin.mk | 8 +- depends/config.guess | 329 +- depends/config.site.in | 81 +- depends/config.sub | 649 ++-- depends/funcs.mk | 44 +- depends/gen_id | 74 + depends/hosts/darwin.mk | 112 +- depends/hosts/linux.mk | 2 +- depends/packages/bdb.mk | 7 +- depends/packages/boost.mk | 39 +- depends/packages/capnp.mk | 18 + depends/packages/dbus.mk | 6 +- depends/packages/expat.mk | 2 +- depends/packages/libXau.mk | 6 +- depends/packages/libevent.mk | 19 +- depends/packages/libmultiprocess.mk | 18 + depends/packages/libxcb.mk | 13 +- depends/packages/libxkbcommon.mk | 32 + depends/packages/miniupnpc.mk | 10 +- depends/packages/native_b2.mk | 20 + depends/packages/native_capnp.mk | 18 + depends/packages/native_ccache.mk | 4 +- depends/packages/native_cctools.mk | 102 +- depends/packages/native_clang.mk | 32 + depends/packages/native_ds_store.mk | 5 +- depends/packages/native_libdmg-hfsplus.mk | 10 +- depends/packages/native_libmultiprocess.mk | 18 + depends/packages/native_libtapi.mk | 20 + depends/packages/native_mac_alias.mk | 4 +- depends/packages/native_protobuf.mk | 18 +- depends/packages/openssl.mk | 26 +- depends/packages/packages.mk | 15 +- depends/packages/protobuf.mk | 10 +- depends/packages/qrencode.mk | 1 + depends/packages/qt.mk | 170 +- depends/packages/sqlite.mk | 26 + depends/packages/xcb_proto.mk | 11 +- depends/packages/xproto.mk | 7 +- depends/packages/xtrans.mk | 4 +- depends/packages/zeromq.mk | 7 +- depends/patches/bdb/winioctl.patch | 19 - .../patches/boost/unused_var_in_process.patch | 22 - .../fontconfig/gperf_header_regen.patch | 2 +- .../0001-fix-windows-getaddrinfo.patch | 15 - .../patches/miniupnpc/dont_leak_info.patch | 32 + .../patches/miniupnpc/dont_use_wingen.patch | 26 - .../ld64_disable_threading.patch | 26 - .../patches/qt/drop_lrelease_dependency.patch | 20 - .../patches/qt/fix-cocoahelpers-macos.patch | 70 - .../patches/qt/fix_android_jni_static.patch | 2 +- depends/patches/qt/fix_android_pch.patch | 10 + .../patches/qt/fix_android_qmake_conf.patch | 24 +- depends/patches/qt/fix_configure_mac.patch | 50 - depends/patches/qt/fix_lib_paths.patch | 193 + depends/patches/qt/fix_limits_header.patch | 44 + depends/patches/qt/fix_no_printer.patch | 4 +- depends/patches/qt/fix_powerpc_libpng.patch | 23 - depends/patches/qt/fix_qt_pkgconfig.patch | 12 +- depends/patches/qt/fix_rcc_determinism.patch | 15 - depends/patches/qt/fix_riscv64_arch.patch | 14 - depends/patches/qt/freetype_back_compat.patch | 28 - depends/patches/qt/mac-qmake.conf | 5 +- depends/patches/qt/no-xlib.patch | 17 +- depends/patches/qt/no_sdk_version_check.patch | 20 + depends/patches/qt/qfixed-coretext.patch | 34 - depends/patches/qt/qt.pro | 16 + .../qt/qtbase-moc-ignore-gcc-macro.patch | 17 + depends/patches/qt/qttools_src.pro | 6 + depends/patches/qt/xkb-default.patch | 26 - .../0001-fix-build-with-older-mingw64.patch | 30 - .../0002-disable-pthread_set_name_np.patch | 35 - doc/.gitignore | 1 + doc/Doxyfile | 2753 ++++++++----- doc/Doxyfile.in | 2461 ++++++++++++ doc/JSON-RPC-interface.md | 141 + doc/README_doxygen.md | 15 + doc/REST-interface.md | 76 +- doc/bips.md | 2 +- doc/bitcoin-conf.md | 64 + doc/build-android.md | 12 + doc/build-freebsd.md | 129 + doc/build-netbsd.md | 81 + doc/build-windows.md | 137 +- doc/developer-notes.md | 1229 +++++- doc/files.md | 156 +- doc/gitian-building.md | 475 +-- .../all_files_in_one_partition.png | Bin 3350 -> 0 bytes doc/gitian-building/create_new_vm.png | Bin 119839 -> 0 bytes .../create_vm_file_location_size.png | Bin 111942 -> 0 bytes doc/gitian-building/create_vm_hard_disk.png | Bin 123400 -> 0 bytes .../create_vm_hard_disk_file_type.png | Bin 170503 -> 0 bytes doc/gitian-building/create_vm_memsize.png | Bin 22158 -> 0 bytes .../create_vm_storage_physical_hard_disk.png | Bin 181681 -> 0 bytes .../debian_install_10_configure_clock.png | Bin 7892 -> 0 bytes .../debian_install_11_partition_disks.png | Bin 9511 -> 0 bytes .../debian_install_12_choose_disk.png | Bin 6613 -> 0 bytes .../debian_install_14_finish.png | Bin 10794 -> 0 bytes .../debian_install_15_write_changes.png | Bin 8790 -> 0 bytes .../debian_install_16_choose_a_mirror.png | Bin 11134 -> 0 bytes .../debian_install_18_proxy_settings.png | Bin 7582 -> 0 bytes .../debian_install_19_software_selection.png | Bin 8767 -> 0 bytes .../debian_install_1_boot_menu.png | Bin 110818 -> 0 bytes .../debian_install_20_install_grub.png | Bin 9784 -> 0 bytes ...ian_install_21_install_grub_bootloader.png | Bin 8878 -> 0 bytes .../debian_install_22_finish_installation.png | Bin 6964 -> 0 bytes .../debian_install_2_select_a_language.png | Bin 13131 -> 0 bytes .../debian_install_3_select_location.png | Bin 10388 -> 0 bytes .../debian_install_4_configure_keyboard.png | Bin 10224 -> 0 bytes ...debian_install_5_configure_the_network.png | Bin 7612 -> 0 bytes .../debian_install_6_domain_name.png | Bin 6526 -> 0 bytes ...debian_install_6a_set_up_root_password.png | Bin 11876 -> 0 bytes .../debian_install_7_set_up_user_fullname.png | Bin 8407 -> 0 bytes .../debian_install_8_set_up_username.png | Bin 7058 -> 0 bytes .../debian_install_9_user_password.png | Bin 6322 -> 0 bytes doc/gitian-building/debian_root_login.png | Bin 7028 -> 0 bytes doc/gitian-building/network_settings.png | Bin 72185 -> 0 bytes doc/gitian-building/port_forwarding_rules.png | Bin 44052 -> 0 bytes doc/gitian-building/select_startup_disk.png | Bin 72785 -> 0 bytes doc/init.md | 91 +- doc/man/Makefile.am | 19 +- doc/man/{bitcoin-cli.1 => blackmore-cli.1} | 0 doc/man/{bitcoin-qt.1 => blackmore-qt.1} | 0 doc/man/{bitcoin-tx.1 => blackmore-tx.1} | 0 doc/man/{bitcoind.1 => blackmored.1} | 0 doc/productivity.md | 218 ++ doc/reduce-memory.md | 54 + doc/reduce-traffic.md | 27 +- doc/release-notes.md | 121 +- doc/release-notes/release-notes-0.12.0.md | 2 +- doc/release-notes/release-notes-0.12.1.md | 198 + doc/release-notes/release-notes-0.13.0.md | 15 +- doc/release-process.md | 426 +- doc/shared-libraries.md | 7 +- doc/tor.md | 267 +- doc/translation_process.md | 36 +- doc/translation_strings_policy.md | 29 +- doc/travis-ci.txt | 39 - doc/zmq.md | 79 +- libbitcoinconsensus.pc.in | 2 +- qa/README.md | 14 +- qa/pull-tester/rpc-tests.py | 4 +- qa/pull-tester/run-bitcoind-for-test.sh.in | 4 +- qa/rpc-tests/nulldummy.py | 149 + qa/rpc-tests/proxy_test.py | 8 +- qa/rpc-tests/test_framework/test_framework.py | 16 +- qa/rpc-tests/test_framework/util.py | 16 +- qa/rpc-tests/txindex.py | 73 + qa/rpc-tests/zmq_test.py | 2 +- share/genbuild.sh | 6 +- share/pixmaps/nsis-header.bmp | Bin 25818 -> 25820 bytes share/pixmaps/nsis-wizard.bmp | Bin 154542 -> 154544 bytes share/qt/Info.plist.in | 14 +- share/qt/extract_strings_qt.py | 15 +- share/rpcauth/README.md | 18 + share/rpcauth/rpcauth.py | 46 + share/rpcuser/rpcuser.py | 2 +- share/setup.nsi.in | 44 +- src/.clang-format | 17 +- src/Makefile.am | 80 +- src/Makefile.bench.include | 29 +- src/Makefile.crc32c.include | 75 + src/Makefile.leveldb.include | 37 +- src/Makefile.qt.include | 26 +- src/Makefile.qttest.include | 32 +- src/Makefile.test.include | 34 +- src/bench/.gitignore | 2 +- src/bench/Examples.cpp | 6 +- src/bench/base58.cpp | 6 +- src/bench/bench.cpp | 4 +- src/bench/bench_bitcoin.cpp | 8 +- src/bench/cashaddr.cpp | 4 +- src/bench/ccoins_caching.cpp | 8 +- src/bench/coin_selection.cpp | 4 +- src/bench/crypto_hash.cpp | 18 +- src/bench/mempool_eviction.cpp | 6 +- src/bench/rollingbloom.cpp | 6 +- src/bitcoin-cli.cpp | 2 +- src/bitcoin-tx.cpp | 2 +- src/bitcoind.cpp | 2 +- src/chainparams.cpp | 9 +- src/chainparamsbase.cpp | 2 +- src/chainparamsseeds.h | 77 +- src/clientversion.cpp | 7 +- src/clientversion.h | 6 +- src/compat.h | 2 +- src/compat/assumptions.h | 66 + src/compat/byteswap.h | 25 +- src/compat/cpuid.h | 24 + src/compat/endian.h | 53 +- src/compat/glibc_compat.cpp | 245 +- src/compat/glibc_sanity.cpp | 6 +- src/compat/glibcxx_sanity.cpp | 4 +- src/compat/stdin.cpp | 72 + src/compat/stdin.h | 18 + src/compat/strnlen.cpp | 4 +- src/consensus/consensus.h | 6 + src/crc32c/.clang-format | 3 + src/crc32c/.clang_complete | 8 + src/crc32c/.gitignore | 8 + src/crc32c/.gitmodules | 0 src/crc32c/.ycm_extra_conf.py | 142 + src/crc32c/AUTHORS | 11 + src/crc32c/CMakeLists.txt | 434 +++ src/crc32c/CONTRIBUTING.md | 23 + src/crc32c/Crc32cConfig.cmake.in | 9 + src/crc32c/LICENSE | 28 + src/crc32c/README.md | 125 + src/crc32c/include/crc32c/crc32c.h | 89 + src/crc32c/src/crc32c.cc | 39 + src/crc32c/src/crc32c_arm64.cc | 125 + src/crc32c/src/crc32c_arm64.h | 27 + src/crc32c/src/crc32c_arm64_check.h | 68 + src/crc32c/src/crc32c_arm64_unittest.cc | 24 + src/crc32c/src/crc32c_benchmark.cc | 106 + src/crc32c/src/crc32c_capi_unittest.c | 66 + src/crc32c/src/crc32c_config.h.in | 36 + src/crc32c/src/crc32c_extend_unittests.h | 112 + src/crc32c/src/crc32c_internal.h | 23 + src/crc32c/src/crc32c_portable.cc | 351 ++ src/crc32c/src/crc32c_portable_unittest.cc | 20 + src/crc32c/src/crc32c_prefetch.h | 46 + src/crc32c/src/crc32c_prefetch_unittest.cc | 9 + src/crc32c/src/crc32c_read_le.h | 53 + src/crc32c/src/crc32c_read_le_unittest.cc | 32 + src/crc32c/src/crc32c_round_up.h | 34 + src/crc32c/src/crc32c_round_up_unittest.cc | 84 + src/crc32c/src/crc32c_sse42.cc | 258 ++ src/crc32c/src/crc32c_sse42.h | 33 + src/crc32c/src/crc32c_sse42_check.h | 50 + src/crc32c/src/crc32c_sse42_unittest.cc | 24 + src/crc32c/src/crc32c_test_main.cc | 22 + src/crc32c/src/crc32c_unittest.cc | 129 + src/crypto/aes.cpp | 6 +- src/crypto/aes.h | 2 +- src/crypto/chacha20.cpp | 310 ++ src/crypto/chacha20.h | 34 + src/crypto/common.h | 34 +- src/crypto/hmac_sha256.cpp | 4 +- src/crypto/hmac_sha256.h | 6 +- src/crypto/hmac_sha512.cpp | 4 +- src/crypto/hmac_sha512.h | 4 +- src/crypto/ripemd160.cpp | 8 +- src/crypto/ripemd160.h | 2 +- src/crypto/scrypt-sse2.cpp | 7 +- src/crypto/scrypt.cpp | 22 +- src/crypto/scrypt.h | 10 +- src/crypto/sha1.cpp | 8 +- src/crypto/sha1.h | 2 +- src/crypto/sha256.h | 2 +- src/crypto/sha512.cpp | 8 +- src/crypto/sha512.h | 5 +- src/cuckoocache.h | 483 +++ src/dbwrapper.h | 4 +- src/init.cpp | 17 +- src/leveldb/.clang-format | 18 + src/leveldb/.gitignore | 21 +- src/leveldb/CMakeLists.txt | 465 +++ src/leveldb/CONTRIBUTING.md | 4 +- src/leveldb/Makefile | 227 -- src/leveldb/README | 51 - src/leveldb/README.md | 135 +- src/leveldb/WINDOWS.md | 39 - src/leveldb/{db => benchmarks}/db_bench.cc | 257 +- .../bench => benchmarks}/db_bench_sqlite3.cc | 184 +- .../bench => benchmarks}/db_bench_tree_db.cc | 130 +- src/leveldb/build_detect_platform | 231 -- src/leveldb/cmake/leveldbConfig.cmake | 1 + src/leveldb/db/autocompact_test.cc | 36 +- src/leveldb/db/builder.cc | 25 +- src/leveldb/db/builder.h | 8 +- src/leveldb/db/c.cc | 389 +- src/leveldb/db/c_test.c | 36 +- src/leveldb/db/corruption_test.cc | 100 +- src/leveldb/db/db_impl.cc | 710 ++-- src/leveldb/db/db_impl.h | 154 +- src/leveldb/db/db_iter.cc | 93 +- src/leveldb/db/db_iter.h | 12 +- src/leveldb/db/db_test.cc | 748 ++-- src/leveldb/db/dbformat.cc | 43 +- src/leveldb/db/dbformat.h | 80 +- src/leveldb/db/dbformat_test.cc | 95 +- src/leveldb/db/dumpfile.cc | 29 +- src/leveldb/db/fault_injection_test.cc | 552 +++ src/leveldb/db/filename.cc | 37 +- src/leveldb/db/filename.h | 31 +- src/leveldb/db/filename_test.cc | 86 +- .../db/{leveldb_main.cc => leveldbutil.cc} | 20 +- src/leveldb/db/log_format.h | 2 +- src/leveldb/db/log_reader.cc | 50 +- src/leveldb/db/log_reader.h | 42 +- src/leveldb/db/log_test.cc | 344 +- src/leveldb/db/log_writer.cc | 38 +- src/leveldb/db/log_writer.h | 20 +- src/leveldb/db/memtable.cc | 70 +- src/leveldb/db/memtable.h | 28 +- src/leveldb/db/recovery_test.cc | 330 ++ src/leveldb/db/repair.cc | 95 +- src/leveldb/db/skiplist.h | 190 +- src/leveldb/db/skiplist_test.cc | 65 +- src/leveldb/db/snapshot.h | 79 +- src/leveldb/db/table_cache.cc | 47 +- src/leveldb/db/table_cache.h | 33 +- src/leveldb/db/version_edit.cc | 55 +- src/leveldb/db/version_edit.h | 27 +- src/leveldb/db/version_edit_test.cc | 6 +- src/leveldb/db/version_set.cc | 604 +-- src/leveldb/db/version_set.h | 129 +- src/leveldb/db/version_set_test.cc | 243 +- src/leveldb/db/write_batch.cc | 23 +- src/leveldb/db/write_batch_internal.h | 10 +- src/leveldb/db/write_batch_test.cc | 73 +- src/leveldb/doc/benchmark.html | 6 +- src/leveldb/doc/doc.css | 89 - src/leveldb/doc/impl.html | 213 - src/leveldb/doc/impl.md | 172 + src/leveldb/doc/index.html | 549 --- src/leveldb/doc/index.md | 523 +++ src/leveldb/doc/log_format.md | 75 + src/leveldb/doc/log_format.txt | 75 - src/leveldb/doc/table_format.md | 107 + src/leveldb/doc/table_format.txt | 104 - src/leveldb/helpers/memenv/memenv.cc | 205 +- src/leveldb/helpers/memenv/memenv.h | 4 +- src/leveldb/helpers/memenv/memenv_test.cc | 73 +- src/leveldb/include/leveldb/c.h | 320 +- src/leveldb/include/leveldb/cache.h | 32 +- src/leveldb/include/leveldb/comparator.h | 11 +- src/leveldb/include/leveldb/db.h | 60 +- src/leveldb/include/leveldb/dumpfile.h | 5 +- src/leveldb/include/leveldb/env.h | 237 +- src/leveldb/include/leveldb/export.h | 33 + src/leveldb/include/leveldb/filter_policy.h | 12 +- src/leveldb/include/leveldb/iterator.h | 36 +- src/leveldb/include/leveldb/options.h | 110 +- src/leveldb/include/leveldb/slice.h | 38 +- src/leveldb/include/leveldb/status.h | 58 +- src/leveldb/include/leveldb/table.h | 33 +- src/leveldb/include/leveldb/table_builder.h | 11 +- src/leveldb/include/leveldb/write_batch.h | 37 +- src/leveldb/issues/issue178_test.cc | 12 +- src/leveldb/issues/issue200_test.cc | 10 +- src/leveldb/issues/issue320_test.cc | 128 + src/leveldb/port/{README => README.md} | 2 +- src/leveldb/port/atomic_pointer.h | 223 -- src/leveldb/port/port.h | 8 +- src/leveldb/port/port_config.h.in | 39 + src/leveldb/port/port_example.h | 69 +- src/leveldb/port/port_posix.cc | 54 - src/leveldb/port/port_posix.h | 158 - src/leveldb/port/port_stdcxx.h | 153 + src/leveldb/port/port_win.cc | 147 - src/leveldb/port/port_win.h | 174 - src/leveldb/port/thread_annotations.h | 78 +- src/leveldb/port/win/stdint.h | 24 - src/leveldb/table/block.cc | 69 +- src/leveldb/table/block.h | 16 +- src/leveldb/table/block_builder.cc | 23 +- src/leveldb/table/block_builder.h | 26 +- src/leveldb/table/filter_block.cc | 25 +- src/leveldb/table/filter_block.h | 21 +- src/leveldb/table/filter_block_test.cc | 38 +- src/leveldb/table/format.cc | 24 +- src/leveldb/table/format.h | 42 +- src/leveldb/table/iterator.cc | 75 +- src/leveldb/table/iterator_wrapper.h | 61 +- src/leveldb/table/merger.cc | 52 +- src/leveldb/table/merger.h | 4 +- src/leveldb/table/table.cc | 68 +- src/leveldb/table/table_builder.cc | 61 +- src/leveldb/table/table_test.cc | 333 +- src/leveldb/table/two_level_iterator.cc | 91 +- src/leveldb/table/two_level_iterator.h | 11 +- src/leveldb/util/arena.cc | 18 +- src/leveldb/util/arena.h | 29 +- src/leveldb/util/arena_test.cc | 19 +- src/leveldb/util/bloom.cc | 29 +- src/leveldb/util/bloom_test.cc | 59 +- src/leveldb/util/cache.cc | 231 +- src/leveldb/util/cache_test.cc | 96 +- src/leveldb/util/coding.cc | 84 +- src/leveldb/util/coding.h | 136 +- src/leveldb/util/coding_test.cc | 42 +- src/leveldb/util/comparator.cc | 40 +- src/leveldb/util/crc32c.cc | 646 +-- src/leveldb/util/crc32c.h | 6 +- src/leveldb/util/crc32c_test.cc | 31 +- src/leveldb/util/env.cc | 28 +- src/leveldb/util/env_posix.cc | 1110 ++++-- src/leveldb/util/env_posix_test.cc | 350 ++ src/leveldb/util/env_posix_test_helper.h | 28 + src/leveldb/util/env_test.cc | 241 +- src/leveldb/util/env_win.cc | 873 ----- src/leveldb/util/env_windows.cc | 849 ++++ src/leveldb/util/env_windows_test.cc | 64 + src/leveldb/util/env_windows_test_helper.h | 25 + src/leveldb/util/filter_policy.cc | 2 +- src/leveldb/util/hash.cc | 15 +- src/leveldb/util/hash.h | 4 +- src/leveldb/util/hash_test.cc | 32 +- src/leveldb/util/histogram.cc | 207 +- src/leveldb/util/histogram.h | 20 +- src/leveldb/util/logging.cc | 52 +- src/leveldb/util/logging.h | 14 +- src/leveldb/util/logging_test.cc | 143 + src/leveldb/util/mutexlock.h | 12 +- src/leveldb/util/no_destructor.h | 46 + src/leveldb/util/no_destructor_test.cc | 47 + src/leveldb/util/options.cc | 17 +- src/leveldb/util/posix_logger.h | 168 +- src/leveldb/util/random.h | 9 +- src/leveldb/util/status.cc | 14 +- src/leveldb/util/status_test.cc | 40 + src/leveldb/util/testharness.cc | 18 +- src/leveldb/util/testharness.h | 85 +- src/leveldb/util/testutil.cc | 12 +- src/leveldb/util/testutil.h | 33 +- src/leveldb/util/windows_logger.h | 124 + src/main.cpp | 2 +- src/main.h | 6 +- src/miner.cpp | 8 - src/miner.h | 2 - src/net.cpp | 4 +- src/netaddress.cpp | 2 +- src/netaddress.h | 2 +- src/netbase.cpp | 2 +- src/netbase.h | 2 +- src/pos.h | 20 +- src/qt/README.md | 124 + src/qt/addressbookpage.cpp | 2 +- src/qt/askpassphrasedialog.cpp | 2 +- src/qt/bitcoin.cpp | 8 +- src/qt/bitcoingui.cpp | 2 +- src/qt/intro.cpp | 6 +- src/qt/macnotificationhandler.mm | 2 +- src/qt/macos_appnap.h | 24 + src/qt/macos_appnap.mm | 71 + src/qt/optionsdialog.cpp | 2 +- src/qt/optionsmodel.cpp | 2 +- src/qt/platformstyle.cpp | 2 +- src/qt/receiverequestdialog.cpp | 2 +- src/qt/res/bitcoin-qt-res.rc | 4 +- src/qt/res/fonts/RobotoMono-Bold.ttf | Bin 0 -> 87008 bytes src/qt/res/icons/bitcoin.icns | Bin 106823 -> 122168 bytes src/qt/res/src/bitcoin.svg | 59 +- src/qt/rpcconsole.cpp | 2 +- src/qt/splashscreen.cpp | 2 +- src/qt/test/test_main.cpp | 4 +- src/qt/utilitydialog.cpp | 2 +- src/rpc/mining.cpp | 3 +- src/rpc/misc.cpp | 33 +- src/rpc/net.cpp | 10 +- src/rpc/server.cpp | 6 +- src/script/bitcoinconsensus.h | 2 +- src/secp256k1/.gitignore | 6 +- src/secp256k1/.travis.yml | 69 - src/secp256k1/Makefile.am | 103 +- src/secp256k1/README.md | 71 +- src/secp256k1/SECURITY.md | 15 + src/secp256k1/TODO | 3 - .../build-aux/m4/ax_jni_include_dir.m4 | 140 - .../build-aux/m4/ax_prog_cc_for_build.m4 | 2 +- src/secp256k1/build-aux/m4/bitcoin_secp.m4 | 49 +- src/secp256k1/ci/cirrus.sh | 86 + src/secp256k1/ci/linux-debian.Dockerfile | 13 + src/secp256k1/configure.ac | 548 +-- src/secp256k1/contrib/lax_der_parsing.c | 17 +- src/secp256k1/contrib/lax_der_parsing.h | 20 +- .../contrib/lax_der_privatekey_parsing.c | 10 +- .../contrib/lax_der_privatekey_parsing.h | 20 +- src/secp256k1/doc/safegcd_implementation.md | 765 ++++ src/secp256k1/include/secp256k1.h | 328 +- src/secp256k1/include/secp256k1_ecdh.h | 59 +- src/secp256k1/include/secp256k1_extrakeys.h | 249 ++ .../include/secp256k1_preallocated.h | 128 + src/secp256k1/include/secp256k1_recovery.h | 42 +- src/secp256k1/include/secp256k1_schnorr.h | 173 - src/secp256k1/include/secp256k1_schnorrsig.h | 111 + src/secp256k1/libsecp256k1.pc.in | 2 +- src/secp256k1/sage/gen_exhaustive_groups.sage | 124 + .../sage/gen_split_lambda_constants.sage | 114 + src/secp256k1/sage/group_prover.sage | 27 +- ....sage => prove_group_implementations.sage} | 0 src/secp256k1/sage/secp256k1_params.sage | 36 + src/secp256k1/sage/weierstrass_prover.sage | 32 +- src/secp256k1/src/asm/field_10x26_arm.s | 18 +- src/secp256k1/src/assumptions.h | 80 + src/secp256k1/src/basic-config.h | 37 +- src/secp256k1/src/bench.h | 129 +- src/secp256k1/src/bench_ecdh.c | 35 +- src/secp256k1/src/bench_ecmult.c | 213 + src/secp256k1/src/bench_internal.c | 454 ++- src/secp256k1/src/bench_recover.c | 26 +- src/secp256k1/src/bench_schnorr_verify.c | 73 - src/secp256k1/src/bench_schnorrsig.c | 102 + src/secp256k1/src/bench_sign.c | 26 +- src/secp256k1/src/bench_verify.c | 33 +- src/secp256k1/src/ecdsa.h | 16 +- src/secp256k1/src/ecdsa_impl.h | 120 +- src/secp256k1/src/eckey.h | 16 +- src/secp256k1/src/eckey_impl.h | 41 +- src/secp256k1/src/ecmult.h | 42 +- src/secp256k1/src/ecmult_const.h | 23 +- src/secp256k1/src/ecmult_const_impl.h | 187 +- src/secp256k1/src/ecmult_gen.h | 45 +- src/secp256k1/src/ecmult_gen_impl.h | 118 +- src/secp256k1/src/ecmult_impl.h | 951 ++++- src/secp256k1/src/field.h | 57 +- src/secp256k1/src/field_10x26.h | 21 +- src/secp256k1/src/field_10x26_impl.h | 202 +- src/secp256k1/src/field_5x52.h | 26 +- src/secp256k1/src/field_5x52_asm_impl.h | 16 +- src/secp256k1/src/field_5x52_impl.h | 209 +- src/secp256k1/src/field_5x52_int128_impl.h | 20 +- src/secp256k1/src/field_impl.h | 205 +- src/secp256k1/src/gen_context.c | 53 +- src/secp256k1/src/group.h | 68 +- src/secp256k1/src/group_impl.h | 272 +- src/secp256k1/src/hash.h | 42 +- src/secp256k1/src/hash_impl.h | 86 +- .../src/java/org/bitcoin/NativeSecp256k1.java | 446 --- .../java/org/bitcoin/NativeSecp256k1Test.java | 226 -- .../java/org/bitcoin/NativeSecp256k1Util.java | 45 - .../java/org/bitcoin/Secp256k1Context.java | 51 - .../src/java/org_bitcoin_NativeSecp256k1.c | 377 -- .../src/java/org_bitcoin_NativeSecp256k1.h | 119 - .../src/java/org_bitcoin_Secp256k1Context.c | 15 - .../src/java/org_bitcoin_Secp256k1Context.h | 22 - src/secp256k1/src/modinv32.h | 42 + src/secp256k1/src/modinv32_impl.h | 587 +++ src/secp256k1/src/modinv64.h | 46 + src/secp256k1/src/modinv64_impl.h | 593 +++ src/secp256k1/src/modules/ecdh/main_impl.h | 87 +- src/secp256k1/src/modules/ecdh/tests_impl.h | 95 +- .../src/modules/extrakeys/Makefile.am.include | 4 + .../src/modules/extrakeys/main_impl.h | 261 ++ .../modules/extrakeys/tests_exhaustive_impl.h | 68 + .../src/modules/extrakeys/tests_impl.h | 549 +++ .../src/modules/recovery/Makefile.am.include | 1 + .../src/modules/recovery/main_impl.h | 67 +- .../modules/recovery/tests_exhaustive_impl.h | 149 + .../src/modules/recovery/tests_impl.h | 169 +- .../src/modules/schnorr/Makefile.am.include | 10 - src/secp256k1/src/modules/schnorr/main_impl.h | 164 - src/secp256k1/src/modules/schnorr/schnorr.h | 20 - .../src/modules/schnorr/schnorr_impl.h | 207 - .../src/modules/schnorr/tests_impl.h | 175 - .../modules/schnorrsig/Makefile.am.include | 9 + .../src/modules/schnorrsig/main_impl.h | 239 ++ .../schnorrsig/tests_exhaustive_impl.h | 206 + .../src/modules/schnorrsig/tests_impl.h | 806 ++++ src/secp256k1/src/num.h | 74 - src/secp256k1/src/num_gmp.h | 20 - src/secp256k1/src/num_gmp_impl.h | 288 -- src/secp256k1/src/num_impl.h | 24 - src/secp256k1/src/scalar.h | 59 +- src/secp256k1/src/scalar_4x64.h | 16 +- src/secp256k1/src/scalar_4x64_impl.h | 297 +- src/secp256k1/src/scalar_8x32.h | 16 +- src/secp256k1/src/scalar_8x32_impl.h | 240 +- src/secp256k1/src/scalar_impl.h | 531 ++- src/secp256k1/src/scalar_low.h | 18 +- src/secp256k1/src/scalar_low_impl.h | 59 +- src/secp256k1/src/scratch.h | 42 + src/secp256k1/src/scratch_impl.h | 99 + src/secp256k1/src/secp256k1.c | 476 ++- src/secp256k1/src/selftest.h | 32 + src/secp256k1/src/testrand.h | 39 +- src/secp256k1/src/testrand_impl.h | 90 +- src/secp256k1/src/tests.c | 3461 +++++++++++++---- src/secp256k1/src/tests_exhaustive.c | 305 +- src/secp256k1/src/util.h | 262 +- src/secp256k1/src/valgrind_ctime_test.c | 173 + src/support/allocators/secure.h | 2 +- src/support/allocators/zeroafterfree.h | 2 +- src/support/cleanse.cpp | 46 +- src/support/cleanse.h | 4 +- src/support/pagelocker.cpp | 8 +- src/support/pagelocker.h | 2 +- src/test/DoS_tests.cpp | 19 +- src/test/README.md | 12 +- src/test/addrman_tests.cpp | 12 +- src/test/allocator_tests.cpp | 6 +- src/test/amount_tests.cpp | 4 +- src/test/arith_uint256_tests.cpp | 10 +- src/test/base32_tests.cpp | 4 +- src/test/base58_tests.cpp | 21 +- src/test/base64_tests.cpp | 4 +- src/test/bctest.py | 3 - src/test/bip32_tests.cpp | 12 +- src/test/blockencodings_tests.cpp | 12 +- src/test/bloom_tests.cpp | 28 +- src/test/data/base58_encode_decode.json | 4 +- src/test/data/script_tests.json | 811 +++- src/test/data/tx_invalid.json | 310 +- src/test/data/tx_valid.json | 445 ++- src/test/script_P2PKH_tests.cpp | 57 + src/test/scrypt_tests.cpp | 10 +- src/test/serialize_tests.cpp | 12 +- src/test/sighash_tests.cpp | 26 +- src/test/sigopcount_tests.cpp | 28 +- src/test/skiplist_tests.cpp | 12 +- src/test/streams_tests.cpp | 29 +- src/test/test_bitcoin.cpp | 41 +- src/test/test_bitcoin.h | 12 +- src/test/testutil.cpp | 2 +- src/test/timedata_tests.cpp | 6 +- src/test/transaction_tests.cpp | 38 +- src/test/txvalidationcache_tests.cpp | 22 +- src/test/uint256_tests.cpp | 8 +- src/test/univalue_tests.cpp | 34 +- src/test/util_tests.cpp | 58 +- src/test/versionbits_tests.cpp | 20 +- src/timedata.cpp | 2 +- src/tinyformat.h | 991 +++-- src/univalue/.travis.yml | 52 - src/univalue/Makefile.am | 31 +- src/univalue/README | 7 - src/univalue/README.md | 21 + src/univalue/configure.ac | 6 +- src/univalue/gen/gen.cpp | 2 - src/univalue/include/univalue.h | 80 +- src/univalue/lib/univalue.cpp | 232 +- src/univalue/lib/univalue_get.cpp | 147 + src/univalue/lib/univalue_read.cpp | 93 +- src/univalue/lib/univalue_utffilter.h | 44 +- src/univalue/lib/univalue_write.cpp | 20 +- src/univalue/test/.gitignore | 4 + src/univalue/test/fail1.json | 2 +- src/univalue/test/fail42.json | Bin 0 -> 37 bytes src/univalue/test/fail44.json | 1 + src/univalue/test/fail45.json | 1 + src/univalue/test/no_nul.cpp | 8 + src/univalue/test/object.cpp | 420 ++ src/univalue/test/pass4.json | 1 + src/univalue/test/round3.json | 1 + .../compat => src/univalue/test/round4.json | 0 src/univalue/test/round5.json | 1 + src/univalue/test/round6.json | 1 + src/univalue/test/round7.json | 1 + src/univalue/test/test_json.cpp | 24 + src/univalue/test/unitester.cpp | 24 +- src/util.h | 2 +- src/utiltime.cpp | 2 +- src/version.h | 2 +- src/wallet/rpcwallet.cpp | 252 ++ src/wallet/wallet.cpp | 2 +- src/zmq/zmqabstractnotifier.cpp | 4 +- src/zmq/zmqabstractnotifier.h | 2 +- src/zmq/zmqconfig.h | 6 +- src/zmq/zmqnotificationinterface.cpp | 20 +- src/zmq/zmqnotificationinterface.h | 4 +- src/zmq/zmqpublishnotifier.cpp | 10 +- src/zmq/zmqpublishnotifier.h | 4 +- 808 files changed, 49426 insertions(+), 29224 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/good_first_issue.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .travis.yml create mode 100644 build-aux/m4/ax_boost_process.m4 create mode 100644 build-aux/m4/ax_boost_random.m4 create mode 100644 build-aux/m4/bitcoin_runtime_lib.m4 create mode 100644 build-aux/m4/l_socket.m4 create mode 100644 contrib/builder-keys/README.md create mode 100644 contrib/builder-keys/keys.txt delete mode 100644 contrib/debian/README.md delete mode 100644 contrib/debian/bitcoin-qt.desktop delete mode 100644 contrib/debian/bitcoin-qt.install delete mode 100644 contrib/debian/bitcoin-qt.lintian-overrides delete mode 100644 contrib/debian/bitcoin-qt.protocol delete mode 100644 contrib/debian/bitcoin-tx.bash-completion delete mode 100644 contrib/debian/bitcoin-tx.install delete mode 100644 contrib/debian/bitcoind.bash-completion delete mode 100644 contrib/debian/bitcoind.examples delete mode 100644 contrib/debian/bitcoind.install delete mode 100644 contrib/debian/bitcoind.lintian-overrides delete mode 100644 contrib/debian/bitcoind.manpages delete mode 100644 contrib/debian/changelog delete mode 100644 contrib/debian/control delete mode 100644 contrib/debian/examples/bitcoin.conf delete mode 100644 contrib/debian/gbp.conf delete mode 100644 contrib/debian/manpages/bitcoin-cli.1 delete mode 100644 contrib/debian/manpages/bitcoin-qt.1 delete mode 100644 contrib/debian/manpages/bitcoin-tx.1 delete mode 100644 contrib/debian/manpages/bitcoin.conf.5 delete mode 100644 contrib/debian/manpages/bitcoind.1 delete mode 100644 contrib/debian/patches/README delete mode 100644 contrib/debian/patches/series delete mode 100755 contrib/debian/rules delete mode 100644 contrib/debian/source/format delete mode 100644 contrib/debian/watch create mode 100755 contrib/devtools/circular-dependencies.py create mode 100755 contrib/devtools/copyright_header.py create mode 100644 contrib/devtools/pixie.py create mode 100755 contrib/devtools/test-symbol-check.py create mode 100755 contrib/devtools/test_deterministic_coverage.sh create mode 100755 contrib/devtools/utils.py create mode 100755 contrib/devtools/utxo_snapshot.sh create mode 100755 contrib/filter-lcov.py create mode 100755 contrib/gitian-build.py delete mode 100755 contrib/gitian-build.sh delete mode 100644 contrib/gitian-descriptors/README.md create mode 100644 contrib/gitian-descriptors/assign_DISTNAME delete mode 100644 contrib/gitian-keys/achow101-key.pgp delete mode 100644 contrib/gitian-keys/aschildbach-key.pgp delete mode 100644 contrib/gitian-keys/bluematt-key.pgp delete mode 100644 contrib/gitian-keys/btcdrak-key.pgp delete mode 100644 contrib/gitian-keys/cdecker-key.pgp delete mode 100644 contrib/gitian-keys/centaur1-key.pgp delete mode 100644 contrib/gitian-keys/cfields-key.pgp delete mode 100644 contrib/gitian-keys/devrandom-key.pgp delete mode 100644 contrib/gitian-keys/erkmos.pgp delete mode 100644 contrib/gitian-keys/fanquake-key.pgp delete mode 100644 contrib/gitian-keys/gavinandresen-key.pgp delete mode 100644 contrib/gitian-keys/jl2012-key.pgp delete mode 100644 contrib/gitian-keys/jonasschnelli-key.pgp delete mode 100644 contrib/gitian-keys/laanwj-key.pgp delete mode 100644 contrib/gitian-keys/luke-jr-key.pgp delete mode 100644 contrib/gitian-keys/marcofalke-key.pgp delete mode 100644 contrib/gitian-keys/michagogo-key.pgp delete mode 100644 contrib/gitian-keys/petertodd-key.pgp delete mode 100644 contrib/gitian-keys/prab-key.pgp delete mode 100644 contrib/gitian-keys/sipa-key.pgp delete mode 100644 contrib/gitian-keys/tcatm-key.pgp delete mode 100644 contrib/gitian-keys/wtogami-key.pgp create mode 100644 contrib/init/blackmored.conf create mode 100644 contrib/init/blackmored.init create mode 100644 contrib/init/blackmored.openrc create mode 100644 contrib/init/blackmored.openrcconf create mode 100644 contrib/init/blackmored.service create mode 100644 contrib/init/org.blackcoin.blackmored.plist create mode 100755 contrib/install_db4.sh create mode 100755 contrib/macdeploy/gen-sdk create mode 100644 contrib/message-capture/message-capture-docs.md create mode 100755 contrib/message-capture/message-capture-parser.py delete mode 100644 contrib/rpm/README.md delete mode 100644 contrib/rpm/bitcoin-0.12.0-libressl.patch delete mode 100644 contrib/rpm/bitcoin.fc delete mode 100644 contrib/rpm/bitcoin.if delete mode 100644 contrib/rpm/bitcoin.spec delete mode 100644 contrib/rpm/bitcoin.te create mode 100644 contrib/seeds/.gitignore create mode 100644 contrib/shell/git-utils.bash create mode 100644 contrib/shell/realpath.bash create mode 100755 contrib/testgen/gen_key_io_test_vectors.py delete mode 100755 contrib/tidy_datadir.sh create mode 100644 contrib/valgrind.supp create mode 100644 contrib/verify-commits/allow-incorrect-sha512-commits create mode 100644 contrib/verify-commits/allow-unclean-merge-commits create mode 100644 contrib/verify-commits/trusted-sha512-root-commit create mode 100755 contrib/verify-commits/verify-commits.py delete mode 100755 contrib/verify-commits/verify-commits.sh create mode 100644 contrib/windeploy/detached-sig-create.sh create mode 100644 contrib/windeploy/win-codesign.cert create mode 100644 depends/SDKs/.gitignore create mode 100755 depends/gen_id create mode 100644 depends/packages/capnp.mk create mode 100644 depends/packages/libmultiprocess.mk create mode 100644 depends/packages/libxkbcommon.mk create mode 100644 depends/packages/native_b2.mk create mode 100644 depends/packages/native_capnp.mk create mode 100644 depends/packages/native_clang.mk create mode 100644 depends/packages/native_libmultiprocess.mk create mode 100644 depends/packages/native_libtapi.mk create mode 100644 depends/packages/sqlite.mk delete mode 100644 depends/patches/bdb/winioctl.patch delete mode 100644 depends/patches/boost/unused_var_in_process.patch delete mode 100644 depends/patches/libevent/0001-fix-windows-getaddrinfo.patch create mode 100644 depends/patches/miniupnpc/dont_leak_info.patch delete mode 100644 depends/patches/miniupnpc/dont_use_wingen.patch delete mode 100644 depends/patches/native_cctools/ld64_disable_threading.patch delete mode 100644 depends/patches/qt/drop_lrelease_dependency.patch delete mode 100644 depends/patches/qt/fix-cocoahelpers-macos.patch create mode 100644 depends/patches/qt/fix_android_pch.patch delete mode 100644 depends/patches/qt/fix_configure_mac.patch create mode 100644 depends/patches/qt/fix_lib_paths.patch create mode 100644 depends/patches/qt/fix_limits_header.patch delete mode 100644 depends/patches/qt/fix_powerpc_libpng.patch delete mode 100644 depends/patches/qt/fix_rcc_determinism.patch delete mode 100644 depends/patches/qt/fix_riscv64_arch.patch delete mode 100644 depends/patches/qt/freetype_back_compat.patch create mode 100644 depends/patches/qt/no_sdk_version_check.patch delete mode 100644 depends/patches/qt/qfixed-coretext.patch create mode 100644 depends/patches/qt/qt.pro create mode 100644 depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch create mode 100644 depends/patches/qt/qttools_src.pro delete mode 100644 depends/patches/qt/xkb-default.patch delete mode 100644 depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch delete mode 100644 depends/patches/zeromq/0002-disable-pthread_set_name_np.patch create mode 100644 doc/.gitignore create mode 100644 doc/Doxyfile.in create mode 100644 doc/JSON-RPC-interface.md create mode 100644 doc/README_doxygen.md create mode 100644 doc/bitcoin-conf.md create mode 100644 doc/build-android.md create mode 100644 doc/build-freebsd.md create mode 100644 doc/build-netbsd.md delete mode 100644 doc/gitian-building/all_files_in_one_partition.png delete mode 100644 doc/gitian-building/create_new_vm.png delete mode 100644 doc/gitian-building/create_vm_file_location_size.png delete mode 100644 doc/gitian-building/create_vm_hard_disk.png delete mode 100644 doc/gitian-building/create_vm_hard_disk_file_type.png delete mode 100644 doc/gitian-building/create_vm_memsize.png delete mode 100644 doc/gitian-building/create_vm_storage_physical_hard_disk.png delete mode 100644 doc/gitian-building/debian_install_10_configure_clock.png delete mode 100644 doc/gitian-building/debian_install_11_partition_disks.png delete mode 100644 doc/gitian-building/debian_install_12_choose_disk.png delete mode 100644 doc/gitian-building/debian_install_14_finish.png delete mode 100644 doc/gitian-building/debian_install_15_write_changes.png delete mode 100644 doc/gitian-building/debian_install_16_choose_a_mirror.png delete mode 100644 doc/gitian-building/debian_install_18_proxy_settings.png delete mode 100644 doc/gitian-building/debian_install_19_software_selection.png delete mode 100644 doc/gitian-building/debian_install_1_boot_menu.png delete mode 100644 doc/gitian-building/debian_install_20_install_grub.png delete mode 100644 doc/gitian-building/debian_install_21_install_grub_bootloader.png delete mode 100644 doc/gitian-building/debian_install_22_finish_installation.png delete mode 100644 doc/gitian-building/debian_install_2_select_a_language.png delete mode 100644 doc/gitian-building/debian_install_3_select_location.png delete mode 100644 doc/gitian-building/debian_install_4_configure_keyboard.png delete mode 100644 doc/gitian-building/debian_install_5_configure_the_network.png delete mode 100644 doc/gitian-building/debian_install_6_domain_name.png delete mode 100644 doc/gitian-building/debian_install_6a_set_up_root_password.png delete mode 100644 doc/gitian-building/debian_install_7_set_up_user_fullname.png delete mode 100644 doc/gitian-building/debian_install_8_set_up_username.png delete mode 100644 doc/gitian-building/debian_install_9_user_password.png delete mode 100644 doc/gitian-building/debian_root_login.png delete mode 100644 doc/gitian-building/network_settings.png delete mode 100644 doc/gitian-building/port_forwarding_rules.png delete mode 100644 doc/gitian-building/select_startup_disk.png rename doc/man/{bitcoin-cli.1 => blackmore-cli.1} (100%) rename doc/man/{bitcoin-qt.1 => blackmore-qt.1} (100%) rename doc/man/{bitcoin-tx.1 => blackmore-tx.1} (100%) rename doc/man/{bitcoind.1 => blackmored.1} (100%) create mode 100644 doc/productivity.md create mode 100644 doc/reduce-memory.md create mode 100644 doc/release-notes/release-notes-0.12.1.md delete mode 100644 doc/travis-ci.txt create mode 100755 qa/rpc-tests/nulldummy.py create mode 100755 qa/rpc-tests/txindex.py create mode 100644 share/rpcauth/README.md create mode 100755 share/rpcauth/rpcauth.py create mode 100644 src/Makefile.crc32c.include create mode 100644 src/compat/assumptions.h create mode 100644 src/compat/cpuid.h create mode 100644 src/compat/stdin.cpp create mode 100644 src/compat/stdin.h create mode 100644 src/crc32c/.clang-format create mode 100644 src/crc32c/.clang_complete create mode 100644 src/crc32c/.gitignore create mode 100644 src/crc32c/.gitmodules create mode 100644 src/crc32c/.ycm_extra_conf.py create mode 100644 src/crc32c/AUTHORS create mode 100644 src/crc32c/CMakeLists.txt create mode 100644 src/crc32c/CONTRIBUTING.md create mode 100644 src/crc32c/Crc32cConfig.cmake.in create mode 100644 src/crc32c/LICENSE create mode 100644 src/crc32c/README.md create mode 100644 src/crc32c/include/crc32c/crc32c.h create mode 100644 src/crc32c/src/crc32c.cc create mode 100644 src/crc32c/src/crc32c_arm64.cc create mode 100644 src/crc32c/src/crc32c_arm64.h create mode 100644 src/crc32c/src/crc32c_arm64_check.h create mode 100644 src/crc32c/src/crc32c_arm64_unittest.cc create mode 100644 src/crc32c/src/crc32c_benchmark.cc create mode 100644 src/crc32c/src/crc32c_capi_unittest.c create mode 100644 src/crc32c/src/crc32c_config.h.in create mode 100644 src/crc32c/src/crc32c_extend_unittests.h create mode 100644 src/crc32c/src/crc32c_internal.h create mode 100644 src/crc32c/src/crc32c_portable.cc create mode 100644 src/crc32c/src/crc32c_portable_unittest.cc create mode 100644 src/crc32c/src/crc32c_prefetch.h create mode 100644 src/crc32c/src/crc32c_prefetch_unittest.cc create mode 100644 src/crc32c/src/crc32c_read_le.h create mode 100644 src/crc32c/src/crc32c_read_le_unittest.cc create mode 100644 src/crc32c/src/crc32c_round_up.h create mode 100644 src/crc32c/src/crc32c_round_up_unittest.cc create mode 100644 src/crc32c/src/crc32c_sse42.cc create mode 100644 src/crc32c/src/crc32c_sse42.h create mode 100644 src/crc32c/src/crc32c_sse42_check.h create mode 100644 src/crc32c/src/crc32c_sse42_unittest.cc create mode 100644 src/crc32c/src/crc32c_test_main.cc create mode 100644 src/crc32c/src/crc32c_unittest.cc create mode 100644 src/crypto/chacha20.cpp create mode 100644 src/crypto/chacha20.h create mode 100644 src/cuckoocache.h create mode 100644 src/leveldb/.clang-format create mode 100644 src/leveldb/CMakeLists.txt delete mode 100644 src/leveldb/Makefile delete mode 100644 src/leveldb/README delete mode 100644 src/leveldb/WINDOWS.md rename src/leveldb/{db => benchmarks}/db_bench.cc (82%) rename src/leveldb/{doc/bench => benchmarks}/db_bench_sqlite3.cc (83%) rename src/leveldb/{doc/bench => benchmarks}/db_bench_tree_db.cc (85%) delete mode 100755 src/leveldb/build_detect_platform create mode 100644 src/leveldb/cmake/leveldbConfig.cmake create mode 100644 src/leveldb/db/fault_injection_test.cc rename src/leveldb/db/{leveldb_main.cc => leveldbutil.cc} (71%) create mode 100644 src/leveldb/db/recovery_test.cc delete mode 100644 src/leveldb/doc/doc.css delete mode 100644 src/leveldb/doc/impl.html create mode 100644 src/leveldb/doc/impl.md delete mode 100644 src/leveldb/doc/index.html create mode 100644 src/leveldb/doc/index.md create mode 100644 src/leveldb/doc/log_format.md delete mode 100644 src/leveldb/doc/log_format.txt create mode 100644 src/leveldb/doc/table_format.md delete mode 100644 src/leveldb/doc/table_format.txt create mode 100644 src/leveldb/include/leveldb/export.h create mode 100644 src/leveldb/issues/issue320_test.cc rename src/leveldb/port/{README => README.md} (82%) delete mode 100644 src/leveldb/port/atomic_pointer.h create mode 100644 src/leveldb/port/port_config.h.in delete mode 100644 src/leveldb/port/port_posix.cc delete mode 100644 src/leveldb/port/port_posix.h create mode 100644 src/leveldb/port/port_stdcxx.h delete mode 100644 src/leveldb/port/port_win.cc delete mode 100644 src/leveldb/port/port_win.h delete mode 100644 src/leveldb/port/win/stdint.h create mode 100644 src/leveldb/util/env_posix_test.cc create mode 100644 src/leveldb/util/env_posix_test_helper.h delete mode 100644 src/leveldb/util/env_win.cc create mode 100644 src/leveldb/util/env_windows.cc create mode 100644 src/leveldb/util/env_windows_test.cc create mode 100644 src/leveldb/util/env_windows_test_helper.h create mode 100644 src/leveldb/util/logging_test.cc create mode 100644 src/leveldb/util/no_destructor.h create mode 100644 src/leveldb/util/no_destructor_test.cc create mode 100644 src/leveldb/util/status_test.cc create mode 100644 src/leveldb/util/windows_logger.h create mode 100644 src/qt/README.md create mode 100644 src/qt/macos_appnap.h create mode 100644 src/qt/macos_appnap.mm create mode 100644 src/qt/res/fonts/RobotoMono-Bold.ttf delete mode 100644 src/secp256k1/.travis.yml create mode 100644 src/secp256k1/SECURITY.md delete mode 100644 src/secp256k1/TODO delete mode 100644 src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 create mode 100755 src/secp256k1/ci/cirrus.sh create mode 100644 src/secp256k1/ci/linux-debian.Dockerfile create mode 100644 src/secp256k1/doc/safegcd_implementation.md create mode 100644 src/secp256k1/include/secp256k1_extrakeys.h create mode 100644 src/secp256k1/include/secp256k1_preallocated.h delete mode 100644 src/secp256k1/include/secp256k1_schnorr.h create mode 100644 src/secp256k1/include/secp256k1_schnorrsig.h create mode 100644 src/secp256k1/sage/gen_exhaustive_groups.sage create mode 100644 src/secp256k1/sage/gen_split_lambda_constants.sage rename src/secp256k1/sage/{secp256k1.sage => prove_group_implementations.sage} (100%) create mode 100644 src/secp256k1/sage/secp256k1_params.sage create mode 100644 src/secp256k1/src/assumptions.h create mode 100644 src/secp256k1/src/bench_ecmult.c delete mode 100644 src/secp256k1/src/bench_schnorr_verify.c create mode 100644 src/secp256k1/src/bench_schnorrsig.c delete mode 100644 src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java delete mode 100644 src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java delete mode 100644 src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java delete mode 100644 src/secp256k1/src/java/org/bitcoin/Secp256k1Context.java delete mode 100644 src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c delete mode 100644 src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h delete mode 100644 src/secp256k1/src/java/org_bitcoin_Secp256k1Context.c delete mode 100644 src/secp256k1/src/java/org_bitcoin_Secp256k1Context.h create mode 100644 src/secp256k1/src/modinv32.h create mode 100644 src/secp256k1/src/modinv32_impl.h create mode 100644 src/secp256k1/src/modinv64.h create mode 100644 src/secp256k1/src/modinv64_impl.h create mode 100644 src/secp256k1/src/modules/extrakeys/Makefile.am.include create mode 100644 src/secp256k1/src/modules/extrakeys/main_impl.h create mode 100644 src/secp256k1/src/modules/extrakeys/tests_exhaustive_impl.h create mode 100644 src/secp256k1/src/modules/extrakeys/tests_impl.h create mode 100644 src/secp256k1/src/modules/recovery/tests_exhaustive_impl.h delete mode 100644 src/secp256k1/src/modules/schnorr/Makefile.am.include delete mode 100644 src/secp256k1/src/modules/schnorr/main_impl.h delete mode 100644 src/secp256k1/src/modules/schnorr/schnorr.h delete mode 100644 src/secp256k1/src/modules/schnorr/schnorr_impl.h delete mode 100644 src/secp256k1/src/modules/schnorr/tests_impl.h create mode 100644 src/secp256k1/src/modules/schnorrsig/Makefile.am.include create mode 100644 src/secp256k1/src/modules/schnorrsig/main_impl.h create mode 100644 src/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h create mode 100644 src/secp256k1/src/modules/schnorrsig/tests_impl.h delete mode 100644 src/secp256k1/src/num.h delete mode 100644 src/secp256k1/src/num_gmp.h delete mode 100644 src/secp256k1/src/num_gmp_impl.h delete mode 100644 src/secp256k1/src/num_impl.h create mode 100644 src/secp256k1/src/scratch.h create mode 100644 src/secp256k1/src/scratch_impl.h create mode 100644 src/secp256k1/src/selftest.h create mode 100644 src/secp256k1/src/valgrind_ctime_test.c create mode 100644 src/test/script_P2PKH_tests.cpp delete mode 100644 src/univalue/.travis.yml delete mode 100644 src/univalue/README create mode 100644 src/univalue/README.md create mode 100644 src/univalue/lib/univalue_get.cpp create mode 100644 src/univalue/test/fail42.json create mode 100644 src/univalue/test/fail44.json create mode 100644 src/univalue/test/fail45.json create mode 100644 src/univalue/test/no_nul.cpp create mode 100644 src/univalue/test/object.cpp create mode 100644 src/univalue/test/pass4.json create mode 100644 src/univalue/test/round3.json rename contrib/debian/compat => src/univalue/test/round4.json (100%) create mode 100644 src/univalue/test/round5.json create mode 100644 src/univalue/test/round6.json create mode 100644 src/univalue/test/round7.json create mode 100644 src/univalue/test/test_json.cpp diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..688dcfa0f0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..bc36f19810 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Create a report to help us improve (use this for suspected bugs only, if not sure, open a regular issue below) +title: '' +labels: Bug +assignees: '' + +--- + + + + + +**Expected behavior** + + + +**Actual behavior** + + + +**To reproduce** + + + +**System information** + + + + + + + + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..2d5685185e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: Feature +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** + + +**Describe the solution you'd like** + + +**Describe alternatives you've considered** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/good_first_issue.md b/.github/ISSUE_TEMPLATE/good_first_issue.md new file mode 100644 index 0000000000..d087fa8609 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/good_first_issue.md @@ -0,0 +1,22 @@ +--- +name: Good first issue +about: '(Regular devs only): Suggest a new good first issue' +title: '' +labels: '' +assignees: '' + +--- + + + + + + + +#### Useful skills: + + + +#### Want to work on this issue? + +For guidance on contributing, please read [CONTRIBUTING.md](https://gitlab.com/blackcoin/blackcoin-more/blob/master/CONTRIBUTING.md) before opening your pull request. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..e7f0a396c0 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,41 @@ + + + + + diff --git a/.gitignore b/.gitignore index 59c923bbe8..d8539af8a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,18 @@ *.tar.gz *.exe -src/blackmore -src/blackmored -src/blackmore-cli -src/blackmore-tx -src/test/test_blackmore -src/qt/test/test_blackmore-qt +*.pdb +src/bitcoin +src/bitcoind +src/bitcoin-cli +src/bitcoin-gui +src/bitcoin-node +src/bitcoin-tx +src/bitcoin-util +src/bitcoin-wallet +src/test/fuzz/fuzz +src/test/test_bitcoin +src/qt/test/test_bitcoin-qt # autoreconf Makefile.in @@ -45,17 +51,17 @@ src/qt/forms/ui_*.h src/qt/test/moc*.cpp -src/qt/blackmore-qt.config -src/qt/blackmore-qt.creator -src/qt/blackmore-qt.creator.user -src/qt/blackmore-qt.files -src/qt/blackmore-qt.includes +src/qt/bitcoin-qt.config +src/qt/bitcoin-qt.creator +src/qt/bitcoin-qt.creator.user +src/qt/bitcoin-qt.files +src/qt/bitcoin-qt.includes .deps .dirstamp .libs .*.swp -*.*~* +*~ *.bak *.rej *.orig @@ -70,6 +76,7 @@ src/qt/blackmore-qt.includes *.log *.trs *.dmg +*.iso *.json.h *.raw.h @@ -86,8 +93,8 @@ src/qt/blackmore-qt.includes *.qm Makefile !depends/Makefile -src/qt/blackmore-qt -Blackmore-Qt.app +src/qt/bitcoin-qt +Bitcoin-Qt.app background.tiff* # Qt Creator @@ -95,8 +102,7 @@ Makefile.am.user # Unit-tests Makefile.test -blackmore-qt_test -src/test/buildenv.py +bitcoin-qt_test # Resources cpp qrc_*.cpp @@ -114,7 +120,10 @@ releases /*.info test_bitcoin.coverage/ total.coverage/ +fuzz.coverage/ coverage_percent.txt +/cov_tool_wrapper.sh +qa-assets/ #build tests linux-coverage-build @@ -122,8 +131,7 @@ linux-build win32-build test/config.ini test/cache/* -qa/pull-tester/run-bitcoind-for-test.sh -qa/pull-tester/tests_config.py +test/.mypy_cache/ !src/leveldb*/Makefile @@ -132,13 +140,46 @@ qa/pull-tester/tests_config.py libbitcoinconsensus.pc contrib/devtools/split-debug.sh -#Visual Studio -.vscode/* -.vs/* +# Output from running db4 installation +db4/ # clang-check *.plist osx_volname dist/ -*.background.tiff \ No newline at end of file +*.background.tiff + +/guix-build-* + +# Blackcoin More +src/blackmore +src/blackmored +src/blackmore-cli +src/blackmore-tx +src/test/test_blackmore +src/qt/blackmore-qt_test +src/qt/test/test_blackmore-qt +qa/pull-tester/run-bitcoind-for-test.sh +qa/pull-tester/tests_config.py + + +#Visual Studio +.vscode/* +.vs/* + +# Output from running db6 installation +db6/ + +# Unit-tests + +src/test/buildenv.py + +# Compilation and Qt preprocessor part +src/qt/blackmore-qt +Blackmore-Qt.app +src/qt/blackmore-qt.config +src/qt/blackmore-qt.creator +src/qt/blackmore-qt.creator.user +src/qt/blackmore-qt.files +src/qt/blackmore-qt.includes diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 27f2b42a1e..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,73 +0,0 @@ -sudo: required -dist: trusty - -#workaround for https://github.com/travis-ci/travis-ci/issues/5227 -addons: - hostname: bitcoin-tester - -os: linux -language: generic -cache: - directories: - - depends/built - - depends/sdk-sources - - $HOME/.ccache -env: - global: - - MAKEJOBS=-j3 - - RUN_TESTS=false - - CHECK_DOC=0 - - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID - - CCACHE_SIZE=100M - - CCACHE_TEMPDIR=/tmp/.ccache-temp - - CCACHE_COMPRESS=1 - - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - - SDK_URL=https://bitcoincore.org/depends-sources/sdks - - PYTHON_DEBUG=1 - - WINEDEBUG=fixme-all - matrix: -# ARM - - HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" -# Win32 - - HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-i686 wine1.6 bc openjdk-7-jre-headless" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" -# 32-bit + dash - - HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python3-zmq openjdk-7-jre-headless" DEP_OPTS="NO_QT=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" -# Win64 - - HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine1.6 bc openjdk-7-jre-headless" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" -# bitcoind - - HOST=x86_64-unknown-linux-gnu PACKAGES="bc python3-zmq openjdk-7-jre-headless" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" -# No wallet - - HOST=x86_64-unknown-linux-gnu PACKAGES=" openjdk-7-jre-headless python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" -# Cross-Mac - - HOST=x86_64-apple-darwin14 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports --enable-werror" OSX_SDK=10.11 GOAL="all deploy" - -before_install: - - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g") -install: - - if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi - - if [ -n "$DPKG_ADD_ARCH" ]; then sudo dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi - - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi -before_script: - - unset CC; unset CXX - - if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/check-doc.py; fi - - mkdir -p depends/SDKs depends/sdk-sources - - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS -script: - - export TRAVIS_COMMIT_LOG=`git log --format=fuller -1` - - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi - - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST - - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" - - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE - - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - - mkdir build && cd build - - ../configure $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) - - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - - if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS check VERBOSE=1; fi - - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.py --coverage; fi -after_script: - - echo $TRAVIS_COMMIT_RANGE - - echo $TRAVIS_COMMIT_LOG diff --git a/CHANGELOG.md b/CHANGELOG.md index c1326db1d0..1b137709aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,20 @@ -# Changelog +# Changelog# Changelog +## v2.13.2.9 (2022-02-24) +- Update leveldb, which should resolve the "missing UTXO" staking issue +- Update dependencies and ported build system from Bitcoin Core 0.20+ +- Updated crypto and added CRC32 for ARM64 +- Updated univalue to v1.0.3 +- Updated to Qt v5.12.11 +- Updated to OpenSSL v1.1.1m +- Added "getstakereport" RPC call +- Added --use-sse2 to enable SSE2 +- Code cleanup (headers, names, etc) + ## v2.13.2.8 (2021-02-24) -- Immediately ban clients operating on forked chains older than nMaxReorganizationDepth -- Fixed IsDust() policy to allow atomic swaps -- Updated fixed seeds for mainnet and testnet -- Updated dependencies for MacOS +- Immediately ban clients operating on forked chains older than nMaxReorganizationDepth. +- Fixed IsDust() policy to allow atomic swaps. +- Updated fixed seeds for mainnet and testnet. +- Updated dependencies for MacOS. ## v2.13.2.7 (2020-11-24) - Dust mitigation in mempool (by JJ12880 from Radium Core) diff --git a/COPYING b/COPYING index 2b41c4482e..8c163889ed 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2018-2019 The Blackcoin More developers +Copyright (c) 2018-2022 The Blackcoin More developers Copyright (c) 2014-2018 The BlackCoin Developers Copyright (c) 2013-2014 The NovaCoin Developers Copyright (c) 2011-2013 The PPCoin Developers diff --git a/INSTALL.md b/INSTALL.md index f6af661f34..cf276ac9f6 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,4 +1,4 @@ -Building Blackcoin +Building Blackcoin More ================ See doc/build-*.md for instructions on building the various diff --git a/Makefile.am b/Makefile.am index 6ba6e7b0a3..f7a04e50d7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,13 +1,18 @@ -# Copyright (c) 2013-2016 The Bitcoin Core developers +# Copyright (c) 2013-2020 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +# Pattern rule to print variables, e.g. make print-top_srcdir +print-%: FORCE + @echo '$*'='$($*)' + ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src if ENABLE_MAN SUBDIRS += doc/man endif .PHONY: deploy FORCE +.INTERMEDIATE: $(OSX_TEMP_ISO) $(COVERAGE_INFO) export PYTHONPATH @@ -19,7 +24,8 @@ endif BITCOIND_BIN=$(top_builddir)/src/$(BITCOIN_DAEMON_NAME)$(EXEEXT) BITCOIN_QT_BIN=$(top_builddir)/src/qt/$(BITCOIN_GUI_NAME)$(EXEEXT) BITCOIN_CLI_BIN=$(top_builddir)/src/$(BITCOIN_CLI_NAME)$(EXEEXT) -BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) +BITCOIN_TX_BIN=$(top_builddir)/src/$(BITCOIN_TX_NAME)$(EXEEXT) +BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win64-setup$(EXEEXT) empty := space := $(empty) $(empty) @@ -27,29 +33,36 @@ space := $(empty) $(empty) OSX_APP=Blackmore-Qt.app OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) OSX_DMG = $(OSX_VOLNAME).dmg +OSX_TEMP_ISO = $(OSX_DMG:.dmg=).temp.iso OSX_BACKGROUND_SVG=background.svg OSX_BACKGROUND_IMAGE=background.tiff OSX_BACKGROUND_IMAGE_DPIS=36 72 -OSX_DSSTORE_GEN=$(top_srcdir)/contrib/macdeploy/custom_dsstore.py OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus -OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed -OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW + +DIST_CONTRIB = \ + $(top_srcdir)/contrib/linearize/linearize-data.py \ + $(top_srcdir)/contrib/linearize/linearize-hashes.py + +DIST_SHARE = \ + $(top_srcdir)/share/genbuild.sh \ + $(top_srcdir)/share/rpcauth DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ - $(top_srcdir)/contrib/devtools/security-check.py + $(top_srcdir)/contrib/devtools/security-check.py \ + $(top_srcdir)/contrib/devtools/utils.py \ + $(top_srcdir)/contrib/devtools/pixie.py WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-header.bmp \ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp \ $(top_srcdir)/doc/README_windows.txt -OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ +OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_INSTALLER_ICONS) \ $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_SVG) \ - $(OSX_DSSTORE_GEN) \ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh @@ -61,25 +74,28 @@ COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ dist-hook: -$(GIT) archive --format=tar HEAD -- src/clientversion.cpp | $(AMTAR) -C $(top_distdir) -xf - +if TARGET_WINDOWS $(BITCOIN_WIN_INSTALLER): all-recursive $(MKDIR_P) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIND_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_QT_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_CLI_BIN) $(top_builddir)/release - @test -f $(MAKENSIS) && $(MAKENSIS) -V2 $(top_builddir)/share/setup.nsi || \ + STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_TX_BIN) $(top_builddir)/release + @test -f $(MAKENSIS) && echo 'OutFile "$@"' | cat $(top_builddir)/share/setup.nsi - | $(MAKENSIS) -V2 - || \ echo error: could not build $@ @echo built $@ -$(if $(findstring src/,$(MAKECMDGOALS)),$(MAKECMDGOALS), none): FORCE - $(MAKE) -C src $(patsubst src/%,%,$@) +deploy: $(BITCOIN_WIN_INSTALLER) +endif +if TARGET_DARWIN $(OSX_APP)/Contents/PkgInfo: $(MKDIR_P) $(@D) @echo "APPL????" > $@ $(OSX_APP)/Contents/Resources/empty.lproj: $(MKDIR_P) $(@D) - @touch $@ + @touch $@ $(OSX_APP)/Contents/Info.plist: $(OSX_PLIST) $(MKDIR_P) $(@D) @@ -89,9 +105,9 @@ $(OSX_APP)/Contents/Resources/bitcoin.icns: $(OSX_INSTALLER_ICONS) $(MKDIR_P) $(@D) $(INSTALL_DATA) $< $@ -$(OSX_APP)/Contents/MacOS/Blackmore-Qt: $(BITCOIN_QT_BIN) +$(OSX_APP)/Contents/MacOS/Blackmore-Qt: all-recursive $(MKDIR_P) $(@D) - STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $< $@ + STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_QT_BIN) $@ $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings: $(MKDIR_P) $(@D) @@ -106,7 +122,7 @@ osx_volname: if BUILD_DARWIN $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) $(OSX_BACKGROUND_IMAGE) - $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2 -volname $(OSX_VOLNAME) + $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) -dmg $(OSX_BACKGROUND_IMAGE).png: contrib/macdeploy/$(OSX_BACKGROUND_SVG) sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d 36 -p 36 -o $@ @@ -116,7 +132,7 @@ $(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE).png $(OSX_BACKGROUND_IMAGE)@2x. tiffutil -cathidpicheck $^ -out $@ deploydir: $(OSX_DMG) -else +else !BUILD_DARWIN APP_DIST_DIR=$(top_builddir)/dist APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE) $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications @@ -126,8 +142,11 @@ $(APP_DIST_DIR)/Applications: $(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Blackmore-Qt -$(OSX_DMG): $(APP_DIST_EXTRAS) - $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -apple -o $@ dist +$(OSX_TEMP_ISO): $(APP_DIST_EXTRAS) + $(XORRISOFS) -D -l -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -o $@ $(APP_DIST_DIR) -- $(if $(SOURCE_DATE_EPOCH),-volume_date all_file_dates =$(SOURCE_DATE_EPOCH)) + +$(OSX_DMG): $(OSX_TEMP_ISO) + $(DMG) dmg "$<" "$@" dpi%.$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_SVG) sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d $* -p $* | $(IMAGEMAGICK_CONVERT) - $@ @@ -136,22 +155,15 @@ $(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIF $(MKDIR_P) $(@D) $(TIFFCP) -c none $(OSX_BACKGROUND_IMAGE_DPIFILES) $@ -$(APP_DIST_DIR)/.DS_Store: $(OSX_DSSTORE_GEN) - $(PYTHON) $< "$@" "$(OSX_VOLNAME)" - $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Blackmore-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) - INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2 + INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) deploydir: $(APP_DIST_EXTRAS) -endif +endif !BUILD_DARWIN -if TARGET_DARWIN appbundle: $(OSX_APP_BUILT) deploy: $(OSX_DMG) endif -if TARGET_WINDOWS -deploy: $(BITCOIN_WIN_INSTALLER) -endif $(BITCOIN_QT_BIN): FORCE $(MAKE) -C src qt/$(@F) @@ -162,6 +174,9 @@ $(BITCOIND_BIN): FORCE $(BITCOIN_CLI_BIN): FORCE $(MAKE) -C src $(@F) +$(BITCOIN_TX_BIN): FORCE + $(MAKE) -C src $(@F) + if USE_LCOV baseline.info: @@ -221,6 +236,8 @@ total.coverage/.dirstamp: total_coverage.info $(GENHTML) -s $< -o $(@D) @touch $@ +cov_fuzz: fuzz.coverage/.dirstamp + cov: test_bitcoin.coverage/.dirstamp total.coverage/.dirstamp endif @@ -233,7 +250,7 @@ endif dist_noinst_SCRIPTS = autogen.sh -EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) +EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_DOCS) $(DIST_SHARE) $(DIST_CONTRIB) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) @@ -244,6 +261,36 @@ DISTCLEANFILES = qa/pull-tester/tests_config.pyc DISTCHECK_CONFIGURE_FLAGS = --enable-man -clean-local: +doc/doxygen/.stamp: doc/Doxyfile FORCE + $(MKDIR_P) $(@D) + $(DOXYGEN) $^ + $(AM_V_at) touch $@ + +if HAVE_DOXYGEN +docs: doc/doxygen/.stamp +else +docs: + @echo "error: doxygen not found" +endif + +clean-docs: + rm -rf doc/doxygen + +clean-local: clean-docs rm -rf coverage_percent.txt test_bitcoin.coverage/ total.coverage/ qa/tmp/ cache/ $(OSX_APP) - rm -rf qa/pull-tester/__pycache__ + rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache share/rpcauth/__pycache__ qa/pull-tester/__pycache__ + rm -rf osx_volname dist/ dpi36.background.tiff dpi72.background.tiff + +test-security-check: +if TARGET_DARWIN + $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO + $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO +endif +if TARGET_WINDOWS + $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE + $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE +endif +if TARGET_LINUX + $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF + $(AM_V_at) CC='$(CC)' CPPFILT='$(CPPFILT)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF +endif diff --git a/autogen.sh b/autogen.sh index 27417daf76..de16260b56 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,15 +1,16 @@ #!/bin/sh -# Copyright (c) 2013-2016 The Bitcoin Core developers +# Copyright (c) 2013-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. +export LC_ALL=C set -e -srcdir="$(dirname $0)" +srcdir="$(dirname "$0")" cd "$srcdir" -if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then +if [ -z "${LIBTOOLIZE}" ] && GLIBTOOLIZE="$(command -v glibtoolize)"; then LIBTOOLIZE="${GLIBTOOLIZE}" export LIBTOOLIZE fi -which autoreconf >/dev/null || \ +command -v autoreconf >/dev/null || \ (echo "configuration failed, please install autoconf first" && exit 1) autoreconf --install --force --warnings=all diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4 index 650c94fa64..d5f59f6063 100644 --- a/build-aux/m4/ax_boost_base.m4 +++ b/build-aux/m4/ax_boost_base.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_base.html # =========================================================================== # # SYNOPSIS @@ -11,7 +11,7 @@ # Test for the Boost C++ libraries of a particular version (or newer) # # If no path to the installed boost library is given the macro searchs -# under /usr, /usr/local, /opt and /opt/local and evaluates the +# under /usr, /usr/local, /opt, /opt/local and /opt/homebrew and evaluates the # $BOOST_ROOT environment variable. Further documentation is available at # . # @@ -33,7 +33,15 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 27 +#serial 48 + +# example boost program (need to pass version) +m4_define([_AX_BOOST_BASE_PROGRAM], + [AC_LANG_PROGRAM([[ +#include +]],[[ +(void) ((void)sizeof(char[1 - 2*!!((BOOST_VERSION) < ($1))])); +]])]) AC_DEFUN([AX_BOOST_BASE], [ @@ -44,73 +52,80 @@ AC_ARG_WITH([boost], or disable it (ARG=no) @<:@ARG=yes@:>@ ])], [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ac_boost_path="" - else - want_boost="yes" - ac_boost_path="$withval" - fi + AS_CASE([$withval], + [no],[want_boost="no";_AX_BOOST_BASE_boost_path=""], + [yes],[want_boost="yes";_AX_BOOST_BASE_boost_path=""], + [want_boost="yes";_AX_BOOST_BASE_boost_path="$withval"]) ], [want_boost="yes"]) AC_ARG_WITH([boost-libdir], - AS_HELP_STRING([--with-boost-libdir=LIB_DIR], - [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), - [ - if test -d "$withval" - then - ac_boost_lib_path="$withval" - else - AC_MSG_ERROR(--with-boost-libdir expected directory name) - fi - ], - [ac_boost_lib_path=""] -) + [AS_HELP_STRING([--with-boost-libdir=LIB_DIR], + [Force given directory for boost libraries. + Note that this will override library path detection, + so use this parameter only if default library detection fails + and you know exactly where your boost libraries are located.])], + [ + AS_IF([test -d "$withval"], + [_AX_BOOST_BASE_boost_lib_path="$withval"], + [AC_MSG_ERROR([--with-boost-libdir expected directory name])]) + ], + [_AX_BOOST_BASE_boost_lib_path=""]) -if test "x$want_boost" = "xyes"; then - boost_lib_version_req=ifelse([$1], ,1.20.0,$1) - boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` - boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` - boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` - boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` - if test "x$boost_lib_version_req_sub_minor" = "x" ; then - boost_lib_version_req_sub_minor="0" - fi - WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` - AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) +BOOST_LDFLAGS="" +BOOST_CPPFLAGS="" +AS_IF([test "x$want_boost" = "xyes"], + [_AX_BOOST_BASE_RUNDETECT([$1],[$2],[$3])]) +AC_SUBST(BOOST_CPPFLAGS) +AC_SUBST(BOOST_LDFLAGS) +]) + + +# convert a version string in $2 to numeric and affect to polymorphic var $1 +AC_DEFUN([_AX_BOOST_BASE_TONUMERICVERSION],[ + AS_IF([test "x$2" = "x"],[_AX_BOOST_BASE_TONUMERICVERSION_req="1.20.0"],[_AX_BOOST_BASE_TONUMERICVERSION_req="$2"]) + _AX_BOOST_BASE_TONUMERICVERSION_req_shorten=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([[0-9]]*\.[[0-9]]*\)'` + _AX_BOOST_BASE_TONUMERICVERSION_req_major=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([[0-9]]*\)'` + AS_IF([test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_major" = "x"], + [AC_MSG_ERROR([You should at least specify libboost major version])]) + _AX_BOOST_BASE_TONUMERICVERSION_req_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[[0-9]]*\.\([[0-9]]*\)'` + AS_IF([test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_minor" = "x"], + [_AX_BOOST_BASE_TONUMERICVERSION_req_minor="0"]) + _AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` + AS_IF([test "X$_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor" = "X"], + [_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor="0"]) + _AX_BOOST_BASE_TONUMERICVERSION_RET=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req_major \* 100000 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_minor \* 100 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor` + AS_VAR_SET($1,$_AX_BOOST_BASE_TONUMERICVERSION_RET) +]) + +dnl Run the detection of boost should be run only if $want_boost +AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ + _AX_BOOST_BASE_TONUMERICVERSION(WANT_BOOST_VERSION,[$1]) succeeded=no + + AC_REQUIRE([AC_CANONICAL_HOST]) dnl On 64-bit systems check for system libraries in both lib64 and lib. dnl The former is specified by FHS, but e.g. Debian does not adhere to dnl this (as it rises problems for generic multi-arch support). dnl The last entry in the list is chosen by default when no libraries dnl are found, e.g. when only header-only libraries are installed! - libsubdirs="lib" - ax_arch=`uname -m` - case $ax_arch in - x86_64) - libsubdirs="lib64 libx32 lib lib64" - ;; - ppc64|s390x|sparc64|aarch64|ppc64le) - libsubdirs="lib64 lib lib64" - ;; - esac + AS_CASE([${host_cpu}], + [x86_64],[libsubdirs="lib64 libx32 lib lib64"], + [mips*64*],[libsubdirs="lib64 lib32 lib lib64"], + [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"], + [libsubdirs="lib"] + ) dnl allow for real multi-arch paths e.g. /usr/lib/x86_64-linux-gnu. Give dnl them priority over the other paths since, if libs are found there, they dnl are almost assuredly the ones desired. - AC_REQUIRE([AC_CANONICAL_HOST]) - libsubdirs="lib/${host_cpu}-${host_os} $libsubdirs" - - case ${host_cpu} in - i?86) - libsubdirs="lib/i386-${host_os} $libsubdirs" - ;; - esac + AS_CASE([${host_cpu}], + [i?86],[multiarch_libsubdir="lib/i386-${host_os}"], + [armv7l],[multiarch_libsubdir="lib/arm-${host_os}"], + [multiarch_libsubdir="lib/${host_cpu}-${host_os}"] + ) dnl some arches may advertise a cpu type that doesn't line up with their dnl prefix's cpu type. For example, uname may report armv7l while libs are @@ -119,35 +134,47 @@ if test "x$want_boost" = "xyes"; then libsubdirs="lib/`$CXX -dumpmachine 2>/dev/null` $libsubdirs" dnl first we check the system location for boost libraries - dnl this location ist chosen if boost libraries are installed with the --layout=system option + dnl this location is chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM - if test "$ac_boost_path" != ""; then - BOOST_CPPFLAGS="-I$ac_boost_path/include" - for ac_boost_path_tmp in $libsubdirs; do - if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then - BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" - break - fi - done - elif test "$cross_compiling" != yes; then - for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then - for libsubdir in $libsubdirs ; do - if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + AS_IF([test "x$_AX_BOOST_BASE_boost_path" != "x"],[ + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) includes in "$_AX_BOOST_BASE_boost_path/include"]) + AS_IF([test -d "$_AX_BOOST_BASE_boost_path/include" && test -r "$_AX_BOOST_BASE_boost_path/include"],[ + AC_MSG_RESULT([yes]) + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include" + for _AX_BOOST_BASE_boost_path_tmp in $multiarch_libsubdir $libsubdirs; do + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) lib path in "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"]) + AS_IF([test -d "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" && test -r "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" ],[ + AC_MSG_RESULT([yes]) + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"; + break; + ], + [AC_MSG_RESULT([no])]) + done],[ + AC_MSG_RESULT([no])]) + ],[ + if test X"$cross_compiling" = Xyes; then + search_libsubdirs=$multiarch_libsubdir + else + search_libsubdirs="$multiarch_libsubdir $libsubdirs" + fi + for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local /opt/homebrew/; do + if test -d "$_AX_BOOST_BASE_boost_path_tmp/include/boost" && test -r "$_AX_BOOST_BASE_boost_path_tmp/include/boost" ; then + for libsubdir in $search_libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done - BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" - BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path_tmp/$libsubdir" + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path_tmp/include" break; fi done - fi + ]) dnl overwrite ld flags if we have required special directory with dnl --with-boost-libdir parameter - if test "$ac_boost_lib_path" != ""; then - BOOST_LDFLAGS="-L$ac_boost_lib_path" - fi + AS_IF([test "x$_AX_BOOST_BASE_boost_lib_path" != "x"], + [BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_lib_path"]) + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION)]) CPPFLAGS_SAVED="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS @@ -158,15 +185,7 @@ if test "x$want_boost" = "xyes"; then AC_REQUIRE([AC_PROG_CXX]) AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ + AC_COMPILE_IFELSE([_AX_BOOST_BASE_PROGRAM($WANT_BOOST_VERSION)],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes @@ -178,40 +197,50 @@ if test "x$want_boost" = "xyes"; then dnl if we found no boost with system layout we search for boost libraries dnl built and installed without the --layout=system option or for a staged(not installed) version - if test "x$succeeded" != "xyes"; then + if test "x$succeeded" != "xyes" ; then CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" BOOST_CPPFLAGS= - BOOST_LDFLAGS= + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + BOOST_LDFLAGS= + fi _version=0 - if test "$ac_boost_path" != ""; then - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + if test -n "$_AX_BOOST_BASE_boost_path" ; then + if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path"; then + for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then + if test "x$V_CHECK" = "x1" ; then _version=$_version_tmp fi VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` - BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include/boost-$VERSION_UNDERSCORE" done dnl if nothing found search for layout used in Windows distributions if test -z "$BOOST_CPPFLAGS"; then - if test -d "$ac_boost_path/boost" && test -r "$ac_boost_path/boost"; then - BOOST_CPPFLAGS="-I$ac_boost_path" + if test -d "$_AX_BOOST_BASE_boost_path/boost" && test -r "$_AX_BOOST_BASE_boost_path/boost"; then + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path" fi fi + dnl if we found something and BOOST_LDFLAGS was unset before + dnl (because "$_AX_BOOST_BASE_boost_lib_path" = ""), set it here. + if test -n "$BOOST_CPPFLAGS" && test -z "$BOOST_LDFLAGS"; then + for libsubdir in $libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$libsubdir" + fi fi else - if test "$cross_compiling" != yes; then - for ac_boost_path in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + if test "x$cross_compiling" != "xyes" ; then + for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local /opt/homebrew ; do + if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path" ; then + for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then + if test "x$V_CHECK" = "x1" ; then _version=$_version_tmp - best_path=$ac_boost_path + best_path=$_AX_BOOST_BASE_boost_path fi done fi @@ -219,7 +248,7 @@ if test "x$want_boost" = "xyes"; then VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" - if test "$ac_boost_lib_path" = ""; then + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then for libsubdir in $libsubdirs ; do if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done @@ -227,7 +256,7 @@ if test "x$want_boost" = "xyes"; then fi fi - if test "x$BOOST_ROOT" != "x"; then + if test -n "$BOOST_ROOT" ; then for libsubdir in $libsubdirs ; do if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done @@ -236,7 +265,7 @@ if test "x$want_boost" = "xyes"; then stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` V_CHECK=`expr $stage_version_shorten \>\= $_version` - if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then + if test "x$V_CHECK" = "x1" && test -z "$_AX_BOOST_BASE_boost_lib_path" ; then AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) BOOST_CPPFLAGS="-I$BOOST_ROOT" BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" @@ -251,15 +280,7 @@ if test "x$want_boost" = "xyes"; then export LDFLAGS AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ + AC_COMPILE_IFELSE([_AX_BOOST_BASE_PROGRAM($WANT_BOOST_VERSION)],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes @@ -268,17 +289,15 @@ if test "x$want_boost" = "xyes"; then AC_LANG_POP([C++]) fi - if test "$succeeded" != "yes" ; then - if test "$_version" = "0" ; then - AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) + if test "x$succeeded" != "xyes" ; then + if test "x$_version" = "x0" ; then + AC_MSG_NOTICE([[We could not detect the boost libraries (version $1 or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) else AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) fi # execute ACTION-IF-NOT-FOUND (if present): ifelse([$3], , :, [$3]) else - AC_SUBST(BOOST_CPPFLAGS) - AC_SUBST(BOOST_LDFLAGS) AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) # execute ACTION-IF-FOUND (if present): ifelse([$2], , :, [$2]) @@ -286,6 +305,5 @@ if test "x$want_boost" = "xyes"; then CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" -fi ]) diff --git a/build-aux/m4/ax_boost_chrono.m4 b/build-aux/m4/ax_boost_chrono.m4 index 318ecea17f..4cd3b86041 100644 --- a/build-aux/m4/ax_boost_chrono.m4 +++ b/build-aux/m4/ax_boost_chrono.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html # =========================================================================== # # SYNOPSIS @@ -8,7 +8,7 @@ # # DESCRIPTION # -# Test for System library from the Boost C++ libraries. The macro requires +# Test for Chrono library from the Boost C++ libraries. The macro requires # a preceding call to AX_BOOST_BASE. Further documentation is available at # . # @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 1 +#serial 5 AC_DEFUN([AX_BOOST_CHRONO], [ @@ -68,7 +68,7 @@ AC_DEFUN([AX_BOOST_CHRONO], CXXFLAGS_SAVE=$CXXFLAGS AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::chrono::system_clock::time_point time;]])], + [[boost::chrono::system_clock::time_point* time = new boost::chrono::system_clock::time_point; delete time;]])], ax_cv_boost_chrono=yes, ax_cv_boost_chrono=no) CXXFLAGS=$CXXFLAGS_SAVE AC_LANG_POP([C++]) @@ -81,7 +81,6 @@ AC_DEFUN([AX_BOOST_CHRONO], LDFLAGS_SAVE=$LDFLAGS if test "x$ax_boost_user_chrono_lib" = "x"; then - ax_lib= for libextension in `ls $BOOSTLIBDIR/libboost_chrono*.so* $BOOSTLIBDIR/libboost_chrono*.dylib* $BOOSTLIBDIR/libboost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_chrono.*\)\.so.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.a.*$;\1;'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, @@ -106,7 +105,7 @@ AC_DEFUN([AX_BOOST_CHRONO], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_chrono library!) + AC_MSG_ERROR(Could not find a version of the Boost::Chrono library!) fi if test "x$link_chrono" = "xno"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_filesystem.m4 b/build-aux/m4/ax_boost_filesystem.m4 index f5c9d56470..12f7bc5e2e 100644 --- a/build-aux/m4/ax_boost_filesystem.m4 +++ b/build-aux/m4/ax_boost_filesystem.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html # =========================================================================== # # SYNOPSIS @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 26 +#serial 28 AC_DEFUN([AX_BOOST_FILESYSTEM], [ @@ -80,7 +80,6 @@ AC_DEFUN([AX_BOOST_FILESYSTEM], if test "x$ax_cv_boost_filesystem" = "xyes"; then AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - ax_lib= if test "x$ax_boost_user_filesystem_lib" = "x"; then for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} @@ -105,7 +104,7 @@ AC_DEFUN([AX_BOOST_FILESYSTEM], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_filesystem library!) + AC_MSG_ERROR(Could not find a version of the Boost::Filesystem library!) fi if test "x$link_filesystem" != "xyes"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_process.m4 b/build-aux/m4/ax_boost_process.m4 new file mode 100644 index 0000000000..5d20e67464 --- /dev/null +++ b/build-aux/m4/ax_boost_process.m4 @@ -0,0 +1,121 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_boost_process.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_PROCESS +# +# DESCRIPTION +# +# Test for Process library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. Further documentation is +# available at . +# +# This macro calls: +# +# AC_SUBST(BOOST_PROCESS_LIB) +# +# And sets: +# +# HAVE_BOOST_PROCESS +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Daniel Casimiro +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AC_DEFUN([AX_BOOST_PROCESS], +[ + AC_ARG_WITH([boost-process], + AS_HELP_STRING([--with-boost-process@<:@=special-lib@:>@], + [use the Process library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-process=boost_process-gcc-mt ]), + [ + if test "$withval" = "no"; then + want_boost_process="no" + elif test "$withval" = "yes"; then + want_boost_process="yes" + ax_boost_user_process_lib="" + else + want_boost_process="yes" + ax_boost_user_process_lib="$withval" + fi + ], + [want_boost_process="yes"] + ) + + if test "x$want_boost_process" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::Process library is available, + ax_cv_boost_process, + [AC_LANG_PUSH([C++]) + CXXFLAGS_SAVE=$CXXFLAGS + CXXFLAGS= + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [[boost::process::child* child = new boost::process::child; delete child;]])], + ax_cv_boost_process=yes, ax_cv_boost_process=no) + CXXFLAGS=$CXXFLAGS_SAVE + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_process" = "xyes"; then + AC_SUBST(BOOST_CPPFLAGS) + + AC_DEFINE(HAVE_BOOST_PROCESS,,[define if the Boost::Process library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + LDFLAGS_SAVE=$LDFLAGS + if test "x$ax_boost_user_process_lib" = "x"; then + for libextension in `ls -r $BOOSTLIBDIR/libboost_process* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_PROCESS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROCESS_LIB) link_process="yes"; break], + [link_process="no"]) + done + if test "x$link_process" != "xyes"; then + for libextension in `ls -r $BOOSTLIBDIR/boost_process* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_PROCESS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROCESS_LIB) link_process="yes"; break], + [link_process="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_process_lib boost_process-$ax_boost_user_process_lib; do + AC_CHECK_LIB($ax_lib, exit, + [BOOST_PROCESS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROCESS_LIB) link_process="yes"; break], + [link_process="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the Boost::Process library!) + fi + if test "x$link_process" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/build-aux/m4/ax_boost_random.m4 b/build-aux/m4/ax_boost_random.m4 new file mode 100644 index 0000000000..f0b64ae20a --- /dev/null +++ b/build-aux/m4/ax_boost_random.m4 @@ -0,0 +1,122 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_boost_random.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_RANDOM +# +# DESCRIPTION +# +# Test for Random library from the Boost C++ libraries. The macro requires a +# preceding call to AX_BOOST_BASE. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_RANDOM_LIB) +# +# And sets: +# +# HAVE_BOOST_RANDOM +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2013 Daniel Casimiro +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 1 + +AC_DEFUN([AX_BOOST_RANDOM], +[ + AC_ARG_WITH([boost-random], + AS_HELP_STRING([--with-boost-random@<:@=special-lib@:>@], + [use the Random library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-random=boost_random-gcc-mt ]), [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_random_lib="" + else + want_boost="yes" + ax_boost_user_random_lib="$withval" + fi + ], [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::Random library is available, + ax_cv_boost_random, + [AC_LANG_PUSH([C++]) + CXXFLAGS_SAVE=$CXXFLAGS + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[@%:@include ]], + [[boost::random::random_device()();]])], + ax_cv_boost_random=yes, ax_cv_boost_random=no) + CXXFLAGS=$CXXFLAGS_SAVE + AC_LANG_POP([C++]) + ]) + + if test "x$ax_cv_boost_random" = "xyes"; then + AC_SUBST(BOOST_CPPFLAGS) + + AC_DEFINE(HAVE_BOOST_RANDOM,,[define if the Boost::Random library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + if test "x$ax_boost_user_random_lib" = "x"; then + for libextension in `ls $BOOSTLIBDIR/libboost_random*.so* $BOOSTLIBDIR/libboost_random*.dylib* $BOOSTLIBDIR/libboost_random*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_random.*\)\.so.*$;\1;' -e 's;^lib\(boost_random.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_random.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_RANDOM_LIB="-l$ax_lib"; AC_SUBST(BOOST_RANDOM_LIB) link_random="yes"; break], + [link_random="no"]) + done + + if test "x$link_random" != "xyes"; then + for libextension in `ls $BOOSTLIBDIR/boost_random*.dll* $BOOSTLIBDIR/boost_random*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_random.*\)\.dll.*$;\1;' -e 's;^\(boost_random.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_RANDOM_LIB="-l$ax_lib"; AC_SUBST(BOOST_RANDOM_LIB) link_random="yes"; break], + [link_random="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_random_lib boost_random-$ax_boost_user_random_lib; do + AC_CHECK_LIB($ax_lib, exit, + [BOOST_RANDOM_LIB="-l$ax_lib"; AC_SUBST(BOOST_RANDOM_LIB) link_random="yes"; break], + [link_random="no"]) + done + fi + + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the library!) + fi + + if test "x$link_random" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/build-aux/m4/ax_boost_system.m4 b/build-aux/m4/ax_boost_system.m4 index 1c05450cbe..323e2a676a 100644 --- a/build-aux/m4/ax_boost_system.m4 +++ b/build-aux/m4/ax_boost_system.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_system.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_system.html # =========================================================================== # # SYNOPSIS @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 18 +#serial 20 AC_DEFUN([AX_BOOST_SYSTEM], [ @@ -84,7 +84,6 @@ AC_DEFUN([AX_BOOST_SYSTEM], LDFLAGS_SAVE=$LDFLAGS if test "x$ax_boost_user_system_lib" = "x"; then - ax_lib= for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, @@ -109,7 +108,7 @@ AC_DEFUN([AX_BOOST_SYSTEM], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_system library!) + AC_MSG_ERROR(Could not find a version of the Boost::System library!) fi if test "x$link_system" = "xno"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_thread.m4 b/build-aux/m4/ax_boost_thread.m4 index 9f0bd0b23c..75e80e6e75 100644 --- a/build-aux/m4/ax_boost_thread.m4 +++ b/build-aux/m4/ax_boost_thread.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_thread.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_thread.html # =========================================================================== # # SYNOPSIS @@ -30,73 +30,96 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 27 +#serial 33 AC_DEFUN([AX_BOOST_THREAD], [ - AC_ARG_WITH([boost-thread], - AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], - [use the Thread library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-thread=boost_thread-gcc-mt ]), + AC_ARG_WITH([boost-thread], + AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], + [use the Thread library from boost - + it is possible to specify a certain library for the linker + e.g. --with-boost-thread=boost_thread-gcc-mt ]), [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then + if test "$withval" = "yes"; then want_boost="yes" ax_boost_user_thread_lib="" else - want_boost="yes" - ax_boost_user_thread_lib="$withval" - fi + want_boost="yes" + ax_boost_user_thread_lib="$withval" + fi ], [want_boost="yes"] - ) + ) - if test "x$want_boost" = "xyes"; then + if test "x$want_boost" = "xyes"; then AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS AC_CACHE_CHECK(whether the Boost::Thread library is available, - ax_cv_boost_thread, + ax_cv_boost_thread, [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS + CXXFLAGS_SAVE=$CXXFLAGS + + case "x$host_os" in + xsolaris ) + CXXFLAGS="-pthreads $CXXFLAGS" + break; + ;; + xmingw32 ) + CXXFLAGS="-mthreads $CXXFLAGS" + break; + ;; + *android* ) + break; + ;; + * ) + CXXFLAGS="-pthread $CXXFLAGS" + break; + ;; + esac - if test "x$host_os" = "xsolaris" ; then - CXXFLAGS="-pthreads $CXXFLAGS" - elif test "x$host_os" = "xmingw32" ; then - CXXFLAGS="-mthreads $CXXFLAGS" - else - CXXFLAGS="-pthread $CXXFLAGS" - fi - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::thread_group thrds; - return 0;]])], - ax_cv_boost_thread=yes, ax_cv_boost_thread=no) - CXXFLAGS=$CXXFLAGS_SAVE + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [[@%:@include ]], + [[boost::thread_group thrds; + return 0;]])], + ax_cv_boost_thread=yes, ax_cv_boost_thread=no) + CXXFLAGS=$CXXFLAGS_SAVE AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_thread" = "xyes"; then - if test "x$host_os" = "xsolaris" ; then - BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" - elif test "x$host_os" = "xmingw32" ; then - BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" - else - BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" - fi + ]) + if test "x$ax_cv_boost_thread" = "xyes"; then + case "x$host_os" in + xsolaris ) + BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" + break; + ;; + xmingw32 ) + BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" + break; + ;; + *android* ) + break; + ;; + * ) + BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" + break; + ;; + esac - AC_SUBST(BOOST_CPPFLAGS) + AC_SUBST(BOOST_CPPFLAGS) - AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available]) + AC_DEFINE(HAVE_BOOST_THREAD,, + [define if the Boost::Thread library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - LDFLAGS_SAVE=$LDFLAGS + LDFLAGS_SAVE=$LDFLAGS case "x$host_os" in *bsd* ) LDFLAGS="-pthread $LDFLAGS" @@ -104,47 +127,61 @@ AC_DEFUN([AX_BOOST_THREAD], ;; esac if test "x$ax_boost_user_thread_lib" = "x"; then - ax_lib= for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) - done + done if test "x$link_thread" != "xyes"; then for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) - done + done fi else for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) done fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_thread library!) + AC_MSG_ERROR(Could not find a version of the Boost::Thread library!) fi - if test "x$link_thread" = "xno"; then - AC_MSG_ERROR(Could not link against $ax_lib !) - else - case "x$host_os" in - *bsd* ) - BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" - break; - ;; - esac - - fi - fi + if test "x$link_thread" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + else + BOOST_THREAD_LIB="-l$ax_lib" + case "x$host_os" in + *bsd* ) + BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" + break; + ;; + xsolaris ) + BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread" + break; + ;; + xmingw32 ) + break; + ;; + *android* ) + break; + ;; + * ) + BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread" + break; + ;; + esac + AC_SUBST(BOOST_THREAD_LIB) + fi + fi - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi ]) diff --git a/build-aux/m4/ax_boost_unit_test_framework.m4 b/build-aux/m4/ax_boost_unit_test_framework.m4 index 4efd1e2f18..4cca32fcfd 100644 --- a/build-aux/m4/ax_boost_unit_test_framework.m4 +++ b/build-aux/m4/ax_boost_unit_test_framework.m4 @@ -1,6 +1,6 @@ -# ================================================================================ -# http://www.gnu.org/software/autoconf-archive/ax_boost_unit_test_framework.html -# ================================================================================ +# ================================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_boost_unit_test_framework.html +# ================================================================================= # # SYNOPSIS # @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 19 +#serial 22 AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], [ @@ -66,7 +66,7 @@ AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], [AC_LANG_PUSH([C++]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[using boost::unit_test::test_suite; - test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" ); return 0;]])], + test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" ); if (test == NULL) { return 1; } else { return 0; }]])], ax_cv_boost_unit_test_framework=yes, ax_cv_boost_unit_test_framework=no) AC_LANG_POP([C++]) ]) @@ -76,7 +76,6 @@ AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], if test "x$ax_boost_user_unit_test_framework_lib" = "x"; then saved_ldflags="${LDFLAGS}" - ax_lib= for monitor_library in `ls $BOOSTLIBDIR/libboost_unit_test_framework*.so* $BOOSTLIBDIR/libboost_unit_test_framework*.dylib* $BOOSTLIBDIR/libboost_unit_test_framework*.a* 2>/dev/null` ; do if test -r $monitor_library ; then libextension=`echo $monitor_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a.*$;\1;'` @@ -125,7 +124,7 @@ AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], done fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_unit_test_framework library!) + AC_MSG_ERROR(Could not find a version of the Boost::Unit_Test_Framework library!) fi if test "x$link_unit_test_framework" != "xyes"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 index f147cee3b1..43087b2e68 100644 --- a/build-aux/m4/ax_cxx_compile_stdcxx.m4 +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS @@ -33,21 +33,23 @@ # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 4 +#serial 11 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl - m4_if([$1], [11], [], - [$1], [14], [], - [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], @@ -57,26 +59,13 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) - m4_if([$4], [], [ax_cxx_compile_cxx$1_try_default=true], - [$4], [default], [ax_cxx_compile_cxx$1_try_default=true], - [$4], [nodefault], [ax_cxx_compile_cxx$1_try_default=false], - [m4_fatal([invalid fourth argument `$4' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no - m4_if([$4], [nodefault], [], [dnl - AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, - ax_cv_cxx_compile_cxx$1, - [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [ax_cv_cxx_compile_cxx$1=yes], - [ax_cv_cxx_compile_cxx$1=no])]) - if test x$ax_cv_cxx_compile_cxx$1 = xyes; then - ac_success=yes - fi]) - m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then - for switch in -std=gnu++$1 -std=gnu++0x; do + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, @@ -102,22 +91,27 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" - for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, - $cachevar, - [ac_save_CXX="$CXX" - CXX="$CXX $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXX="$ac_save_CXX"]) - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break fi - ac_success=yes + done + if test x$ac_success = xyes; then break fi done @@ -154,6 +148,11 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) dnl Tests for new features in C++11 @@ -191,11 +190,13 @@ namespace cxx11 struct Base { + virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { + virtual ~Derived() override {} virtual void f() override {} }; @@ -524,7 +525,7 @@ namespace cxx14 } - namespace test_digit_seperators + namespace test_digit_separators { constexpr auto ten_million = 100'000'000; @@ -566,3 +567,385 @@ namespace cxx14 #endif // __cplusplus >= 201402L ]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) diff --git a/build-aux/m4/ax_pthread.m4 b/build-aux/m4/ax_pthread.m4 index 4c4051ea37..1598d077ff 100644 --- a/build-aux/m4/ax_pthread.m4 +++ b/build-aux/m4/ax_pthread.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS @@ -55,6 +55,7 @@ # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. +# Copyright (c) 2019 Marc Stevens # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -67,7 +68,7 @@ # Public License for more details. # # You should have received a copy of the GNU General Public License along -# with this program. If not, see . +# with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure @@ -82,7 +83,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 23 +#serial 27 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ @@ -123,10 +124,12 @@ fi # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" @@ -194,14 +197,47 @@ case $host_os in # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). - ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + + # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC + AS_IF([test "x$GCC" = "xyes"], - [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) + +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) + # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is @@ -224,25 +260,86 @@ AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) -# Are we compiling with Clang? -AC_CACHE_CHECK([whether $CC is Clang], - [ax_cv_PTHREAD_CLANG], - [ax_cv_PTHREAD_CLANG=no - # Note that Autoconf sets GCC=yes for Clang as well as GCC - if test "x$GCC" = "xyes"; then - AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], - [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ -# if defined(__clang__) && defined(__llvm__) - AX_PTHREAD_CC_IS_CLANG -# endif - ], - [ax_cv_PTHREAD_CLANG=yes]) - fi - ]) -ax_pthread_clang="$ax_cv_PTHREAD_CLANG" +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi -ax_pthread_clang_warning=no # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way @@ -261,11 +358,6 @@ if test "x$ax_pthread_clang" = "xyes"; then # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) - PTHREAD_CFLAGS="-pthread" - PTHREAD_LIBS= - - ax_pthread_ok=yes - # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused @@ -320,78 +412,7 @@ if test "x$ax_pthread_clang" = "xyes"; then fi # $ax_pthread_clang = yes -if test "x$ax_pthread_ok" = "xno"; then -for ax_pthread_try_flag in $ax_pthread_flags; do - - case $ax_pthread_try_flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -mt,pthread) - AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) - PTHREAD_CFLAGS="-mt" - PTHREAD_LIBS="-lpthread" - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) - PTHREAD_CFLAGS="$ax_pthread_try_flag" - ;; - - pthread-config) - AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - *) - AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) - PTHREAD_LIBS="-l$ax_pthread_try_flag" - ;; - esac - - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include -# if $ax_pthread_check_cond -# error "$ax_pthread_check_macro must be defined" -# endif - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) - - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" - - AC_MSG_RESULT([$ax_pthread_ok]) - AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" -done -fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then @@ -438,7 +459,8 @@ if test "x$ax_pthread_ok" = "xyes"; then AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 201649c9dc..b58253a414 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -5,8 +5,8 @@ dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. dnl Helper for cases where a qt dependency is not met. dnl Output: If qt version is auto, set bitcoin_enable_qt to false. Else, exit. AC_DEFUN([BITCOIN_QT_FAIL],[ - if test "x$bitcoin_qt_want_version" = "xauto" && test x$bitcoin_qt_force != xyes; then - if test x$bitcoin_enable_qt != xno; then + if test "x$bitcoin_qt_want_version" = xauto && test "x$bitcoin_qt_force" != xyes; then + if test "x$bitcoin_enable_qt" != xno; then AC_MSG_WARN([$1; bitcoin-qt frontend will not be built]) fi bitcoin_enable_qt=no @@ -17,7 +17,7 @@ AC_DEFUN([BITCOIN_QT_FAIL],[ ]) AC_DEFUN([BITCOIN_QT_CHECK],[ - if test "x$bitcoin_enable_qt" != "xno" && test x$bitcoin_qt_want_version != xno; then + if test "x$bitcoin_enable_qt" != xno && test "x$bitcoin_qt_want_version" != xno; then true $1 else @@ -35,12 +35,12 @@ dnl Inputs: $4: If "yes", don't fail if $2 is not found. dnl Output: $1 is set to the path of $2 if found. $2 are searched in order. AC_DEFUN([BITCOIN_QT_PATH_PROGS],[ BITCOIN_QT_CHECK([ - if test "x$3" != "x"; then + if test "x$3" != x; then AC_PATH_PROGS($1,$2,,$3) else AC_PATH_PROGS($1,$2) fi - if test "x$$1" = "x" && test "x$4" != "xyes"; then + if test "x$$1" = x && test "x$4" != xyes; then BITCOIN_QT_FAIL([$1 not found]) fi ]) @@ -53,17 +53,24 @@ dnl CAUTION: Do not use this inside of a conditional. AC_DEFUN([BITCOIN_QT_INIT],[ dnl enable qt support AC_ARG_WITH([gui], - [AS_HELP_STRING([--with-gui@<:@=no|qt4|qt5|auto@:>@], - [build bitcoin-qt GUI (default=auto, qt5 tried first)])], + [AS_HELP_STRING([--with-gui@<:@=no|qt5|auto@:>@], + [build blackmore-qt GUI (default=auto)])], [ bitcoin_qt_want_version=$withval - if test x$bitcoin_qt_want_version = xyes; then + if test "x$bitcoin_qt_want_version" = xyes; then bitcoin_qt_force=yes bitcoin_qt_want_version=auto fi ], [bitcoin_qt_want_version=auto]) + AS_IF([test "x$with_gui" = xqt5_debug], + [AS_CASE([$host], + [*darwin*], [qt_lib_suffix=_debug], + [*mingw*], [qt_lib_suffix=d], + [qt_lib_suffix= ]); bitcoin_qt_want_version=qt5], + [qt_lib_suffix= ]) + AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], []) AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], []) AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], []) @@ -79,105 +86,99 @@ AC_DEFUN([BITCOIN_QT_INIT],[ AC_SUBST(QT_TRANSLATION_DIR,$qt_translation_path) ]) -dnl Find the appropriate version of Qt libraries and includes. -dnl Inputs: $1: Whether or not pkg-config should be used. yes|no. Default: yes. -dnl Inputs: $2: If $1 is "yes" and --with-gui=auto, which qt version should be -dnl tried first. -dnl Outputs: See _BITCOIN_QT_FIND_LIBS_* +dnl Find Qt libraries and includes. +dnl +dnl BITCOIN_QT_CONFIGURE([MINIMUM-VERSION]) +dnl +dnl Outputs: See _BITCOIN_QT_FIND_LIBS dnl Outputs: Sets variables for all qt-related tools. dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test AC_DEFUN([BITCOIN_QT_CONFIGURE],[ - use_pkgconfig=$1 - - if test x$use_pkgconfig = x; then - use_pkgconfig=yes - fi - - if test x$use_pkgconfig = xyes; then - BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG([$2])]) - else - BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG]) - fi + qt_version=">= $1" + qt_lib_prefix="Qt5" + BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS]) dnl This is ugly and complicated. Yuck. Works as follows: - dnl We can't discern whether Qt4 builds are static or not. For Qt5, we can - dnl check a header to find out. When Qt is built statically, some plugins must - dnl be linked into the final binary as well. These plugins have changed between - dnl Qt4 and Qt5. With Qt5, languages moved into core and the WindowsIntegration - dnl plugin was added. Since we can't tell if Qt4 is static or not, it is - dnl assumed for windows builds. - dnl _BITCOIN_QT_CHECK_STATIC_PLUGINS does a quick link-check and appends the - dnl results to QT_LIBS. + dnl We check a header to find out whether Qt is built statically. + dnl When Qt is built statically, some plugins must be linked into + dnl the final binary as well. _BITCOIN_QT_CHECK_STATIC_PLUGIN does + dnl a quick link-check and appends the results to QT_LIBS. BITCOIN_QT_CHECK([ TEMP_CPPFLAGS=$CPPFLAGS TEMP_CXXFLAGS=$CXXFLAGS CPPFLAGS="$QT_INCLUDES $CPPFLAGS" CXXFLAGS="$PIC_FLAGS $CXXFLAGS" - if test x$bitcoin_qt_got_major_vers = x5; then - _BITCOIN_QT_IS_STATIC - if test x$bitcoin_cv_static_qt = xyes; then - _BITCOIN_QT_FIND_STATIC_PLUGINS - AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) - AC_CACHE_CHECK(for Qt < 5.4, bitcoin_cv_need_acc_widget,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM( - [[#include ]],[[ - #if QT_VERSION >= 0x050400 - choke; - #endif - ]])], - [bitcoin_cv_need_acc_widget=yes], - [bitcoin_cv_need_acc_widget=no]) - ]) - if test "x$bitcoin_cv_need_acc_widget" = "xyes"; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) + _BITCOIN_QT_IS_STATIC + if test "x$bitcoin_cv_static_qt" = xyes; then + _BITCOIN_QT_CHECK_STATIC_LIBS + + if test "x$qt_plugin_path" != x; then + if test -d "$qt_plugin_path/platforms"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms" fi - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal]) - AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) - if test x$TARGET_OS = xwindows; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) - AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) - elif test x$TARGET_OS = xlinux; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static]) - AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) - elif test x$TARGET_OS = xdarwin; then - AX_CHECK_LINK_FLAG([[-framework IOKit]],[QT_LIBS="$QT_LIBS -framework IOKit"],[AC_MSG_ERROR(could not iokit framework)]) - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa]) - AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) + if test -d "$qt_plugin_path/styles"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/styles" + fi + if test -d "$qt_plugin_path/accessible"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" + fi + if test -d "$qt_plugin_path/platforms/android"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" fi fi - else - if test x$TARGET_OS = xwindows; then - AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) - _BITCOIN_QT_CHECK_STATIC_PLUGINS([ - Q_IMPORT_PLUGIN(qcncodecs) - Q_IMPORT_PLUGIN(qjpcodecs) - Q_IMPORT_PLUGIN(qtwcodecs) - Q_IMPORT_PLUGIN(qkrcodecs) - Q_IMPORT_PLUGIN(AccessibleFactory)], - [-lqcncodecs -lqjpcodecs -lqtwcodecs -lqkrcodecs -lqtaccessiblewidgets]) + + AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) + if test "x$TARGET_OS" != xandroid; then + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMinimalIntegrationPlugin], [-lqminimal]) + AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) + fi + if test "x$TARGET_OS" = xwindows; then + dnl Linking against wtsapi32 is required. See #17749 and + dnl https://bugreports.qt.io/browse/QTBUG-27097. + AX_CHECK_LINK_FLAG([-lwtsapi32], [QT_LIBS="$QT_LIBS -lwtsapi32"], [AC_MSG_ERROR([could not link against -lwtsapi32])]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsIntegrationPlugin], [-lqwindows]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsVistaStylePlugin], [-lqwindowsvistastyle]) + AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) + elif test "x$TARGET_OS" = xlinux; then + dnl workaround for https://bugreports.qt.io/browse/QTBUG-74874 + AX_CHECK_LINK_FLAG([-lxcb-shm], [QT_LIBS="$QT_LIBS -lxcb-shm"], [AC_MSG_ERROR([could not link against -lxcb-shm])]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QXcbIntegrationPlugin], [-lqxcb -lxcb-static]) + AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) + elif test "x$TARGET_OS" = xdarwin; then + AX_CHECK_LINK_FLAG([[-framework Carbon]],[QT_LIBS="$QT_LIBS -framework Carbon"],[AC_MSG_ERROR(could not link against Carbon framework)]) + AX_CHECK_LINK_FLAG([[-framework IOSurface]],[QT_LIBS="$QT_LIBS -framework IOSurface"],[AC_MSG_ERROR(could not link against IOSurface framework)]) + AX_CHECK_LINK_FLAG([[-framework Metal]],[QT_LIBS="$QT_LIBS -framework Metal"],[AC_MSG_ERROR(could not link against Metal framework)]) + AX_CHECK_LINK_FLAG([[-framework QuartzCore]],[QT_LIBS="$QT_LIBS -framework QuartzCore"],[AC_MSG_ERROR(could not link against QuartzCore framework)]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QCocoaIntegrationPlugin], [-lqcocoa]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMacStylePlugin], [-lqmacstyle]) + AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) fi fi CPPFLAGS=$TEMP_CPPFLAGS CXXFLAGS=$TEMP_CXXFLAGS ]) - if test x$use_pkgconfig$qt_bin_path = xyes; then - if test x$bitcoin_qt_got_major_vers = x5; then - qt_bin_path="`$PKG_CONFIG --variable=host_bins Qt5Core 2>/dev/null`" - fi + if test "x$qt_bin_path" = x; then + qt_bin_path="`$PKG_CONFIG --variable=host_bins ${qt_lib_prefix}Core 2>/dev/null`" fi - if test x$use_hardening != xno; then + if test "x$use_hardening" != xno; then BITCOIN_QT_CHECK([ AC_MSG_CHECKING(whether -fPIE can be used with this Qt config) TEMP_CPPFLAGS=$CPPFLAGS TEMP_CXXFLAGS=$CXXFLAGS CPPFLAGS="$QT_INCLUDES $CPPFLAGS" CXXFLAGS="$PIE_FLAGS $CXXFLAGS" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #ifndef QT_VERSION + # include + #endif + ]], [[ - #if defined(QT_REDUCE_RELOCATIONS) - choke; - #endif + #if defined(QT_REDUCE_RELOCATIONS) + choke + #endif ]])], [ AC_MSG_RESULT(yes); QT_PIE_FLAGS=$PIE_FLAGS ], [ AC_MSG_RESULT(no); QT_PIE_FLAGS=$PIC_FLAGS] @@ -190,11 +191,16 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AC_MSG_CHECKING(whether -fPIC is needed with this Qt config) TEMP_CPPFLAGS=$CPPFLAGS CPPFLAGS="$QT_INCLUDES $CPPFLAGS" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #ifndef QT_VERSION + # include + #endif + ]], [[ - #if defined(QT_REDUCE_RELOCATIONS) - choke; - #endif + #if defined(QT_REDUCE_RELOCATIONS) + choke + #endif ]])], [ AC_MSG_RESULT(no)], [ AC_MSG_RESULT(yes); QT_PIE_FLAGS=$PIC_FLAGS] @@ -203,11 +209,12 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ ]) fi - BITCOIN_QT_PATH_PROGS([MOC], [moc-qt${bitcoin_qt_got_major_vers} moc${bitcoin_qt_got_major_vers} moc], $qt_bin_path) - BITCOIN_QT_PATH_PROGS([UIC], [uic-qt${bitcoin_qt_got_major_vers} uic${bitcoin_qt_got_major_vers} uic], $qt_bin_path) - BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt${bitcoin_qt_got_major_vers} rcc${bitcoin_qt_got_major_vers} rcc], $qt_bin_path) - BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt${bitcoin_qt_got_major_vers} lrelease${bitcoin_qt_got_major_vers} lrelease], $qt_bin_path) - BITCOIN_QT_PATH_PROGS([LUPDATE], [lupdate-qt${bitcoin_qt_got_major_vers} lupdate${bitcoin_qt_got_major_vers} lupdate],$qt_bin_path, yes) + BITCOIN_QT_PATH_PROGS([MOC], [moc-qt5 moc5 moc], $qt_bin_path) + BITCOIN_QT_PATH_PROGS([UIC], [uic-qt5 uic5 uic], $qt_bin_path) + BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt5 rcc5 rcc], $qt_bin_path) + BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt5 lrelease5 lrelease], $qt_bin_path) + BITCOIN_QT_PATH_PROGS([LUPDATE], [lupdate-qt5 lupdate5 lupdate],$qt_bin_path, yes) + BITCOIN_QT_PATH_PROGS([LCONVERT], [lconvert-qt5 lconvert5 lconvert], $qt_bin_path, yes) MOC_DEFS='-DHAVE_CONFIG_H -I$(srcdir)' case $host in @@ -226,27 +233,34 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ dnl enable qt support - AC_MSG_CHECKING(whether to build [AC_PACKAGE_NAME] GUI) + AC_MSG_CHECKING([whether to build ]AC_PACKAGE_NAME[ GUI]) BITCOIN_QT_CHECK([ bitcoin_enable_qt=yes bitcoin_enable_qt_test=yes - if test x$have_qt_test = xno; then + if test "x$have_qt_test" = xno; then bitcoin_enable_qt_test=no fi bitcoin_enable_qt_dbus=no - if test x$use_dbus != xno && test x$have_qt_dbus = xyes; then + if test "x$use_dbus" != xno && test "x$have_qt_dbus" = xyes; then bitcoin_enable_qt_dbus=yes fi - if test x$use_dbus = xyes && test x$have_qt_dbus = xno; then - AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.") + if test "x$use_dbus" = xyes && test "x$have_qt_dbus" = xno; then + AC_MSG_ERROR([libQtDBus not found. Install libQtDBus or remove --with-qtdbus.]) fi - if test x$LUPDATE = x; then - AC_MSG_WARN("lupdate is required to update qt translations") + if test "x$LUPDATE" = x; then + AC_MSG_WARN([lupdate tool is required to update Qt translations.]) + fi + if test "x$LCONVERT" = x; then + AC_MSG_WARN([lconvert tool is required to update Qt translations.]) fi ],[ bitcoin_enable_qt=no ]) - AC_MSG_RESULT([$bitcoin_enable_qt (Qt${bitcoin_qt_got_major_vers})]) + if test x$bitcoin_enable_qt = xyes; then + AC_MSG_RESULT([$bitcoin_enable_qt ($qt_lib_prefix)]) + else + AC_MSG_RESULT([$bitcoin_enable_qt]) + fi AC_SUBST(QT_PIE_FLAGS) AC_SUBST(QT_INCLUDES) @@ -256,61 +270,24 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AC_SUBST(QT_DBUS_LIBS) AC_SUBST(QT_TEST_INCLUDES) AC_SUBST(QT_TEST_LIBS) - AC_SUBST(QT_SELECT, qt${bitcoin_qt_got_major_vers}) + AC_SUBST(QT_SELECT, qt5) AC_SUBST(MOC_DEFS) ]) -dnl All macros below are internal and should _not_ be used from the main -dnl configure.ac. -dnl ---- - -dnl Internal. Check if the included version of Qt is Qt5. -dnl Requires: INCLUDES must be populated as necessary. -dnl Output: bitcoin_cv_qt5=yes|no -AC_DEFUN([_BITCOIN_QT_CHECK_QT5],[ - AC_CACHE_CHECK(for Qt 5, bitcoin_cv_qt5,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( - [[#include ]], - [[ - #if QT_VERSION < 0x050000 || QT_VERSION_MAJOR < 5 - choke - #endif - ]])], - [bitcoin_cv_qt5=yes], - [bitcoin_cv_qt5=no]) -])]) - -dnl Internal. Check if the included version of Qt is greater than Qt58. -dnl Requires: INCLUDES must be populated as necessary. -dnl Output: bitcoin_cv_qt5=yes|no -AC_DEFUN([_BITCOIN_QT_CHECK_QT58],[ - AC_CACHE_CHECK(for > Qt 5.7, bitcoin_cv_qt58,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION_MINOR < 8 - choke - #endif - ]])], - [bitcoin_cv_qt58=yes], - [bitcoin_cv_qt58=no]) -])]) - +dnl All macros below are internal and should _not_ be used from configure.ac. -dnl Internal. Check if the linked version of Qt was built as static libs. -dnl Requires: Qt5. +dnl Internal. Check if the linked version of Qt was built statically. +dnl +dnl _BITCOIN_QT_IS_STATIC +dnl --------------------- +dnl dnl Requires: INCLUDES and LIBS must be populated as necessary. dnl Output: bitcoin_cv_static_qt=yes|no -dnl Output: Defines QT_STATICPLUGIN if plugins are static. AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ AC_CACHE_CHECK(for static Qt, bitcoin_cv_static_qt,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - #ifndef QT_VERSION OR QT_VERSION_STR + #ifndef QT_VERSION # include #endif ]], @@ -322,243 +299,88 @@ AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ [bitcoin_cv_static_qt=yes], [bitcoin_cv_static_qt=no]) ]) - if test "x$bitcoin_cv_static_qt" = xyes; then - AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol for static Qt plugins]) - fi ]) -dnl Internal. Check if the link-requirements for static plugins are met. +dnl Internal. Check if the link-requirements for a static plugin are met. +dnl +dnl _BITCOIN_QT_CHECK_STATIC_PLUGIN(PLUGIN, LIBRARIES) +dnl -------------------------------------------------- +dnl dnl Requires: INCLUDES and LIBS must be populated as necessary. -dnl Inputs: $1: A series of Q_IMPORT_PLUGIN(). +dnl Inputs: $1: A static plugin name. dnl Inputs: $2: The libraries that resolve $1. dnl Output: QT_LIBS is prepended or configure exits. -AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[ - AC_MSG_CHECKING(for static Qt plugins: $2) +AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGIN], [ + AC_MSG_CHECKING([for $1 ($2)]) CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS" - LIBS="$2 $QT_LIBS $LIBS" + LIBS="$2${qt_lib_suffix} $QT_LIBS $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #define QT_STATICPLUGIN - #include - $1]], - [[return 0;]])], - [AC_MSG_RESULT(yes); QT_LIBS="$2 $QT_LIBS"], - [AC_MSG_RESULT(no); BITCOIN_QT_FAIL(Could not resolve: $2)]) + #include + Q_IMPORT_PLUGIN($1) + ]])], + [AC_MSG_RESULT([yes]); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"], + [AC_MSG_RESULT([no]); BITCOIN_QT_FAIL([$1 not found.])]) LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS" ]) -dnl Internal. Find paths necessary for linking qt static plugins -dnl Inputs: bitcoin_qt_got_major_vers. 4 or 5. -dnl Inputs: qt_plugin_path. optional. -dnl Outputs: QT_LIBS is appended -AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ - if test x$bitcoin_qt_got_major_vers = x5; then - if test x$qt_plugin_path != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms" - if test -d "$qt_plugin_path/accessible"; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" - fi - fi - if test "x$use_pkgconfig" = xyes; then - : dnl - m4_ifdef([PKG_CHECK_MODULES],[ - if test x$bitcoin_cv_qt58 = xno; then - PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) - else - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport], [QT_LIBS="-lQt5EventDispatcherSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport], [QT_LIBS="-lQt5ThemeSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport], [QT_LIBS="-lQt5DeviceDiscoverySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport], [QT_LIBS="-lQt5AccessibilitySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTFB], [Qt5FbSupport], [QT_LIBS="-lQt5FbSupport $QT_LIBS"]) - fi - if test "x$TARGET_OS" = xlinux; then - PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"]) - if ${PKG_CONFIG} --exists "Qt5Core >= 5.5" 2>/dev/null; then - PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) - fi - elif test "x$TARGET_OS" = xdarwin; then - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport], [QT_LIBS="-lQt5ClipboardSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport], [QT_LIBS="-lQt5GraphicsSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"]) - fi - ]) - else - if test "x$TARGET_OS" = xwindows; then - AC_CACHE_CHECK(for Qt >= 5.6, bitcoin_cv_need_platformsupport,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION < 0x050600 || QT_VERSION_MINOR < 6 - choke - #endif - ]])], - [bitcoin_cv_need_platformsupport=yes], - [bitcoin_cv_need_platformsupport=no]) - ]) - if test "x$bitcoin_cv_need_platformsupport" = xyes; then - if test x$bitcoin_cv_qt58 = xno; then - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}PlatformSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXPlatformSupport not found))) - else - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}FontDatabaseSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXFontDatabaseSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}EventDispatcherSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXEventDispatcherSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}ThemeSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXThemeSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}FbSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXFbSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}DeviceDiscoverySupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXDeviceDiscoverySupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}AccessibilitySupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXAccessibilitySupport not found))) - QT_LIBS="$QT_LIBS -lversion -ldwmapi -luxtheme" - fi - fi - fi - fi - else - if test x$qt_plugin_path != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" - QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs" - fi +dnl Internal. Check Qt static libs with PKG_CHECK_MODULES. +dnl +dnl _BITCOIN_QT_CHECK_STATIC_LIBS +dnl ----------------------------- +dnl +dnl Outputs: QT_LIBS is prepended. +AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ + PKG_CHECK_MODULES([QT_ACCESSIBILITY], [${qt_lib_prefix}AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="$QT_ACCESSIBILITY_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_DEVICEDISCOVERY], [${qt_lib_prefix}DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="$QT_DEVICEDISCOVERY_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_EDID], [${qt_lib_prefix}EdidSupport${qt_lib_suffix}], [QT_LIBS="$QT_EDID_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_EVENTDISPATCHER], [${qt_lib_prefix}EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="$QT_EVENTDISPATCHER_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_FB], [${qt_lib_prefix}FbSupport${qt_lib_suffix}], [QT_LIBS="$QT_FB_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_FONTDATABASE], [${qt_lib_prefix}FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="$QT_FONTDATABASE_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_THEME], [${qt_lib_prefix}ThemeSupport${qt_lib_suffix}], [QT_LIBS="$QT_THEME_LIBS $QT_LIBS"]) + if test "x$TARGET_OS" = xlinux; then + PKG_CHECK_MODULES([QT_INPUT], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_INPUT_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_XCBQPA], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_XCBQPA_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xdarwin; then + PKG_CHECK_MODULES([QT_CLIPBOARD], [${qt_lib_prefix}ClipboardSupport${qt_lib_suffix}], [QT_LIBS="$QT_CLIPBOARD_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_GRAPHICS], [${qt_lib_prefix}GraphicsSupport${qt_lib_suffix}], [QT_LIBS="$QT_GRAPHICS_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport${qt_lib_suffix}], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xwindows; then + PKG_CHECK_MODULES([QT_WINDOWSUIAUTOMATION], [${qt_lib_prefix}WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="$QT_WINDOWSUIAUTOMATION_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xandroid; then + PKG_CHECK_MODULES([QT_EGL], [${qt_lib_prefix}EglSupport], [QT_LIBS="$QT_EGL_LIBS $QT_LIBS"]) fi ]) dnl Internal. Find Qt libraries using pkg-config. -dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to check -dnl first. -dnl Inputs: $1: If bitcoin_qt_want_version is "auto", check for this version -dnl first. +dnl +dnl _BITCOIN_QT_FIND_LIBS +dnl --------------------- +dnl dnl Outputs: All necessary QT_* variables are set. -dnl Outputs: bitcoin_qt_got_major_vers is set to "4" or "5". dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. -AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[ - m4_ifdef([PKG_CHECK_MODULES],[ - auto_priority_version=$1 - if test x$auto_priority_version = x; then - auto_priority_version=qt5 - fi - if test x$bitcoin_qt_want_version = xqt5 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt5 ); then - QT_LIB_PREFIX=Qt5 - bitcoin_qt_got_major_vers=5 - else - QT_LIB_PREFIX=Qt - bitcoin_qt_got_major_vers=4 - fi - qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets" - qt4_modules="QtCore QtGui QtNetwork" - BITCOIN_QT_CHECK([ - if test x$bitcoin_qt_want_version = xqt5 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt5 ); then - PKG_CHECK_MODULES([QT5], [$qt5_modules], [QT_INCLUDES="$QT5_CFLAGS"; QT_LIBS="$QT5_LIBS" have_qt=yes],[have_qt=no]) - elif test x$bitcoin_qt_want_version = xqt4 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt4 ); then - PKG_CHECK_MODULES([QT4], [$qt4_modules], [QT_INCLUDES="$QT4_CFLAGS"; QT_LIBS="$QT4_LIBS" ; have_qt=yes], [have_qt=no]) - fi - - dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other. - if test x$have_qt = xno && test x$bitcoin_qt_want_version = xauto; then - if test x$auto_priority_version = xqt5; then - PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no]) - else - PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt5; bitcoin_qt_got_major_vers=5], [have_qt=no]) - fi - fi - if test x$have_qt != xyes; then - have_qt=no - BITCOIN_QT_FAIL([Qt dependencies not found]) - fi - ]) - BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_TEST], [${QT_LIB_PREFIX}Test], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) - if test x$use_dbus != xno; then - PKG_CHECK_MODULES([QT_DBUS], [${QT_LIB_PREFIX}DBus], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) - fi - ]) +AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[ + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CORE_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CORE_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Core${qt_lib_suffix} $qt_version not found])]) ]) - true; dnl -]) - -dnl Internal. Find Qt libraries without using pkg-config. Version is deduced -dnl from the discovered headers. -dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to use. -dnl If "auto", the version will be discovered by _BITCOIN_QT_CHECK_QT5. -dnl Outputs: All necessary QT_* variables are set. -dnl Outputs: bitcoin_qt_got_major_vers is set to "4" or "5". -dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. -AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[ - TEMP_CPPFLAGS="$CPPFLAGS" - TEMP_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$PIC_FLAGS $CXXFLAGS" - TEMP_LIBS="$LIBS" BITCOIN_QT_CHECK([ - if test x$qt_include_path != x; then - QT_INCLUDES="-I$qt_include_path -I$qt_include_path/QtCore -I$qt_include_path/QtGui -I$qt_include_path/QtWidgets -I$qt_include_path/QtNetwork -I$qt_include_path/QtTest -I$qt_include_path/QtDBus" - CPPFLAGS="$QT_INCLUDES $CPPFLAGS" - fi + PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_GUI_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_GUI_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version not found])]) ]) - - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITCOIN_QT_FAIL(QtCore headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITCOIN_QT_FAIL(QtGui headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITCOIN_QT_FAIL(QtNetwork headers missing))]) - BITCOIN_QT_CHECK([ - if test x$bitcoin_qt_want_version = xauto; then - _BITCOIN_QT_CHECK_QT5 - _BITCOIN_QT_CHECK_QT58 - fi - if test x$bitcoin_cv_qt5 = xyes || test x$bitcoin_qt_want_version = xqt5; then - QT_LIB_PREFIX=Qt5 - bitcoin_qt_got_major_vers=5 - else - QT_LIB_PREFIX=Qt - bitcoin_qt_got_major_vers=4 - fi + PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_WIDGETS_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_WIDGETS_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version not found])]) ]) - BITCOIN_QT_CHECK([ - LIBS= - if test x$qt_lib_path != x; then - LIBS="$LIBS -L$qt_lib_path" - fi - - if test x$TARGET_OS = xwindows; then - AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found)) - fi + PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_NETWORK_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_NETWORK_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Network${qt_lib_suffix} $qt_version not found])]) ]) - BITCOIN_QT_CHECK(AC_CHECK_LIB([z] ,[main],,AC_MSG_WARN([zlib not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([jpeg_create_decompress] ,[qtjpeg jpeg],,AC_MSG_WARN([libjpeg not found. Assuming qt has it built-in]))) - if test x$bitcoin_cv_qt58 = xno; then - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([pcre16_exec], [qtpcre pcre16],,AC_MSG_WARN([libpcre16 not found. Assuming qt has it built-in]))) - else - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtlibpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([pcre2_match_16], [qtpcre2 libqtpcre2],,AC_MSG_WARN([libqtpcre2 not found. Assuming qt has it built-in]))) - fi - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([hb_ot_tags_from_script] ,[qtharfbuzzng qtharfbuzz harfbuzz],,AC_MSG_WARN([libharfbuzz not found. Assuming qt has it built-in or support is disabled]))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Core not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Gui not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Network],[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Network not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Widgets],[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Widgets not found))) - QT_LIBS="$LIBS" - LIBS="$TEMP_LIBS" - BITCOIN_QT_CHECK([ - LIBS= - if test x$qt_lib_path != x; then - LIBS="-L$qt_lib_path" - fi - AC_CHECK_LIB([${QT_LIB_PREFIX}Test], [main],, have_qt_test=no) - AC_CHECK_HEADER([QTest],, have_qt_test=no) - QT_TEST_LIBS="$LIBS" - if test x$use_dbus != xno; then - LIBS= - if test x$qt_lib_path != x; then - LIBS="-L$qt_lib_path" - fi - AC_CHECK_LIB([${QT_LIB_PREFIX}DBus], [main],, have_qt_dbus=no) - AC_CHECK_HEADER([QtDBus],, have_qt_dbus=no) - QT_DBUS_LIBS="$LIBS" + PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) + if test "x$use_dbus" != xno; then + PKG_CHECK_MODULES([QT_DBUS], [${qt_lib_prefix}DBus $qt_version], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) fi ]) - CPPFLAGS="$TEMP_CPPFLAGS" - CXXFLAGS="$TEMP_CXXFLAGS" - LIBS="$TEMP_LIBS" ]) diff --git a/build-aux/m4/bitcoin_runtime_lib.m4 b/build-aux/m4/bitcoin_runtime_lib.m4 new file mode 100644 index 0000000000..1a6922deca --- /dev/null +++ b/build-aux/m4/bitcoin_runtime_lib.m4 @@ -0,0 +1,42 @@ +# On some platforms clang builtin implementations +# require compiler-rt as a runtime library to use. +# +# See: +# - https://bugs.llvm.org/show_bug.cgi?id=28629 + +m4_define([_CHECK_RUNTIME_testbody], [[ + bool f(long long x, long long y, long long* p) + { + return __builtin_mul_overflow(x, y, p); + } + int main() { return 0; } +]]) + +AC_DEFUN([CHECK_RUNTIME_LIB], [ + + AC_LANG_PUSH([C++]) + + AC_MSG_CHECKING([for __builtin_mul_overflow]) + AC_LINK_IFELSE( + [AC_LANG_SOURCE([_CHECK_RUNTIME_testbody])], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_BUILTIN_MUL_OVERFLOW], [1], [Define if you have a working __builtin_mul_overflow]) + ], + [ + ax_check_save_flags="$LDFLAGS" + LDFLAGS="$LDFLAGS --rtlib=compiler-rt -lgcc_s" + AC_LINK_IFELSE( + [AC_LANG_SOURCE([_CHECK_RUNTIME_testbody])], + [ + AC_MSG_RESULT([yes, with additional linker flags]) + RUNTIME_LDFLAGS="--rtlib=compiler-rt -lgcc_s" + AC_DEFINE([HAVE_BUILTIN_MUL_OVERFLOW], [1], [Define if you have a working __builtin_mul_overflow]) + ], + [AC_MSG_RESULT([no])]) + LDFLAGS="$ax_check_save_flags" + ]) + + AC_LANG_POP + AC_SUBST([RUNTIME_LDFLAGS]) +]) diff --git a/build-aux/m4/l_atomic.m4 b/build-aux/m4/l_atomic.m4 index 3ceea16bbb..75c43f9a92 100644 --- a/build-aux/m4/l_atomic.m4 +++ b/build-aux/m4/l_atomic.m4 @@ -38,7 +38,7 @@ AC_DEFUN([CHECK_ATOMIC], [ AC_MSG_RESULT([yes]) ],[ AC_MSG_RESULT([no]) - AC_MSG_FAILURE([cannot figure our how to use std::atomic]) + AC_MSG_FAILURE([cannot figure out how to use std::atomic]) ]) ]) diff --git a/build-aux/m4/l_socket.m4 b/build-aux/m4/l_socket.m4 new file mode 100644 index 0000000000..38923a98fc --- /dev/null +++ b/build-aux/m4/l_socket.m4 @@ -0,0 +1,36 @@ +# Illumos/SmartOS requires linking with -lsocket if +# using getifaddrs & freeifaddrs + +m4_define([_CHECK_SOCKET_testbody], [[ + #include + #include + + int main() { + struct ifaddrs *ifaddr; + getifaddrs(&ifaddr); + freeifaddrs(ifaddr); + } +]]) + +AC_DEFUN([CHECK_SOCKET], [ + + AC_LANG_PUSH(C++) + + AC_MSG_CHECKING([whether ifaddrs funcs can be used without link library]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_SOCKET_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + LIBS="$LIBS -lsocket" + AC_MSG_CHECKING([whether getifaddrs needs -lsocket]) + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_SOCKET_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([cannot figure out how to use getifaddrs]) + ]) + ]) + + AC_LANG_POP +]) diff --git a/configure.ac b/configure.ac index 4a4fe0d409..486f21c4ce 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,10 @@ -dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) -AC_PREREQ([2.60]) +AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 2) define(_CLIENT_VERSION_MINOR, 13) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 8) +define(_CLIENT_VERSION_BUILD, 9) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2021) +define(_COPYRIGHT_YEAR, 2022) define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Blackcoin More]]) AC_INIT([Blackcoin More],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://gitlab.com/blackcoin/blackcoin-more],[blackcoin-more]) @@ -14,11 +13,23 @@ AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) +m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR([PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh])]) +PKG_PROG_PKG_CONFIG +if test "x$PKG_CONFIG" = x; then + AC_MSG_ERROR([pkg-config not found]) +fi + BITCOIN_DAEMON_NAME=blackmored BITCOIN_GUI_NAME=blackmore-qt BITCOIN_CLI_NAME=blackmore-cli BITCOIN_TX_NAME=blackmore-tx +dnl Unless the user specified ARFLAGS, force it to be cr +AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to if not set]) +if test "x${ARFLAGS+set}" != "xset"; then + ARFLAGS="cr" +fi + AC_CANONICAL_HOST AH_TOP([#ifndef BITCOIN_CONFIG_H]) @@ -29,14 +40,14 @@ dnl faketime breaks configure and is only needed for make. Disable it here. unset FAKETIME dnl Automake init set-up and checks -AM_INIT_AUTOMAKE([no-define subdir-objects foreign]) +AM_INIT_AUTOMAKE([1.13 no-define subdir-objects foreign]) dnl faketime messes with timestamps and causes configure to be re-run. dnl --disable-maintainer-mode can be used to bypass this. AM_MAINTAINER_MODE([enable]) dnl make the compilation flags quiet unless V=1 is used -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AM_SILENT_RULES([yes]) dnl Compiler checks (here before libtool). if test "x${CXXFLAGS+set}" = "xset"; then @@ -49,13 +60,28 @@ AC_PROG_CXX dnl By default, libtool for mingw refuses to link static libs into a dll for dnl fear of mixing pic/non-pic objects, and import/export complications. Since dnl we have those under control, re-enable that functionality. +dnl Compiler with posix support is needed for cross compile some of c++ 14 features for mingw like threads and mutexes. case $host in *mingw*) lt_cv_deplibs_check_method="pass_all" + CC="$CC-posix" + CXX="$CXX-posix" ;; esac -dnl Require C++11 compiler (no GNU extensions) -AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory], [nodefault]) + +AC_ARG_ENABLE([c++17], + [AS_HELP_STRING([--enable-c++17], + [enable compilation in c++17 mode (disabled by default)])], + [use_cxx17=$enableval], + [use_cxx17=no]) + +dnl Require C++11 or C++17 compiler (no GNU extensions) +if test "x$use_cxx17" = xyes -o "x$enable_fuzz" = xyes ; then + AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) +else + AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) +fi + dnl Check if -latomic is required for CHECK_ATOMIC @@ -68,6 +94,10 @@ fi AC_PROG_OBJCXX ]) +dnl Since libtool 1.5.2 (released 2004-01-25), on Linux libtool no longer +dnl sets RPATH for any directories in the dynamic linker search path. +dnl See more: https://wiki.debian.org/RpathIssue +LT_PREREQ([1.5.2]) dnl Libtool init checks. LT_INIT([pic-only]) @@ -76,9 +106,10 @@ AC_PATH_TOOL(AR, ar) AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) +AC_PATH_TOOL(LLVM_COV, llvm-cov) AC_PATH_PROG(LCOV, lcov) -dnl Python 3.x is supported from 3.4 on (see https://github.com/bitcoin/bitcoin/issues/7893) -AC_PATH_PROGS([PYTHON], [python3.6 python3.5 python3.4 python3 python2.7 python2 python]) +dnl Python 3.6 is specified in .python-version and should be used if available, see doc/dependencies.md +AC_PATH_PROGS([PYTHON], [python3.6 python3.7 python3.8 python3.9, python3.10, python3 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) @@ -87,15 +118,16 @@ AC_PATH_PROG(HEXDUMP,hexdump) AC_PATH_TOOL(READELF, readelf) AC_PATH_TOOL(CPPFILT, c++filt) AC_PATH_TOOL(OBJCOPY, objcopy) +AC_PATH_PROG(DOXYGEN, doxygen) +AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"]) AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) -# Enable wallet AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], [disable wallet (enabled by default)])], [enable_wallet=$enableval], - [enable_wallet=yes]) + [enable_wallet=auto]) AC_ARG_WITH([miniupnpc], [AS_HELP_STRING([--with-miniupnpc], @@ -147,9 +179,9 @@ AC_ARG_WITH([qrencode], AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--disable-hardening], - [do not attempt to harden the resulting executables (default is to harden)])], + [do not attempt to harden the resulting executables (default is to harden when possible)])], [use_hardening=$enableval], - [use_hardening=yes]) + [use_hardening=auto]) AC_ARG_ENABLE([reduce-exports], [AS_HELP_STRING([--enable-reduce-exports], @@ -163,10 +195,20 @@ AC_ARG_ENABLE([ccache], [use_ccache=$enableval], [use_ccache=auto]) +dnl Suppress warnings from external headers (e.g. Boost, Qt). +dnl May be useful if warnings from external headers clutter the build output +dnl too much, so that it becomes difficult to spot Bitcoin Core warnings +dnl or if they cause a build failure with --enable-werror. +AC_ARG_ENABLE([suppress-external-warnings], + [AS_HELP_STRING([--enable-suppress-external-warnings], + [Suppress warnings from external headers (default is no)])], + [suppress_external_warnings=$enableval], + [suppress_external_warnings=no]) + AC_ARG_ENABLE([lcov], [AS_HELP_STRING([--enable-lcov], [enable lcov testing (default is no)])], - [use_lcov=yes], + [use_lcov=$enableval], [use_lcov=no]) AC_ARG_ENABLE([glibc-back-compat], @@ -175,6 +217,22 @@ AC_ARG_ENABLE([glibc-back-compat], [use_glibc_compat=$enableval], [use_glibc_compat=no]) +AC_ARG_ENABLE([threadlocal], + [AS_HELP_STRING([--enable-threadlocal], + [enable features that depend on the c++ thread_local keyword (currently just thread names in debug logs). (default is to enabled if there is platform support and glibc-back-compat is not enabled)])], + [use_thread_local=$enableval], + [use_thread_local=auto]) + +AC_ARG_ENABLE([asm], + [AS_HELP_STRING([--disable-asm], + [disable assembly routines (enabled by default)])], + [use_asm=$enableval], + [use_asm=yes]) + +if test "x$use_asm" = xyes; then + AC_DEFINE(USE_ASM, 1, [Define this symbol to build in assembly routines]) +fi + AC_ARG_WITH([system-univalue], [AS_HELP_STRING([--with-system-univalue], [Build with system UniValue (default is no)])], @@ -189,20 +247,26 @@ AC_ARG_ENABLE([zmq], AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) +AC_ARG_ENABLE([sse2], + [AS_HELP_STRING([--enable-sse2], + [enable SSE2 instructions in the scrypt library. (default is disabled)])], + [use_sse2=$enableval], + [use_sse2=no]) + AC_ARG_ENABLE(man, [AS_HELP_STRING([--disable-man], [do not install man pages (default is to install)])],, enable_man=yes) AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no) -# Enable debug +dnl Enable debug AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], - [use debug compiler flags and macros (default is no)])], + [use compiler flags and macros suited for debugging (default is no)])], [enable_debug=$enableval], [enable_debug=no]) -# Turn warnings into errors +dnl Turn warnings into errors AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], [Treat certain compiler warnings as errors (default is no)])], @@ -210,17 +274,50 @@ AC_ARG_ENABLE([werror], [enable_werror=no]) AC_LANG_PUSH([C++]) + +dnl Check for a flag to turn compiler warnings into errors. This is helpful for checks which may +dnl appear to succeed because by default they merely emit warnings when they fail. +dnl +dnl Note that this is not necessarily a check to see if -Werror is supported, but rather to see if +dnl a compile with -Werror can succeed. This is important because the compiler may already be +dnl warning about something unrelated, for example about some path issue. If that is the case, +dnl -Werror cannot be used because all of those warnings would be turned into errors. AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) +dnl Check for a flag to turn linker warnings into errors. When flags are passed to linkers via the +dnl compiler driver using a -Wl,-foo flag, linker warnings may be swallowed rather than bubbling up. +dnl See note above, the same applies here as well. +dnl +dnl LDFLAG_WERROR Should only be used when testing -Wl,* +case $host in + *darwin*) + AX_CHECK_LINK_FLAG([-Wl,-fatal_warnings],[LDFLAG_WERROR="-Wl,-fatal_warnings"],[LDFLAG_WERROR=""]) + ;; + *) + AX_CHECK_LINK_FLAG([-Wl,--fatal-warnings],[LDFLAG_WERROR="-Wl,--fatal-warnings"],[LDFLAG_WERROR=""]) + ;; +esac + if test "x$enable_debug" = xyes; then - CPPFLAGS="$CPPFLAGS -DDEBUG -DDEBUG_LOCKORDER" - if test "x$GCC" = xyes; then - CFLAGS="$CFLAGS -g3 -O0" - fi + dnl Clear default -g -O2 flags + if test "x$CXXFLAGS_overridden" = xno; then + CXXFLAGS="" + fi - if test "x$GXX" = xyes; then - CXXFLAGS="$CXXFLAGS -g3 -O0" - fi + dnl Disable all optimizations + AX_CHECK_COMPILE_FLAG([-O0], [[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -O0"]],,[[$CXXFLAG_WERROR]]) + + dnl Prefer -g3, fall back to -g if that is unavailable. + AX_CHECK_COMPILE_FLAG( + [-g3], + [[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -g3"]], + [AX_CHECK_COMPILE_FLAG([-g],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -g"]],,[[$CXXFLAG_WERROR]])], + [[$CXXFLAG_WERROR]]) + + AX_CHECK_PREPROC_FLAG([-DDEBUG],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DDEBUG"]],,[[$CXXFLAG_WERROR]]) + AX_CHECK_PREPROC_FLAG([-DDEBUG_LOCKORDER],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DDEBUG_LOCKORDER"]],,[[$CXXFLAG_WERROR]]) + AX_CHECK_PREPROC_FLAG([-DABORT_ON_FAILED_ASSUME],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DABORT_ON_FAILED_ASSUME"]],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-ftrapv],[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -ftrapv"],,[[$CXXFLAG_WERROR]]) fi ERROR_CXXFLAGS= @@ -228,32 +325,197 @@ if test "x$enable_werror" = "xyes"; then if test "x$CXXFLAG_WERROR" = "x"; then AC_MSG_ERROR("enable-werror set but -Werror is not usable") fi + AX_CHECK_COMPILE_FLAG([-Werror=gnu],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=gnu"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Werror=vla],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=vla"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=shadow-field],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=shadow-field"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=switch],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=switch"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=thread-safety],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=thread-safety"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=range-loop-analysis],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=range-loop-analysis"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=unused-variable],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=unused-variable"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=date-time],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=date-time"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=return-type],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=return-type"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=conditional-uninitialized],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=conditional-uninitialized"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=sign-compare],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=sign-compare"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=unreachable-code-loop-increment],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=unreachable-code-loop-increment"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Werror=mismatched-tags], [ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=mismatched-tags"], [], [$CXXFLAG_WERROR]) + AX_CHECK_COMPILE_FLAG([-Werror=implicit-fallthrough], [ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=implicit-fallthrough"], [], [$CXXFLAG_WERROR]) + + if test x$suppress_external_warnings != xno ; then + AX_CHECK_COMPILE_FLAG([-Werror=documentation],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=documentation"],,[[$CXXFLAG_WERROR]]) + fi fi if test "x$CXXFLAGS_overridden" = "xno"; then - AX_CHECK_COMPILE_FLAG([-Wall],[CXXFLAGS="$CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wextra],[CXXFLAGS="$CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wvla],[CXXFLAGS="$CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) - - ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all - ## unknown options if any other warning is produced. Test the -Wfoo case, and - ## set the -Wno-foo case if it works. - AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[CXXFLAGS="$CXXFLAGS -Wno-unused-parameter"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wself-assign],[CXXFLAGS="$CXXFLAGS -Wno-self-assign"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[CXXFLAGS="$CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wdeprecated-register],[CXXFLAGS="$CXXFLAGS -Wno-deprecated-register"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wall],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wextra],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wgnu],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wgnu"],,[[$CXXFLAG_WERROR]]) + dnl some compilers will ignore -Wformat-security without -Wformat, so just combine the two here. + AX_CHECK_COMPILE_FLAG([-Wformat -Wformat-security],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wformat -Wformat-security"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wvla],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wshadow-field],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wshadow-field"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wswitch],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wswitch"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wthread-safety],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wthread-safety"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wrange-loop-analysis],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wrange-loop-analysis"],,[[$CXXFLAG_WERROR]]) + dnl X_CHECK_COMPILE_FLAG([-Wredundant-decls],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wredundant-decls"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunused-variable],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wunused-variable"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunused-member-function],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wunused-member-function"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wdate-time],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wdate-time"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wconditional-uninitialized],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wconditional-uninitialized"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wsign-compare],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wsign-compare"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wduplicated-branches],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wduplicated-branches"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wduplicated-cond],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wduplicated-cond"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wlogical-op],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wlogical-op"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Woverloaded-virtual],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Woverloaded-virtual"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunreachable-code-loop-increment],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wunreachable-code-loop-increment"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wimplicit-fallthrough"], [], [$CXXFLAG_WERROR]) + + if test x$suppress_external_warnings != xno ; then + AX_CHECK_COMPILE_FLAG([-Wdocumentation],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wdocumentation"],,[[$CXXFLAG_WERROR]]) + fi + + dnl Some compilers (gcc) ignore unknown -Wno-* options, but warn about all + dnl unknown options if any other warning is produced. Test the -Wfoo case, and + dnl set the -Wno-foo case if it works. + AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-parameter"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wself-assign],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-self-assign"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]]) + if test x$suppress_external_warnings != xyes ; then + AX_CHECK_COMPILE_FLAG([-Wdeprecated-copy],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-copy"],,[[$CXXFLAG_WERROR]]) + fi + AX_CHECK_COMPILE_FLAG([-Wno-unknown-pragmas],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unknown-pragmas"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wno-strict-aliasing],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-strict-aliasing"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wno-duplicated-branches],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-duplicated-branches"],,[[$CXXFLAG_WERROR]]) +fi + +dnl Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review. +AX_CHECK_COMPILE_FLAG([-fno-extended-identifiers],[[CXXFLAGS="$CXXFLAGS -fno-extended-identifiers"]],,[[$CXXFLAG_WERROR]]) + +enable_sse42=no +enable_sse41=no +enable_avx2=no +enable_shani=no + +if test "x$use_asm" = "xyes"; then + +dnl Check for optional instruction set support. Enabling these does _not_ imply that all code will +dnl be compiled with them, rather that specific objects/libs may use them after checking for runtime +dnl compatibility. + +dnl x86 +AX_CHECK_COMPILE_FLAG([-msse4.2],[[SSE42_CXXFLAGS="-msse4.2"]],,[[$CXXFLAG_WERROR]]) +AX_CHECK_COMPILE_FLAG([-msse4.1],[[SSE41_CXXFLAGS="-msse4.1"]],,[[$CXXFLAG_WERROR]]) +AX_CHECK_COMPILE_FLAG([-mavx -mavx2],[[AVX2_CXXFLAGS="-mavx -mavx2"]],,[[$CXXFLAG_WERROR]]) +AX_CHECK_COMPILE_FLAG([-msse4 -msha],[[SHANI_CXXFLAGS="-msse4 -msha"]],,[[$CXXFLAG_WERROR]]) + +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $SSE42_CXXFLAGS" +AC_MSG_CHECKING(for SSE4.2 intrinsics) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #if defined(_MSC_VER) + #include + #elif defined(__GNUC__) && defined(__SSE4_2__) + #include + #endif + ]],[[ + uint64_t l = 0; + l = _mm_crc32_u8(l, 0); + l = _mm_crc32_u32(l, 0); + l = _mm_crc32_u64(l, 0); + return l; + ]])], + [ AC_MSG_RESULT(yes); enable_sse42=yes], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $SSE41_CXXFLAGS" +AC_MSG_CHECKING(for SSE4.1 intrinsics) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + __m128i l = _mm_set1_epi32(0); + return _mm_extract_epi32(l, 3); + ]])], + [ AC_MSG_RESULT(yes); enable_sse41=yes; AC_DEFINE(ENABLE_SSE41, 1, [Define this symbol to build code that uses SSE4.1 intrinsics]) ], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $AVX2_CXXFLAGS" +AC_MSG_CHECKING(for AVX2 intrinsics) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + __m256i l = _mm256_set1_epi32(0); + return _mm256_extract_epi32(l, 7); + ]])], + [ AC_MSG_RESULT(yes); enable_avx2=yes; AC_DEFINE(ENABLE_AVX2, 1, [Define this symbol to build code that uses AVX2 intrinsics]) ], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $SHANI_CXXFLAGS" +AC_MSG_CHECKING(for SHA-NI intrinsics) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + __m128i i = _mm_set1_epi32(0); + __m128i j = _mm_set1_epi32(1); + __m128i k = _mm_set1_epi32(2); + return _mm_extract_epi32(_mm_sha256rnds2_epu32(i, i, k), 0); + ]])], + [ AC_MSG_RESULT(yes); enable_shani=yes; AC_DEFINE(ENABLE_SHANI, 1, [Define this symbol to build code that uses SHA-NI intrinsics]) ], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + +# ARM +AX_CHECK_COMPILE_FLAG([-march=armv8-a+crc+crypto],[[ARM_CRC_CXXFLAGS="-march=armv8-a+crc+crypto"]],,[[$CXXFLAG_WERROR]]) + +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $ARM_CRC_CXXFLAGS" +AC_MSG_CHECKING(for ARM CRC32 intrinsics) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + __crc32cb(0, 0); __crc32ch(0, 0); __crc32cw(0, 0); __crc32cd(0, 0); + vmull_p64(0, 0); + ]])], + [ AC_MSG_RESULT(yes); enable_arm_crc=yes; ], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + fi + CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" AC_ARG_WITH([utils], [AS_HELP_STRING([--with-utils], - [build bitcoin-cli bitcoin-tx (default=yes)])], + [build blackmore-cli blackmore-tx (default=yes)])], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) +AC_ARG_ENABLE([util-cli], + [AS_HELP_STRING([--enable-util-cli], + [build blackmore-cli])], + [build_bitcoin_cli=$enableval], + [build_bitcoin_cli=$build_bitcoin_utils]) + +AC_ARG_ENABLE([util-tx], + [AS_HELP_STRING([--enable-util-tx], + [build blackmore-tx])], + [build_bitcoin_tx=$enableval], + [build_bitcoin_tx=$build_bitcoin_utils]) + AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], [build libraries (default=yes)])], @@ -262,40 +524,36 @@ AC_ARG_WITH([libs], AC_ARG_WITH([daemon], [AS_HELP_STRING([--with-daemon], - [build bitcoind daemon (default=yes)])], + [build blackmore daemon (default=yes)])], [build_bitcoind=$withval], [build_bitcoind=yes]) +pkg_openssl=yes use_pkgconfig=yes case $host in *mingw*) - #pkgconfig does more harm than good with MinGW + dnl pkgconfig does more harm than good with MinGW use_pkgconfig=no TARGET_OS=windows - AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([kernel32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([winspool], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([shell32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([ole32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([rpcrt4], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([advapi32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([ws2_32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([mswsock], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([shlwapi], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(lib missing)) - - # -static is interpreted by libtool, where it has a different meaning. - # In libtool-speak, it's -all-static. + AC_CHECK_LIB([kernel32], [GetModuleFileNameA],, AC_MSG_ERROR(libkernel32 missing)) + AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(libuser32 missing)) + AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(libgdi32 missing)) + AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(libcomdlg32 missing)) + AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(libwinmm missing)) + AC_CHECK_LIB([shell32], [SHGetSpecialFolderPathW],, AC_MSG_ERROR(libshell32 missing)) + AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(libcomctl32 missing)) + AC_CHECK_LIB([ole32], [CoCreateInstance],, AC_MSG_ERROR(libole32 missing)) + AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(liboleaut32 missing)) + AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(libuuid missing)) + AC_CHECK_LIB([advapi32], [CryptAcquireContextW],, AC_MSG_ERROR(libadvapi32 missing)) + AC_CHECK_LIB([ws2_32], [WSAStartup],, AC_MSG_ERROR(libws2_32 missing)) + AC_CHECK_LIB([shlwapi], [PathRemoveFileSpecW],, AC_MSG_ERROR(libshlwapi missing)) + AC_CHECK_LIB([iphlpapi], [GetAdaptersAddresses],, AC_MSG_ERROR(libiphlpapi missing)) + + dnl -static is interpreted by libtool, where it has a different meaning. + dnl In libtool-speak, it's -all-static. AX_CHECK_LINK_FLAG([[-static]],[LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"]) AC_PATH_PROG([MAKENSIS], [makensis], none) @@ -308,17 +566,7 @@ case $host in AC_MSG_ERROR("windres not found") fi - CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB" - LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" - if test "x$CXXFLAGS_overridden" = "xno"; then - CXXFLAGS="$CXXFLAGS -w" - fi - case $host in - i?86-*) WINDOWS_BITS=32 ;; - x86_64-*) WINDOWS_BITS=64 ;; - *) AC_MSG_ERROR("Could not determine win32/win64 for installer") ;; - esac - AC_SUBST(WINDOWS_BITS) + CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN" dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against. dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override @@ -328,10 +576,11 @@ case $host in archive_cmds_CXX="\$CC -shared \$libobjs \$deplibs \$compiler_flags -static -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib" postdeps_CXX= + dnl We require Windows 7 (NT 6.1) or later + AX_CHECK_LINK_FLAG([[-Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,1]],[LDFLAGS="$LDFLAGS -Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,1"],,[[$LDFLAG_WERROR]]) ;; *darwin*) TARGET_OS=darwin - LEVELDB_TARGET_FLAGS="-DOS_MACOSX" if test x$cross_compiling != xyes; then BUILD_OS=darwin AC_CHECK_PROG([PORT],port, port) @@ -376,9 +625,11 @@ case $host in BUILD_OS=darwin ;; *) + AC_PATH_TOOL([DSYMUTIL], [dsymutil], dsymutil) AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) - AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) + AC_PATH_PROGS([XORRISOFS], [xorrisofs], xorrisofs) + AC_PATH_PROGS([DMG], [dmg], dmg) AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) @@ -392,37 +643,15 @@ case $host in esac fi - AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"]) + AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"],, [[$LDFLAG_WERROR]]) CPPFLAGS="$CPPFLAGS -DMAC_OSX -DOBJC_OLD_DISPATCH_PROTOTYPES=0" OBJCXXFLAGS="$CXXFLAGS" ;; *linux*) TARGET_OS=linux - LEVELDB_TARGET_FLAGS="-DOS_LINUX" - ;; - *freebsd*) - LEVELDB_TARGET_FLAGS="-DOS_FREEBSD" - ;; - *openbsd*) - LEVELDB_TARGET_FLAGS="-DOS_OPENBSD" - ;; - *) - OTHER_OS=`echo ${host_os} | awk '{print toupper($0)}'` - AC_MSG_WARN([Guessing LevelDB OS as OS_${OTHER_OS}, please check whether this is correct, if not add an entry to configure.ac.]) - LEVELDB_TARGET_FLAGS="-DOS_${OTHER_OS}" ;; esac -if test x$use_pkgconfig = xyes; then - m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) - m4_ifdef([PKG_PROG_PKG_CONFIG], [ - PKG_PROG_PKG_CONFIG - if test x"$PKG_CONFIG" = "x"; then - AC_MSG_ERROR(pkg-config not found.) - fi - ]) -fi - if test x$use_comparison_tool != xno; then AC_SUBST(JAVA_COMPARISON_TOOL, $use_comparison_tool) fi @@ -456,6 +685,33 @@ if test x$use_lcov = xyes; then if test x$GENHTML = x; then AC_MSG_ERROR("lcov testing requested but genhtml not found") fi + + AC_MSG_CHECKING([whether compiler is Clang]) + AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ + #if defined(__clang__) && defined(__llvm__) + // Compiler is Clang + #else + # error Compiler is not Clang + #endif + ]])],[ + AC_MSG_RESULT([yes]) + if test x$LLVM_COV = x; then + AC_MSG_ERROR([lcov testing requested but llvm-cov not found]) + fi + COV_TOOL="$LLVM_COV gcov" + ],[ + AC_MSG_RESULT([no]) + if test x$GCOV = x; then + AC_MSG_ERROR([lcov testing requested but gcov not found]) + fi + COV_TOOL="$GCOV" + ]) + AC_SUBST(COV_TOOL) + AC_SUBST(COV_TOOL_WRAPPER, "cov_tool_wrapper.sh") + LCOV="$LCOV --gcov-tool $(pwd)/$COV_TOOL_WRAPPER" + + AX_CHECK_LINK_FLAG([[--coverage]], [LDFLAGS="$LDFLAGS --coverage"], + [AC_MSG_ERROR("lcov testing requested but --coverage linker flag does not work")]) if test x$use_comparison_tool = x; then AC_MSG_ERROR("lcov testing requested but comparison tool was not specified") fi @@ -464,6 +720,7 @@ if test x$use_lcov = xyes; then [AC_MSG_ERROR("lcov testing requested but --coverage linker flag does not work")]) AX_CHECK_COMPILE_FLAG([--coverage],[CXXFLAGS="$CXXFLAGS --coverage"], [AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")]) + CXXFLAGS="$CXXFLAGS -Og" fi dnl Check for endianness @@ -472,11 +729,11 @@ AC_C_BIGENDIAN dnl Check for pthread compile/link requirements AX_PTHREAD -# The following macro will add the necessary defines to bitcoin-config.h, but -# they also need to be passed down to any subprojects. Pull the results out of -# the cache and add them to CPPFLAGS. +dnl The following macro will add the necessary defines to bitcoin-config.h, but +dnl they also need to be passed down to any subprojects. Pull the results out of +dnl the cache and add them to CPPFLAGS. AC_SYS_LARGEFILE -# detect POSIX or GNU variant of strerror_r +dnl detect POSIX or GNU variant of strerror_r AC_FUNC_STRERROR_R if test x$ac_cv_sys_file_offset_bits != x && @@ -516,53 +773,106 @@ if test x$use_glibc_compat != xno; then [ fdelt_type="long int"]) AC_MSG_RESULT($fdelt_type) AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=__divmoddi4]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=__divmoddi4"]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=log2f]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=log2f"]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=glob]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=glob"]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=log]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=log"]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=pow]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=pow"]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=exp]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=exp"]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=explicit_bzero]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=explicit_bzero"]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=fcntl]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=fcntl"]) + case $host in + # Need to add glob64 for 32bit builds + i?86-* | arm*) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=glob64]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=glob64"]) + AX_CHECK_LINK_FLAG([[-Wl,--wrap=fcntl64]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=fcntl64"]) + ;; + esac else AC_SEARCH_LIBS([clock_gettime],[rt]) fi if test x$TARGET_OS != xwindows; then - # All windows code is PIC, forcing it on just adds useless compile warnings + dnl All windows code is PIC, forcing it on just adds useless compile warnings AX_CHECK_COMPILE_FLAG([-fPIC],[PIC_FLAGS="-fPIC"]) fi +dnl All versions of gcc that we commonly use for building are subject to bug +dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90348. To work around that, set +dnl -fstack-reuse=none for all gcc builds. (Only gcc understands this flag) +AX_CHECK_COMPILE_FLAG([-fstack-reuse=none],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-reuse=none"]) if test x$use_hardening != xno; then + use_hardening=yes AX_CHECK_COMPILE_FLAG([-Wstack-protector],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wstack-protector"]) AX_CHECK_COMPILE_FLAG([-fstack-protector-all],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-protector-all"]) - AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[ - AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[ - HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -U_FORTIFY_SOURCE" - ]) - HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2" - ]) + dnl -fcf-protection used with Clang 7 causes ld to emit warnings: + dnl ld: error: ... + dnl Use CHECK_LINK_FLAG & --fatal-warnings to ensure we won't use the flag in this case. + AX_CHECK_LINK_FLAG([-fcf-protection=full],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fcf-protection=full"],, [[$LDFLAG_WERROR]]) - AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"]) - AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"]) - AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"]) - AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"]) - AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"]) + case $host in + *mingw*) + dnl stack-clash-protection doesn't currently work, and likely should just be skipped for Windows. + dnl See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 for more details. + ;; + *) + AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-clash-protection"], [], [$CXXFLAG_WERROR]) + ;; + esac - if test x$TARGET_OS != xwindows; then - AX_CHECK_COMPILE_FLAG([-fPIE],[PIE_FLAGS="-fPIE"]) - AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"]) + + dnl When enable_debug is yes, all optimizations are disabled. + dnl However, FORTIFY_SOURCE requires that there is some level of optimization, otherwise it does nothing and just creates a compiler warning. + dnl Since FORTIFY_SOURCE is a no-op without optimizations, do not enable it when enable_debug is yes. + if test x$enable_debug != xyes; then + AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[ + AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[ + HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -U_FORTIFY_SOURCE" + ]) + HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2" + ]) fi + AX_CHECK_LINK_FLAG([[-Wl,--enable-reloc-section]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--enable-reloc-section"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,-z,separate-code]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,separate-code"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-fPIE -pie]], [PIE_FLAGS="-fPIE"; HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"],, [[$CXXFLAG_WERROR]]) + case $host in *mingw*) - AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(lib missing)) + AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(libssp missing)) ;; esac fi -dnl this flag screws up non-darwin gcc even when the check fails. special-case it. +dnl These flags are specific to ld64, and may cause issues with other linkers. +dnl For example: GNU ld will interpret -dead_strip as -de and then try and use +dnl "ad_strip" as the symbol for the entry point. if test x$TARGET_OS = xdarwin; then - AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) + AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,-dead_strip_dylibs]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip_dylibs"],, [[$LDFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,-bind_at_load]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-bind_at_load"],, [[$LDFLAG_WERROR]]) fi -AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) +AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h sys/sysctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h]) +AC_CHECK_DECLS([getifaddrs, freeifaddrs],[CHECK_SOCKET],, + [#include + #include ] +) AC_CHECK_DECLS([strnlen]) +dnl These are used for daemonization in blackmored +AC_CHECK_DECLS([fork]) +AC_CHECK_DECLS([setsid]) + +AC_CHECK_DECLS([pipe2]) + AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,, [#if HAVE_ENDIAN_H #include @@ -575,21 +885,61 @@ AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,, #include #endif]) -dnl Check for MSG_NOSIGNAL -AC_MSG_CHECKING(for MSG_NOSIGNAL) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[ int f = MSG_NOSIGNAL; ]])], - [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MSG_NOSIGNAL, 1,[Define this symbol if you have MSG_NOSIGNAL]) ], +AC_MSG_CHECKING(for __builtin_clzl) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ + (void) __builtin_clzl(0); + ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_BUILTIN_CLZL, 1, [Define this symbol if you have __builtin_clzl])], [ AC_MSG_RESULT(no)] ) -AC_MSG_CHECKING([for visibility attribute]) -AC_LINK_IFELSE([AC_LANG_SOURCE([ - int foo_def( void ) __attribute__((visibility("default"))); +AC_MSG_CHECKING(for __builtin_clzll) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ + (void) __builtin_clzll(0); + ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_BUILTIN_CLZLL, 1, [Define this symbol if you have __builtin_clzll])], + [ AC_MSG_RESULT(no)] +) + +dnl Check for malloc_info (for memory statistics information in getmemoryinfo) +AC_MSG_CHECKING(for getmemoryinfo) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ int f = malloc_info(0, NULL); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MALLOC_INFO, 1,[Define this symbol if you have malloc_info]) ], + [ AC_MSG_RESULT(no)] +) + +dnl Check for mallopt(M_ARENA_MAX) (to set glibc arenas) +AC_MSG_CHECKING(for mallopt M_ARENA_MAX) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ mallopt(M_ARENA_MAX, 1); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MALLOPT_ARENA_MAX, 1,[Define this symbol if you have mallopt with M_ARENA_MAX]) ], + [ AC_MSG_RESULT(no)] +) + +dnl Check for posix_fallocate +AC_MSG_CHECKING(for posix_fallocate) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + // same as in src/util/system.cpp + #ifdef __linux__ + #ifdef _POSIX_C_SOURCE + #undef _POSIX_C_SOURCE + #endif + #define _POSIX_C_SOURCE 200112L + #endif // __linux__ + #include ]], + [[ int f = posix_fallocate(0, 0, 0); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_POSIX_FALLOCATE, 1,[Define this symbol if you have posix_fallocate]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING([for default visibility attribute]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + int foo(void) __attribute__((visibility("default"))); int main(){} ])], [ - AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE,1,[Define if the visibility attribute is supported.]) + AC_DEFINE(HAVE_DEFAULT_VISIBILITY_ATTRIBUTE,1,[Define if the visibility attribute is supported.]) AC_MSG_RESULT(yes) ], [ @@ -600,11 +950,223 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([ ] ) -if test x$use_reduce_exports = xyes; then - AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], - [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) +AC_MSG_CHECKING([for dllexport attribute]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + __declspec(dllexport) int foo(void); + int main(){} + ])], + [ + AC_DEFINE(HAVE_DLLEXPORT_ATTRIBUTE,1,[Define if the dllexport attribute is supported.]) + AC_MSG_RESULT(yes) + ], + [AC_MSG_RESULT(no)] +) + +dnl thread_local is currently disabled when building with glibc back compat. +dnl Our minimum supported glibc is 2.17, however support for thread_local +dnl did not arrive in glibc until 2.18. +if test "x$use_thread_local" = xyes || { test "x$use_thread_local" = xauto && test "x$use_glibc_compat" = xno; }; then + TEMP_LDFLAGS="$LDFLAGS" + LDFLAGS="$TEMP_LDFLAGS $PTHREAD_CFLAGS" + AC_MSG_CHECKING([for thread_local support]) + AC_LINK_IFELSE([AC_LANG_SOURCE([ + #include + static thread_local int foo = 0; + static void run_thread() { foo++;} + int main(){ + for(int i = 0; i < 10; i++) { std::thread(run_thread).detach();} + return foo; + } + ])], + [ + case $host in + *mingw*) + dnl mingw32's implementation of thread_local has also been shown to behave + dnl erroneously under concurrent usage; see: + dnl https://gist.github.com/jamesob/fe9a872051a88b2025b1aa37bfa98605 + AC_MSG_RESULT(no) + ;; + *freebsd*) + dnl FreeBSD's implementation of thread_local is also buggy (per + dnl https://groups.google.com/d/msg/bsdmailinglist/22ncTZAbDp4/Dii_pII5AwAJ) + AC_MSG_RESULT(no) + ;; + *) + AC_DEFINE(HAVE_THREAD_LOCAL,1,[Define if thread_local is supported.]) + AC_MSG_RESULT(yes) + ;; + esac + ], + [ + AC_MSG_RESULT(no) + ] + ) + LDFLAGS="$TEMP_LDFLAGS" fi +dnl check for gmtime_r(), fallback to gmtime_s() if that is unavailable +dnl fail if neither are available. +AC_MSG_CHECKING(for gmtime_r) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ gmtime_r((const time_t *) nullptr, (struct tm *) nullptr); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GMTIME_R, 1, [Define this symbol if gmtime_r is available]) ], + [ AC_MSG_RESULT(no); + AC_MSG_CHECKING(for gmtime_s); + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ gmtime_s((struct tm *) nullptr, (const time_t *) nullptr); ]])], + [ AC_MSG_RESULT(yes)], + [ AC_MSG_RESULT(no); AC_MSG_ERROR(Both gmtime_r and gmtime_s are unavailable) ] + ) + ] +) + +dnl Check for different ways of gathering OS randomness +AC_MSG_CHECKING(for Linux getrandom syscall) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + #include + #include ]], + [[ syscall(SYS_getrandom, nullptr, 32, 0); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYS_GETRANDOM, 1,[Define this symbol if the Linux getrandom system call is available]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING(for getentropy) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ getentropy(nullptr, 32) ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GETENTROPY, 1,[Define this symbol if the BSD getentropy system call is available]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING(for getentropy via random.h) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + #include ]], + [[ getentropy(nullptr, 32) ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GETENTROPY_RAND, 1,[Define this symbol if the BSD getentropy system call is available with sys/random.h]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING(for sysctl) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + #include ]], + [[ #ifdef __linux__ + #error "Don't use sysctl on Linux, it's deprecated even when it works" + #endif + sysctl(nullptr, 2, nullptr, nullptr, nullptr, 0); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSCTL, 1,[Define this symbol if the BSD sysctl() is available]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING(for sysctl KERN_ARND) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + #include ]], + [[ #ifdef __linux__ + #error "Don't use sysctl on Linux, it's deprecated even when it works" + #endif + static int name[2] = {CTL_KERN, KERN_ARND}; + sysctl(name, 2, nullptr, nullptr, nullptr, 0); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSCTL_ARND, 1,[Define this symbol if the BSD sysctl(KERN_ARND) is available]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING(for if type char equals int8_t) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + #include ]], + [[ static_assert(std::is_same::value, ""); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(CHAR_EQUALS_INT8, 1,[Define this symbol if type char equals int8_t]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING(for fdatasync) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ fdatasync(0); ]])], + [ AC_MSG_RESULT(yes); HAVE_FDATASYNC=1 ], + [ AC_MSG_RESULT(no); HAVE_FDATASYNC=0 ] +) +AC_DEFINE_UNQUOTED([HAVE_FDATASYNC], [$HAVE_FDATASYNC], [Define to 1 if fdatasync is available.]) + +AC_MSG_CHECKING(for F_FULLFSYNC) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ fcntl(0, F_FULLFSYNC, 0); ]])], + [ AC_MSG_RESULT(yes); HAVE_FULLFSYNC=1 ], + [ AC_MSG_RESULT(no); HAVE_FULLFSYNC=0 ] +) + +AC_MSG_CHECKING(for O_CLOEXEC) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ open("", O_CLOEXEC); ]])], + [ AC_MSG_RESULT(yes); HAVE_O_CLOEXEC=1 ], + [ AC_MSG_RESULT(no); HAVE_O_CLOEXEC=0 ] +) +AC_DEFINE_UNQUOTED([HAVE_O_CLOEXEC], [$HAVE_O_CLOEXEC], [Define to 1 if O_CLOEXEC flag is available.]) + +dnl crc32c platform checks +AC_MSG_CHECKING(for __builtin_prefetch) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ + char data = 0; + const char* address = &data; + __builtin_prefetch(address, 0, 0); + ]])], + [ AC_MSG_RESULT(yes); HAVE_BUILTIN_PREFETCH=1 ], + [ AC_MSG_RESULT(no); HAVE_BUILTIN_PREFETCH=0 ] +) + +AC_MSG_CHECKING(for _mm_prefetch) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + char data = 0; + const char* address = &data; + _mm_prefetch(address, _MM_HINT_NTA); + ]])], + [ AC_MSG_RESULT(yes); HAVE_MM_PREFETCH=1 ], + [ AC_MSG_RESULT(no); HAVE_MM_PREFETCH=0 ] +) + +AC_MSG_CHECKING(for strong getauxval support in the system headers) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + #include + ]], [[ + getauxval(AT_HWCAP); + ]])], + [ AC_MSG_RESULT(yes); HAVE_STRONG_GETAUXVAL=1; AC_DEFINE(HAVE_STRONG_GETAUXVAL, 1, [Define this symbol to build code that uses getauxval)]) ], + [ AC_MSG_RESULT(no); HAVE_STRONG_GETAUXVAL=0 ] +) + +AC_MSG_CHECKING(for weak getauxval support in the compiler) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #ifdef __linux__ + unsigned long getauxval(unsigned long type) __attribute__((weak)); + #define AT_HWCAP 16 + #endif + ]], [[ + getauxval(AT_HWCAP); + ]])], + [ AC_MSG_RESULT(yes); HAVE_WEAK_GETAUXVAL=1; AC_DEFINE(HAVE_WEAK_GETAUXVAL, 1, [Define this symbol to build code that uses getauxval (weak linking)]) ], + [ AC_MSG_RESULT(no); HAVE_WEAK_GETAUXVAL=0 ] +) + +AC_MSG_CHECKING([for std::system]) +AC_LINK_IFELSE( + [ AC_LANG_PROGRAM( + [[ #include ]], + [[ int nErr = std::system(""); ]] + )], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STD__SYSTEM, 1, Define to 1 if std::system is available.)], + [ AC_MSG_RESULT(no) ] +) + +AC_MSG_CHECKING([for ::_wsystem]) +AC_LINK_IFELSE( + [ AC_LANG_PROGRAM( + [[ ]], + [[ int nErr = ::_wsystem(""); ]] + )], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_WSYSTEM, 1, Define to 1 if ::wsystem is available.)], + [ AC_MSG_RESULT(no) ] +) + +AC_DEFINE([HAVE_SYSTEM], [HAVE_STD__SYSTEM || HAVE_WSYSTEM], [std::system or ::wsystem]) + LEVELDB_CPPFLAGS= LIBLEVELDB= LIBMEMENV= @@ -613,6 +1175,24 @@ AC_SUBST(LEVELDB_CPPFLAGS) AC_SUBST(LIBLEVELDB) AC_SUBST(LIBMEMENV) +dnl SUPPRESSED_CPPFLAGS=SUPPRESS_WARNINGS([$SOME_CPPFLAGS]) +dnl Replace -I with -isystem in $SOME_CPPFLAGS to suppress warnings from +dnl headers from its include directories and return the result. +dnl See -isystem documentation: +dnl https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html +dnl https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-isystem-directory +dnl Do not change "-I/usr/include" to "-isystem /usr/include" because that +dnl is not necessary (/usr/include is already a system directory) and because +dnl it would break GCC's #include_next. +AC_DEFUN([SUPPRESS_WARNINGS], + [$(echo $1 |${SED} -E -e 's/(^| )-I/\1-isystem /g' -e 's;-isystem /usr/include([/ ]|$);-I/usr/include\1;g')]) + + AX_CHECK_PREPROC_FLAG([-DABORT_ON_FAILED_ASSUME],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DABORT_ON_FAILED_ASSUME"]],,[[$CXXFLAG_WERROR]]) + +BITCOIN_QT_INIT + +dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus +BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt5]) if test x$enable_wallet != xno; then dnl Check for libdb_cxx only if wallet enabled BITCOIN_FIND_BDB62 @@ -622,60 +1202,68 @@ dnl Check for libminiupnpc (optional) if test x$use_upnp != xno; then AC_CHECK_HEADERS( [miniupnpc/miniwget.h miniupnpc/miniupnpc.h miniupnpc/upnpcommands.h miniupnpc/upnperrors.h], - [AC_CHECK_LIB([miniupnpc], [main],[MINIUPNPC_LIBS=-lminiupnpc], [have_miniupnpc=no])], + [AC_CHECK_LIB([miniupnpc], [upnpDiscover], [MINIUPNPC_LIBS=-lminiupnpc], [have_miniupnpc=no])], [have_miniupnpc=no] ) +dnl The minimum supported miniUPnPc API version is set to 10. This keeps compatibility +dnl with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages. +if test x$have_miniupnpc != xno; then + AC_MSG_CHECKING([whether miniUPnPc API version is supported]) + AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + #if MINIUPNPC_API_VERSION >= 10 + // Everything is okay + #else + # error miniUPnPc API version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + AC_MSG_WARN([miniUPnPc API version < 10 is unsupported, disabling UPnP support.]) + have_miniupnpc=no + ]) +fi fi - -BITCOIN_QT_INIT - -dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus -BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt5]) if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then - use_boost=no + use_boost=no else - use_boost=yes + use_boost=yes fi if test x$use_boost = xyes; then -dnl Minimum required Boost version -define(MINIMUM_REQUIRED_BOOST, 1.47.0) - -dnl Check for boost libs -AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) + dnl Check for Boost headers + AX_BOOST_BASE([1.64.0],[],[AC_MSG_ERROR([Boost is not available!])]) + if test x$want_boost = xno; then + AC_MSG_ERROR([[only libbitcoinconsensus can be built without boost]]) +fi AX_BOOST_SYSTEM AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS AX_BOOST_THREAD +AX_BOOST_RANDOM AX_BOOST_CHRONO - -if test x$use_reduce_exports = xyes; then - AC_MSG_CHECKING([for working boost reduced exports]) - TEMP_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS" - AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= 104900 - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ - AC_MSG_RESULT(yes) - ],[ - AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.]) - ]) - CPPFLAGS="$TEMP_CPPFLAGS" +if test x$suppress_external_warnings != xno; then + BOOST_CPPFLAGS=SUPPRESS_WARNINGS($BOOST_CPPFLAGS) fi + +dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic +dnl counter implementations. In 1.63 and later the std::atomic approach is default. +m4_pattern_allow(DBOOST_AC_USE_STD_ATOMIC) dnl otherwise it's treated like a macro +BOOST_CPPFLAGS="-DBOOST_SP_USE_STD_ATOMIC -DBOOST_AC_USE_STD_ATOMIC $BOOST_CPPFLAGS" + +BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB $BOOST_RANDOM_LIB" fi +dnl Check for reduced exports if test x$use_reduce_exports = xyes; then - CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS" - AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"]) + AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[CXXFLAGS="$CXXFLAGS -fvisibility=hidden"], + [AC_MSG_ERROR([Cannot set hidden symbol visibility. Use --disable-reduce-exports.])],[[$CXXFLAG_WERROR]]) + AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]],[RELDFLAGS="-Wl,--exclude-libs,ALL"],,[[$LDFLAG_WERROR]]) fi if test x$use_tests = xyes; then @@ -684,35 +1272,34 @@ if test x$use_tests = xyes; then AC_MSG_ERROR(hexdump is required for tests) fi - if test x$use_boost = xyes; then - AX_BOOST_UNIT_TEST_FRAMEWORK - - dnl Determine if -DBOOST_TEST_DYN_LINK is needed - AC_MSG_CHECKING([for dynamic linked boost test]) - TEMP_LIBS="$LIBS" - LIBS="$LIBS $BOOST_LDFLAGS $BOOST_UNIT_TEST_FRAMEWORK_LIB" - TEMP_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - AC_LINK_IFELSE([AC_LANG_SOURCE([ - #define BOOST_TEST_DYN_LINK - #define BOOST_TEST_MAIN - #include - - ])], - [AC_MSG_RESULT(yes)] - [TESTDEFS="$TESTDEFS -DBOOST_TEST_DYN_LINK"], - [AC_MSG_RESULT(no)]) - LIBS="$TEMP_LIBS" - CPPFLAGS="$TEMP_CPPFLAGS" + AX_BOOST_UNIT_TEST_FRAMEWORK + + dnl Determine if -DBOOST_TEST_DYN_LINK is needed + AC_MSG_CHECKING([for dynamic linked boost test]) + TEMP_LIBS="$LIBS" + LIBS="$LIBS $BOOST_LDFLAGS $BOOST_UNIT_TEST_FRAMEWORK_LIB" + TEMP_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + AC_LINK_IFELSE([AC_LANG_SOURCE([ + #define BOOST_TEST_DYN_LINK + #define BOOST_TEST_MAIN + #include + + ])], + [AC_MSG_RESULT(yes)] + [TESTDEFS="$TESTDEFS -DBOOST_TEST_DYN_LINK"], + [AC_MSG_RESULT(no)]) + LIBS="$TEMP_LIBS" + CPPFLAGS="$TEMP_CPPFLAGS" fi fi if test x$use_boost = xyes; then -BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" +BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB $BOOST_RANDOM_LIB" dnl If boost (prior to 1.57) was built without c++11, it emulated scoped enums @@ -803,130 +1390,93 @@ fi fi -if test x$use_pkgconfig = xyes; then - : dnl - m4_ifdef( - [PKG_CHECK_MODULES], - [ - PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) - PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) - BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])]) - if test x$use_qr != xno; then - BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) - fi - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then - PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)]) - if test x$TARGET_OS != xwindows; then - PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)]) - fi - fi +dnl openssl check - if test "x$use_zmq" = "xyes"; then - PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], - [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], - [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) - use_zmq=no]) - else - AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - fi - ] - ) +if test "x$pkg_openssl" = xyes; then + PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) + PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) else AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) - AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) +fi - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then - AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),) - AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing)) - if test x$TARGET_OS != xwindows; then - AC_CHECK_LIB([event_pthreads],[main],EVENT_PTHREADS_LIBS=-levent_pthreads,AC_MSG_ERROR(libevent_pthreads missing)) - fi - fi +dnl libevent check - if test "x$use_zmq" = "xyes"; then - AC_CHECK_HEADER([zmq.h], - [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], - [AC_MSG_WARN([zmq.h not found, disabling zmq support]) - use_zmq=no - AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) - AC_CHECK_LIB([zmq],[zmq_ctx_shutdown],ZMQ_LIBS=-lzmq, - [AC_MSG_WARN([libzmq >= 4.0 not found, disabling zmq support]) - use_zmq=no - AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) - else - AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) +if test x$build_bitcoin_cli$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench != xnonononono; then + PKG_CHECK_MODULES([EVENT], [libevent >= 2.0.21], [use_libevent=yes], [AC_MSG_ERROR([libevent version 2.0.21 or greater not found.])]) + if test x$TARGET_OS != xwindows; then + PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads >= 2.0.21],, [AC_MSG_ERROR([libevent_pthreads version 2.0.21 or greater not found.])]) fi +fi - if test "x$use_zmq" = "xyes"; then - dnl Assume libzmq was built for static linking - case $host in - *mingw*) - ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" - ;; - esac - fi +dnl QR Code encoding library check + +if test "x$use_qr" != xno; then + BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) +fi + +dnl ZMQ check + +if test "x$use_zmq" = xyes; then + PKG_CHECK_MODULES([ZMQ], [libzmq >= 4], + AC_DEFINE([ENABLE_ZMQ], [1], [Define to 1 to enable ZMQ functions]), + [AC_DEFINE([ENABLE_ZMQ], [0], [Define to 1 to enable ZMQ functions]) + AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) + use_zmq=no]) +else + AC_DEFINE_UNQUOTED([ENABLE_ZMQ], [0], [Define to 1 to enable ZMQ functions]) +fi + +if test "x$use_zmq" = xyes; then + dnl Assume libzmq was built for static linking + case $host in + *mingw*) + ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" + ;; + esac +fi BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) fi -fi - -save_CXXFLAGS="${CXXFLAGS}" -CXXFLAGS="${CXXFLAGS} ${CRYPTO_CFLAGS} ${SSL_CFLAGS}" -AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT -#include -]) -CXXFLAGS="${save_CXXFLAGS}" dnl univalue check need_bundled_univalue=yes - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then need_bundled_univalue=no else - -if test x$system_univalue != xno ; then - found_univalue=no - if test x$use_pkgconfig = xyes; then - : #NOP - m4_ifdef( - [PKG_CHECK_MODULES], - [ - PKG_CHECK_MODULES([UNIVALUE],[libunivalue],[found_univalue=yes],[true]) - ] - ) - else - AC_CHECK_HEADER([univalue.h],[ - AC_CHECK_LIB([univalue], [main],[ - UNIVALUE_LIBS=-lunivalue - found_univalue=yes - ],[true]) - ],[true]) + if test x$system_univalue != xno; then + PKG_CHECK_MODULES([UNIVALUE], [libunivalue >= 1.0.4], [found_univalue=yes], [found_univalue=no]) + if test x$found_univalue = xyes; then + system_univalue=yes + need_bundled_univalue=no + elif test x$system_univalue = xyes; then + AC_MSG_ERROR([univalue not found]) + else + system_univalue=no + fi fi - if test x$found_univalue = xyes ; then - system_univalue=yes - need_bundled_univalue=no - elif test x$system_univalue = xyes ; then - AC_MSG_ERROR([univalue not found]) - else - system_univalue=no + if test x$need_bundled_univalue = xyes; then + UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' + UNIVALUE_LIBS='univalue/libunivalue.la' fi fi -if test x$need_bundled_univalue = xyes ; then - UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' - UNIVALUE_LIBS='univalue/libunivalue.la' -fi +# These packages don't provide pkgconfig config files across all +# platforms, so we use older autoconf detection mechanisms: -fi +save_CXXFLAGS="${CXXFLAGS}" +CXXFLAGS="${CXXFLAGS} ${CRYPTO_CFLAGS} ${SSL_CFLAGS}" +AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT +#include +]) +CXXFLAGS="${save_CXXFLAGS}" AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) AC_SUBST(UNIVALUE_CFLAGS) @@ -934,11 +1484,19 @@ AC_SUBST(UNIVALUE_LIBS) BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) -AC_MSG_CHECKING([whether to build bitcoind]) +AC_MSG_CHECKING([whether to build blackmored]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) -AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)]) +AC_MSG_CHECKING([whether to build blackmore-cli]) +AM_CONDITIONAL([BUILD_BITCOIN_CLI], [test x$build_bitcoin_cli = xyes]) +AC_MSG_RESULT($build_bitcoin_cli) + +AC_MSG_CHECKING([whether to build blackmore-tx]) +AM_CONDITIONAL([BUILD_BITCOIN_TX], [test x$build_bitcoin_tx = xyes]) +AC_MSG_RESULT($build_bitcoin_tx) + +AC_MSG_CHECKING([whether to build utils (blackmore-cli blackmore-tx)]) AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) AC_MSG_RESULT($build_bitcoin_utils) @@ -966,9 +1524,10 @@ if test "x$use_ccache" != "xno"; then CXX="$ac_cv_path_CCACHE $CXX" fi AC_MSG_RESULT($use_ccache) -fi -if test "x$use_ccache" = "xyes"; then - AX_CHECK_PREPROC_FLAG([-Qunused-arguments],[CPPFLAGS="-Qunused-arguments $CPPFLAGS"]) + if test "x$use_ccache" = "xyes"; then + AX_CHECK_COMPILE_FLAG([-fdebug-prefix-map=A=B],[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -fdebug-prefix-map=\$(abs_srcdir)=."],,[[$CXXFLAG_WERROR]]) + AX_CHECK_PREPROC_FLAG([-fmacro-prefix-map=A=B],[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -fmacro-prefix-map=\$(abs_srcdir)=."],,[[$CXXFLAG_WERROR]]) + fi fi dnl enable wallet @@ -976,6 +1535,7 @@ AC_MSG_CHECKING([if wallet should be enabled]) if test x$enable_wallet != xno; then AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED([ENABLE_WALLET],[1],[Define to 1 to enable wallet functions]) + enable_wallet=yes else AC_MSG_RESULT(no) @@ -985,9 +1545,10 @@ dnl enable upnp support AC_MSG_CHECKING([whether to build with support for UPnP]) if test x$have_miniupnpc = xno; then if test x$use_upnp = xyes; then - AC_MSG_ERROR("UPnP requested but cannot be built. use --without-miniupnpc") + AC_MSG_ERROR("UPnP requested but cannot be built. Use --without-miniupnpc.") fi AC_MSG_RESULT(no) + use_upnp=no else if test x$use_upnp != xno; then AC_MSG_RESULT(yes) @@ -1022,18 +1583,16 @@ if test x$bitcoin_enable_qt != xno; then AC_MSG_CHECKING([whether to build GUI with support for QR codes]) if test x$have_qrencode = xno; then if test x$use_qr = xyes; then - AC_MSG_ERROR("QR support requested but cannot be built. use --without-qrencode") + AC_MSG_ERROR([QR support requested but cannot be built. Use --without-qrencode]) fi - AC_MSG_RESULT(no) + use_qr=no else if test x$use_qr != xno; then - AC_MSG_RESULT(yes) AC_DEFINE([USE_QRCODE],[1],[Define if QR support should be compiled in]) use_qr=yes - else - AC_MSG_RESULT(no) fi fi + AC_MSG_RESULT([$use_qr]) if test x$XGETTEXT = x; then AC_MSG_WARN("xgettext is required to update qt translations") @@ -1059,6 +1618,16 @@ else BUILD_TEST="" fi +AC_MSG_CHECKING([whether to enable sse2 instructions]) +if test x$use_sse2 != xno; then + AC_MSG_RESULT(yes) + AC_DEFINE([USE_SSE2],[1],[Define if SSE2 support should be compiled in]) + use_sse2=yes + CPPFLAGS="$CPPFLAGS -DUSE_SSE2=1" +else + AC_MSG_RESULT(no) +fi + AC_MSG_CHECKING([whether to reduce exports]) if test x$use_reduce_exports = xyes; then AC_MSG_RESULT([yes]) @@ -1072,6 +1641,7 @@ fi AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin]) +AM_CONDITIONAL([TARGET_LINUX], [test x$TARGET_OS = xlinux]) AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) @@ -1079,11 +1649,20 @@ AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes]) AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes]) AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes]) AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes]) +AM_CONDITIONAL([USE_SSE2], [test x$use_sse2 = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) +AM_CONDITIONAL([USE_LIBEVENT],[test x$use_libevent = xyes]) AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno]) AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) +AM_CONDITIONAL([ENABLE_SSE42],[test x$enable_sse42 = xyes]) +AM_CONDITIONAL([ENABLE_SSE41],[test x$enable_sse41 = xyes]) +AM_CONDITIONAL([ENABLE_AVX2],[test x$enable_avx2 = xyes]) +AM_CONDITIONAL([ENABLE_SHANI],[test x$enable_shani = xyes]) +AM_CONDITIONAL([ENABLE_ARM_CRC],[test x$enable_arm_crc = xyes]) +AM_CONDITIONAL([USE_ASM],[test x$use_asm = xyes]) +AM_CONDITIONAL([WORDS_BIGENDIAN],[test x$ac_cv_c_bigendian = xyes]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) @@ -1110,18 +1689,28 @@ AC_SUBST(BITCOIN_CLI_NAME) AC_SUBST(BITCOIN_TX_NAME) AC_SUBST(RELDFLAGS) +AC_SUBST(DEBUG_CPPFLAGS) +AC_SUBST(WARN_CXXFLAGS) +AC_SUBST(NOWARN_CXXFLAGS) +AC_SUBST(DEBUG_CXXFLAGS) +AC_SUBST(COMPAT_LDFLAGS) AC_SUBST(ERROR_CXXFLAGS) AC_SUBST(HARDENED_CXXFLAGS) AC_SUBST(HARDENED_CPPFLAGS) AC_SUBST(HARDENED_LDFLAGS) AC_SUBST(PIC_FLAGS) AC_SUBST(PIE_FLAGS) +AC_SUBST(SSE42_CXXFLAGS) +AC_SUBST(SSE41_CXXFLAGS) +AC_SUBST(AVX2_CXXFLAGS) +AC_SUBST(SHANI_CXXFLAGS) +AC_SUBST(ARM_CRC_CXXFLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) AC_SUBST(USE_UPNP) AC_SUBST(USE_QRCODE) +AC_SUBST(USE_SSE2) AC_SUBST(BOOST_LIBS) AC_SUBST(TESTDEFS) -AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) AC_SUBST(CRYPTO_LIBS) @@ -1131,10 +1720,19 @@ AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) +AC_SUBST(HAVE_GMTIME_R) +AC_SUBST(HAVE_FDATASYNC) +AC_SUBST(HAVE_FULLFSYNC) +AC_SUBST(HAVE_O_CLOEXEC) +AC_SUBST(HAVE_BUILTIN_PREFETCH) +AC_SUBST(HAVE_MM_PREFETCH) +AC_SUBST(HAVE_STRONG_GETAUXVAL) +AC_SUBST(HAVE_WEAK_GETAUXVAL) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) +AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])]) AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) dnl boost's m4 checks do something really nasty: they export these vars. As a @@ -1164,7 +1762,7 @@ if test x$need_bundled_univalue = xyes; then AC_CONFIG_SUBDIRS([src/univalue]) fi -ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery" +ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --with-bignum=no --enable-module-recovery --enable-module-ecdh" AC_CONFIG_SUBDIRS([src/secp256k1]) AC_OUTPUT @@ -1180,36 +1778,35 @@ case $host in ;; esac -dnl Replace the BUILDDIR path with the correct Windows path if compiling on Native Windows -case ${OS} in - *Windows*) - sed 's/BUILDDIR="\/\([[a-z]]\)/BUILDDIR="\1:/' qa/pull-tester/tests_config.py > qa/pull-tester/tests_config-2.py - mv qa/pull-tester/tests_config-2.py qa/pull-tester/tests_config.py - ;; -esac - -echo +echo echo "Options used to compile and link:" echo " with wallet = $enable_wallet" echo " with gui / qt = $bitcoin_enable_qt" if test x$bitcoin_enable_qt != xno; then - echo " qt version = $bitcoin_qt_got_major_vers" echo " with qr = $use_qr" fi +echo " pkg openssl = $pkg_openssl" echo " with zmq = $use_zmq" echo " with test = $use_tests" echo " with bench = $use_bench" echo " with upnp = $use_upnp" +dnl echo " with natpmp = $use_natpmp" +echo " use asm = $use_asm" +dnl echo " ebpf tracing = $have_sdt" +dnl echo " sanitizers = $use_sanitizers" +echo " scrypt sse2 = $use_sse2" echo " debug enabled = $enable_debug" +dnl echo " gprof enabled = $enable_gprof" echo " werror = $enable_werror" -echo +echo echo " target os = $TARGET_OS" -echo " build os = $BUILD_OS" +echo " build os = $build_os" echo echo " CC = $CC" -echo " CFLAGS = $CFLAGS" -echo " CPPFLAGS = $CPPFLAGS" +echo " CFLAGS = $PTHREAD_CFLAGS $CFLAGS" +echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" echo " CXX = $CXX" -echo " CXXFLAGS = $CXXFLAGS" -echo " LDFLAGS = $LDFLAGS" -echo +echo " CXXFLAGS = $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" +echo " LDFLAGS = $PTHREAD_LIBS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " ARFLAGS = $ARFLAGS" +echo diff --git a/contrib/builder-keys/README.md b/contrib/builder-keys/README.md new file mode 100644 index 0000000000..a271020603 --- /dev/null +++ b/contrib/builder-keys/README.md @@ -0,0 +1,23 @@ +## PGP keys of builders and Developers + +The file `keys.txt` contains fingerprints of the public keys of builders and +active developers. + +The associated keys are mainly used to sign git commits + +The most recent version of each pgp key can be found on most pgp key servers. + +Fetch the latest version from the key server to see if any key was revoked in +the meantime. +To fetch the latest version of all pgp keys in your gpg homedir, + +```sh +gpg --refresh-keys +``` + +To fetch keys of builders and active developers, feed the list of fingerprints +of the primary keys into gpg: + +```sh +while read fingerprint keyholder_name; do gpg --keyserver hkps://keys.openpgp.org --recv-keys ${fingerprint}; done < ./keys.txt +``` diff --git a/contrib/builder-keys/keys.txt b/contrib/builder-keys/keys.txt new file mode 100644 index 0000000000..045d207684 --- /dev/null +++ b/contrib/builder-keys/keys.txt @@ -0,0 +1,2 @@ +959E1836C72EE404A161DC61A8D82124A918C480 Michel van Kessel (michelvankessel) + diff --git a/contrib/debian/README.md b/contrib/debian/README.md deleted file mode 100644 index fab9cc2381..0000000000 --- a/contrib/debian/README.md +++ /dev/null @@ -1,21 +0,0 @@ - -Debian -==================== -This directory contains files used to package bitcoind/bitcoin-qt -for Debian-based Linux systems. If you compile bitcoind/bitcoin-qt yourself, there are some useful files here. - -## bitcoin: URI support ## - - -bitcoin-qt.desktop (Gnome / Open Desktop) -To install: - - sudo desktop-file-install bitcoin-qt.desktop - sudo update-desktop-database - -If you build yourself, you will either need to modify the paths in -the .desktop file or copy or symlink your bitcoin-qt binary to `/usr/bin` -and the `../../share/pixmaps/bitcoin128.png` to `/usr/share/pixmaps` - -bitcoin-qt.protocol (KDE) - diff --git a/contrib/debian/bitcoin-qt.desktop b/contrib/debian/bitcoin-qt.desktop deleted file mode 100644 index 593d7584ab..0000000000 --- a/contrib/debian/bitcoin-qt.desktop +++ /dev/null @@ -1,13 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Name=Bitcoin Core -Comment=Connect to the Bitcoin P2P Network -Comment[de]=Verbinde mit dem Bitcoin peer-to-peer Netzwerk -Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair -Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi -Exec=bitcoin-qt %u -Terminal=false -Type=Application -Icon=bitcoin128 -MimeType=x-scheme-handler/bitcoin; -Categories=Office;Finance; diff --git a/contrib/debian/bitcoin-qt.install b/contrib/debian/bitcoin-qt.install deleted file mode 100644 index e0b32373be..0000000000 --- a/contrib/debian/bitcoin-qt.install +++ /dev/null @@ -1,6 +0,0 @@ -usr/local/bin/bitcoin-qt usr/bin -share/pixmaps/bitcoin32.xpm usr/share/pixmaps -share/pixmaps/bitcoin16.xpm usr/share/pixmaps -share/pixmaps/bitcoin128.png usr/share/pixmaps -debian/bitcoin-qt.desktop usr/share/applications -debian/bitcoin-qt.protocol usr/share/kde4/services/ diff --git a/contrib/debian/bitcoin-qt.lintian-overrides b/contrib/debian/bitcoin-qt.lintian-overrides deleted file mode 100644 index 7fb230eca8..0000000000 --- a/contrib/debian/bitcoin-qt.lintian-overrides +++ /dev/null @@ -1,2 +0,0 @@ -# Linked code is Expat - only Debian packaging is GPL-2+ -bitcoin-qt: possible-gpl-code-linked-with-openssl diff --git a/contrib/debian/bitcoin-qt.protocol b/contrib/debian/bitcoin-qt.protocol deleted file mode 100644 index 014588d536..0000000000 --- a/contrib/debian/bitcoin-qt.protocol +++ /dev/null @@ -1,11 +0,0 @@ -[Protocol] -exec=bitcoin-qt '%u' -protocol=bitcoin -input=none -output=none -helper=true -listing= -reading=false -writing=false -makedir=false -deleting=false diff --git a/contrib/debian/bitcoin-tx.bash-completion b/contrib/debian/bitcoin-tx.bash-completion deleted file mode 100644 index 7acb0b0aea..0000000000 --- a/contrib/debian/bitcoin-tx.bash-completion +++ /dev/null @@ -1 +0,0 @@ -contrib/bitcoin-tx.bash-completion bitcoin-tx diff --git a/contrib/debian/bitcoin-tx.install b/contrib/debian/bitcoin-tx.install deleted file mode 100644 index 2c21052a68..0000000000 --- a/contrib/debian/bitcoin-tx.install +++ /dev/null @@ -1 +0,0 @@ -usr/local/bin/bitcoin-tx usr/bin diff --git a/contrib/debian/bitcoind.bash-completion b/contrib/debian/bitcoind.bash-completion deleted file mode 100644 index 5c69d78fbb..0000000000 --- a/contrib/debian/bitcoind.bash-completion +++ /dev/null @@ -1,2 +0,0 @@ -contrib/bitcoind.bash-completion bitcoind -contrib/bitcoin-cli.bash-completion bitcoin-cli diff --git a/contrib/debian/bitcoind.examples b/contrib/debian/bitcoind.examples deleted file mode 100644 index 4ded67d98e..0000000000 --- a/contrib/debian/bitcoind.examples +++ /dev/null @@ -1 +0,0 @@ -debian/examples/bitcoin.conf diff --git a/contrib/debian/bitcoind.install b/contrib/debian/bitcoind.install deleted file mode 100644 index 798ea851f6..0000000000 --- a/contrib/debian/bitcoind.install +++ /dev/null @@ -1,2 +0,0 @@ -usr/local/bin/bitcoind usr/bin -usr/local/bin/bitcoin-cli usr/bin diff --git a/contrib/debian/bitcoind.lintian-overrides b/contrib/debian/bitcoind.lintian-overrides deleted file mode 100644 index 3f9f140bd8..0000000000 --- a/contrib/debian/bitcoind.lintian-overrides +++ /dev/null @@ -1,2 +0,0 @@ -# Linked code is Expat - only Debian packaging is GPL-2+ -bitcoind: possible-gpl-code-linked-with-openssl diff --git a/contrib/debian/bitcoind.manpages b/contrib/debian/bitcoind.manpages deleted file mode 100644 index 6d3e683855..0000000000 --- a/contrib/debian/bitcoind.manpages +++ /dev/null @@ -1,3 +0,0 @@ -debian/manpages/bitcoind.1 -debian/manpages/bitcoin.conf.5 -debian/manpages/bitcoin-cli.1 diff --git a/contrib/debian/changelog b/contrib/debian/changelog deleted file mode 100644 index 110bfe03ef..0000000000 --- a/contrib/debian/changelog +++ /dev/null @@ -1,459 +0,0 @@ -bitcoin (0.11.0-precise1) precise; urgency=medium - - * New upstream release. - - -- Matt Corallo (BlueMatt) Tue, 14 Jul 2015 14:39:00 -1000 - -bitcoin (0.10.2-precise1) precise; urgency=medium - - * New upstream release. - - -- Matt Corallo (BlueMatt) Mon, 29 Jun 2015 17:33:00 -1000 - -bitcoin (0.10.1-precise3) precise; urgency=medium - - * Fix build dep (include python). - - -- Matt Corallo (BlueMatt) Tue, 5 May 2015 09:28:00 -1000 - -bitcoin (0.10.1-precise2) precise; urgency=medium - - * Fix miniupnpc dep. - - -- Matt Corallo (BlueMatt) Tue, 5 May 2015 00:33:00 -1000 - -bitcoin (0.10.1-precise1) precise; urgency=medium - - * New upstream release. - - -- Matt Corallo (BlueMatt) Tue, 5 May 2015 00:07:00 -1000 - -bitcoin (0.10.0-precise1) precise; urgency=medium - - * New upstream releases. - - -- Matt Corallo (BlueMatt) Wed, 18 Feb 2015 13:22:00 -1000 - -bitcoin (0.9.4-precise1) precise; urgency=high - - * New upstream releases. - - -- Matt Corallo (laptop - only while traveling) Mon, 12 Jan 2015 23:30:00 -1000 - -bitcoin (0.9.3-precise1) precise; urgency=medium - - * New upstream releases. - - -- Matt Corallo (BlueMatt) Fri, 26 Sep 2014 12:01:00 -0700 - -bitcoin (0.9.1-precise1) precise; urgency=medium - - * New upstream release. - * Backport pull #4019 - - -- Matt Corallo Sat, 19 Apr 2014 17:29:00 -0400 - -bitcoin (0.9.0-precise1) precise; urgency=medium - - * New upstream release. - - -- Matt Corallo Thu, 20 Mar 2014 13:10:00 -0400 - -bitcoin (0.8.6-precise1) precise; urgency=medium - - * New upstream release. - * Make .desktop paths non-fixed (suggested by prusnak@github) - - -- Matt Corallo Fri, 13 Dec 2013 13:31:00 -0400 - -bitcoin (0.8.5-precise1) precise; urgency=medium - - * New upstream release. - - -- Matt Corallo Sun, 15 Sep 2013 14:02:00 -0400 - -bitcoin (0.8.4-precise1) precise; urgency=medium - - * New upstream release. - - -- Matt Corallo Wed, 4 Sep 2013 10:25:00 -0400 - -bitcoin (0.8.3-natty1) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Wed, 26 Jun 2013 00:18:00 +0100 - -bitcoin (0.8.2-natty1) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Wed, 29 Mar 2013 23:23:00 +0100 - -bitcoin (0.8.1-natty3) natty; urgency=low - - * New pixmaps - - -- Jonas Schnelli Mon, 13 May 2013 16:14:00 +0100 - -bitcoin (0.8.1-natty2) natty; urgency=low - - * Remove dumb broken launcher script - - -- Matt Corallo Sun, 24 Mar 2013 20:01:00 -0400 - -bitcoin (0.8.1-natty1) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Tue, 19 Mar 2013 13:03:00 -0400 - -bitcoin (0.8.0-natty1) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Sat, 23 Feb 2013 16:01:00 -0500 - -bitcoin (0.7.2-natty1) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Sat, 15 Dec 2012 10:59:00 -0400 - -bitcoin (0.7.1-natty1) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Wed, 24 Oct 2012 15:06:00 -0400 - -bitcoin (0.7.0-natty1) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Mon, 17 Sep 2012 13:45:00 +0200 - -bitcoin (0.6.3-natty1) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Mon, 25 Jun 2012 23:47:00 +0200 - -bitcoin (0.6.2-natty1) natty; urgency=low - - * Update package description and launch scripts. - - -- Matt Corallo Sat, 2 Jun 2012 16:41:00 +0200 - -bitcoin (0.6.2-natty0) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Tue, 8 May 2012 16:27:00 -0500 - -bitcoin (0.6.1-natty0) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Sun, 6 May 2012 20:09:00 -0500 - -bitcoin (0.6.0-natty0) natty; urgency=low - - * New upstream release. - * Add GNOME/KDE support for bitcoin-qt's bitcoin: URI support. - Thanks to luke-jr for the KDE .protocol file. - - -- Matt Corallo Sat, 31 Mar 2012 15:35:00 -0500 - -bitcoin (0.5.3-natty1) natty; urgency=low - - * Mark for upload to PPA. - - -- Matt Corallo Wed, 14 Mar 2012 23:06:00 -0400 - -bitcoin (0.5.3-natty0) natty; urgency=low - - * New upstream release. - - -- Luke Dashjr Tue, 10 Jan 2012 15:57:00 -0500 - -bitcoin (0.5.2-natty1) natty; urgency=low - - * Remove mentions on anonymity in package descriptions and manpage. - These should never have been there, bitcoin isn't anonymous without - a ton of work that virtually no users will ever be willing and - capable of doing - - -- Matt Corallo Sat, 7 Jan 2012 13:37:00 -0500 - -bitcoin (0.5.2-natty0) natty; urgency=low - - * New upstream release. - - -- Luke Dashjr Fri, 16 Dec 2011 17:57:00 -0500 - -bitcoin (0.5.1-natty0) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Fri, 16 Dec 2011 13:27:00 -0500 - -bitcoin (0.5.0-natty0) natty; urgency=low - - * New upstream release. - - -- Matt Corallo Mon, 21 Nov 2011 11:32:00 -0500 - -bitcoin (0.5.0~rc7-natty0) natty; urgency=low - - * New upstream release candidate. - - -- Matt Corallo Sun, 20 Nov 2011 17:08:00 -0500 - -bitcoin (0.5.0~rc3-natty0) natty; urgency=low - - * New upstream release candidate. - * Don't set rpcpassword for bitcoin-qt. - - -- Matt Corallo Tue, 8 Nov 2011 11:56:00 -0400 - -bitcoin (0.5.0~rc1-natty1) natty; urgency=low - - * Add test_bitcoin to build test - * Fix clean - * Remove unnecessary build-dependancies - - -- Matt Corallo Wed, 26 Oct 2011 14:37:18 -0400 - -bitcoin (0.5.0~rc1-natty0) natty; urgency=low - - * Mark for natty - * Fix broken build - * Fix copyright listing - * Remove bitcoin: URL handler until bitcoin actually has support for it (Oops) - - -- Matt Corallo Wed, 26 Oct 2011 14:37:18 -0400 - -bitcoin (0.5.0~rc1-2) experimental; urgency=low - - * Add bitcoin-qt - - -- Matt Corallo Tue, 25 Oct 2011 15:24:18 -0400 - -bitcoin (0.5.0~rc1-1) experimental; urgency=low - - * New upstream prerelease. - * Add Github as alternate upstream source in watch file. - * Stop build-depending on libcrypto++-dev, and drop patch 1000: - Upstream no longer use crypto++. - * Drop patch 1003: Upstream builds dynamic by default now. - * Update copyright file: Drop notes on longer included sources. - - -- Jonas Smedegaard Fri, 14 Oct 2011 00:16:18 +0200 - -bitcoin (0.4.0-1) unstable; urgency=low - - * New upstream release. - * Stop repackaging source tarballs: No DFSG-violating stripping left. - * Update copyright file: - + Add Github URL to Source. - * Drop dpkg-source local-options hint: Declared options are default - since dpkg-source 1.16.1. - + Add irc URL to Upstream-Contact. - + Add comment on Bitcoin Developers to catch-all Files section. - + Add Files sections for newly readded src/cryptopp/* (new custom - BSD-like license), and newly added doc/build-osx.txt and - src/makefile.osx (Expat). - * Bump debhelper compatibility level to 7. - * Suppress binary icns and gpg files. - * Enable regression tests: - + Build-depend on libboost-test-dev. - + Extend patch 1003 to also dynamically link test binary. - + Build and invoke test binary unless tests are disabled. - * Tighten build-dependency on cdbs: Recent version needed to support - debhelper 7. - * Relax build-depend unversioned on debhelper: needed version - satisfied even in oldstable. - * Stop suppress optional build-dependencies: Satisfied in stable. - Build-depend on devscripts (enabling copyright-check). - - -- Jonas Smedegaard Wed, 05 Oct 2011 01:48:53 +0200 - -bitcoin (0.3.24~dfsg-1) unstable; urgency=low - - * New upstream release. - - [ Jonas Smedegaard ] - * Improve various usage hints: - + Explicitly mention in long description that bitcoind contains - daemon and command-line interface. - + Extend README.Debian with section on lack of GUI, and add primary - headline. - + Avoid installing upstream README: contains no parts relevant for - Debian usage. - Thanks to richard for suggestions (see bug#629443). - * Favor final releases over prereleases in rules and watch file. - Thanks to Jan Dittberner. - * Track -src (not -linux) tarballs in rules and watch file. - Thanks to Jan Dittberner. - * Drop patches 1004 and 1005 (integrated upstream) and simplify - CXXFLAGS in rules file. - * Stop stripping no longer included source-less binaries from upstream - tarballs. - - [ Jan Dittberner ] - * refresh debian/patches/1000_use_system_crypto++.patch - - -- Jonas Smedegaard Tue, 19 Jul 2011 15:08:54 +0200 - -bitcoin (0.3.21~dfsg-2) unstable; urgency=low - - * Enable UPNP support: - + Drop patch 1006. - + Build-depend on libminiupnpc-dev. - Thanks to Matt Corallo. - - -- Jonas Smedegaard Sat, 28 May 2011 15:52:44 +0200 - -bitcoin (0.3.21~dfsg-1) unstable; urgency=low - - * New upstream release. - * Refresh patches. - * Drop patch 1002: no longer needed, as upstream use pkgconfig now. - * Add patch 1006 to really unset USE_UPNP as aparently intended. - * Adjust cleanup rule to preserve .gitignore files. - * Update copyright file: - + Bump format to draft 174 of DEP-5. - + Shorten comments. - * Bump policy compliance to standards-version 3.9.2. - * Shorten Vcs-Browser paragraph in control file. - * Fix mention daemon (not CLI tools) in short description. - * Stop conflicting with or replace bitcoin-cli: Only transitional, no - longer needed. - * Link against unversioned berkeleydb. Update NEWS and README.Debian - accordingly (and improve wording while at it). - Closes: Bug#621425. Thanks to Ondřej Surý. - * This release also implicitly updates linkage against libcrypto++, - which closes: bug#626953, #627024. - * Disable linkage against not yet Debian packaged MiniUPnP. - * Silence seemingly harmless noise about unused variables. - - -- Jonas Smedegaard Tue, 17 May 2011 15:31:24 +0200 - -bitcoin (0.3.20.2~dfsg-2) unstable; urgency=medium - - * Fix have wrapper script execute real binary (not loop executing - itself). - Closes: bug#617290. Thanks to Philippe Gauthier and Etienne Laurin. - * Set urgency=medium as the only (user-exposed) binary is useless - without this fix and has been for some time. - - -- Jonas Smedegaard Wed, 16 Mar 2011 09:11:06 +0100 - -bitcoin (0.3.20.2~dfsg-1) unstable; urgency=low - - * New upstream release. - * Fix provide and replace former package name bitcoin-cli. - Closes: bug#618439. Thanks to Shane Wegner. - - -- Jonas Smedegaard Tue, 15 Mar 2011 11:41:43 +0100 - -bitcoin (0.3.20.01~dfsg-1) unstable; urgency=low - - * New upstream release. - - [ Micah Anderson ] - * Add myself as uploader. - - [ Jonas Smedegaard ] - * Add wrapper for bitcoind to ease initial startup. - * Update patches: - + Drop patch 2002: Applied upstream. - + Add patch 1005 to add phtread linker option. - Closes: bug#615619. Thanks to Shane Wegner. - + Refresh patches. - * Extend copyright years in rules file header. - * Rewrite copyright file using draft svn166 of DEP5 format. - * Rename binary package to bitcoind (from bincoin-cli). - Closes: bug#614025. Thanks to Luke-Jr. - - -- Jonas Smedegaard Tue, 01 Mar 2011 15:55:04 +0100 - -bitcoin (0.3.19~dfsg-6) unstable; urgency=low - - * Fix override aggressive optimizations. - * Fix tighten build-dependencies to really fit backporting to Lenny: - + Add fallback build-dependency on libdb4.6++-dev. - + Tighten unversioned Boost build-dependencies to recent versions, - To force use of versioned Boost when backporting to Lenny. - ...needs more love, though: actual build fails. - - -- Jonas Smedegaard Mon, 17 Jan 2011 19:48:35 +0100 - -bitcoin (0.3.19~dfsg-5) unstable; urgency=low - - * Fix lower Boost fallback-build-dependencies to 1.35, really - available in Lenny. - * Correct comment in rules file regarding reason for versioned Boost - fallback-build-dependency. - * Add patch 2002 adding -mt decoration to Boost flags, to ease - backporting to Lenny. - * Respect DEB_BUILD_OPTIONS, and suppress arch-specific optimizations: - + Add patch 1004 to allow overriding optimization flags. - + Set optimization flags conditionally at build time. - + Drop patch 2002 unconditionally suppressing arch-optimizations. - - -- Jonas Smedegaard Mon, 17 Jan 2011 16:04:48 +0100 - -bitcoin (0.3.19~dfsg-4) unstable; urgency=low - - [ Micah Anderson ] - * Provide example bitcoin.conf. - * Add bitcoind(1) and bitcoin.conf(5) man pages. - - [ Jonas Smedegaard ] - * Ease backporting: - + Suppress optional build-dependencies. - + Add fallback build-dependencies on the most recent Boost libs - available in Lenny (where unversioned Boost libs are missing). - * Add Micah as copyright holder for manpages, licensed as GPL-3+. - * Bump copyright format to Subversion candidate draft 162 of DEP5. - - -- Jonas Smedegaard Mon, 17 Jan 2011 14:00:48 +0100 - -bitcoin (0.3.19~dfsg-3) unstable; urgency=low - - * Document in copyright file files excluded from repackaged source. - * Update copyright file: - + Bump DEP5 format hint to Subversion draft rev. 153. - + Consistently wrap at 72 chars. - + Refer to GPL-2 file (not GPL symlink). - * Link against Berkeley DB 4.8 (not 4.7): - + Build-depend on libdb4.8++-dev (and on on libdb4.7++-dev). - + Suggest libdb4.8-util and db4.7-util. - + Add README.Debian note on (untested) upgrade routine. - + Add NEWS entry on changed db version, referring to README.Debian. - - -- Jonas Smedegaard Fri, 07 Jan 2011 22:50:57 +0100 - -bitcoin (0.3.19~dfsg-2) unstable; urgency=low - - * Adjust build options to use optimized miner only for amd64. Fixes - FTBFS on i386 (and other archs, if compiling anywhere else at all). - * Avoid static linking. - * Adjust patch 2001 to avoid only arch-specific optimizations (keep - -O3). - * Extend long description to mention disk consumption and initial use - of IRC. - All of above changes thanks to Helmuth Grohne. - * Add lintian override regarding OpenSSL and GPL: Linked code is Expat - - only Debian packaging is GPL-2+. - - -- Jonas Smedegaard Wed, 29 Dec 2010 00:27:54 +0100 - -bitcoin (0.3.19~dfsg-1) unstable; urgency=low - - [ Jonas Smedegaard ] - * Initial release. - Closes: bug#578157. - - -- Jonas Smedegaard Tue, 28 Dec 2010 15:49:22 +0100 diff --git a/contrib/debian/control b/contrib/debian/control deleted file mode 100644 index d615b318aa..0000000000 --- a/contrib/debian/control +++ /dev/null @@ -1,67 +0,0 @@ -Source: bitcoin -Section: utils -Priority: optional -Maintainer: Jonas Smedegaard -Uploaders: Micah Anderson -Build-Depends: debhelper, - devscripts, - automake, - libtool, - bash-completion, - libboost-system-dev (>> 1.35) | libboost-system1.35-dev, - libdb++-dev, - libssl-dev, - pkg-config, - libminiupnpc8-dev | libminiupnpc-dev (>> 1.6), - libboost-filesystem-dev (>> 1.35) | libboost-filesystem1.35-dev, - libboost-program-options-dev (>> 1.35) | libboost-program-options1.35-dev, - libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev, - libboost-test-dev (>> 1.35) | libboost-test1.35-dev, - qt4-qmake, - libqt4-dev, - libqrencode-dev, - libprotobuf-dev, protobuf-compiler, - python -Standards-Version: 3.9.2 -Homepage: https://bitcoincore.org/ -Vcs-Git: git://github.com/bitcoin/bitcoin.git -Vcs-Browser: https://github.com/bitcoin/bitcoin - -Package: bitcoind -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: peer-to-peer network based digital currency - daemon - Bitcoin is an experimental new digital currency that enables instant - payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer - technology to operate with no central authority: managing transactions - and issuing money are carried out collectively by the network. Bitcoin Core - is the name of the open source software which enables the use of this currency. - . - This package provides the daemon, bitcoind, and the CLI tool - bitcoin-cli to interact with the daemon. - -Package: bitcoin-qt -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: peer-to-peer network based digital currency - Qt GUI - Bitcoin is an experimental new digital currency that enables instant - payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer - technology to operate with no central authority: managing transactions - and issuing money are carried out collectively by the network. Bitcoin Core - is the name of the open source software which enables the use of this currency. - . - This package provides Bitcoin-Qt, a GUI for Bitcoin based on Qt. - -Package: bitcoin-tx -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: peer-to-peer digital currency - standalone transaction tool - Bitcoin is an experimental new digital currency that enables instant - payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer - technology to operate with no central authority: managing transactions - and issuing money are carried out collectively by the network. Bitcoin Core - is the name of the open source software which enables the use of this currency. - . - This package provides bitcoin-tx, a command-line transaction creation - tool which can be used without a bitcoin daemon. Some means of - exchanging minimal transaction data with peers is still required. diff --git a/contrib/debian/copyright b/contrib/debian/copyright index cc4606ca88..6d23f600c3 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -1,11 +1,11 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Bitcoin Upstream-Contact: Satoshi Nakamoto - irc://#bitcoin@freenode.net + irc://#bitcoin-core-dev@libera.chat Source: https://github.com/bitcoin/bitcoin Files: * -Copyright: 2009-2016, Bitcoin Core Developers +Copyright: 2009-2021, Bitcoin Core Developers License: Expat Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org, as well as the numerous contributors to the project. @@ -15,28 +15,25 @@ Copyright: 2010-2011, Jonas Smedegaard 2011, Matt Corallo License: GPL-2+ -Files: debian/manpages/* -Copyright: Micah Anderson -License: GPL-3+ +Files: src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 +Copyright: 2008 Don Anderson +License: GNU-All-permissive-License + +Files: src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 +Copyright: 2008 Paolo Bonzini +License: GNU-All-permissive-License Files: src/qt/res/icons/add.png src/qt/res/icons/address-book.png src/qt/res/icons/chevron.png - src/qt/res/icons/configure.png - src/qt/res/icons/debugwindow.png src/qt/res/icons/edit.png src/qt/res/icons/editcopy.png src/qt/res/icons/editpaste.png src/qt/res/icons/export.png src/qt/res/icons/eye.png - src/qt/res/icons/filesave.png src/qt/res/icons/history.png - src/qt/res/icons/info.png - src/qt/res/icons/key.png src/qt/res/icons/lock_*.png - src/qt/res/icons/open.png src/qt/res/icons/overview.png - src/qt/res/icons/quit.png src/qt/res/icons/receive.png src/qt/res/icons/remove.png src/qt/res/icons/send.png @@ -51,9 +48,12 @@ Comment: Site: https://github.com/stephenhutchings/typicons.font Files: src/qt/res/icons/connect*.png src/qt/res/src/connect-*.svg + src/qt/res/icons/network_disabled.png + src/qt/res/src/network_disabled.svg Copyright: Marco Falke + Luke Dashjr License: Expat -Comment: Inspired by Stephan Hutchings Typicons +Comment: Inspired by Stephen Hutchings' Typicons Files: src/qt/res/icons/tx_mined.png src/qt/res/src/mine.svg @@ -65,27 +65,32 @@ Files: src/qt/res/icons/tx_mined.png src/qt/res/src/hd_enabled.svg Copyright: Jonas Schnelli License: Expat -Comment: Files: src/qt/res/icons/clock*.png src/qt/res/icons/eye_*.png - src/qt/res/icons/verify.png src/qt/res/icons/tx_in*.png src/qt/res/src/clock_*.svg src/qt/res/src/tx_*.svg - src/qt/res/src/verify.svg -Copyright: Stephan Hutching, Jonas Schnelli +Copyright: Stephen Hutchings, Jonas Schnelli License: Expat -Comment: Modifications of Stephan Hutchings Typicons +Comment: Modifications of Stephen Hutchings' Typicons -Files: src/qt/res/icons/about.png - src/qt/res/icons/bitcoin.* +Files: src/qt/res/icons/bitcoin.* share/pixmaps/bitcoin* src/qt/res/src/bitcoin.svg Copyright: Bitboy, Jonas Schnelli License: public-domain Comment: Site: https://bitcointalk.org/?topic=1756.0 +Files: src/qt/res/icons/proxy.png + src/qt/res/src/proxy.svg +Copyright: Cristian Mircea Messel +License: public-domain + +Files: src/qt/res/fonts/RobotoMono-Bold.ttf +License: Apache-2.0 +Comment: Site: https://fonts.google.com/specimen/Roboto+Mono + License: Expat Permission is hereby granted, free of charge, to any person obtaining a @@ -107,6 +112,12 @@ License: Expat TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +License: GNU-All-permissive-License + Copying and distribution of this file, with or without modification, are + permitted in any medium without royalty provided the copyright notice + and this notice are preserved. This file is offered as-is, without any + warranty. + License: GPL-2+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -137,3 +148,14 @@ Comment: License: public-domain This work is in the public domain. + +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/contrib/debian/examples/bitcoin.conf b/contrib/debian/examples/bitcoin.conf deleted file mode 100644 index 2831c07292..0000000000 --- a/contrib/debian/examples/bitcoin.conf +++ /dev/null @@ -1,124 +0,0 @@ -## -## bitcoin.conf configuration file. Lines beginning with # are comments. -## - -# Network-related settings: - -# Run on the test network instead of the real bitcoin network. -#testnet=0 - -# Run a regression test network -#regtest=0 - -# Connect via a SOCKS5 proxy -#proxy=127.0.0.1:9050 - -# Bind to given address and always listen on it. Use [host]:port notation for IPv6 -#bind= - -# Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 -#whitebind= - -############################################################## -## Quick Primer on addnode vs connect ## -## Let's say for instance you use addnode=4.2.2.4 ## -## addnode will connect you to and tell you about the ## -## nodes connected to 4.2.2.4. In addition it will tell ## -## the other nodes connected to it that you exist so ## -## they can connect to you. ## -## connect will not do the above when you 'connect' to it. ## -## It will *only* connect you to 4.2.2.4 and no one else.## -## ## -## So if you're behind a firewall, or have other problems ## -## finding nodes, add some using 'addnode'. ## -## ## -## If you want to stay private, use 'connect' to only ## -## connect to "trusted" nodes. ## -## ## -## If you run multiple nodes on a LAN, there's no need for ## -## all of them to open lots of connections. Instead ## -## 'connect' them all to one node that is port forwarded ## -## and has lots of connections. ## -## Thanks goes to [Noodle] on Freenode. ## -############################################################## - -# Use as many addnode= settings as you like to connect to specific peers -#addnode=69.164.218.197 -#addnode=10.0.0.2:8333 - -# Alternatively use as many connect= settings as you like to connect ONLY to specific peers -#connect=69.164.218.197 -#connect=10.0.0.1:8333 - -# Listening mode, enabled by default except when 'connect' is being used -#listen=1 - -# Maximum number of inbound+outbound connections. -#maxconnections= - -# -# JSON-RPC options (for controlling a running Bitcoin/bitcoind process) -# - -# server=1 tells Bitcoin-Qt and bitcoind to accept JSON-RPC commands -#server=0 - -# Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. -# This option can be specified multiple times (default: bind to all interfaces) -#rpcbind= - -# You must set rpcuser and rpcpassword to secure the JSON-RPC api -#rpcuser=Ulysseys -#rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593 - -# How many seconds bitcoin will wait for a complete RPC HTTP request. -# after the HTTP connection is established. -#rpcclienttimeout=30 - -# By default, only RPC connections from localhost are allowed. -# Specify as many rpcallowip= settings as you like to allow connections from other hosts, -# either as a single IPv4/IPv6 or with a subnet specification. - -# NOTE: opening up the RPC port to hosts outside your local trusted network is NOT RECOMMENDED, -# because the rpcpassword is transmitted over the network unencrypted. - -# server=1 tells Bitcoin-Qt to accept JSON-RPC commands. -# it is also read by bitcoind to determine if RPC should be enabled -#rpcallowip=10.1.1.34/255.255.255.0 -#rpcallowip=1.2.3.4/24 -#rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96 - -# Listen for RPC connections on this TCP port: -#rpcport=8332 - -# You can use Bitcoin or bitcoind to send commands to Bitcoin/bitcoind -# running on another host using this option: -#rpcconnect=127.0.0.1 - -# Transaction Fee Changes in 0.10.0 - -# Send transactions as zero-fee transactions if possible (default: 0) -#sendfreetransactions=0 - -# Create transactions that have enough fees (or priority) so they are likely to begin confirmation within n blocks (default: 1). -# This setting is over-ridden by the -paytxfee option. -#txconfirmtarget=n - -# Miscellaneous options - -# Pre-generate this many public/private key pairs, so wallet backups will be valid for -# both prior transactions and several dozen future transactions. -#keypool=100 - -# Pay an optional transaction fee every time you send bitcoins. Transactions with fees -# are more likely than free transactions to be included in generated blocks, so may -# be validated sooner. -#paytxfee=0.00 - -# User interface options - -# Start Bitcoin minimized -#min=1 - -# Minimize to the system tray -#minimizetotray=1 diff --git a/contrib/debian/gbp.conf b/contrib/debian/gbp.conf deleted file mode 100644 index a7281f94b2..0000000000 --- a/contrib/debian/gbp.conf +++ /dev/null @@ -1,5 +0,0 @@ -# Configuration file for git-buildpackage and friends - -[DEFAULT] -pristine-tar = True -sign-tags = True diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1 deleted file mode 100644 index dbd4745d19..0000000000 --- a/contrib/debian/manpages/bitcoin-cli.1 +++ /dev/null @@ -1,84 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH BITCOIN-CLI "1" "December 2016" "bitcoin-cli v0.13.2.0" "User Commands" -.SH NAME -bitcoin-cli \- manual page for bitcoin-cli v0.13.2.0 -.SH DESCRIPTION -Bitcoin Core RPC client version v0.13.2.0 -.SS "Usage:" -.TP -bitcoin\-cli [options] [params] -Send command to Bitcoin Core -.TP -bitcoin\-cli [options] help -List commands -.TP -bitcoin\-cli [options] help -Get help for a command -.SH OPTIONS -.HP -\-? -.IP -This help message -.HP -\fB\-conf=\fR -.IP -Specify configuration file (default: bitcoin.conf) -.HP -\fB\-datadir=\fR -.IP -Specify data directory -.PP -Chain selection options: -.HP -\fB\-testnet\fR -.IP -Use the test chain -.HP -\fB\-regtest\fR -.IP -Enter regression test mode, which uses a special chain in which blocks -can be solved instantly. This is intended for regression testing -tools and app development. -.HP -\fB\-rpcconnect=\fR -.IP -Send commands to node running on (default: 127.0.0.1) -.HP -\fB\-rpcport=\fR -.IP -Connect to JSON\-RPC on (default: 8332 or testnet: 18332) -.HP -\fB\-rpcwait\fR -.IP -Wait for RPC server to start -.HP -\fB\-rpcuser=\fR -.IP -Username for JSON\-RPC connections -.HP -\fB\-rpcpassword=\fR -.IP -Password for JSON\-RPC connections -.HP -\fB\-rpcclienttimeout=\fR -.IP -Timeout during HTTP requests (default: 900) -.HP -\fB\-stdin\fR -.IP -Read extra arguments from standard input, one per line until EOF/Ctrl\-D -(recommended for sensitive information such as passphrases) -.SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers - -Please contribute if you find Bitcoin Core useful. Visit - for further information about the software. -The source code is available from . - -This is experimental software. -Distributed under the MIT software license, see the accompanying file COPYING -or . - -This product includes software developed by the OpenSSL Project for use in the -OpenSSL Toolkit and cryptographic software written -by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1 deleted file mode 100644 index e14e1480af..0000000000 --- a/contrib/debian/manpages/bitcoin-qt.1 +++ /dev/null @@ -1,501 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH BITCOIN-QT "1" "December 2016" "bitcoin-qt v0.13.2.0" "User Commands" -.SH NAME -bitcoin-qt \- manual page for bitcoin-qt v0.13.2.0 -.SH DESCRIPTION -Bitcoin Core version v0.13.2.0 (64\-bit) -Usage: -.IP -bitcoin\-qt [command\-line options] -.SH OPTIONS -.HP -\-? -.IP -Print this help message and exit -.HP -\fB\-version\fR -.IP -Print version and exit -.HP -\fB\-alertnotify=\fR -.IP -Execute command when a relevant alert is received or we see a really -long fork (%s in cmd is replaced by message) -.HP -\fB\-blocknotify=\fR -.IP -Execute command when the best block changes (%s in cmd is replaced by -block hash) -.HP -\fB\-checkblocks=\fR -.IP -How many blocks to check at startup (default: 6, 0 = all) -.HP -\fB\-checklevel=\fR -.IP -How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) -.HP -\fB\-conf=\fR -.IP -Specify configuration file (default: bitcoin.conf) -.HP -\fB\-datadir=\fR -.IP -Specify data directory -.HP -\fB\-dbcache=\fR -.IP -Set database cache size in megabytes (4 to 16384, default: 300) -.HP -\fB\-loadblock=\fR -.IP -Imports blocks from external blk000??.dat file on startup -.HP -\fB\-maxorphantx=\fR -.IP -Keep at most unconnectable transactions in memory (default: 100) -.HP -\fB\-maxmempool=\fR -.IP -Keep the transaction memory pool below megabytes (default: 300) -.HP -\fB\-mempoolexpiry=\fR -.IP -Do not keep transactions in the mempool longer than hours (default: -72) -.HP -\fB\-par=\fR -.IP -Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = -leave that many cores free, default: 0) -.HP -\fB\-pid=\fR -.IP -Specify pid file (default: bitcoind.pid) -.HP -\fB\-prune=\fR -.IP -Reduce storage requirements by pruning (deleting) old blocks. This mode -is incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting -this setting requires re\-downloading the entire blockchain. -(default: 0 = disable pruning blocks, >550 = target size in MiB -to use for block files) -.HP -\fB\-reindex\-chainstate\fR -.IP -Rebuild chain state from the currently indexed blocks -.HP -\fB\-reindex\fR -.IP -Rebuild chain state and block index from the blk*.dat files on disk -.HP -\fB\-sysperms\fR -.IP -Create new files with system default permissions, instead of umask 077 -(only effective with disabled wallet functionality) -.HP -\fB\-txindex\fR -.IP -Maintain a full transaction index, used by the getrawtransaction rpc -call (default: 0) -.PP -Connection options: -.HP -\fB\-addnode=\fR -.IP -Add a node to connect to and attempt to keep the connection open -.HP -\fB\-banscore=\fR -.IP -Threshold for disconnecting misbehaving peers (default: 100) -.HP -\fB\-bantime=\fR -.IP -Number of seconds to keep misbehaving peers from reconnecting (default: -86400) -.HP -\fB\-bind=\fR -.IP -Bind to given address and always listen on it. Use [host]:port notation -for IPv6 -.HP -\fB\-connect=\fR -.IP -Connect only to the specified node(s) -.HP -\fB\-discover\fR -.IP -Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR -or \fB\-proxy\fR) -.HP -\fB\-dns\fR -.IP -Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) -.HP -\fB\-dnsseed\fR -.IP -Query for peer addresses via DNS lookup, if low on addresses (default: 1 -unless \fB\-connect\fR) -.HP -\fB\-externalip=\fR -.IP -Specify your own public address -.HP -\fB\-forcednsseed\fR -.IP -Always query for peer addresses via DNS lookup (default: 0) -.HP -\fB\-listen\fR -.IP -Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) -.HP -\fB\-listenonion\fR -.IP -Automatically create Tor hidden service (default: 1) -.HP -\fB\-maxconnections=\fR -.IP -Maintain at most connections to peers (default: 125) -.HP -\fB\-maxreceivebuffer=\fR -.IP -Maximum per\-connection receive buffer, *1000 bytes (default: 5000) -.HP -\fB\-maxsendbuffer=\fR -.IP -Maximum per\-connection send buffer, *1000 bytes (default: 1000) -.HP -\fB\-maxtimeadjustment\fR -.IP -Maximum allowed median peer time offset adjustment. Local perspective of -time may be influenced by peers forward or backward by this -amount. (default: 4200 seconds) -.HP -\fB\-onion=\fR -.IP -Use separate SOCKS5 proxy to reach peers via Tor hidden services -(default: \fB\-proxy\fR) -.HP -\fB\-onlynet=\fR -.IP -Only connect to nodes in network (ipv4, ipv6 or onion) -.HP -\fB\-permitbaremultisig\fR -.IP -Relay non\-P2SH multisig (default: 1) -.HP -\fB\-peerbloomfilters\fR -.IP -Support filtering of blocks and transaction with bloom filters (default: -1) -.HP -\fB\-port=\fR -.IP -Listen for connections on (default: 8333 or testnet: 18333) -.HP -\fB\-proxy=\fR -.IP -Connect through SOCKS5 proxy -.HP -\fB\-proxyrandomize\fR -.IP -Randomize credentials for every proxy connection. This enables Tor -stream isolation (default: 1) -.HP -\fB\-rpcserialversion\fR -.IP -Sets the serialization of raw transaction or block hex returned in -non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1) -.HP -\fB\-seednode=\fR -.IP -Connect to a node to retrieve peer addresses, and disconnect -.HP -\fB\-timeout=\fR -.IP -Specify connection timeout in milliseconds (minimum: 1, default: 5000) -.HP -\fB\-torcontrol=\fR: -.IP -Tor control port to use if onion listening enabled (default: -127.0.0.1:9051) -.HP -\fB\-torpassword=\fR -.IP -Tor control port password (default: empty) -.HP -\fB\-whitebind=\fR -.IP -Bind to given address and whitelist peers connecting to it. Use -[host]:port notation for IPv6 -.HP -\fB\-whitelist=\fR -.IP -Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or -CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple -times. Whitelisted peers cannot be DoS banned and their -transactions are always relayed, even if they are already in the -mempool, useful e.g. for a gateway -.HP -\fB\-whitelistrelay\fR -.IP -Accept relayed transactions received from whitelisted peers even when -not relaying transactions (default: 1) -.HP -\fB\-whitelistforcerelay\fR -.IP -Force relay of transactions from whitelisted peers even if they violate -local relay policy (default: 1) -.HP -\fB\-maxuploadtarget=\fR -.IP -Tries to keep outbound traffic under the given target (in MiB per 24h), -0 = no limit (default: 0) -.PP -Wallet options: -.HP -\fB\-disablewallet\fR -.IP -Do not load the wallet and disable wallet RPC calls -.HP -\fB\-keypool=\fR -.IP -Set key pool size to (default: 100) -.HP -\fB\-fallbackfee=\fR -.IP -A fee rate (in BTC/kB) that will be used when fee estimation has -insufficient data (default: 0.0002) -.HP -\fB\-mintxfee=\fR -.IP -Fees (in BTC/kB) smaller than this are considered zero fee for -transaction creation (default: 0.00001) -.HP -\fB\-paytxfee=\fR -.IP -Fee (in BTC/kB) to add to transactions you send (default: 0.00) -.HP -\fB\-rescan\fR -.IP -Rescan the block chain for missing wallet transactions on startup -.HP -\fB\-salvagewallet\fR -.IP -Attempt to recover private keys from a corrupt wallet on startup -.HP -\fB\-spendzeroconfchange\fR -.IP -Spend unconfirmed change when sending transactions (default: 1) -.HP -\fB\-txconfirmtarget=\fR -.IP -If paytxfee is not set, include enough fee so transactions begin -confirmation on average within n blocks (default: 2) -.HP -\fB\-usehd\fR -.IP -Use hierarchical deterministic key generation (HD) after BIP32. Only has -effect during wallet creation/first start (default: 1) -.HP -\fB\-upgradewallet\fR -.IP -Upgrade wallet to latest format on startup -.HP -\fB\-wallet=\fR -.IP -Specify wallet file (within data directory) (default: wallet.dat) -.HP -\fB\-walletbroadcast\fR -.IP -Make the wallet broadcast transactions (default: 1) -.HP -\fB\-walletnotify=\fR -.IP -Execute command when a wallet transaction changes (%s in cmd is replaced -by TxID) -.HP -\fB\-zapwallettxes=\fR -.IP -Delete all wallet transactions and only recover those parts of the -blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. -account owner and payment request information, 2 = drop tx meta -data) -.PP -Debugging/Testing options: -.HP -\fB\-uacomment=\fR -.IP -Append comment to the user agent string -.HP -\fB\-debug=\fR -.IP -Output debugging information (default: 0, supplying is -optional). If is not supplied or if = 1, -output all debugging information. can be: addrman, -alert, bench, cmpctblock, coindb, db, http, libevent, lock, -mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, -selectcoins, tor, zmq, qt. -.HP -\fB\-help\-debug\fR -.IP -Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR) -.HP -\fB\-logips\fR -.IP -Include IP addresses in debug output (default: 0) -.HP -\fB\-logtimestamps\fR -.IP -Prepend debug output with timestamp (default: 1) -.HP -\fB\-minrelaytxfee=\fR -.IP -Fees (in BTC/kB) smaller than this are considered zero fee for relaying, -mining and transaction creation (default: 0.00001) -.HP -\fB\-maxtxfee=\fR -.IP -Maximum total fees (in BTC) to use in a single wallet transaction or raw -transaction; setting this too low may abort large transactions -(default: 0.10) -.HP -\fB\-printtoconsole\fR -.IP -Send trace/debug info to console instead of debug.log file -.HP -\fB\-shrinkdebugfile\fR -.IP -Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) -.PP -Chain selection options: -.HP -\fB\-testnet\fR -.IP -Use the test chain -.PP -Node relay options: -.HP -\fB\-bytespersigop\fR -.IP -Equivalent bytes per sigop in transactions for relay and mining -(default: 20) -.HP -\fB\-datacarrier\fR -.IP -Relay and mine data carrier transactions (default: 1) -.HP -\fB\-datacarriersize\fR -.IP -Maximum size of data in data carrier transactions we relay and mine -(default: 83) -.HP -\fB\-mempoolreplacement\fR -.IP -Enable transaction replacement in the memory pool (default: 1) -.PP -Block creation options: -.HP -\fB\-blockmaxweight=\fR -.IP -Set maximum BIP141 block weight (default: 3000000) -.HP -\fB\-blockmaxsize=\fR -.IP -Set maximum block size in bytes (default: 750000) -.HP -\fB\-blockprioritysize=\fR -.IP -Set maximum size of high\-priority/low\-fee transactions in bytes -(default: 0) -.PP -RPC server options: -.HP -\fB\-server\fR -.IP -Accept command line and JSON\-RPC commands -.HP -\fB\-rest\fR -.IP -Accept public REST requests (default: 0) -.HP -\fB\-rpcbind=\fR -.IP -Bind to given address to listen for JSON\-RPC connections. Use -[host]:port notation for IPv6. This option can be specified -multiple times (default: bind to all interfaces) -.HP -\fB\-rpccookiefile=\fR -.IP -Location of the auth cookie (default: data dir) -.HP -\fB\-rpcuser=\fR -.IP -Username for JSON\-RPC connections -.HP -\fB\-rpcpassword=\fR -.IP -Password for JSON\-RPC connections -.HP -\fB\-rpcauth=\fR -.IP -Username and hashed password for JSON\-RPC connections. The field - comes in the format: :$. A -canonical python script is included in share/rpcuser. This option -can be specified multiple times -.HP -\fB\-rpcport=\fR -.IP -Listen for JSON\-RPC connections on (default: 8332 or testnet: -18332) -.HP -\fB\-rpcallowip=\fR -.IP -Allow JSON\-RPC connections from specified source. Valid for are a -single IP (e.g. 1.2.3.4), a network/netmask (e.g. -1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This -option can be specified multiple times -.HP -\fB\-rpcthreads=\fR -.IP -Set the number of threads to service RPC calls (default: 4) -.PP -UI Options: -.HP -\fB\-choosedatadir\fR -.IP -Choose data directory on startup (default: 0) -.HP -\fB\-lang=\fR -.IP -Set language, for example "de_DE" (default: system locale) -.HP -\fB\-min\fR -.IP -Start minimized -.HP -\fB\-rootcertificates=\fR -.IP -Set SSL root certificates for payment request (default: \fB\-system\-\fR) -.HP -\fB\-splash\fR -.IP -Show splash screen on startup (default: 1) -.HP -\fB\-resetguisettings\fR -.IP -Reset all settings changed in the GUI -.SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers - -Please contribute if you find Bitcoin Core useful. Visit - for further information about the software. -The source code is available from . - -This is experimental software. -Distributed under the MIT software license, see the accompanying file COPYING -or . - -This product includes software developed by the OpenSSL Project for use in the -OpenSSL Toolkit and cryptographic software written -by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoin-tx.1 b/contrib/debian/manpages/bitcoin-tx.1 deleted file mode 100644 index 0cbb4ad58f..0000000000 --- a/contrib/debian/manpages/bitcoin-tx.1 +++ /dev/null @@ -1,107 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH BITCOIN-TX "1" "December 2016" "bitcoin-tx v0.13.2.0" "User Commands" -.SH NAME -bitcoin-tx \- manual page for bitcoin-tx v0.13.2.0 -.SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v0.13.2.0 -.SS "Usage:" -.TP -bitcoin\-tx [options] [commands] -Update hex\-encoded bitcoin transaction -.TP -bitcoin\-tx [options] \fB\-create\fR [commands] -Create hex\-encoded bitcoin transaction -.SH OPTIONS -.HP -\-? -.IP -This help message -.HP -\fB\-create\fR -.IP -Create new, empty TX. -.HP -\fB\-json\fR -.IP -Select JSON output -.HP -\fB\-txid\fR -.IP -Output only the hex\-encoded transaction id of the resultant transaction. -.PP -Chain selection options: -.HP -\fB\-testnet\fR -.IP -Use the test chain -.HP -\fB\-regtest\fR -.IP -Enter regression test mode, which uses a special chain in which blocks -can be solved instantly. This is intended for regression testing -tools and app development. -.PP -Commands: -.IP -delin=N -.IP -Delete input N from TX -.IP -delout=N -.IP -Delete output N from TX -.IP -in=TXID:VOUT(:SEQUENCE_NUMBER) -.IP -Add input to TX -.IP -locktime=N -.IP -Set TX lock time to N -.IP -nversion=N -.IP -Set TX version to N -.IP -outaddr=VALUE:ADDRESS -.IP -Add address\-based output to TX -.IP -outdata=[VALUE:]DATA -.IP -Add data\-based output to TX -.IP -outscript=VALUE:SCRIPT -.IP -Add raw script output to TX -.IP -sign=SIGHASH\-FLAGS -.IP -Add zero or more signatures to transaction. This command requires JSON -registers:prevtxs=JSON object, privatekeys=JSON object. See -signrawtransaction docs for format of sighash flags, JSON -objects. -.PP -Register Commands: -.IP -load=NAME:FILENAME -.IP -Load JSON file FILENAME into register NAME -.IP -set=NAME:JSON\-STRING -.IP -Set register NAME to given JSON\-STRING -.SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers - -Please contribute if you find Bitcoin Core useful. Visit - for further information about the software. -The source code is available from . - -This is experimental software. -Distributed under the MIT software license, see the accompanying file COPYING -or . - -This product includes software developed by the OpenSSL Project for use in the -OpenSSL Toolkit and cryptographic software written -by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5 deleted file mode 100644 index 839dc26c1a..0000000000 --- a/contrib/debian/manpages/bitcoin.conf.5 +++ /dev/null @@ -1,19 +0,0 @@ -.TH BITCOIN.CONF "5" "February 2016" "bitcoin.conf 0.12" -.SH NAME -bitcoin.conf \- bitcoin configuration file -.SH SYNOPSIS -All command-line options (except for '\-conf') may be specified in a configuration file, and all configuration file options may also be specified on the command line. Command-line options override values set in the configuration file. -.TP -The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character. Please refer to bitcoind(1) for a up to date list of valid options. -.TP -The configuration file is not automatically created; you can create it using your favorite plain-text editor. By default, bitcoind(1) will look for a file named bitcoin.conf(5) in the bitcoin data directory, but both the data directory and the configuration file path may be changed using the '\-datadir' and '\-conf' command-line arguments. -.SH LOCATION -bitcoin.conf should be located in $HOME/.bitcoin - -.SH "SEE ALSO" -bitcoind(1) -.SH AUTHOR -This manual page was written by Micah Anderson for the Debian system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation. - -On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL. - diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 deleted file mode 100644 index 3b83f52ccc..0000000000 --- a/contrib/debian/manpages/bitcoind.1 +++ /dev/null @@ -1,480 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH BITCOIND "1" "December 2016" "bitcoind v0.13.2.0" "User Commands" -.SH NAME -bitcoind \- manual page for bitcoind v0.13.2.0 -.SH DESCRIPTION -Bitcoin Core Daemon version v0.13.2.0 -.SS "Usage:" -.TP -bitcoind [options] -Start Bitcoin Core Daemon -.SH OPTIONS -.HP -\-? -.IP -Print this help message and exit -.HP -\fB\-version\fR -.IP -Print version and exit -.HP -\fB\-alertnotify=\fR -.IP -Execute command when a relevant alert is received or we see a really -long fork (%s in cmd is replaced by message) -.HP -\fB\-blocknotify=\fR -.IP -Execute command when the best block changes (%s in cmd is replaced by -block hash) -.HP -\fB\-checkblocks=\fR -.IP -How many blocks to check at startup (default: 6, 0 = all) -.HP -\fB\-checklevel=\fR -.IP -How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) -.HP -\fB\-conf=\fR -.IP -Specify configuration file (default: bitcoin.conf) -.HP -\fB\-daemon\fR -.IP -Run in the background as a daemon and accept commands -.HP -\fB\-datadir=\fR -.IP -Specify data directory -.HP -\fB\-dbcache=\fR -.IP -Set database cache size in megabytes (4 to 16384, default: 300) -.HP -\fB\-loadblock=\fR -.IP -Imports blocks from external blk000??.dat file on startup -.HP -\fB\-maxorphantx=\fR -.IP -Keep at most unconnectable transactions in memory (default: 100) -.HP -\fB\-maxmempool=\fR -.IP -Keep the transaction memory pool below megabytes (default: 300) -.HP -\fB\-mempoolexpiry=\fR -.IP -Do not keep transactions in the mempool longer than hours (default: -72) -.HP -\fB\-par=\fR -.IP -Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = -leave that many cores free, default: 0) -.HP -\fB\-pid=\fR -.IP -Specify pid file (default: bitcoind.pid) -.HP -\fB\-prune=\fR -.IP -Reduce storage requirements by pruning (deleting) old blocks. This mode -is incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting -this setting requires re\-downloading the entire blockchain. -(default: 0 = disable pruning blocks, >550 = target size in MiB -to use for block files) -.HP -\fB\-reindex\-chainstate\fR -.IP -Rebuild chain state from the currently indexed blocks -.HP -\fB\-reindex\fR -.IP -Rebuild chain state and block index from the blk*.dat files on disk -.HP -\fB\-sysperms\fR -.IP -Create new files with system default permissions, instead of umask 077 -(only effective with disabled wallet functionality) -.HP -\fB\-txindex\fR -.IP -Maintain a full transaction index, used by the getrawtransaction rpc -call (default: 0) -.PP -Connection options: -.HP -\fB\-addnode=\fR -.IP -Add a node to connect to and attempt to keep the connection open -.HP -\fB\-banscore=\fR -.IP -Threshold for disconnecting misbehaving peers (default: 100) -.HP -\fB\-bantime=\fR -.IP -Number of seconds to keep misbehaving peers from reconnecting (default: -86400) -.HP -\fB\-bind=\fR -.IP -Bind to given address and always listen on it. Use [host]:port notation -for IPv6 -.HP -\fB\-connect=\fR -.IP -Connect only to the specified node(s) -.HP -\fB\-discover\fR -.IP -Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR -or \fB\-proxy\fR) -.HP -\fB\-dns\fR -.IP -Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) -.HP -\fB\-dnsseed\fR -.IP -Query for peer addresses via DNS lookup, if low on addresses (default: 1 -unless \fB\-connect\fR) -.HP -\fB\-externalip=\fR -.IP -Specify your own public address -.HP -\fB\-forcednsseed\fR -.IP -Always query for peer addresses via DNS lookup (default: 0) -.HP -\fB\-listen\fR -.IP -Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) -.HP -\fB\-listenonion\fR -.IP -Automatically create Tor hidden service (default: 1) -.HP -\fB\-maxconnections=\fR -.IP -Maintain at most connections to peers (default: 125) -.HP -\fB\-maxreceivebuffer=\fR -.IP -Maximum per\-connection receive buffer, *1000 bytes (default: 5000) -.HP -\fB\-maxsendbuffer=\fR -.IP -Maximum per\-connection send buffer, *1000 bytes (default: 1000) -.HP -\fB\-maxtimeadjustment\fR -.IP -Maximum allowed median peer time offset adjustment. Local perspective of -time may be influenced by peers forward or backward by this -amount. (default: 4200 seconds) -.HP -\fB\-onion=\fR -.IP -Use separate SOCKS5 proxy to reach peers via Tor hidden services -(default: \fB\-proxy\fR) -.HP -\fB\-onlynet=\fR -.IP -Only connect to nodes in network (ipv4, ipv6 or onion) -.HP -\fB\-permitbaremultisig\fR -.IP -Relay non\-P2SH multisig (default: 1) -.HP -\fB\-peerbloomfilters\fR -.IP -Support filtering of blocks and transaction with bloom filters (default: -1) -.HP -\fB\-port=\fR -.IP -Listen for connections on (default: 8333 or testnet: 18333) -.HP -\fB\-proxy=\fR -.IP -Connect through SOCKS5 proxy -.HP -\fB\-proxyrandomize\fR -.IP -Randomize credentials for every proxy connection. This enables Tor -stream isolation (default: 1) -.HP -\fB\-rpcserialversion\fR -.IP -Sets the serialization of raw transaction or block hex returned in -non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1) -.HP -\fB\-seednode=\fR -.IP -Connect to a node to retrieve peer addresses, and disconnect -.HP -\fB\-timeout=\fR -.IP -Specify connection timeout in milliseconds (minimum: 1, default: 5000) -.HP -\fB\-torcontrol=\fR: -.IP -Tor control port to use if onion listening enabled (default: -127.0.0.1:9051) -.HP -\fB\-torpassword=\fR -.IP -Tor control port password (default: empty) -.HP -\fB\-whitebind=\fR -.IP -Bind to given address and whitelist peers connecting to it. Use -[host]:port notation for IPv6 -.HP -\fB\-whitelist=\fR -.IP -Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or -CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple -times. Whitelisted peers cannot be DoS banned and their -transactions are always relayed, even if they are already in the -mempool, useful e.g. for a gateway -.HP -\fB\-whitelistrelay\fR -.IP -Accept relayed transactions received from whitelisted peers even when -not relaying transactions (default: 1) -.HP -\fB\-whitelistforcerelay\fR -.IP -Force relay of transactions from whitelisted peers even if they violate -local relay policy (default: 1) -.HP -\fB\-maxuploadtarget=\fR -.IP -Tries to keep outbound traffic under the given target (in MiB per 24h), -0 = no limit (default: 0) -.PP -Wallet options: -.HP -\fB\-disablewallet\fR -.IP -Do not load the wallet and disable wallet RPC calls -.HP -\fB\-keypool=\fR -.IP -Set key pool size to (default: 100) -.HP -\fB\-fallbackfee=\fR -.IP -A fee rate (in BTC/kB) that will be used when fee estimation has -insufficient data (default: 0.0002) -.HP -\fB\-mintxfee=\fR -.IP -Fees (in BTC/kB) smaller than this are considered zero fee for -transaction creation (default: 0.00001) -.HP -\fB\-paytxfee=\fR -.IP -Fee (in BTC/kB) to add to transactions you send (default: 0.00) -.HP -\fB\-rescan\fR -.IP -Rescan the block chain for missing wallet transactions on startup -.HP -\fB\-salvagewallet\fR -.IP -Attempt to recover private keys from a corrupt wallet on startup -.HP -\fB\-spendzeroconfchange\fR -.IP -Spend unconfirmed change when sending transactions (default: 1) -.HP -\fB\-txconfirmtarget=\fR -.IP -If paytxfee is not set, include enough fee so transactions begin -confirmation on average within n blocks (default: 2) -.HP -\fB\-usehd\fR -.IP -Use hierarchical deterministic key generation (HD) after BIP32. Only has -effect during wallet creation/first start (default: 1) -.HP -\fB\-upgradewallet\fR -.IP -Upgrade wallet to latest format on startup -.HP -\fB\-wallet=\fR -.IP -Specify wallet file (within data directory) (default: wallet.dat) -.HP -\fB\-walletbroadcast\fR -.IP -Make the wallet broadcast transactions (default: 1) -.HP -\fB\-walletnotify=\fR -.IP -Execute command when a wallet transaction changes (%s in cmd is replaced -by TxID) -.HP -\fB\-zapwallettxes=\fR -.IP -Delete all wallet transactions and only recover those parts of the -blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. -account owner and payment request information, 2 = drop tx meta -data) -.PP -Debugging/Testing options: -.HP -\fB\-uacomment=\fR -.IP -Append comment to the user agent string -.HP -\fB\-debug=\fR -.IP -Output debugging information (default: 0, supplying is -optional). If is not supplied or if = 1, -output all debugging information. can be: addrman, -alert, bench, cmpctblock, coindb, db, http, libevent, lock, -mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, -selectcoins, tor, zmq. -.HP -\fB\-help\-debug\fR -.IP -Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR) -.HP -\fB\-logips\fR -.IP -Include IP addresses in debug output (default: 0) -.HP -\fB\-logtimestamps\fR -.IP -Prepend debug output with timestamp (default: 1) -.HP -\fB\-minrelaytxfee=\fR -.IP -Fees (in BTC/kB) smaller than this are considered zero fee for relaying, -mining and transaction creation (default: 0.00001) -.HP -\fB\-maxtxfee=\fR -.IP -Maximum total fees (in BTC) to use in a single wallet transaction or raw -transaction; setting this too low may abort large transactions -(default: 0.10) -.HP -\fB\-printtoconsole\fR -.IP -Send trace/debug info to console instead of debug.log file -.HP -\fB\-shrinkdebugfile\fR -.IP -Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) -.PP -Chain selection options: -.HP -\fB\-testnet\fR -.IP -Use the test chain -.PP -Node relay options: -.HP -\fB\-bytespersigop\fR -.IP -Equivalent bytes per sigop in transactions for relay and mining -(default: 20) -.HP -\fB\-datacarrier\fR -.IP -Relay and mine data carrier transactions (default: 1) -.HP -\fB\-datacarriersize\fR -.IP -Maximum size of data in data carrier transactions we relay and mine -(default: 83) -.HP -\fB\-mempoolreplacement\fR -.IP -Enable transaction replacement in the memory pool (default: 1) -.PP -Block creation options: -.HP -\fB\-blockmaxweight=\fR -.IP -Set maximum BIP141 block weight (default: 3000000) -.HP -\fB\-blockmaxsize=\fR -.IP -Set maximum block size in bytes (default: 750000) -.HP -\fB\-blockprioritysize=\fR -.IP -Set maximum size of high\-priority/low\-fee transactions in bytes -(default: 0) -.PP -RPC server options: -.HP -\fB\-server\fR -.IP -Accept command line and JSON\-RPC commands -.HP -\fB\-rest\fR -.IP -Accept public REST requests (default: 0) -.HP -\fB\-rpcbind=\fR -.IP -Bind to given address to listen for JSON\-RPC connections. Use -[host]:port notation for IPv6. This option can be specified -multiple times (default: bind to all interfaces) -.HP -\fB\-rpccookiefile=\fR -.IP -Location of the auth cookie (default: data dir) -.HP -\fB\-rpcuser=\fR -.IP -Username for JSON\-RPC connections -.HP -\fB\-rpcpassword=\fR -.IP -Password for JSON\-RPC connections -.HP -\fB\-rpcauth=\fR -.IP -Username and hashed password for JSON\-RPC connections. The field - comes in the format: :$. A -canonical python script is included in share/rpcuser. This option -can be specified multiple times -.HP -\fB\-rpcport=\fR -.IP -Listen for JSON\-RPC connections on (default: 8332 or testnet: -18332) -.HP -\fB\-rpcallowip=\fR -.IP -Allow JSON\-RPC connections from specified source. Valid for are a -single IP (e.g. 1.2.3.4), a network/netmask (e.g. -1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This -option can be specified multiple times -.HP -\fB\-rpcthreads=\fR -.IP -Set the number of threads to service RPC calls (default: 4) -.SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers - -Please contribute if you find Bitcoin Core useful. Visit - for further information about the software. -The source code is available from . - -This is experimental software. -Distributed under the MIT software license, see the accompanying file COPYING -or . - -This product includes software developed by the OpenSSL Project for use in the -OpenSSL Toolkit and cryptographic software written -by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/patches/README b/contrib/debian/patches/README deleted file mode 100644 index 80c1584376..0000000000 --- a/contrib/debian/patches/README +++ /dev/null @@ -1,3 +0,0 @@ -0xxx: Grabbed from upstream development. -1xxx: Possibly relevant for upstream adoption. -2xxx: Only relevant for official Debian release. diff --git a/contrib/debian/patches/series b/contrib/debian/patches/series deleted file mode 100644 index 8b13789179..0000000000 --- a/contrib/debian/patches/series +++ /dev/null @@ -1 +0,0 @@ - diff --git a/contrib/debian/rules b/contrib/debian/rules deleted file mode 100755 index 52b357cf01..0000000000 --- a/contrib/debian/rules +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/make -f -# -*- mode: makefile; coding: utf-8 -*- - -#DEB_MAKE_CHECK_TARGET = test_bitcoin -#build/bitcoind:: -# $(if $(filter nocheck,$(DEB_BUILD_OPTIONS)),,src/test_bitcoin) - -DEB_INSTALL_EXAMPLES_bitcoind += debian/examples/* -DEB_INSTALL_MANPAGES_bitcoind += debian/manpages/* - -%: - dh --with bash-completion $@ - -override_dh_auto_clean: - if [ -f Makefile ]; then $(MAKE) distclean; fi - rm -rf Makefile.in aclocal.m4 configure src/Makefile.in src/bitcoin-config.h.in src/build-aux src/qt/Makefile.in src/qt/test/Makefile.in src/test/Makefile.in - -# Yea, autogen should be run on the source archive, but I like doing git archive -override_dh_auto_configure: - ./autogen.sh - ./configure - -override_dh_auto_test: - make check diff --git a/contrib/debian/source/format b/contrib/debian/source/format deleted file mode 100644 index 163aaf8d82..0000000000 --- a/contrib/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/contrib/debian/watch b/contrib/debian/watch deleted file mode 100644 index 4d9e0cfa57..0000000000 --- a/contrib/debian/watch +++ /dev/null @@ -1,5 +0,0 @@ -# Run the "uscan" command to check for upstream updates and more. -version=3 -# use qa.debian.org redirector; see man uscan -opts=uversionmangle=s/(\d)(alpha|beta|rc)/$1~$2/,dversionmangle=s/~dfsg\d*// \ - http://githubredir.debian.net/github/bitcoin/bitcoin v(.*).tar.gz diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 60fe69e7e3..46d149b14b 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -18,6 +18,9 @@ clang-format-diff.py A script to format unified git diffs according to [.clang-format](../../src/.clang-format). +Requires `clang-format`, installed e.g. via `brew install clang-format` on macOS, +or `sudo apt install clang-format` on Debian/Ubuntu. + For instance, to format the last commit with 0 lines of context, the script should be called from the git root folder as follows. @@ -39,6 +42,64 @@ For example a file changed in 2015 (with 2015 being the current year): would be changed to: ```// Copyright (c) 2009-2015 The Bitcoin Core developers``` +copyright\_header.py +==================== + +Provides utilities for managing copyright headers of `The Bitcoin Core +developers` in repository source files. It has three subcommands: + +``` +$ ./copyright_header.py report [verbose] +$ ./copyright_header.py update +$ ./copyright_header.py insert +``` +Running these subcommands without arguments displays a usage string. + +copyright\_header.py report \ [verbose] +--------------------------------------------------------- + +Produces a report of all copyright header notices found inside the source files +of a repository. Useful to quickly visualize the state of the headers. +Specifying `verbose` will list the full filenames of files of each category. + +copyright\_header.py update \ [verbose] +--------------------------------------------------------- +Updates all the copyright headers of `The Bitcoin Core developers` which were +changed in a year more recent than is listed. For example: +``` +// Copyright (c) - The Bitcoin Core developers +``` +will be updated to: +``` +// Copyright (c) - The Bitcoin Core developers +``` +where `` is obtained from the `git log` history. + +This subcommand also handles copyright headers that have only a single year. In +those cases: +``` +// Copyright (c) The Bitcoin Core developers +``` +will be updated to: +``` +// Copyright (c) - The Bitcoin Core developers +``` +where the update is appropriate. + +copyright\_header.py insert \ +------------------------------------ +Inserts a copyright header for `The Bitcoin Core developers` at the top of the +file in either Python or C++ style as determined by the file extension. If the +file is a Python file and it has `#!` starting the first line, the header is +inserted in the line below it. + +The copyright dates will be set to be `-` where +`` is according to the `git log` history. If +`` is equal to ``, it will be set as a single +year rather than two hyphenated years. + +If the file already has a copyright for `The Bitcoin Core developers`, the +script will exit. gen-manpages.sh =============== @@ -46,6 +107,13 @@ gen-manpages.sh A small script to automatically create manpages in ../../doc/man by running the release binaries with the -help option. This requires help2man which can be found at: https://www.gnu.org/software/help2man/ +With in-tree builds this tool can be run from any directory within the +repostitory. To use this tool with out-of-tree builds set `BUILDDIR`. For +example: + +```bash +BUILDDIR=$PWD/build contrib/devtools/gen-manpages.sh +``` git-subtree-check.sh ==================== @@ -96,7 +164,6 @@ Configuring the github-merge tool for the bitcoin repository is done in the foll git config githubmerge.repository bitcoin/bitcoin git config githubmerge.testcmd "make -j4 check" (adapt to whatever you want to use for testing) git config --global user.signingkey mykeyid (if you want to GPG sign) - optimize-pngs.py ================ @@ -106,22 +173,26 @@ repository (requires pngcrush). security-check.py and test-security-check.py ============================================ -Perform basic ELF security checks on a series of executables. +Perform basic security checks on a series of executables. symbol-check.py =============== -A script to check that the (Linux) executables produced by gitian only contain -allowed gcc, glibc and libstdc++ version symbols. This makes sure they are -still compatible with the minimum supported Linux distribution versions. +A script to check that the executables produced by gitian only contain +certain symbols and are only linked against allowed libraries. + +For Linux this means checking for allowed gcc, glibc and libstdc++ version symbols. +This makes sure they are still compatible with the minimum supported distribution versions. + +For macOS and Windows we check that the executables are only linked against libraries we allow. Example usage after a gitian build: - find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py + find ../gitian-builder/build -type f -executable | xargs python3 contrib/devtools/symbol-check.py -If only supported symbols are used the return value will be 0 and the output will be empty. +If no errors occur the return value will be 0 and the output will be empty. -If there are 'unsupported' symbols, the return value will be 1 a list like this will be printed: +If there are any errors the return value will be 1 and output like this will be printed: .../64/test_bitcoin: symbol memcpy from unsupported version GLIBC_2.14 .../64/test_bitcoin: symbol __fdelt_chk from unsupported version GLIBC_2.15 @@ -139,3 +210,13 @@ It will do the following automatically: - add missing translations to the build system (TODO) See doc/translation-process.md for more information. +circular-dependencies.py +======================== + +Run this script from the root of the source tree (`src/`) to find circular dependencies in the source code. +This looks only at which files include other files, treating the `.cpp` and `.h` file as one unit. + +Example usage: + + cd .../src + ../contrib/devtools/circular-dependencies.py {*,*/*,*/*/*}.{h,cpp} diff --git a/contrib/devtools/circular-dependencies.py b/contrib/devtools/circular-dependencies.py new file mode 100755 index 0000000000..b1d9f2b7db --- /dev/null +++ b/contrib/devtools/circular-dependencies.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018-2020 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import sys +import re +from typing import Dict, List, Set + +MAPPING = { + 'core_read.cpp': 'core_io.cpp', + 'core_write.cpp': 'core_io.cpp', +} + +# Directories with header-based modules, where the assumption that .cpp files +# define functions and variables declared in corresponding .h files is +# incorrect. +HEADER_MODULE_PATHS = [ + 'interfaces/' +] + +def module_name(path): + if path in MAPPING: + path = MAPPING[path] + if any(path.startswith(dirpath) for dirpath in HEADER_MODULE_PATHS): + return path + if path.endswith(".h"): + return path[:-2] + if path.endswith(".c"): + return path[:-2] + if path.endswith(".cpp"): + return path[:-4] + return None + +files = dict() +deps: Dict[str, Set[str]] = dict() + +RE = re.compile("^#include <(.*)>") + +# Iterate over files, and create list of modules +for arg in sys.argv[1:]: + module = module_name(arg) + if module is None: + print("Ignoring file %s (does not constitute module)\n" % arg) + else: + files[arg] = module + deps[module] = set() + +# Iterate again, and build list of direct dependencies for each module +# TODO: implement support for multiple include directories +for arg in sorted(files.keys()): + module = files[arg] + with open(arg, 'r', encoding="utf8") as f: + for line in f: + match = RE.match(line) + if match: + include = match.group(1) + included_module = module_name(include) + if included_module is not None and included_module in deps and included_module != module: + deps[module].add(included_module) + +# Loop to find the shortest (remaining) circular dependency +have_cycle: bool = False +while True: + shortest_cycle = None + for module in sorted(deps.keys()): + # Build the transitive closure of dependencies of module + closure: Dict[str, List[str]] = dict() + for dep in deps[module]: + closure[dep] = [] + while True: + old_size = len(closure) + old_closure_keys = sorted(closure.keys()) + for src in old_closure_keys: + for dep in deps[src]: + if dep not in closure: + closure[dep] = closure[src] + [src] + if len(closure) == old_size: + break + # If module is in its own transitive closure, it's a circular dependency; check if it is the shortest + if module in closure and (shortest_cycle is None or len(closure[module]) + 1 < len(shortest_cycle)): + shortest_cycle = [module] + closure[module] + if shortest_cycle is None: + break + # We have the shortest circular dependency; report it + module = shortest_cycle[0] + print("Circular dependency: %s" % (" -> ".join(shortest_cycle + [module]))) + # And then break the dependency to avoid repeating in other cycles + deps[shortest_cycle[-1]] = deps[shortest_cycle[-1]] - set([module]) + have_cycle = True + +sys.exit(1 if have_cycle else 0) diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py index 13d2573b9f..98eee67f43 100755 --- a/contrib/devtools/clang-format-diff.py +++ b/contrib/devtools/clang-format-diff.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # #===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===# # @@ -69,10 +69,9 @@ import argparse import difflib +import io import re -import string import subprocess -import StringIO import sys @@ -107,10 +106,10 @@ def main(): filename = None lines_by_file = {} for line in sys.stdin: - match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) + match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) if match: filename = match.group(2) - if filename == None: + if filename is None: continue if args.regex is not None: @@ -120,7 +119,7 @@ def main(): if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE): continue - match = re.search('^@@.*\+(\d+)(,(\d+))?', line) + match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line) if match: start_line = int(match.group(1)) line_count = 1 @@ -128,14 +127,14 @@ def main(): line_count = int(match.group(3)) if line_count == 0: continue - end_line = start_line + line_count - 1; + end_line = start_line + line_count - 1 lines_by_file.setdefault(filename, []).extend( ['-lines', str(start_line) + ':' + str(end_line)]) # Reformat files containing changes in place. - for filename, lines in lines_by_file.iteritems(): + for filename, lines in lines_by_file.items(): if args.i and args.verbose: - print 'Formatting', filename + print('Formatting {}'.format(filename)) command = [binary, filename] if args.i: command.append('-i') @@ -143,20 +142,23 @@ def main(): command.append('-sort-includes') command.extend(lines) command.extend(['-style=file', '-fallback-style=none']) - p = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=None, stdin=subprocess.PIPE) + p = subprocess.Popen(command, + stdout=subprocess.PIPE, + stderr=None, + stdin=subprocess.PIPE, + universal_newlines=True) stdout, stderr = p.communicate() if p.returncode != 0: - sys.exit(p.returncode); + sys.exit(p.returncode) if not args.i: - with open(filename) as f: + with open(filename, encoding="utf8") as f: code = f.readlines() - formatted_code = StringIO.StringIO(stdout).readlines() + formatted_code = io.StringIO(stdout).readlines() diff = difflib.unified_diff(code, formatted_code, filename, filename, '(before formatting)', '(after formatting)') - diff_string = string.join(diff, '') + diff_string = ''.join(diff) if len(diff_string) > 0: sys.stdout.write(diff_string) diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py new file mode 100755 index 0000000000..9a555c70bb --- /dev/null +++ b/contrib/devtools/copyright_header.py @@ -0,0 +1,606 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016-2020 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import re +import fnmatch +import sys +import subprocess +import datetime +import os + +################################################################################ +# file filtering +################################################################################ + +EXCLUDE = [ + # auto generated: + 'src/qt/bitcoinstrings.cpp', + 'src/chainparamsseeds.h', + # other external copyrights: + 'src/reverse_iterator.h', + 'src/test/fuzz/FuzzedDataProvider.h', + 'src/tinyformat.h', + 'src/bench/nanobench.h', + 'test/functional/test_framework/bignum.py', + # python init: + '*__init__.py', +] +EXCLUDE_COMPILED = re.compile('|'.join([fnmatch.translate(m) for m in EXCLUDE])) + +EXCLUDE_DIRS = [ + # git subtrees + "src/crypto/ctaes/", + "src/leveldb/", + "src/secp256k1/", + "src/univalue/", + "src/crc32c/", +] + +INCLUDE = ['*.h', '*.cpp', '*.cc', '*.c', '*.mm', '*.py', '*.sh', '*.bash-completion'] +INCLUDE_COMPILED = re.compile('|'.join([fnmatch.translate(m) for m in INCLUDE])) + +def applies_to_file(filename): + for excluded_dir in EXCLUDE_DIRS: + if filename.startswith(excluded_dir): + return False + return ((EXCLUDE_COMPILED.match(filename) is None) and + (INCLUDE_COMPILED.match(filename) is not None)) + +################################################################################ +# obtain list of files in repo according to INCLUDE and EXCLUDE +################################################################################ + +GIT_LS_CMD = 'git ls-files --full-name'.split(' ') +GIT_TOPLEVEL_CMD = 'git rev-parse --show-toplevel'.split(' ') + +def call_git_ls(base_directory): + out = subprocess.check_output([*GIT_LS_CMD, base_directory]) + return [f for f in out.decode("utf-8").split('\n') if f != ''] + +def call_git_toplevel(): + "Returns the absolute path to the project root" + return subprocess.check_output(GIT_TOPLEVEL_CMD).strip().decode("utf-8") + +def get_filenames_to_examine(base_directory): + "Returns an array of absolute paths to any project files in the base_directory that pass the include/exclude filters" + root = call_git_toplevel() + filenames = call_git_ls(base_directory) + return sorted([os.path.join(root, filename) for filename in filenames if + applies_to_file(filename)]) + +################################################################################ +# define and compile regexes for the patterns we are looking for +################################################################################ + + +COPYRIGHT_WITH_C = r'Copyright \(c\)' +COPYRIGHT_WITHOUT_C = 'Copyright' +ANY_COPYRIGHT_STYLE = '(%s|%s)' % (COPYRIGHT_WITH_C, COPYRIGHT_WITHOUT_C) + +YEAR = "20[0-9][0-9]" +YEAR_RANGE = '(%s)(-%s)?' % (YEAR, YEAR) +YEAR_LIST = '(%s)(, %s)+' % (YEAR, YEAR) +ANY_YEAR_STYLE = '(%s|%s)' % (YEAR_RANGE, YEAR_LIST) +ANY_COPYRIGHT_STYLE_OR_YEAR_STYLE = ("%s %s" % (ANY_COPYRIGHT_STYLE, + ANY_YEAR_STYLE)) + +ANY_COPYRIGHT_COMPILED = re.compile(ANY_COPYRIGHT_STYLE_OR_YEAR_STYLE) + +def compile_copyright_regex(copyright_style, year_style, name): + return re.compile(r'%s %s,? %s( +\*)?\n' % (copyright_style, year_style, name)) + +EXPECTED_HOLDER_NAMES = [ + r"Satoshi Nakamoto", + r"The Bitcoin Core developers", + r"BitPay Inc\.", + r"University of Illinois at Urbana-Champaign\.", + r"Pieter Wuille", + r"Wladimir J\. van der Laan", + r"Jeff Garzik", + r"Jan-Klaas Kollhof", + r"ArtForz -- public domain half-a-node", + r"Intel Corporation ?", + r"The Zcash developers", + r"Jeremy Rubin", +] + +DOMINANT_STYLE_COMPILED = {} +YEAR_LIST_STYLE_COMPILED = {} +WITHOUT_C_STYLE_COMPILED = {} + +for holder_name in EXPECTED_HOLDER_NAMES: + DOMINANT_STYLE_COMPILED[holder_name] = ( + compile_copyright_regex(COPYRIGHT_WITH_C, YEAR_RANGE, holder_name)) + YEAR_LIST_STYLE_COMPILED[holder_name] = ( + compile_copyright_regex(COPYRIGHT_WITH_C, YEAR_LIST, holder_name)) + WITHOUT_C_STYLE_COMPILED[holder_name] = ( + compile_copyright_regex(COPYRIGHT_WITHOUT_C, ANY_YEAR_STYLE, + holder_name)) + +################################################################################ +# search file contents for copyright message of particular category +################################################################################ + +def get_count_of_copyrights_of_any_style_any_holder(contents): + return len(ANY_COPYRIGHT_COMPILED.findall(contents)) + +def file_has_dominant_style_copyright_for_holder(contents, holder_name): + match = DOMINANT_STYLE_COMPILED[holder_name].search(contents) + return match is not None + +def file_has_year_list_style_copyright_for_holder(contents, holder_name): + match = YEAR_LIST_STYLE_COMPILED[holder_name].search(contents) + return match is not None + +def file_has_without_c_style_copyright_for_holder(contents, holder_name): + match = WITHOUT_C_STYLE_COMPILED[holder_name].search(contents) + return match is not None + +################################################################################ +# get file info +################################################################################ + +def read_file(filename): + return open(filename, 'r', encoding="utf8").read() + +def gather_file_info(filename): + info = {} + info['filename'] = filename + c = read_file(filename) + info['contents'] = c + + info['all_copyrights'] = get_count_of_copyrights_of_any_style_any_holder(c) + + info['classified_copyrights'] = 0 + info['dominant_style'] = {} + info['year_list_style'] = {} + info['without_c_style'] = {} + for holder_name in EXPECTED_HOLDER_NAMES: + has_dominant_style = ( + file_has_dominant_style_copyright_for_holder(c, holder_name)) + has_year_list_style = ( + file_has_year_list_style_copyright_for_holder(c, holder_name)) + has_without_c_style = ( + file_has_without_c_style_copyright_for_holder(c, holder_name)) + info['dominant_style'][holder_name] = has_dominant_style + info['year_list_style'][holder_name] = has_year_list_style + info['without_c_style'][holder_name] = has_without_c_style + if has_dominant_style or has_year_list_style or has_without_c_style: + info['classified_copyrights'] = info['classified_copyrights'] + 1 + return info + +################################################################################ +# report execution +################################################################################ + +SEPARATOR = '-'.join(['' for _ in range(80)]) + +def print_filenames(filenames, verbose): + if not verbose: + return + for filename in filenames: + print("\t%s" % filename) + +def print_report(file_infos, verbose): + print(SEPARATOR) + examined = [i['filename'] for i in file_infos] + print("%d files examined according to INCLUDE and EXCLUDE fnmatch rules" % + len(examined)) + print_filenames(examined, verbose) + + print(SEPARATOR) + print('') + zero_copyrights = [i['filename'] for i in file_infos if + i['all_copyrights'] == 0] + print("%4d with zero copyrights" % len(zero_copyrights)) + print_filenames(zero_copyrights, verbose) + one_copyright = [i['filename'] for i in file_infos if + i['all_copyrights'] == 1] + print("%4d with one copyright" % len(one_copyright)) + print_filenames(one_copyright, verbose) + two_copyrights = [i['filename'] for i in file_infos if + i['all_copyrights'] == 2] + print("%4d with two copyrights" % len(two_copyrights)) + print_filenames(two_copyrights, verbose) + three_copyrights = [i['filename'] for i in file_infos if + i['all_copyrights'] == 3] + print("%4d with three copyrights" % len(three_copyrights)) + print_filenames(three_copyrights, verbose) + four_or_more_copyrights = [i['filename'] for i in file_infos if + i['all_copyrights'] >= 4] + print("%4d with four or more copyrights" % len(four_or_more_copyrights)) + print_filenames(four_or_more_copyrights, verbose) + print('') + print(SEPARATOR) + print('Copyrights with dominant style:\ne.g. "Copyright (c)" and ' + '"" or "-":\n') + for holder_name in EXPECTED_HOLDER_NAMES: + dominant_style = [i['filename'] for i in file_infos if + i['dominant_style'][holder_name]] + if len(dominant_style) > 0: + print("%4d with '%s'" % (len(dominant_style), + holder_name.replace('\n', '\\n'))) + print_filenames(dominant_style, verbose) + print('') + print(SEPARATOR) + print('Copyrights with year list style:\ne.g. "Copyright (c)" and ' + '", , ...":\n') + for holder_name in EXPECTED_HOLDER_NAMES: + year_list_style = [i['filename'] for i in file_infos if + i['year_list_style'][holder_name]] + if len(year_list_style) > 0: + print("%4d with '%s'" % (len(year_list_style), + holder_name.replace('\n', '\\n'))) + print_filenames(year_list_style, verbose) + print('') + print(SEPARATOR) + print('Copyrights with no "(c)" style:\ne.g. "Copyright" and "" or ' + '"-":\n') + for holder_name in EXPECTED_HOLDER_NAMES: + without_c_style = [i['filename'] for i in file_infos if + i['without_c_style'][holder_name]] + if len(without_c_style) > 0: + print("%4d with '%s'" % (len(without_c_style), + holder_name.replace('\n', '\\n'))) + print_filenames(without_c_style, verbose) + + print('') + print(SEPARATOR) + + unclassified_copyrights = [i['filename'] for i in file_infos if + i['classified_copyrights'] < i['all_copyrights']] + print("%d with unexpected copyright holder names" % + len(unclassified_copyrights)) + print_filenames(unclassified_copyrights, verbose) + print(SEPARATOR) + +def exec_report(base_directory, verbose): + filenames = get_filenames_to_examine(base_directory) + file_infos = [gather_file_info(f) for f in filenames] + print_report(file_infos, verbose) + +################################################################################ +# report cmd +################################################################################ + +REPORT_USAGE = """ +Produces a report of all copyright header notices found inside the source files +of a repository. + +Usage: + $ ./copyright_header.py report [verbose] + +Arguments: + - The base directory of a bitcoin source code repository. + [verbose] - Includes a list of every file of each subcategory in the report. +""" + +def report_cmd(argv): + if len(argv) == 2: + sys.exit(REPORT_USAGE) + + base_directory = argv[2] + if not os.path.exists(base_directory): + sys.exit("*** bad : %s" % base_directory) + + if len(argv) == 3: + verbose = False + elif argv[3] == 'verbose': + verbose = True + else: + sys.exit("*** unknown argument: %s" % argv[2]) + + exec_report(base_directory, verbose) + +################################################################################ +# query git for year of last change +################################################################################ + +GIT_LOG_CMD = "git log --pretty=format:%%ai %s" + +def call_git_log(filename): + out = subprocess.check_output((GIT_LOG_CMD % filename).split(' ')) + return out.decode("utf-8").split('\n') + +def get_git_change_years(filename): + git_log_lines = call_git_log(filename) + if len(git_log_lines) == 0: + return [datetime.date.today().year] + # timestamp is in ISO 8601 format. e.g. "2016-09-05 14:25:32 -0600" + return [line.split(' ')[0].split('-')[0] for line in git_log_lines] + +def get_most_recent_git_change_year(filename): + return max(get_git_change_years(filename)) + +################################################################################ +# read and write to file +################################################################################ + +def read_file_lines(filename): + f = open(filename, 'r', encoding="utf8") + file_lines = f.readlines() + f.close() + return file_lines + +def write_file_lines(filename, file_lines): + f = open(filename, 'w', encoding="utf8") + f.write(''.join(file_lines)) + f.close() + +################################################################################ +# update header years execution +################################################################################ + +COPYRIGHT = r'Copyright \(c\)' +YEAR = "20[0-9][0-9]" +YEAR_RANGE = '(%s)(-%s)?' % (YEAR, YEAR) +HOLDER = 'The Bitcoin Core developers' +UPDATEABLE_LINE_COMPILED = re.compile(' '.join([COPYRIGHT, YEAR_RANGE, HOLDER])) + +def get_updatable_copyright_line(file_lines): + index = 0 + for line in file_lines: + if UPDATEABLE_LINE_COMPILED.search(line) is not None: + return index, line + index = index + 1 + return None, None + +def parse_year_range(year_range): + year_split = year_range.split('-') + start_year = year_split[0] + if len(year_split) == 1: + return start_year, start_year + return start_year, year_split[1] + +def year_range_to_str(start_year, end_year): + if start_year == end_year: + return start_year + return "%s-%s" % (start_year, end_year) + +def create_updated_copyright_line(line, last_git_change_year): + copyright_splitter = 'Copyright (c) ' + copyright_split = line.split(copyright_splitter) + # Preserve characters on line that are ahead of the start of the copyright + # notice - they are part of the comment block and vary from file-to-file. + before_copyright = copyright_split[0] + after_copyright = copyright_split[1] + + space_split = after_copyright.split(' ') + year_range = space_split[0] + start_year, end_year = parse_year_range(year_range) + if end_year == last_git_change_year: + return line + return (before_copyright + copyright_splitter + + year_range_to_str(start_year, last_git_change_year) + ' ' + + ' '.join(space_split[1:])) + +def update_updatable_copyright(filename): + file_lines = read_file_lines(filename) + index, line = get_updatable_copyright_line(file_lines) + if not line: + print_file_action_message(filename, "No updatable copyright.") + return + last_git_change_year = get_most_recent_git_change_year(filename) + new_line = create_updated_copyright_line(line, last_git_change_year) + if line == new_line: + print_file_action_message(filename, "Copyright up-to-date.") + return + file_lines[index] = new_line + write_file_lines(filename, file_lines) + print_file_action_message(filename, + "Copyright updated! -> %s" % last_git_change_year) + +def exec_update_header_year(base_directory): + for filename in get_filenames_to_examine(base_directory): + update_updatable_copyright(filename) + +################################################################################ +# update cmd +################################################################################ + +UPDATE_USAGE = """ +Updates all the copyright headers of "The Bitcoin Core developers" which were +changed in a year more recent than is listed. For example: + +// Copyright (c) - The Bitcoin Core developers + +will be updated to: + +// Copyright (c) - The Bitcoin Core developers + +where is obtained from the 'git log' history. + +This subcommand also handles copyright headers that have only a single year. In those cases: + +// Copyright (c) The Bitcoin Core developers + +will be updated to: + +// Copyright (c) - The Bitcoin Core developers + +where the update is appropriate. + +Usage: + $ ./copyright_header.py update + +Arguments: + - The base directory of a bitcoin source code repository. +""" + +def print_file_action_message(filename, action): + print("%-52s %s" % (filename, action)) + +def update_cmd(argv): + if len(argv) != 3: + sys.exit(UPDATE_USAGE) + + base_directory = argv[2] + if not os.path.exists(base_directory): + sys.exit("*** bad base_directory: %s" % base_directory) + exec_update_header_year(base_directory) + +################################################################################ +# inserted copyright header format +################################################################################ + +def get_header_lines(header, start_year, end_year): + lines = header.split('\n')[1:-1] + lines[0] = lines[0] % year_range_to_str(start_year, end_year) + return [line + '\n' for line in lines] + +CPP_HEADER = ''' +// Copyright (c) %s The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +''' + +def get_cpp_header_lines_to_insert(start_year, end_year): + return reversed(get_header_lines(CPP_HEADER, start_year, end_year)) + +SCRIPT_HEADER = ''' +# Copyright (c) %s The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +''' + +def get_script_header_lines_to_insert(start_year, end_year): + return reversed(get_header_lines(SCRIPT_HEADER, start_year, end_year)) + +################################################################################ +# query git for year of last change +################################################################################ + +def get_git_change_year_range(filename): + years = get_git_change_years(filename) + return min(years), max(years) + +################################################################################ +# check for existing core copyright +################################################################################ + +def file_already_has_core_copyright(file_lines): + index, _ = get_updatable_copyright_line(file_lines) + return index is not None + +################################################################################ +# insert header execution +################################################################################ + +def file_has_hashbang(file_lines): + if len(file_lines) < 1: + return False + if len(file_lines[0]) <= 2: + return False + return file_lines[0][:2] == '#!' + +def insert_script_header(filename, file_lines, start_year, end_year): + if file_has_hashbang(file_lines): + insert_idx = 1 + else: + insert_idx = 0 + header_lines = get_script_header_lines_to_insert(start_year, end_year) + for line in header_lines: + file_lines.insert(insert_idx, line) + write_file_lines(filename, file_lines) + +def insert_cpp_header(filename, file_lines, start_year, end_year): + file_lines.insert(0, '\n') + header_lines = get_cpp_header_lines_to_insert(start_year, end_year) + for line in header_lines: + file_lines.insert(0, line) + write_file_lines(filename, file_lines) + +def exec_insert_header(filename, style): + file_lines = read_file_lines(filename) + if file_already_has_core_copyright(file_lines): + sys.exit('*** %s already has a copyright by The Bitcoin Core developers' + % (filename)) + start_year, end_year = get_git_change_year_range(filename) + if style in ['python', 'shell']: + insert_script_header(filename, file_lines, start_year, end_year) + else: + insert_cpp_header(filename, file_lines, start_year, end_year) + +################################################################################ +# insert cmd +################################################################################ + +INSERT_USAGE = """ +Inserts a copyright header for "The Bitcoin Core developers" at the top of the +file in either Python or C++ style as determined by the file extension. If the +file is a Python file and it has a '#!' starting the first line, the header is +inserted in the line below it. + +The copyright dates will be set to be: + +"-" + +where is according to the 'git log' history. If + is equal to , the date will be set to be: + +"" + +If the file already has a copyright for "The Bitcoin Core developers", the +script will exit. + +Usage: + $ ./copyright_header.py insert + +Arguments: + - A source file in the bitcoin repository. +""" + +def insert_cmd(argv): + if len(argv) != 3: + sys.exit(INSERT_USAGE) + + filename = argv[2] + if not os.path.isfile(filename): + sys.exit("*** bad filename: %s" % filename) + _, extension = os.path.splitext(filename) + if extension not in ['.h', '.cpp', '.cc', '.c', '.py', '.sh']: + sys.exit("*** cannot insert for file extension %s" % extension) + + if extension == '.py': + style = 'python' + elif extension == '.sh': + style = 'shell' + else: + style = 'cpp' + exec_insert_header(filename, style) + +################################################################################ +# UI +################################################################################ + +USAGE = """ +copyright_header.py - utilities for managing copyright headers of 'The Bitcoin +Core developers' in repository source files. + +Usage: + $ ./copyright_header + +Subcommands: + report + update + insert + +To see subcommand usage, run them without arguments. +""" + +SUBCOMMANDS = ['report', 'update', 'insert'] + +if __name__ == "__main__": + if len(sys.argv) == 1: + sys.exit(USAGE) + subcommand = sys.argv[1] + if subcommand not in SUBCOMMANDS: + sys.exit(USAGE) + if subcommand == 'report': + report_cmd(sys.argv) + elif subcommand == 'update': + update_cmd(sys.argv) + elif subcommand == 'insert': + insert_cmd(sys.argv) diff --git a/contrib/devtools/gen-manpages.sh b/contrib/devtools/gen-manpages.sh index 967717e1e0..ac54357e7d 100755 --- a/contrib/devtools/gen-manpages.sh +++ b/contrib/devtools/gen-manpages.sh @@ -1,18 +1,42 @@ -#!/bin/sh +#!/usr/bin/env bash +# Copyright (c) 2016-2020 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +export LC_ALL=C TOPDIR=${TOPDIR:-$(git rev-parse --show-toplevel)} -SRCDIR=${SRCDIR:-$TOPDIR/src} +BUILDDIR=${BUILDDIR:-$TOPDIR} + +BINDIR=${BINDIR:-$BUILDDIR/src} MANDIR=${MANDIR:-$TOPDIR/doc/man} -BITCOIND=${BITCOIND:-$SRCDIR/bitcoind} -BITCOINCLI=${BITCOINCLI:-$SRCDIR/bitcoin-cli} -BITCOINTX=${BITCOINTX:-$SRCDIR/bitcoin-tx} -BITCOINQT=${BITCOINQT:-$SRCDIR/qt/bitcoin-qt} +BITCOIND=${BITCOIND:-$BINDIR/blackmored} +BITCOINCLI=${BITCOINCLI:-$BINDIR/blackmore-cli} +BITCOINTX=${BITCOINTX:-$BINDIR/blackmore-tx} +#WALLET_TOOL=${WALLET_TOOL:-$BINDIR/bitcoin-wallet} +#BITCOINUTIL=${BITCOINQT:-$BINDIR/bitcoin-util} +#BITCOINQT=${BITCOINQT:-$BINDIR/qt/bitcoin-qt} [ ! -x $BITCOIND ] && echo "$BITCOIND not found or not executable." && exit 1 +# Don't allow man pages to be generated for binaries built from a dirty tree +DIRTY="" +for cmd in $BITCOIND $BITCOINCLI $BITCOINTX $WALLET_TOOL $BITCOINUTIL $BITCOINQT; do + VERSION_OUTPUT=$($cmd --version) + if [[ $VERSION_OUTPUT == *"dirty"* ]]; then + DIRTY="${DIRTY}${cmd}\n" + fi +done +if [ -n "$DIRTY" ] +then + echo -e "WARNING: the following binaries were built from a dirty tree:\n" + echo -e $DIRTY + echo "man pages generated from dirty binaries should NOT be committed." + echo "To properly generate man pages, please commit your changes to the above binaries, rebuild them, then run this script again." +fi + # The autodetected version git tag can screw up manpage output a little bit -BTCVER=($($BITCOINCLI --version | head -n1 | awk -F'[ -]' '{ print $6, $7 }')) +read -r -a BTCVER <<< "$($BITCOINCLI --version | head -n1 | awk -F'[ -]' '{ print $6, $7 }')" # Create a footer file with copyright content. # This gets autodetected fine for bitcoind if --version-string is not set, @@ -20,10 +44,9 @@ BTCVER=($($BITCOINCLI --version | head -n1 | awk -F'[ -]' '{ print $6, $7 }')) echo "[COPYRIGHT]" > footer.h2m $BITCOIND --version | sed -n '1!p' >> footer.h2m -for cmd in $BITCOIND $BITCOINCLI $BITCOINTX $BITCOINQT; do +for cmd in $BITCOIND $BITCOINCLI $BITCOINTX $WALLET_TOOL $BITCOINUTIL $BITCOINQT; do cmdname="${cmd##*/}" help2man -N --version-string=${BTCVER[0]} --include=footer.h2m -o ${MANDIR}/${cmdname}.1 ${cmd} - sed -i "s/\\\-${BTCVER[1]}//g" ${MANDIR}/${cmdname}.1 done rm -f footer.h2m diff --git a/contrib/devtools/pixie.py b/contrib/devtools/pixie.py new file mode 100644 index 0000000000..64660968ad --- /dev/null +++ b/contrib/devtools/pixie.py @@ -0,0 +1,323 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 Wladimir J. van der Laan +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +''' +Compact, self-contained ELF implementation for bitcoin-core security checks. +''' +import struct +import types +from typing import Dict, List, Optional, Union, Tuple + +# you can find all these values in elf.h +EI_NIDENT = 16 + +# Byte indices in e_ident +EI_CLASS = 4 # ELFCLASSxx +EI_DATA = 5 # ELFDATAxxxx + +ELFCLASS32 = 1 # 32-bit +ELFCLASS64 = 2 # 64-bit + +ELFDATA2LSB = 1 # little endian +ELFDATA2MSB = 2 # big endian + +# relevant values for e_machine +EM_386 = 3 +EM_PPC64 = 21 +EM_ARM = 40 +EM_AARCH64 = 183 +EM_X86_64 = 62 +EM_RISCV = 243 + +# relevant values for e_type +ET_DYN = 3 + +# relevant values for sh_type +SHT_PROGBITS = 1 +SHT_STRTAB = 3 +SHT_DYNAMIC = 6 +SHT_DYNSYM = 11 +SHT_GNU_verneed = 0x6ffffffe +SHT_GNU_versym = 0x6fffffff + +# relevant values for p_type +PT_LOAD = 1 +PT_GNU_STACK = 0x6474e551 +PT_GNU_RELRO = 0x6474e552 + +# relevant values for p_flags +PF_X = (1 << 0) +PF_W = (1 << 1) +PF_R = (1 << 2) + +# relevant values for d_tag +DT_NEEDED = 1 +DT_FLAGS = 30 + +# relevant values of `d_un.d_val' in the DT_FLAGS entry +DF_BIND_NOW = 0x00000008 + +# relevant d_tags with string payload +STRING_TAGS = {DT_NEEDED} + +# rrlevant values for ST_BIND subfield of st_info (symbol binding) +STB_LOCAL = 0 + +class ELFRecord(types.SimpleNamespace): + '''Unified parsing for ELF records.''' + def __init__(self, data: bytes, offset: int, eh: 'ELFHeader', total_size: Optional[int]) -> None: + hdr_struct = self.STRUCT[eh.ei_class][0][eh.ei_data] + if total_size is not None and hdr_struct.size > total_size: + raise ValueError(f'{self.__class__.__name__} header size too small ({total_size} < {hdr_struct.size})') + for field, value in zip(self.STRUCT[eh.ei_class][1], hdr_struct.unpack(data[offset:offset + hdr_struct.size])): + setattr(self, field, value) + +def BiStruct(chars: str) -> Dict[int, struct.Struct]: + '''Compile a struct parser for both endians.''' + return { + ELFDATA2LSB: struct.Struct('<' + chars), + ELFDATA2MSB: struct.Struct('>' + chars), + } + +class ELFHeader(ELFRecord): + FIELDS = ['e_type', 'e_machine', 'e_version', 'e_entry', 'e_phoff', 'e_shoff', 'e_flags', 'e_ehsize', 'e_phentsize', 'e_phnum', 'e_shentsize', 'e_shnum', 'e_shstrndx'] + STRUCT = { + ELFCLASS32: (BiStruct('HHIIIIIHHHHHH'), FIELDS), + ELFCLASS64: (BiStruct('HHIQQQIHHHHHH'), FIELDS), + } + + def __init__(self, data: bytes, offset: int) -> None: + self.e_ident = data[offset:offset + EI_NIDENT] + if self.e_ident[0:4] != b'\x7fELF': + raise ValueError('invalid ELF magic') + self.ei_class = self.e_ident[EI_CLASS] + self.ei_data = self.e_ident[EI_DATA] + + super().__init__(data, offset + EI_NIDENT, self, None) + + def __repr__(self) -> str: + return f'Header(e_ident={self.e_ident!r}, e_type={self.e_type}, e_machine={self.e_machine}, e_version={self.e_version}, e_entry={self.e_entry}, e_phoff={self.e_phoff}, e_shoff={self.e_shoff}, e_flags={self.e_flags}, e_ehsize={self.e_ehsize}, e_phentsize={self.e_phentsize}, e_phnum={self.e_phnum}, e_shentsize={self.e_shentsize}, e_shnum={self.e_shnum}, e_shstrndx={self.e_shstrndx})' + +class Section(ELFRecord): + name: Optional[bytes] = None + FIELDS = ['sh_name', 'sh_type', 'sh_flags', 'sh_addr', 'sh_offset', 'sh_size', 'sh_link', 'sh_info', 'sh_addralign', 'sh_entsize'] + STRUCT = { + ELFCLASS32: (BiStruct('IIIIIIIIII'), FIELDS), + ELFCLASS64: (BiStruct('IIQQQQIIQQ'), FIELDS), + } + + def __init__(self, data: bytes, offset: int, eh: ELFHeader) -> None: + super().__init__(data, offset, eh, eh.e_shentsize) + self._data = data + + def __repr__(self) -> str: + return f'Section(sh_name={self.sh_name}({self.name!r}), sh_type=0x{self.sh_type:x}, sh_flags={self.sh_flags}, sh_addr=0x{self.sh_addr:x}, sh_offset=0x{self.sh_offset:x}, sh_size={self.sh_size}, sh_link={self.sh_link}, sh_info={self.sh_info}, sh_addralign={self.sh_addralign}, sh_entsize={self.sh_entsize})' + + def contents(self) -> bytes: + '''Return section contents.''' + return self._data[self.sh_offset:self.sh_offset + self.sh_size] + +class ProgramHeader(ELFRecord): + STRUCT = { + # different ELF classes have the same fields, but in a different order to optimize space versus alignment + ELFCLASS32: (BiStruct('IIIIIIII'), ['p_type', 'p_offset', 'p_vaddr', 'p_paddr', 'p_filesz', 'p_memsz', 'p_flags', 'p_align']), + ELFCLASS64: (BiStruct('IIQQQQQQ'), ['p_type', 'p_flags', 'p_offset', 'p_vaddr', 'p_paddr', 'p_filesz', 'p_memsz', 'p_align']), + } + + def __init__(self, data: bytes, offset: int, eh: ELFHeader) -> None: + super().__init__(data, offset, eh, eh.e_phentsize) + + def __repr__(self) -> str: + return f'ProgramHeader(p_type={self.p_type}, p_offset={self.p_offset}, p_vaddr={self.p_vaddr}, p_paddr={self.p_paddr}, p_filesz={self.p_filesz}, p_memsz={self.p_memsz}, p_flags={self.p_flags}, p_align={self.p_align})' + +class Symbol(ELFRecord): + STRUCT = { + # different ELF classes have the same fields, but in a different order to optimize space versus alignment + ELFCLASS32: (BiStruct('IIIBBH'), ['st_name', 'st_value', 'st_size', 'st_info', 'st_other', 'st_shndx']), + ELFCLASS64: (BiStruct('IBBHQQ'), ['st_name', 'st_info', 'st_other', 'st_shndx', 'st_value', 'st_size']), + } + + def __init__(self, data: bytes, offset: int, eh: ELFHeader, symtab: Section, strings: bytes, version: Optional[bytes]) -> None: + super().__init__(data, offset, eh, symtab.sh_entsize) + self.name = _lookup_string(strings, self.st_name) + self.version = version + + def __repr__(self) -> str: + return f'Symbol(st_name={self.st_name}({self.name!r}), st_value={self.st_value}, st_size={self.st_size}, st_info={self.st_info}, st_other={self.st_other}, st_shndx={self.st_shndx}, version={self.version!r})' + + @property + def is_import(self) -> bool: + '''Returns whether the symbol is an imported symbol.''' + return self.st_bind != STB_LOCAL and self.st_shndx == 0 + + @property + def is_export(self) -> bool: + '''Returns whether the symbol is an exported symbol.''' + return self.st_bind != STB_LOCAL and self.st_shndx != 0 + + @property + def st_bind(self) -> int: + '''Returns STB_*.''' + return self.st_info >> 4 + +class Verneed(ELFRecord): + DEF = (BiStruct('HHIII'), ['vn_version', 'vn_cnt', 'vn_file', 'vn_aux', 'vn_next']) + STRUCT = { ELFCLASS32: DEF, ELFCLASS64: DEF } + + def __init__(self, data: bytes, offset: int, eh: ELFHeader) -> None: + super().__init__(data, offset, eh, None) + + def __repr__(self) -> str: + return f'Verneed(vn_version={self.vn_version}, vn_cnt={self.vn_cnt}, vn_file={self.vn_file}, vn_aux={self.vn_aux}, vn_next={self.vn_next})' + +class Vernaux(ELFRecord): + DEF = (BiStruct('IHHII'), ['vna_hash', 'vna_flags', 'vna_other', 'vna_name', 'vna_next']) + STRUCT = { ELFCLASS32: DEF, ELFCLASS64: DEF } + + def __init__(self, data: bytes, offset: int, eh: ELFHeader, strings: bytes) -> None: + super().__init__(data, offset, eh, None) + self.name = _lookup_string(strings, self.vna_name) + + def __repr__(self) -> str: + return f'Veraux(vna_hash={self.vna_hash}, vna_flags={self.vna_flags}, vna_other={self.vna_other}, vna_name={self.vna_name}({self.name!r}), vna_next={self.vna_next})' + +class DynTag(ELFRecord): + STRUCT = { + ELFCLASS32: (BiStruct('II'), ['d_tag', 'd_val']), + ELFCLASS64: (BiStruct('QQ'), ['d_tag', 'd_val']), + } + + def __init__(self, data: bytes, offset: int, eh: ELFHeader, section: Section) -> None: + super().__init__(data, offset, eh, section.sh_entsize) + + def __repr__(self) -> str: + return f'DynTag(d_tag={self.d_tag}, d_val={self.d_val})' + +def _lookup_string(data: bytes, index: int) -> bytes: + '''Look up string by offset in ELF string table.''' + endx = data.find(b'\x00', index) + assert endx != -1 + return data[index:endx] + +VERSYM_S = BiStruct('H') # .gnu_version section has a single 16-bit integer per symbol in the linked section +def _parse_symbol_table(section: Section, strings: bytes, eh: ELFHeader, versym: bytes, verneed: Dict[int, bytes]) -> List[Symbol]: + '''Parse symbol table, return a list of symbols.''' + data = section.contents() + symbols = [] + versym_iter = (verneed.get(v[0]) for v in VERSYM_S[eh.ei_data].iter_unpack(versym)) + for ofs, version in zip(range(0, len(data), section.sh_entsize), versym_iter): + symbols.append(Symbol(data, ofs, eh, section, strings, version)) + return symbols + +def _parse_verneed(section: Section, strings: bytes, eh: ELFHeader) -> Dict[int, bytes]: + '''Parse .gnu.version_r section, return a dictionary of {versym: 'GLIBC_...'}.''' + data = section.contents() + ofs = 0 + result = {} + while True: + verneed = Verneed(data, ofs, eh) + aofs = ofs + verneed.vn_aux + while True: + vernaux = Vernaux(data, aofs, eh, strings) + result[vernaux.vna_other] = vernaux.name + if not vernaux.vna_next: + break + aofs += vernaux.vna_next + + if not verneed.vn_next: + break + ofs += verneed.vn_next + + return result + +def _parse_dyn_tags(section: Section, strings: bytes, eh: ELFHeader) -> List[Tuple[int, Union[bytes, int]]]: + '''Parse dynamic tags. Return array of tuples.''' + data = section.contents() + ofs = 0 + result = [] + for ofs in range(0, len(data), section.sh_entsize): + tag = DynTag(data, ofs, eh, section) + val = _lookup_string(strings, tag.d_val) if tag.d_tag in STRING_TAGS else tag.d_val + result.append((tag.d_tag, val)) + + return result + +class ELFFile: + sections: List[Section] + program_headers: List[ProgramHeader] + dyn_symbols: List[Symbol] + dyn_tags: List[Tuple[int, Union[bytes, int]]] + + def __init__(self, data: bytes) -> None: + self.data = data + self.hdr = ELFHeader(self.data, 0) + self._load_sections() + self._load_program_headers() + self._load_dyn_symbols() + self._load_dyn_tags() + self._section_to_segment_mapping() + + def _load_sections(self) -> None: + self.sections = [] + for idx in range(self.hdr.e_shnum): + offset = self.hdr.e_shoff + idx * self.hdr.e_shentsize + self.sections.append(Section(self.data, offset, self.hdr)) + + shstr = self.sections[self.hdr.e_shstrndx].contents() + for section in self.sections: + section.name = _lookup_string(shstr, section.sh_name) + + def _load_program_headers(self) -> None: + self.program_headers = [] + for idx in range(self.hdr.e_phnum): + offset = self.hdr.e_phoff + idx * self.hdr.e_phentsize + self.program_headers.append(ProgramHeader(self.data, offset, self.hdr)) + + def _load_dyn_symbols(self) -> None: + # first, load 'verneed' section + verneed = None + for section in self.sections: + if section.sh_type == SHT_GNU_verneed: + strtab = self.sections[section.sh_link].contents() # associated string table + assert verneed is None # only one section of this kind please + verneed = _parse_verneed(section, strtab, self.hdr) + assert verneed is not None + + # then, correlate GNU versym sections with dynamic symbol sections + versym = {} + for section in self.sections: + if section.sh_type == SHT_GNU_versym: + versym[section.sh_link] = section + + # finally, load dynsym sections + self.dyn_symbols = [] + for idx, section in enumerate(self.sections): + if section.sh_type == SHT_DYNSYM: # find dynamic symbol tables + strtab_data = self.sections[section.sh_link].contents() # associated string table + versym_data = versym[idx].contents() # associated symbol version table + self.dyn_symbols += _parse_symbol_table(section, strtab_data, self.hdr, versym_data, verneed) + + def _load_dyn_tags(self) -> None: + self.dyn_tags = [] + for idx, section in enumerate(self.sections): + if section.sh_type == SHT_DYNAMIC: # find dynamic tag tables + strtab = self.sections[section.sh_link].contents() # associated string table + self.dyn_tags += _parse_dyn_tags(section, strtab, self.hdr) + + def _section_to_segment_mapping(self) -> None: + for ph in self.program_headers: + ph.sections = [] + for section in self.sections: + if ph.p_vaddr <= section.sh_addr < (ph.p_vaddr + ph.p_memsz): + ph.sections.append(section) + + def query_dyn_tags(self, tag_in: int) -> List[Union[int, bytes]]: + '''Return the values of all dyn tags with the specified tag.''' + return [val for (tag, val) in self.dyn_tags if tag == tag_in] + + +def load(filename: str) -> ELFFile: + with open(filename, 'rb') as f: + data = f.read() + return ELFFile(data) diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index 4a5651a851..0b59d8eada 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -1,216 +1,261 @@ -#!/usr/bin/python2 -# Copyright (c) 2015-2016 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2020 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' -Perform basic ELF security checks on a series of executables. +Perform basic security checks on a series of executables. Exit status will be 0 if successful, and the program will be silent. Otherwise the exit status will be 1 and it will log which executables failed which checks. -Needs `readelf` (for ELF) and `objdump` (for PE). ''' -from __future__ import division,print_function,unicode_literals -import subprocess import sys -import os +from typing import List, Optional -READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') -OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump') -NONFATAL = {'HIGH_ENTROPY_VA'} # checks which are non-fatal for now but only generate a warning +import lief +import pixie -def check_ELF_PIE(executable): +def check_ELF_PIE(executable) -> bool: ''' Check for position independent executable (PIE), allowing for address space randomization. ''' - p = subprocess.Popen([READELF_CMD, '-h', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') + elf = pixie.load(executable) + return elf.hdr.e_type == pixie.ET_DYN - ok = False - for line in stdout.split(b'\n'): - line = line.split() - if len(line)>=2 and line[0] == b'Type:' and line[1] == b'DYN': - ok = True - return ok - -def get_ELF_program_headers(executable): - '''Return type and flags for ELF program headers''' - p = subprocess.Popen([READELF_CMD, '-l', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') - in_headers = False - count = 0 - headers = [] - for line in stdout.split(b'\n'): - if line.startswith(b'Program Headers:'): - in_headers = True - if line == b'': - in_headers = False - if in_headers: - if count == 1: # header line - ofs_typ = line.find(b'Type') - ofs_offset = line.find(b'Offset') - ofs_flags = line.find(b'Flg') - ofs_align = line.find(b'Align') - if ofs_typ == -1 or ofs_offset == -1 or ofs_flags == -1 or ofs_align == -1: - raise ValueError('Cannot parse elfread -lW output') - elif count > 1: - typ = line[ofs_typ:ofs_offset].rstrip() - flags = line[ofs_flags:ofs_align].rstrip() - headers.append((typ, flags)) - count += 1 - return headers - -def check_ELF_NX(executable): +def check_ELF_NX(executable) -> bool: ''' Check that no sections are writable and executable (including the stack) ''' + elf = pixie.load(executable) have_wx = False have_gnu_stack = False - for (typ, flags) in get_ELF_program_headers(executable): - if typ == b'GNU_STACK': + for ph in elf.program_headers: + if ph.p_type == pixie.PT_GNU_STACK: have_gnu_stack = True - if b'W' in flags and b'E' in flags: # section is both writable and executable + if (ph.p_flags & pixie.PF_W) != 0 and (ph.p_flags & pixie.PF_X) != 0: # section is both writable and executable have_wx = True return have_gnu_stack and not have_wx -def check_ELF_RELRO(executable): +def check_ELF_RELRO(executable) -> bool: ''' Check for read-only relocations. GNU_RELRO program header must exist Dynamic section must have BIND_NOW flag ''' + elf = pixie.load(executable) have_gnu_relro = False - for (typ, flags) in get_ELF_program_headers(executable): - # Note: not checking flags == 'R': here as linkers set the permission differently - # This does not affect security: the permission flags of the GNU_RELRO program header are ignored, the PT_LOAD header determines the effective permissions. + for ph in elf.program_headers: + # Note: not checking p_flags == PF_R: here as linkers set the permission differently + # This does not affect security: the permission flags of the GNU_RELRO program + # header are ignored, the PT_LOAD header determines the effective permissions. # However, the dynamic linker need to write to this area so these are RW. # Glibc itself takes care of mprotecting this area R after relocations are finished. - # See also http://permalink.gmane.org/gmane.comp.gnu.binutils/71347 - if typ == b'GNU_RELRO': + # See also https://marc.info/?l=binutils&m=1498883354122353 + if ph.p_type == pixie.PT_GNU_RELRO: have_gnu_relro = True have_bindnow = False - p = subprocess.Popen([READELF_CMD, '-d', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') - for line in stdout.split(b'\n'): - tokens = line.split() - if len(tokens)>1 and tokens[1] == b'(BIND_NOW)' or (len(tokens)>2 and tokens[1] == b'(FLAGS)' and b'BIND_NOW' in tokens[2]): + for flags in elf.query_dyn_tags(pixie.DT_FLAGS): + assert isinstance(flags, int) + if flags & pixie.DF_BIND_NOW: have_bindnow = True + return have_gnu_relro and have_bindnow -def check_ELF_Canary(executable): +def check_ELF_Canary(executable) -> bool: ''' Check for use of stack canary ''' - p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') + elf = pixie.load(executable) ok = False - for line in stdout.split(b'\n'): - if b'__stack_chk_fail' in line: + for symbol in elf.dyn_symbols: + if symbol.name == b'__stack_chk_fail': ok = True return ok -def get_PE_dll_characteristics(executable): - ''' - Get PE DllCharacteristics bits. - Returns a tuple (arch,bits) where arch is 'i386:x86-64' or 'i386' - and bits is the DllCharacteristics value. - ''' - p = subprocess.Popen([OBJDUMP_CMD, '-x', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') - arch = '' - bits = 0 - for line in stdout.split('\n'): - tokens = line.split() - if len(tokens)>=2 and tokens[0] == 'architecture:': - arch = tokens[1].rstrip(',') - if len(tokens)>=2 and tokens[0] == 'DllCharacteristics': - bits = int(tokens[1],16) - return (arch,bits) - -IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020 -IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040 -IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100 - -def check_PE_DYNAMIC_BASE(executable): +def check_ELF_separate_code(executable): + ''' + Check that sections are appropriately separated in virtual memory, + based on their permissions. This checks for missing -Wl,-z,separate-code + and potentially other problems. + ''' + elf = pixie.load(executable) + R = pixie.PF_R + W = pixie.PF_W + E = pixie.PF_X + EXPECTED_FLAGS = { + # Read + execute + b'.init': R | E, + b'.plt': R | E, + b'.plt.got': R | E, + b'.plt.sec': R | E, + b'.text': R | E, + b'.fini': R | E, + # Read-only data + b'.interp': R, + b'.note.gnu.property': R, + b'.note.gnu.build-id': R, + b'.note.ABI-tag': R, + b'.gnu.hash': R, + b'.dynsym': R, + b'.dynstr': R, + b'.gnu.version': R, + b'.gnu.version_r': R, + b'.rela.dyn': R, + b'.rela.plt': R, + b'.rodata': R, + b'.eh_frame_hdr': R, + b'.eh_frame': R, + b'.qtmetadata': R, + b'.gcc_except_table': R, + b'.stapsdt.base': R, + # Writable data + b'.init_array': R | W, + b'.fini_array': R | W, + b'.dynamic': R | W, + b'.got': R | W, + b'.data': R | W, + b'.bss': R | W, + } + if elf.hdr.e_machine == pixie.EM_PPC64: + # .plt is RW on ppc64 even with separate-code + EXPECTED_FLAGS[b'.plt'] = R | W + # For all LOAD program headers get mapping to the list of sections, + # and for each section, remember the flags of the associated program header. + flags_per_section = {} + for ph in elf.program_headers: + if ph.p_type == pixie.PT_LOAD: + for section in ph.sections: + assert(section.name not in flags_per_section) + flags_per_section[section.name] = ph.p_flags + # Spot-check ELF LOAD program header flags per section + # If these sections exist, check them against the expected R/W/E flags + for (section, flags) in flags_per_section.items(): + if section in EXPECTED_FLAGS: + if EXPECTED_FLAGS[section] != flags: + return False + return True + +def check_PE_DYNAMIC_BASE(executable) -> bool: '''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)''' - (arch,bits) = get_PE_dll_characteristics(executable) - reqbits = IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE - return (bits & reqbits) == reqbits + binary = lief.parse(executable) + return lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists -# On 64 bit, must support high-entropy 64-bit address space layout randomization in addition to DYNAMIC_BASE -# to have secure ASLR. -def check_PE_HIGH_ENTROPY_VA(executable): +# Must support high-entropy 64-bit address space layout randomization +# in addition to DYNAMIC_BASE to have secure ASLR. +def check_PE_HIGH_ENTROPY_VA(executable) -> bool: '''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR''' - (arch,bits) = get_PE_dll_characteristics(executable) - if arch == 'i386:x86-64': - reqbits = IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA - else: # Unnecessary on 32-bit - assert(arch == 'i386') - reqbits = 0 - return (bits & reqbits) == reqbits - -def check_PE_NX(executable): - '''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)''' - (arch,bits) = get_PE_dll_characteristics(executable) - return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT + binary = lief.parse(executable) + return lief.PE.DLL_CHARACTERISTICS.HIGH_ENTROPY_VA in binary.optional_header.dll_characteristics_lists + +def check_PE_RELOC_SECTION(executable) -> bool: + '''Check for a reloc section. This is required for functional ASLR.''' + binary = lief.parse(executable) + return binary.has_relocations + +def check_MACHO_NOUNDEFS(executable) -> bool: + ''' + Check for no undefined references. + ''' + binary = lief.parse(executable) + return binary.header.has(lief.MachO.HEADER_FLAGS.NOUNDEFS) + +def check_MACHO_LAZY_BINDINGS(executable) -> bool: + ''' + Check for no lazy bindings. + We don't use or check for MH_BINDATLOAD. See #18295. + ''' + binary = lief.parse(executable) + return binary.dyld_info.lazy_bind == (0,0) + +def check_MACHO_Canary(executable) -> bool: + ''' + Check for use of stack canary + ''' + binary = lief.parse(executable) + return binary.has_symbol('___stack_chk_fail') + +def check_PIE(executable) -> bool: + ''' + Check for position independent executable (PIE), + allowing for address space randomization. + ''' + binary = lief.parse(executable) + return binary.is_pie + +def check_NX(executable) -> bool: + ''' + Check for no stack execution + ''' + binary = lief.parse(executable) + return binary.has_nx + +def check_control_flow(executable) -> bool: + ''' + Check for control flow instrumentation + ''' + binary = lief.parse(executable) + + content = binary.get_content_from_virtual_address(binary.entrypoint, 4, lief.Binary.VA_TYPES.AUTO) + + if content == [243, 15, 30, 250]: # endbr64 + return True + return False + CHECKS = { 'ELF': [ ('PIE', check_ELF_PIE), ('NX', check_ELF_NX), ('RELRO', check_ELF_RELRO), - ('Canary', check_ELF_Canary) + ('Canary', check_ELF_Canary), + ('separate_code', check_ELF_separate_code), ], 'PE': [ + ('PIE', check_PIE), ('DYNAMIC_BASE', check_PE_DYNAMIC_BASE), ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), - ('NX', check_PE_NX) + ('NX', check_NX), + ('RELOC_SECTION', check_PE_RELOC_SECTION) +], +'MACHO': [ + ('PIE', check_PIE), + ('NOUNDEFS', check_MACHO_NOUNDEFS), + ('NX', check_NX), + ('LAZY_BINDINGS', check_MACHO_LAZY_BINDINGS), + ('Canary', check_MACHO_Canary), + ('CONTROL_FLOW', check_control_flow), ] } -def identify_executable(executable): +def identify_executable(executable) -> Optional[str]: with open(filename, 'rb') as f: magic = f.read(4) if magic.startswith(b'MZ'): return 'PE' elif magic.startswith(b'\x7fELF'): return 'ELF' + elif magic.startswith(b'\xcf\xfa'): + return 'MACHO' return None if __name__ == '__main__': - retval = 0 + retval: int = 0 for filename in sys.argv[1:]: try: etype = identify_executable(filename) if etype is None: - print('%s: unknown format' % filename) + print(f'{filename}: unknown format') retval = 1 continue - failed = [] - warning = [] + failed: List[str] = [] for (name, func) in CHECKS[etype]: if not func(filename): - if name in NONFATAL: - warning.append(name) - else: - failed.append(name) + failed.append(name) if failed: - print('%s: failed %s' % (filename, ' '.join(failed))) + print(f'{filename}: failed {" ".join(failed)}') retval = 1 - if warning: - print('%s: warning %s' % (filename, ' '.join(warning))) except IOError: - print('%s: cannot open' % filename) + print(f'{filename}: cannot open') retval = 1 - exit(retval) + sys.exit(retval) diff --git a/contrib/devtools/split-debug.sh.in b/contrib/devtools/split-debug.sh.in index deda49cc54..92b72b1446 100644 --- a/contrib/devtools/split-debug.sh.in +++ b/contrib/devtools/split-debug.sh.in @@ -1,5 +1,5 @@ #!/bin/sh - +set -e if [ $# -ne 3 ]; then echo "usage: $0 " fi diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index e26c0fbb94..0523b49bd1 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -1,74 +1,137 @@ -#!/usr/bin/python2 +#!/usr/bin/env python3 # Copyright (c) 2014 Wladimir J. van der Laan # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' -A script to check that the (Linux) executables produced by gitian only contain -allowed gcc, glibc and libstdc++ version symbols. This makes sure they are -still compatible with the minimum supported Linux distribution versions. +A script to check that release executables only contain certain symbols +and are only linked against allowed libraries. Example usage: - find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py + find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py ''' -from __future__ import division, print_function, unicode_literals import subprocess -import re import sys -import os +from typing import List, Optional -# Debian 6.0.9 (Squeeze) has: +import lief +import pixie + +from utils import determine_wellknown_cmd + +# Debian 8 (Jessie) EOL: 2020. https://wiki.debian.org/DebianReleases#Production_Releases +# +# - g++ version 4.9.2 (https://packages.debian.org/search?suite=jessie&arch=any&searchon=names&keywords=g%2B%2B) +# - libc version 2.19 (https://packages.debian.org/search?suite=jessie&arch=any&searchon=names&keywords=libc6) # -# - g++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=g%2B%2B) -# - libc version 2.11.3 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libc6) -# - libstdc++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libstdc%2B%2B6) +# Ubuntu 16.04 (Xenial) EOL: 2024. https://wiki.ubuntu.com/Releases # -# Ubuntu 10.04.4 (Lucid Lynx) has: +# - g++ version 5.3.1 (https://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=xenial§ion=all) +# - libc version 2.23.0 (https://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=xenial§ion=all) # -# - g++ version 4.4.3 (http://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=lucid§ion=all) -# - libc version 2.11.1 (http://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=lucid§ion=all) -# - libstdc++ version 4.4.3 (http://packages.ubuntu.com/search?suite=lucid§ion=all&arch=any&keywords=libstdc%2B%2B&searchon=names) +# CentOS 7 EOL: 2024. https://wiki.centos.org/FAQ/General +# +# - g++ version 4.8.5 (http://mirror.centos.org/centos/7/os/x86_64/Packages/) +# - libc version 2.17 (http://mirror.centos.org/centos/7/os/x86_64/Packages/) # # Taking the minimum of these as our target. # -# According to GNU ABI document (http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to: -# GCC 4.4.0: GCC_4.4.0 -# GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3 -# (glibc) GLIBC_2_11 +# According to GNU ABI document (https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to: +# GCC 4.8.5: GCC_4.8.0 +# (glibc) GLIBC_2_17 # MAX_VERSIONS = { -'GCC': (4,4,0), -'CXXABI': (1,3,3), -'GLIBCXX': (3,4,13), -'GLIBC': (2,11) +'GCC': (4,8,0), +'GLIBC': { + pixie.EM_386: (2,17), + pixie.EM_X86_64: (2,17), + pixie.EM_ARM: (2,17), + pixie.EM_AARCH64:(2,17), + pixie.EM_PPC64: (2,17), + pixie.EM_RISCV: (2,27), +}, +'LIBATOMIC': (1,0), +'V': (0,5,0), # xkb (bitcoin-qt only) } # See here for a description of _IO_stdin_used: # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 # Ignore symbols that are exported as part of every executable IGNORE_EXPORTS = { -b'_edata', b'_end', b'_init', b'__bss_start', b'_fini', b'_IO_stdin_used' +'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__', '__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr', 'in6addr_any', +'environ', '_environ', '__environ', } -READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') -CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') + # Allowed NEEDED libraries -ALLOWED_LIBRARIES = { +ELF_ALLOWED_LIBRARIES = { +# bitcoind and bitcoin-qt +'libgcc_s.so.1', # GCC base support +'libc.so.6', # C library +'libpthread.so.0', # threading +'libm.so.6', # math library +'librt.so.1', # real-time (clock) +'libatomic.so.1', +'ld-linux-x86-64.so.2', # 64-bit dynamic linker +'ld-linux.so.2', # 32-bit dynamic linker +'ld-linux-aarch64.so.1', # 64-bit ARM dynamic linker +'ld-linux-armhf.so.3', # 32-bit ARM dynamic linker +'ld64.so.1', # POWER64 ABIv1 dynamic linker +'ld64.so.2', # POWER64 ABIv2 dynamic linker +'ld-linux-riscv64-lp64d.so.1', # 64-bit RISC-V dynamic linker +# bitcoin-qt only +'libxcb.so.1', # part of X11 +'libxkbcommon.so.0', # keyboard keymapping +'libxkbcommon-x11.so.0', # keyboard keymapping +'libfontconfig.so.1', # font support +'libfreetype.so.6', # font parsing +'libdl.so.2' # programming interface to dynamic linker +} + +MACHO_ALLOWED_LIBRARIES = { # bitcoind and bitcoin-qt -b'libgcc_s.so.1', # GCC base support -b'libc.so.6', # C library -b'libpthread.so.0', # threading -b'libanl.so.1', # DNS resolve -b'libm.so.6', # math library -b'librt.so.1', # real-time (clock) -b'ld-linux-x86-64.so.2', # 64-bit dynamic linker -b'ld-linux.so.2', # 32-bit dynamic linker +'libc++.1.dylib', # C++ Standard Library +'libSystem.B.dylib', # libc, libm, libpthread, libinfo # bitcoin-qt only -b'libX11-xcb.so.1', # part of X11 -b'libX11.so.6', # part of X11 -b'libxcb.so.1', # part of X11 -b'libfontconfig.so.1', # font support -b'libfreetype.so.6', # font parsing -b'libdl.so.2' # programming interface to dynamic linker +'AppKit', # user interface +'ApplicationServices', # common application tasks. +'Carbon', # deprecated c back-compat API +'CoreFoundation', # low level func, data types +'CoreGraphics', # 2D rendering +'CoreServices', # operating system services +'CoreText', # interface for laying out text and handling fonts. +'CoreVideo', # video processing +'Foundation', # base layer functionality for apps/frameworks +'ImageIO', # read and write image file formats. +'IOKit', # user-space access to hardware devices and drivers. +'IOSurface', # cross process image/drawing buffers +'Security', # secure the data your app manages, and control access to your app. +'libobjc.A.dylib', # Objective-C runtime library +'Metal', # 3D graphics +'Security', # access control and authentication +'QuartzCore', # animation +} + +PE_ALLOWED_LIBRARIES = { +'ADVAPI32.dll', # security & registry +'IPHLPAPI.DLL', # IP helper API +'KERNEL32.dll', # win32 base APIs +'msvcrt.dll', # C standard library for MSVC +'SHELL32.dll', # shell API +'USER32.dll', # user interface +'WS2_32.dll', # sockets +# bitcoin-qt only +'dwmapi.dll', # desktop window manager +'GDI32.dll', # graphics device interface +'IMM32.dll', # input method editor +'NETAPI32.dll', +'ole32.dll', # component object model +'OLEAUT32.dll', # OLE Automation API +'SHLWAPI.dll', # light weight shell API +'USERENV.dll', +'UxTheme.dll', +'VERSION.dll', # version checking +'WINMM.dll', # WinMM audio API +'WTSAPI32.dll', } class CPPFilt(object): @@ -78,10 +141,10 @@ class CPPFilt(object): Use a pipe to the 'c++filt' command. ''' def __init__(self): - self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + self.proc = subprocess.Popen(determine_wellknown_cmd('CPPFILT', 'c++filt'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) def __call__(self, mangled): - self.proc.stdin.write(mangled + b'\n') + self.proc.stdin.write(mangled + '\n') self.proc.stdin.flush() return self.proc.stdout.readline().rstrip() @@ -90,75 +153,144 @@ def close(self): self.proc.stdout.close() self.proc.wait() -def read_symbols(executable, imports=True): - ''' - Parse an ELF executable and return a list of (symbol,version) tuples - for dynamic, imported symbols. - ''' - p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip())) - syms = [] - for line in stdout.split(b'\n'): - line = line.split() - if len(line)>7 and re.match(b'[0-9]+:$', line[0]): - (sym, _, version) = line[7].partition(b'@') - is_import = line[6] == b'UND' - if version.startswith(b'@'): - version = version[1:] - if is_import == imports: - syms.append((sym, version)) - return syms - -def check_version(max_versions, version): - if b'_' in version: - (lib, _, ver) = version.rpartition(b'_') +def check_version(max_versions, version, arch) -> bool: + if '_' in version: + (lib, _, ver) = version.rpartition('_') else: lib = version ver = '0' - ver = tuple([int(x) for x in ver.split(b'.')]) + ver = tuple([int(x) for x in ver.split('.')]) if not lib in max_versions: return False - return ver <= max_versions[lib] - -def read_libraries(filename): - p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') - libraries = [] - for line in stdout.split(b'\n'): - tokens = line.split() - if len(tokens)>2 and tokens[1] == b'(NEEDED)': - match = re.match(b'^Shared library: \[(.*)\]$', b' '.join(tokens[2:])) - if match: - libraries.append(match.group(1)) - else: - raise ValueError('Unparseable (NEEDED) specification') - return libraries + if isinstance(max_versions[lib], tuple): + return ver <= max_versions[lib] + else: + return ver <= max_versions[lib][arch] -if __name__ == '__main__': +def check_imported_symbols(filename) -> bool: + elf = pixie.load(filename) + cppfilt = CPPFilt() + ok: bool = True + + for symbol in elf.dyn_symbols: + if not symbol.is_import: + continue + sym = symbol.name.decode() + version = symbol.version.decode() if symbol.version is not None else None + if version and not check_version(MAX_VERSIONS, version, elf.hdr.e_machine): + print('{}: symbol {} from unsupported version {}'.format(filename, cppfilt(sym), version)) + ok = False + return ok + +def check_exported_symbols(filename) -> bool: + elf = pixie.load(filename) cppfilt = CPPFilt() - retval = 0 + ok: bool = True + for symbol in elf.dyn_symbols: + if not symbol.is_export: + continue + sym = symbol.name.decode() + if elf.hdr.e_machine == pixie.EM_RISCV or sym in IGNORE_EXPORTS: + continue + print('{}: export of symbol {} not allowed'.format(filename, cppfilt(sym))) + ok = False + return ok + +def check_ELF_libraries(filename) -> bool: + ok: bool = True + elf = pixie.load(filename) + for library_name in elf.query_dyn_tags(pixie.DT_NEEDED): + assert(isinstance(library_name, bytes)) + if library_name.decode() not in ELF_ALLOWED_LIBRARIES: + print('{}: NEEDED library {} is not allowed'.format(filename, library_name.decode())) + ok = False + return ok + +def check_MACHO_libraries(filename) -> bool: + ok: bool = True + binary = lief.parse(filename) + for dylib in binary.libraries: + split = dylib.name.split('/') + if split[-1] not in MACHO_ALLOWED_LIBRARIES: + print(f'{split[-1]} is not in ALLOWED_LIBRARIES!') + ok = False + return ok + +def check_MACHO_min_os(filename) -> bool: + binary = lief.parse(filename) + if binary.build_version.minos == [10,14,0]: + return True + return False + +def check_MACHO_sdk(filename) -> bool: + binary = lief.parse(filename) + if binary.build_version.sdk == [10, 15, 6]: + return True + return False + +def check_PE_libraries(filename) -> bool: + ok: bool = True + binary = lief.parse(filename) + for dylib in binary.libraries: + if dylib not in PE_ALLOWED_LIBRARIES: + print(f'{dylib} is not in ALLOWED_LIBRARIES!') + ok = False + return ok + +def check_PE_subsystem_version(filename) -> bool: + binary = lief.parse(filename) + major: int = binary.optional_header.major_subsystem_version + minor: int = binary.optional_header.minor_subsystem_version + if major == 6 and minor == 1: + return True + return False + +CHECKS = { +'ELF': [ + ('IMPORTED_SYMBOLS', check_imported_symbols), + ('EXPORTED_SYMBOLS', check_exported_symbols), + ('LIBRARY_DEPENDENCIES', check_ELF_libraries) +], +'MACHO': [ + ('DYNAMIC_LIBRARIES', check_MACHO_libraries), + ('MIN_OS', check_MACHO_min_os), + ('SDK', check_MACHO_sdk), +], +'PE' : [ + ('DYNAMIC_LIBRARIES', check_PE_libraries), + ('SUBSYSTEM_VERSION', check_PE_subsystem_version), +] +} + +def identify_executable(executable) -> Optional[str]: + with open(filename, 'rb') as f: + magic = f.read(4) + if magic.startswith(b'MZ'): + return 'PE' + elif magic.startswith(b'\x7fELF'): + return 'ELF' + elif magic.startswith(b'\xcf\xfa'): + return 'MACHO' + return None + +if __name__ == '__main__': + retval: int = 0 for filename in sys.argv[1:]: - # Check imported symbols - for sym,version in read_symbols(filename, True): - if version and not check_version(MAX_VERSIONS, version): - print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym).decode('utf-8'), version.decode('utf-8'))) + try: + etype = identify_executable(filename) + if etype is None: + print(f'{filename}: unknown format') retval = 1 - # Check exported symbols - for sym,version in read_symbols(filename, False): - if sym in IGNORE_EXPORTS: continue - print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym).decode('utf-8'))) - retval = 1 - # Check dependency libraries - for library_name in read_libraries(filename): - if library_name not in ALLOWED_LIBRARIES: - print('%s: NEEDED library %s is not allowed' % (filename, library_name.decode('utf-8'))) - retval = 1 - - exit(retval) - + failed: List[str] = [] + for (name, func) in CHECKS[etype]: + if not func(filename): + failed.append(name) + if failed: + print(f'{filename}: failed {" ".join(failed)}') + retval = 1 + except IOError: + print(f'{filename}: cannot open') + retval = 1 + sys.exit(retval) diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index 58817089c1..14058e2cc8 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -1,17 +1,18 @@ -#!/usr/bin/python2 -# Copyright (c) 2015-2016 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2020 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Test script for security-check.py ''' -from __future__ import division,print_function +import os import subprocess -import sys import unittest +from utils import determine_wellknown_cmd + def write_testcode(filename): - with open(filename, 'w') as f: + with open(filename, 'w', encoding="utf8") as f: f.write(''' #include int main() @@ -21,43 +22,80 @@ def write_testcode(filename): } ''') +def clean_files(source, executable): + os.remove(source) + os.remove(executable) + def call_security_check(cc, source, executable, options): - subprocess.check_call([cc,source,'-o',executable] + options) - p = subprocess.Popen(['./security-check.py',executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = p.communicate() - return (p.returncode, stdout.rstrip()) + subprocess.run([*cc,source,'-o',executable] + options, check=True) + p = subprocess.run(['./contrib/devtools/security-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True) + return (p.returncode, p.stdout.rstrip()) class TestSecurityChecks(unittest.TestCase): def test_ELF(self): source = 'test1.c' executable = 'test1' - cc = 'gcc' + cc = determine_wellknown_cmd('CC', 'gcc') write_testcode(source) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), (1, executable+': failed PIE NX RELRO Canary')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), (1, executable+': failed PIE RELRO Canary')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), (1, executable+': failed PIE RELRO')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-pie','-fPIE']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), (1, executable+': failed RELRO')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), + (1, executable+': failed separate_code')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), (0, '')) + clean_files(source, executable) + def test_PE(self): source = 'test1.c' executable = 'test1.exe' - cc = 'i686-w64-mingw32-gcc' + cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc') write_testcode(source) - self.assertEqual(call_security_check(cc, source, executable, []), - (1, executable+': failed PIE NX')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat']), - (1, executable+': failed PIE')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase']), - (0, '')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--disable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']), + (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--disable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']), + (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']), + (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-pie','-fPIE']), + (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA')) # -pie -fPIE does nothing unless --dynamicbase is also supplied + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--no-high-entropy-va','-pie','-fPIE']), + (1, executable+': failed HIGH_ENTROPY_VA')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE']), + (0, '')) + + clean_files(source, executable) + + def test_MACHO(self): + source = 'test1.c' + executable = 'test1' + cc = determine_wellknown_cmd('CC', 'clang') + write_testcode(source) + + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector']), + (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS Canary CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fstack-protector-all']), + (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fstack-protector-all']), + (1, executable+': failed PIE NOUNDEFS LAZY_BINDINGS CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all']), + (1, executable+': failed PIE LAZY_BINDINGS CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all']), + (1, executable+': failed PIE CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all', '-fcf-protection=full']), + (1, executable+': failed PIE')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-Wl,-bind_at_load','-fstack-protector-all', '-fcf-protection=full']), + (0, '')) + + clean_files(source, executable) if __name__ == '__main__': unittest.main() - diff --git a/contrib/devtools/test-symbol-check.py b/contrib/devtools/test-symbol-check.py new file mode 100755 index 0000000000..7d83c5f751 --- /dev/null +++ b/contrib/devtools/test-symbol-check.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +''' +Test script for symbol-check.py +''' +import os +import subprocess +from typing import List +import unittest + +from utils import determine_wellknown_cmd + +def call_symbol_check(cc: List[str], source, executable, options): + subprocess.run([*cc,source,'-o',executable] + options, check=True) + p = subprocess.run(['./contrib/devtools/symbol-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True) + os.remove(source) + os.remove(executable) + return (p.returncode, p.stdout.rstrip()) + +def get_machine(cc: List[str]): + p = subprocess.run([*cc,'-dumpmachine'], stdout=subprocess.PIPE, universal_newlines=True) + return p.stdout.rstrip() + +class TestSymbolChecks(unittest.TestCase): + def test_ELF(self): + source = 'test1.c' + executable = 'test1' + cc = determine_wellknown_cmd('CC', 'gcc') + + # there's no way to do this test for RISC-V at the moment; we build for + # RISC-V in a glibc 2.27 envinonment and we allow all symbols from 2.27. + if 'riscv' in get_machine(cc): + self.skipTest("test not available for RISC-V") + + # nextup was introduced in GLIBC 2.24, so is newer than our supported + # glibc (2.17), and available in our release build environment (2.24). + with open(source, 'w', encoding="utf8") as f: + f.write(''' + #define _GNU_SOURCE + #include + + double nextup(double x); + + int main() + { + nextup(3.14); + return 0; + } + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-lm']), + (1, executable + ': symbol nextup from unsupported version GLIBC_2.24\n' + + executable + ': failed IMPORTED_SYMBOLS')) + + # -lutil is part of the libc6 package so a safe bet that it's installed + # it's also out of context enough that it's unlikely to ever become a real dependency + source = 'test2.c' + executable = 'test2' + with open(source, 'w', encoding="utf8") as f: + f.write(''' + #include + + int main() + { + login(0); + return 0; + } + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-lutil']), + (1, executable + ': NEEDED library libutil.so.1 is not allowed\n' + + executable + ': failed LIBRARY_DEPENDENCIES')) + + # finally, check a conforming file that simply uses a math function + source = 'test3.c' + executable = 'test3' + with open(source, 'w', encoding="utf8") as f: + f.write(''' + #include + + int main() + { + return (int)pow(2.0, 4.0); + } + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-lm']), + (0, '')) + + def test_MACHO(self): + source = 'test1.c' + executable = 'test1' + cc = determine_wellknown_cmd('CC', 'clang') + + with open(source, 'w', encoding="utf8") as f: + f.write(''' + #include + + int main() + { + XML_ExpatVersion(); + return 0; + } + + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-lexpat', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']), + (1, 'libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' + + f'{executable}: failed DYNAMIC_LIBRARIES MIN_OS SDK')) + + source = 'test2.c' + executable = 'test2' + with open(source, 'w', encoding="utf8") as f: + f.write(''' + #include + + int main() + { + CGMainDisplayID(); + return 0; + } + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-framework', 'CoreGraphics', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']), + (1, f'{executable}: failed MIN_OS SDK')) + + source = 'test3.c' + executable = 'test3' + with open(source, 'w', encoding="utf8") as f: + f.write(''' + int main() + { + return 0; + } + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,10.14', '-Wl,11.4']), + (1, f'{executable}: failed SDK')) + + def test_PE(self): + source = 'test1.c' + executable = 'test1.exe' + cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc') + + with open(source, 'w', encoding="utf8") as f: + f.write(''' + #include + + int main() + { + PdhConnectMachineA(NULL); + return 0; + } + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-lpdh', '-Wl,--major-subsystem-version', '-Wl,6', '-Wl,--minor-subsystem-version', '-Wl,1']), + (1, 'pdh.dll is not in ALLOWED_LIBRARIES!\n' + + executable + ': failed DYNAMIC_LIBRARIES')) + + source = 'test2.c' + executable = 'test2.exe' + + with open(source, 'w', encoding="utf8") as f: + f.write(''' + int main() + { + return 0; + } + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,--major-subsystem-version', '-Wl,9', '-Wl,--minor-subsystem-version', '-Wl,9']), + (1, executable + ': failed SUBSYSTEM_VERSION')) + + source = 'test3.c' + executable = 'test3.exe' + with open(source, 'w', encoding="utf8") as f: + f.write(''' + #include + + int main() + { + CoFreeUnusedLibrariesEx(0,0); + return 0; + } + ''') + + self.assertEqual(call_symbol_check(cc, source, executable, ['-lole32', '-Wl,--major-subsystem-version', '-Wl,6', '-Wl,--minor-subsystem-version', '-Wl,1']), + (0, '')) + + +if __name__ == '__main__': + unittest.main() diff --git a/contrib/devtools/test_deterministic_coverage.sh b/contrib/devtools/test_deterministic_coverage.sh new file mode 100755 index 0000000000..8501c72f04 --- /dev/null +++ b/contrib/devtools/test_deterministic_coverage.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# Test for deterministic coverage across unit test runs. + +export LC_ALL=C + +# Use GCOV_EXECUTABLE="gcov" if compiling with gcc. +# Use GCOV_EXECUTABLE="llvm-cov gcov" if compiling with clang. +GCOV_EXECUTABLE="gcov" + +# Disable tests known to cause non-deterministic behaviour and document the source or point of non-determinism. +NON_DETERMINISTIC_TESTS=( + "blockfilter_index_tests/blockfilter_index_initial_sync" # src/checkqueue.h: In CCheckQueue::Loop(): while (queue.empty()) { ... } + "coinselector_tests/knapsack_solver_test" # coinselector_tests.cpp: if (equal_sets(setCoinsRet, setCoinsRet2)) + "fs_tests/fsbridge_fstream" # deterministic test failure? + "miner_tests/CreateNewBlock_validity" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "scheduler_tests/manythreads" # scheduler.cpp: CScheduler::serviceQueue() + "scheduler_tests/singlethreadedscheduler_ordered" # scheduler.cpp: CScheduler::serviceQueue() + "txvalidationcache_tests/checkinputs_test" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "txvalidationcache_tests/tx_mempool_block_doublespend" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "txindex_tests/txindex_initial_sync" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "txvalidation_tests/tx_mempool_reject_coinbase" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "validation_block_tests/processnewblock_signals_ordering" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "wallet_tests/coin_mark_dirty_immature_credit" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "wallet_tests/dummy_input_size_test" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "wallet_tests/importmulti_rescan" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "wallet_tests/importwallet_rescan" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "wallet_tests/ListCoins" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "wallet_tests/scan_for_wallet_transactions" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "wallet_tests/wallet_disableprivkeys" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) +) + +TEST_BITCOIN_BINARY="src/test/test_bitcoin" + +print_usage() { + echo "Usage: $0 [custom test filter (default: all but known non-deterministic tests)] [number of test runs (default: 2)]" +} + +N_TEST_RUNS=2 +BOOST_TEST_RUN_FILTERS="" +if [[ $# != 0 ]]; then + if [[ $1 == "--help" ]]; then + print_usage + exit + fi + PARSED_ARGUMENTS=0 + if [[ $1 =~ [a-z] ]]; then + BOOST_TEST_RUN_FILTERS=$1 + PARSED_ARGUMENTS=$((PARSED_ARGUMENTS + 1)) + shift + fi + if [[ $1 =~ ^[0-9]+$ ]]; then + N_TEST_RUNS=$1 + PARSED_ARGUMENTS=$((PARSED_ARGUMENTS + 1)) + shift + fi + if [[ ${PARSED_ARGUMENTS} == 0 || $# -gt 2 || ${N_TEST_RUNS} -lt 2 ]]; then + print_usage + exit + fi +fi +if [[ ${BOOST_TEST_RUN_FILTERS} == "" ]]; then + BOOST_TEST_RUN_FILTERS="$(IFS=":"; echo "!${NON_DETERMINISTIC_TESTS[*]}" | sed 's/:/:!/g')" +else + echo "Using Boost test filter: ${BOOST_TEST_RUN_FILTERS}" + echo +fi + +if ! command -v gcov > /dev/null; then + echo "Error: gcov not installed. Exiting." + exit 1 +fi + +if ! command -v gcovr > /dev/null; then + echo "Error: gcovr not installed. Exiting." + exit 1 +fi + +if [[ ! -e ${TEST_BITCOIN_BINARY} ]]; then + echo "Error: Executable ${TEST_BITCOIN_BINARY} not found. Run \"./configure --enable-lcov\" and compile." + exit 1 +fi + +get_file_suffix_count() { + find src/ -type f -name "*.$1" | wc -l +} + +if [[ $(get_file_suffix_count gcno) == 0 ]]; then + echo "Error: Could not find any *.gcno files. The *.gcno files are generated by the compiler. Run \"./configure --enable-lcov\" and re-compile." + exit 1 +fi + +get_covr_filename() { + echo "gcovr.run-$1.txt" +} + +TEST_RUN_ID=0 +while [[ ${TEST_RUN_ID} -lt ${N_TEST_RUNS} ]]; do + TEST_RUN_ID=$((TEST_RUN_ID + 1)) + echo "[$(date +"%Y-%m-%d %H:%M:%S")] Measuring coverage, run #${TEST_RUN_ID} of ${N_TEST_RUNS}" + find src/ -type f -name "*.gcda" -exec rm {} \; + if [[ $(get_file_suffix_count gcda) != 0 ]]; then + echo "Error: Stale *.gcda files found. Exiting." + exit 1 + fi + TEST_OUTPUT_TEMPFILE=$(mktemp) + if ! BOOST_TEST_RUN_FILTERS="${BOOST_TEST_RUN_FILTERS}" ${TEST_BITCOIN_BINARY} > "${TEST_OUTPUT_TEMPFILE}" 2>&1; then + cat "${TEST_OUTPUT_TEMPFILE}" + rm "${TEST_OUTPUT_TEMPFILE}" + exit 1 + fi + rm "${TEST_OUTPUT_TEMPFILE}" + if [[ $(get_file_suffix_count gcda) == 0 ]]; then + echo "Error: Running the test suite did not create any *.gcda files. The gcda files are generated when the instrumented test programs are executed. Run \"./configure --enable-lcov\" and re-compile." + exit 1 + fi + GCOVR_TEMPFILE=$(mktemp) + if ! gcovr --gcov-executable "${GCOV_EXECUTABLE}" -r src/ > "${GCOVR_TEMPFILE}"; then + echo "Error: gcovr failed. Output written to ${GCOVR_TEMPFILE}. Exiting." + exit 1 + fi + GCOVR_FILENAME=$(get_covr_filename ${TEST_RUN_ID}) + mv "${GCOVR_TEMPFILE}" "${GCOVR_FILENAME}" + if grep -E "^TOTAL *0 *0 " "${GCOVR_FILENAME}"; then + echo "Error: Spurious gcovr output. Make sure the correct GCOV_EXECUTABLE variable is set in $0 (\"gcov\" for gcc, \"llvm-cov gcov\" for clang)." + exit 1 + fi + if [[ ${TEST_RUN_ID} != 1 ]]; then + COVERAGE_DIFF=$(diff -u "$(get_covr_filename 1)" "${GCOVR_FILENAME}") + if [[ ${COVERAGE_DIFF} != "" ]]; then + echo + echo "The line coverage is non-deterministic between runs. Exiting." + echo + echo "The test suite must be deterministic in the sense that the set of lines executed at least" + echo "once must be identical between runs. This is a necessary condition for meaningful" + echo "coverage measuring." + echo + echo "${COVERAGE_DIFF}" + exit 1 + fi + rm "${GCOVR_FILENAME}" + fi +done + +echo +echo "Coverage test passed: Deterministic coverage across ${N_TEST_RUNS} runs." +exit diff --git a/contrib/devtools/utils.py b/contrib/devtools/utils.py new file mode 100755 index 0000000000..68ad1c3aba --- /dev/null +++ b/contrib/devtools/utils.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +''' +Common utility functions +''' +import shutil +import sys +import os +from typing import List + + +def determine_wellknown_cmd(envvar, progname) -> List[str]: + maybe_env = os.getenv(envvar) + maybe_which = shutil.which(progname) + if maybe_env: + return maybe_env.split(' ') # Well-known vars are often meant to be word-split + elif maybe_which: + return [ maybe_which ] + else: + sys.exit(f"{progname} not found") diff --git a/contrib/devtools/utxo_snapshot.sh b/contrib/devtools/utxo_snapshot.sh new file mode 100755 index 0000000000..dee25ff67b --- /dev/null +++ b/contrib/devtools/utxo_snapshot.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# +# Copyright (c) 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. +# +export LC_ALL=C + +set -ueo pipefail + +if (( $# < 3 )); then + echo 'Usage: utxo_snapshot.sh ' + echo + echo " if is '-', don't produce a snapshot file but instead print the " + echo " expected assumeutxo hash" + echo + echo 'Examples:' + echo + echo " ./contrib/devtools/utxo_snapshot.sh 570000 utxo.dat ./src/bitcoin-cli -datadir=\$(pwd)/testdata" + echo ' ./contrib/devtools/utxo_snapshot.sh 570000 - ./src/bitcoin-cli' + exit 1 +fi + +GENERATE_AT_HEIGHT="${1}"; shift; +OUTPUT_PATH="${1}"; shift; +# Most of the calls we make take a while to run, so pad with a lengthy timeout. +BITCOIN_CLI_CALL="${*} -rpcclienttimeout=9999999" + +# Block we'll invalidate/reconsider to rewind/fast-forward the chain. +PIVOT_BLOCKHASH=$($BITCOIN_CLI_CALL getblockhash $(( GENERATE_AT_HEIGHT + 1 )) ) + +(>&2 echo "Rewinding chain back to height ${GENERATE_AT_HEIGHT} (by invalidating ${PIVOT_BLOCKHASH}); this may take a while") +${BITCOIN_CLI_CALL} invalidateblock "${PIVOT_BLOCKHASH}" + +if [[ "${OUTPUT_PATH}" = "-" ]]; then + (>&2 echo "Generating txoutset info...") + ${BITCOIN_CLI_CALL} gettxoutsetinfo | grep hash_serialized_2 | sed 's/^.*: "\(.\+\)\+",/\1/g' +else + (>&2 echo "Generating UTXO snapshot...") + ${BITCOIN_CLI_CALL} dumptxoutset "${OUTPUT_PATH}" +fi + +(>&2 echo "Restoring chain to original height; this may take a while") +${BITCOIN_CLI_CALL} reconsiderblock "${PIVOT_BLOCKHASH}" diff --git a/contrib/filter-lcov.py b/contrib/filter-lcov.py new file mode 100755 index 0000000000..e005cb96da --- /dev/null +++ b/contrib/filter-lcov.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017-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. + +import argparse + +parser = argparse.ArgumentParser(description='Remove the coverage data from a tracefile for all files matching the pattern.') +parser.add_argument('--pattern', '-p', action='append', help='the pattern of files to remove', required=True) +parser.add_argument('tracefile', help='the tracefile to remove the coverage data from') +parser.add_argument('outfile', help='filename for the output to be written to') + +args = parser.parse_args() +tracefile = args.tracefile +pattern = args.pattern +outfile = args.outfile + +in_remove = False +with open(tracefile, 'r', encoding="utf8") as f: + with open(outfile, 'w', encoding="utf8") as wf: + for line in f: + for p in pattern: + if line.startswith("SF:") and p in line: + in_remove = True + if not in_remove: + wf.write(line) + if line == 'end_of_record\n': + in_remove = False diff --git a/contrib/gitian-build.py b/contrib/gitian-build.py new file mode 100755 index 0000000000..d498c9e2c8 --- /dev/null +++ b/contrib/gitian-build.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018-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. + +import argparse +import os +import subprocess +import sys + +def setup(): + global args, workdir + programs = ['ruby', 'git', 'make', 'wget', 'curl'] + if args.kvm: + programs += ['apt-cacher-ng', 'python-vm-builder', 'qemu-kvm', 'qemu-utils'] + elif args.docker and not os.path.isfile('/lib/systemd/system/docker.service'): + dockers = ['docker.io', 'docker-ce'] + for i in dockers: + return_code = subprocess.call(['sudo', 'apt-get', 'install', '-qq', i]) + if return_code == 0: + break + if return_code != 0: + print('Cannot find any way to install Docker.', file=sys.stderr) + sys.exit(1) + else: + programs += ['apt-cacher-ng', 'lxc', 'debootstrap'] + subprocess.check_call(['sudo', 'apt-get', 'install', '-qq'] + programs) + if not os.path.isdir('gitian.sigs'): + subprocess.check_call(['git', 'clone', 'https://github.com/bitcoin-core/gitian.sigs.git']) + if not os.path.isdir('bitcoin-detached-sigs'): + subprocess.check_call(['git', 'clone', 'https://github.com/bitcoin-core/bitcoin-detached-sigs.git']) + if not os.path.isdir('gitian-builder'): + subprocess.check_call(['git', 'clone', 'https://github.com/devrandom/gitian-builder.git']) + if not os.path.isdir('bitcoin'): + subprocess.check_call(['git', 'clone', 'https://github.com/bitcoin/bitcoin.git']) + os.chdir('gitian-builder') + make_image_prog = ['bin/make-base-vm', '--suite', 'bionic', '--arch', 'amd64'] + if args.docker: + make_image_prog += ['--docker'] + elif not args.kvm: + make_image_prog += ['--lxc'] + subprocess.check_call(make_image_prog) + os.chdir(workdir) + if args.is_bionic and not args.kvm and not args.docker: + subprocess.check_call(['sudo', 'sed', '-i', 's/lxcbr0/br0/', '/etc/default/lxc-net']) + print('Reboot is required') + sys.exit(0) + +def build(): + global args, workdir + + os.makedirs('bitcoin-binaries/' + args.version, exist_ok=True) + print('\nBuilding Dependencies\n') + os.chdir('gitian-builder') + os.makedirs('inputs', exist_ok=True) + + subprocess.check_call(['wget', '-O', 'inputs/osslsigncode-2.0.tar.gz', 'https://github.com/mtrojnar/osslsigncode/archive/2.0.tar.gz']) + subprocess.check_call(["echo '5a60e0a4b3e0b4d655317b2f12a810211c50242138322b16e7e01c6fbb89d92f inputs/osslsigncode-2.0.tar.gz' | sha256sum -c"], shell=True) + subprocess.check_call(['make', '-C', '../bitcoin/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common']) + + if args.linux: + print('\nCompiling ' + args.version + ' Linux') + subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'bitcoin='+args.commit, '--url', 'bitcoin='+args.url, '../bitcoin/contrib/gitian-descriptors/gitian-linux.yml']) + subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-linux', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-linux.yml']) + subprocess.check_call('mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../bitcoin-binaries/'+args.version, shell=True) + + if args.windows: + print('\nCompiling ' + args.version + ' Windows') + subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'bitcoin='+args.commit, '--url', 'bitcoin='+args.url, '../bitcoin/contrib/gitian-descriptors/gitian-win.yml']) + subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-win-unsigned', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-win.yml']) + subprocess.check_call('mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/', shell=True) + subprocess.check_call('mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe build/out/src/bitcoin-*.tar.gz ../bitcoin-binaries/'+args.version, shell=True) + + if args.macos: + print('\nCompiling ' + args.version + ' MacOS') + subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'bitcoin='+args.commit, '--url', 'bitcoin='+args.url, '../bitcoin/contrib/gitian-descriptors/gitian-osx.yml']) + subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-osx-unsigned', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-osx.yml']) + subprocess.check_call('mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/', shell=True) + subprocess.check_call('mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg build/out/src/bitcoin-*.tar.gz ../bitcoin-binaries/'+args.version, shell=True) + + os.chdir(workdir) + + if args.commit_files: + print('\nCommitting '+args.version+' Unsigned Sigs\n') + os.chdir('gitian.sigs') + subprocess.check_call(['git', 'add', args.version+'-linux/'+args.signer]) + subprocess.check_call(['git', 'add', args.version+'-win-unsigned/'+args.signer]) + subprocess.check_call(['git', 'add', args.version+'-osx-unsigned/'+args.signer]) + subprocess.check_call(['git', 'commit', '-m', 'Add '+args.version+' unsigned sigs for '+args.signer]) + os.chdir(workdir) + +def sign(): + global args, workdir + os.chdir('gitian-builder') + + if args.windows: + print('\nSigning ' + args.version + ' Windows') + subprocess.check_call('cp inputs/bitcoin-' + args.version + '-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz', shell=True) + subprocess.check_call(['bin/gbuild', '--skip-image', '--upgrade', '--commit', 'signature='+args.commit, '../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml']) + subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-win-signed', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml']) + subprocess.check_call('mv build/out/bitcoin-*win64-setup.exe ../bitcoin-binaries/'+args.version, shell=True) + + if args.macos: + print('\nSigning ' + args.version + ' MacOS') + subprocess.check_call('cp inputs/bitcoin-' + args.version + '-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz', shell=True) + subprocess.check_call(['bin/gbuild', '--skip-image', '--upgrade', '--commit', 'signature='+args.commit, '../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml']) + subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-osx-signed', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml']) + subprocess.check_call('mv build/out/bitcoin-osx-signed.dmg ../bitcoin-binaries/'+args.version+'/bitcoin-'+args.version+'-osx.dmg', shell=True) + + os.chdir(workdir) + + if args.commit_files: + print('\nCommitting '+args.version+' Signed Sigs\n') + os.chdir('gitian.sigs') + subprocess.check_call(['git', 'add', args.version+'-win-signed/'+args.signer]) + subprocess.check_call(['git', 'add', args.version+'-osx-signed/'+args.signer]) + subprocess.check_call(['git', 'commit', '-a', '-m', 'Add '+args.version+' signed binary sigs for '+args.signer]) + os.chdir(workdir) + +def verify(): + global args, workdir + rc = 0 + os.chdir('gitian-builder') + + print('\nVerifying v'+args.version+' Linux\n') + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-linux', '../bitcoin/contrib/gitian-descriptors/gitian-linux.yml']): + print('Verifying v'+args.version+' Linux FAILED\n') + rc = 1 + + print('\nVerifying v'+args.version+' Windows\n') + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win-unsigned', '../bitcoin/contrib/gitian-descriptors/gitian-win.yml']): + print('Verifying v'+args.version+' Windows FAILED\n') + rc = 1 + + print('\nVerifying v'+args.version+' MacOS\n') + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx-unsigned', '../bitcoin/contrib/gitian-descriptors/gitian-osx.yml']): + print('Verifying v'+args.version+' MacOS FAILED\n') + rc = 1 + + print('\nVerifying v'+args.version+' Signed Windows\n') + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win-signed', '../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml']): + print('Verifying v'+args.version+' Signed Windows FAILED\n') + rc = 1 + + print('\nVerifying v'+args.version+' Signed MacOS\n') + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx-signed', '../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml']): + print('Verifying v'+args.version+' Signed MacOS FAILED\n') + rc = 1 + + os.chdir(workdir) + return rc + +def main(): + global args, workdir + + parser = argparse.ArgumentParser(description='Script for running full Gitian builds.') + parser.add_argument('-c', '--commit', action='store_true', dest='commit', help='Indicate that the version argument is for a commit or branch') + parser.add_argument('-p', '--pull', action='store_true', dest='pull', help='Indicate that the version argument is the number of a github repository pull request') + parser.add_argument('-u', '--url', dest='url', default='https://github.com/bitcoin/bitcoin', help='Specify the URL of the repository. Default is %(default)s') + parser.add_argument('-v', '--verify', action='store_true', dest='verify', help='Verify the Gitian build') + parser.add_argument('-b', '--build', action='store_true', dest='build', help='Do a Gitian build') + parser.add_argument('-s', '--sign', action='store_true', dest='sign', help='Make signed binaries for Windows and MacOS') + parser.add_argument('-B', '--buildsign', action='store_true', dest='buildsign', help='Build both signed and unsigned binaries') + parser.add_argument('-o', '--os', dest='os', default='lwm', help='Specify which Operating Systems the build is for. Default is %(default)s. l for Linux, w for Windows, m for MacOS') + parser.add_argument('-j', '--jobs', dest='jobs', default='2', help='Number of processes to use. Default %(default)s') + parser.add_argument('-m', '--memory', dest='memory', default='2000', help='Memory to allocate in MiB. Default %(default)s') + parser.add_argument('-k', '--kvm', action='store_true', dest='kvm', help='Use KVM instead of LXC') + parser.add_argument('-d', '--docker', action='store_true', dest='docker', help='Use Docker instead of LXC') + parser.add_argument('-S', '--setup', action='store_true', dest='setup', help='Set up the Gitian building environment. Only works on Debian-based systems (Ubuntu, Debian)') + parser.add_argument('-D', '--detach-sign', action='store_true', dest='detach_sign', help='Create the assert file for detached signing. Will not commit anything.') + parser.add_argument('-n', '--no-commit', action='store_false', dest='commit_files', help='Do not commit anything to git') + parser.add_argument('signer', nargs='?', help='GPG signer to sign each build assert file') + parser.add_argument('version', nargs='?', help='Version number, commit, or branch to build. If building a commit or branch, the -c option must be specified') + + args = parser.parse_args() + workdir = os.getcwd() + + args.is_bionic = b'bionic' in subprocess.check_output(['lsb_release', '-cs']) + + if args.kvm and args.docker: + raise Exception('Error: cannot have both kvm and docker') + + # Ensure no more than one environment variable for gitian-builder (USE_LXC, USE_VBOX, USE_DOCKER) is set as they + # can interfere (e.g., USE_LXC being set shadows USE_DOCKER; for details see gitian-builder/libexec/make-clean-vm). + os.environ['USE_LXC'] = '' + os.environ['USE_VBOX'] = '' + os.environ['USE_DOCKER'] = '' + if args.docker: + os.environ['USE_DOCKER'] = '1' + elif not args.kvm: + os.environ['USE_LXC'] = '1' + if 'GITIAN_HOST_IP' not in os.environ.keys(): + os.environ['GITIAN_HOST_IP'] = '10.0.3.1' + if 'LXC_GUEST_IP' not in os.environ.keys(): + os.environ['LXC_GUEST_IP'] = '10.0.3.5' + + if args.setup: + setup() + + if args.buildsign: + args.build = True + args.sign = True + + if not args.build and not args.sign and not args.verify: + sys.exit(0) + + args.linux = 'l' in args.os + args.windows = 'w' in args.os + args.macos = 'm' in args.os + + # Disable for MacOS if no SDK found + if args.macos and not os.path.isfile('gitian-builder/inputs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz'): + print('Cannot build for MacOS, SDK does not exist. Will build for other OSes') + args.macos = False + + args.sign_prog = 'true' if args.detach_sign else 'gpg --detach-sign' + + script_name = os.path.basename(sys.argv[0]) + if not args.signer: + print(script_name+': Missing signer') + print('Try '+script_name+' --help for more information') + sys.exit(1) + if not args.version: + print(script_name+': Missing version') + print('Try '+script_name+' --help for more information') + sys.exit(1) + + # Add leading 'v' for tags + if args.commit and args.pull: + raise Exception('Cannot have both commit and pull') + args.commit = ('' if args.commit else 'v') + args.version + + os.chdir('bitcoin') + if args.pull: + subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) + os.chdir('../gitian-builder/inputs/bitcoin') + subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) + args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True, encoding='utf8').strip() + args.version = 'pull-' + args.version + print(args.commit) + subprocess.check_call(['git', 'fetch']) + subprocess.check_call(['git', 'checkout', args.commit]) + os.chdir(workdir) + + os.chdir('gitian-builder') + subprocess.check_call(['git', 'pull']) + os.chdir(workdir) + + if args.build: + build() + + if args.sign: + sign() + + if args.verify: + os.chdir('gitian.sigs') + subprocess.check_call(['git', 'pull']) + os.chdir(workdir) + sys.exit(verify()) + +if __name__ == '__main__': + main() diff --git a/contrib/gitian-build.sh b/contrib/gitian-build.sh deleted file mode 100755 index ee47d138f3..0000000000 --- a/contrib/gitian-build.sh +++ /dev/null @@ -1,388 +0,0 @@ -# What to do -sign=false -verify=false -build=false -setupenv=false - -# Systems to build -linux=true -windows=true -osx=true - -# Other Basic variables -SIGNER= -VERSION= -commit=false -url=https://github.com/bitcoin/bitcoin -proc=2 -mem=2000 -lxc=true -osslTarUrl=http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz -osslPatchUrl=https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch -scriptName=$(basename -- "$0") -signProg="gpg --detach-sign" -commitFiles=true - -# Help Message -read -d '' usage <<- EOF -Usage: $scriptName [-c|u|v|b|s|B|o|h|j|m|] signer version - -Run this script from the directory containing the bitcoin, gitian-builder, gitian.sigs, and bitcoin-detached-sigs. - -Arguments: -signer GPG signer to sign each build assert file -version Version number, commit, or branch to build. If building a commit or branch, the -c option must be specified - -Options: --c|--commit Indicate that the version argument is for a commit or branch --u|--url Specify the URL of the repository. Default is https://github.com/bitcoin/bitcoin --v|--verify Verify the gitian build --b|--build Do a gitiain build --s|--sign Make signed binaries for Windows and Mac OSX --B|--buildsign Build both signed and unsigned binaries --o|--os Specify which Operating Systems the build is for. Default is lwx. l for linux, w for windows, x for osx --j Number of processes to use. Default 2 --m Memory to allocate in MiB. Default 2000 ---kvm Use KVM instead of LXC ---setup Setup the gitian building environment. Uses KVM. If you want to use lxc, use the --lxc option. Only works on Debian-based systems (Ubuntu, Debian) ---detach-sign Create the assert file for detached signing. Will not commit anything. ---no-commit Do not commit anything to git --h|--help Print this help message -EOF - -# Get options and arguments -while :; do - case $1 in - # Verify - -v|--verify) - verify=true - ;; - # Build - -b|--build) - build=true - ;; - # Sign binaries - -s|--sign) - sign=true - ;; - # Build then Sign - -B|--buildsign) - sign=true - build=true - ;; - # PGP Signer - -S|--signer) - if [ -n "$2" ] - then - SIGNER=$2 - shift - else - echo 'Error: "--signer" requires a non-empty argument.' - exit 1 - fi - ;; - # Operating Systems - -o|--os) - if [ -n "$2" ] - then - linux=false - windows=false - osx=false - if [[ "$2" = *"l"* ]] - then - linux=true - fi - if [[ "$2" = *"w"* ]] - then - windows=true - fi - if [[ "$2" = *"x"* ]] - then - osx=true - fi - shift - else - echo 'Error: "--os" requires an argument containing an l (for linux), w (for windows), or x (for Mac OSX)\n' - exit 1 - fi - ;; - # Help message - -h|--help) - echo "$usage" - exit 0 - ;; - # Commit or branch - -c|--commit) - commit=true - ;; - # Number of Processes - -j) - if [ -n "$2" ] - then - proc=$2 - shift - else - echo 'Error: "-j" requires an argument' - exit 1 - fi - ;; - # Memory to allocate - -m) - if [ -n "$2" ] - then - mem=$2 - shift - else - echo 'Error: "-m" requires an argument' - exit 1 - fi - ;; - # URL - -u) - if [ -n "$2" ] - then - url=$2 - shift - else - echo 'Error: "-u" requires an argument' - exit 1 - fi - ;; - # kvm - --kvm) - lxc=false - ;; - # Detach sign - --detach-sign) - signProg="true" - commitFiles=false - ;; - # Commit files - --no-commit) - commitFiles=false - ;; - # Setup - --setup) - setup=true - ;; - *) # Default case: If no more options then break out of the loop. - break - esac - shift -done - -# Set up LXC -if [[ $lxc = true ]] -then - export USE_LXC=1 - export LXC_BRIDGE=lxcbr0 - sudo ifconfig lxcbr0 up 10.0.2.2 -fi - -# Check for OSX SDK -if [[ ! -e "gitian-builder/inputs/MacOSX10.11.sdk.tar.gz" && $osx == true ]] -then - echo "Cannot build for OSX, SDK does not exist. Will build for other OSes" - osx=false -fi - -# Get signer -if [[ -n"$1" ]] -then - SIGNER=$1 - shift -fi - -# Get version -if [[ -n "$1" ]] -then - VERSION=$1 - COMMIT=$VERSION - shift -fi - -# Check that a signer is specified -if [[ $SIGNER == "" ]] -then - echo "$scriptName: Missing signer." - echo "Try $scriptName --help for more information" - exit 1 -fi - -# Check that a version is specified -if [[ $VERSION == "" ]] -then - echo "$scriptName: Missing version." - echo "Try $scriptName --help for more information" - exit 1 -fi - -# Add a "v" if no -c -if [[ $commit = false ]] -then - COMMIT="v${VERSION}" -fi -echo ${COMMIT} - -# Setup build environment -if [[ $setup = true ]] -then - sudo apt-get install ruby apache2 git apt-cacher-ng python-vm-builder qemu-kvm qemu-utils - git clone https://github.com/bitcoin-core/gitian.sigs.git - git clone https://github.com/bitcoin-core/bitcoin-detached-sigs.git - git clone https://github.com/devrandom/gitian-builder.git - pushd ./gitian-builder - if [[ -n "$USE_LXC" ]] - then - sudo apt-get install lxc - bin/make-base-vm --suite trusty --arch amd64 --lxc - else - bin/make-base-vm --suite trusty --arch amd64 - fi - popd -fi - -# Set up build -pushd ./bitcoin -git fetch -git checkout ${COMMIT} -popd - -# Build -if [[ $build = true ]] -then - # Make output folder - mkdir -p ./bitcoin-binaries/${VERSION} - - # Build Dependencies - echo "" - echo "Building Dependencies" - echo "" - pushd ./gitian-builder - mkdir -p inputs - wget -N -P inputs $osslPatchUrl - wget -N -P inputs $osslTarUrl - make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common - - # Linux - if [[ $linux = true ]] - then - echo "" - echo "Compiling ${VERSION} Linux" - echo "" - ./bin/gbuild -j ${proc} -m ${mem} --commit bitcoin=${COMMIT} --url bitcoin=${url} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - ./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../bitcoin-binaries/${VERSION} - fi - # Windows - if [[ $windows = true ]] - then - echo "" - echo "Compiling ${VERSION} Windows" - echo "" - ./bin/gbuild -j ${proc} -m ${mem} --commit bitcoin=${COMMIT} --url bitcoin=${url} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - ./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz - mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../bitcoin-binaries/${VERSION} - fi - # Mac OSX - if [[ $osx = true ]] - then - echo "" - echo "Compiling ${VERSION} Mac OSX" - echo "" - ./bin/gbuild -j ${proc} -m ${mem} --commit bitcoin=${COMMIT} --url bitcoin=${url} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - ./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz - mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../bitcoin-binaries/${VERSION} - fi - popd - - if [[ $commitFiles = true ]] - then - # Commit to gitian.sigs repo - echo "" - echo "Committing ${VERSION} Unsigned Sigs" - echo "" - pushd gitian.sigs - git add ${VERSION}-linux/${SIGNER} - git add ${VERSION}-win-unsigned/${SIGNER} - git add ${VERSION}-osx-unsigned/${SIGNER} - git commit -a -m "Add ${VERSION} unsigned sigs for ${SIGNER}" - popd - fi -fi - -# Verify the build -if [[ $verify = true ]] -then - # Linux - pushd ./gitian-builder - echo "" - echo "Verifying v${VERSION} Linux" - echo "" - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - # Windows - echo "" - echo "Verifying v${VERSION} Windows" - echo "" - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - # Mac OSX - echo "" - echo "Verifying v${VERSION} Mac OSX" - echo "" - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - # Signed Windows - echo "" - echo "Verifying v${VERSION} Signed Windows" - echo "" - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-signed ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml - # Signed Mac OSX - echo "" - echo "Verifying v${VERSION} Signed Mac OSX" - echo "" - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-signed ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml - popd -fi - -# Sign binaries -if [[ $sign = true ]] -then - - pushd ./gitian-builder - # Sign Windows - if [[ $windows = true ]] - then - echo "" - echo "Signing ${VERSION} Windows" - echo "" - ./bin/gbuild -i --commit signature=${COMMIT} ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml - ./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-win-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml - mv build/out/bitcoin-*win64-setup.exe ../bitcoin-binaries/${VERSION} - mv build/out/bitcoin-*win32-setup.exe ../bitcoin-binaries/${VERSION} - fi - # Sign Mac OSX - if [[ $osx = true ]] - then - echo "" - echo "Signing ${VERSION} Mac OSX" - echo "" - ./bin/gbuild -i --commit signature=${COMMIT} ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml - ./bin/gsign -p $signProg --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml - mv build/out/bitcoin-osx-signed.dmg ../bitcoin-binaries/${VERSION}/bitcoin-${VERSION}-osx.dmg - fi - popd - - if [[ $commitFiles = true ]] - then - # Commit Sigs - pushd gitian.sigs - echo "" - echo "Committing ${VERSION} Signed Sigs" - echo "" - git add ${VERSION}-win-signed/${SIGNER} - git add ${VERSION}-osx-signed/${SIGNER} - git commit -a -m "Add ${VERSION} signed binary sigs for ${SIGNER}" - popd - fi -fi diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md deleted file mode 100644 index 6149706596..0000000000 --- a/contrib/gitian-descriptors/README.md +++ /dev/null @@ -1,65 +0,0 @@ -### Gavin's notes on getting gitian builds up and running using KVM - -These instructions distilled from -[https://help.ubuntu.com/community/KVM/Installation](https://help.ubuntu.com/community/KVM/Installation). - -You need the right hardware: you need a 64-bit-capable CPU with hardware virtualization support (Intel VT-x or AMD-V). Not all modern CPUs support hardware virtualization. - -You probably need to enable hardware virtualization in your machine's BIOS. - -You need to be running a recent version of 64-bit-Ubuntu, and you need to install several prerequisites: - - sudo apt-get install ruby apache2 git apt-cacher-ng python-vm-builder qemu-kvm - -Sanity checks: - - sudo service apt-cacher-ng status # Should return apt-cacher-ng is running - ls -l /dev/kvm # Should show a /dev/kvm device - - -Once you've got the right hardware and software: - - git clone git://github.com/bitcoin/bitcoin.git - git clone git://github.com/devrandom/gitian-builder.git - mkdir gitian-builder/inputs - cd gitian-builder/inputs - - # Create base images - cd gitian-builder - bin/make-base-vm --suite trusty --arch amd64 - cd .. - - # Get inputs (see doc/release-process.md for exact inputs needed and where to get them) - ... - - # For further build instructions see doc/release-process.md - ... - ---------------------- - -`gitian-builder` now also supports building using LXC. See -[help.ubuntu.com](https://help.ubuntu.com/14.04/serverguide/lxc.html) -for how to get LXC up and running under Ubuntu. - -If your main machine is a 64-bit Mac or PC with a few gigabytes of memory -and at least 10 gigabytes of free disk space, you can `gitian-build` using -LXC running inside a virtual machine. - -Here's a description of Gavin's setup on OSX 10.6: - -1. Download and install VirtualBox from [https://www.virtualbox.org/](https://www.virtualbox.org/) - -2. Download the 64-bit Ubuntu Desktop 12.04 LTS .iso CD image from - [http://www.ubuntu.com/](http://www.ubuntu.com/) - -3. Run VirtualBox and create a new virtual machine, using the Ubuntu .iso (see the [VirtualBox documentation](https://www.virtualbox.org/wiki/Documentation) for details). Create it with at least 2 gigabytes of memory and a disk that is at least 20 gigabytes big. - -4. Inside the running Ubuntu desktop, install: - - sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder - -5. Still inside Ubuntu, tell gitian-builder to use LXC, then follow the "Once you've got the right hardware and software" instructions above: - - export USE_LXC=1 - git clone git://github.com/bitcoin/bitcoin.git - ... etc diff --git a/contrib/gitian-descriptors/assign_DISTNAME b/contrib/gitian-descriptors/assign_DISTNAME new file mode 100644 index 0000000000..330fbc041b --- /dev/null +++ b/contrib/gitian-descriptors/assign_DISTNAME @@ -0,0 +1,12 @@ +# Copyright (c) 2020 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# A helper script to be sourced into the gitian descriptors + +if RECENT_TAG="$(git describe --exact-match HEAD 2> /dev/null)"; then + VERSION="${RECENT_TAG#v}" +else + VERSION="$(git rev-parse --short=12 HEAD)" +fi +DISTNAME="bitcoin-${VERSION}" diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 9bac6ad67e..e6dce7a8c6 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,53 +1,63 @@ --- -name: "bitcoin-linux-0.14" +name: "bitcoin-core-linux-22" enable_cache: true +distro: "ubuntu" suites: -- "trusty" +- "focal" architectures: - "amd64" packages: -- "curl" -- "g++-aarch64-linux-gnu" -- "g++-4.8-aarch64-linux-gnu" -- "gcc-4.8-aarch64-linux-gnu" -- "binutils-aarch64-linux-gnu" -- "g++-arm-linux-gnueabihf" -- "g++-4.8-arm-linux-gnueabihf" -- "gcc-4.8-arm-linux-gnueabihf" -- "binutils-arm-linux-gnueabihf" -- "g++-4.8-multilib" -- "gcc-4.8-multilib" -- "binutils-gold" -- "git-core" -- "pkg-config" +# Common dependencies. - "autoconf" -- "libtool" - "automake" -- "faketime" +- "binutils" +- "bison" - "bsdmainutils" - "ca-certificates" -- "python" +- "curl" +- "faketime" +- "g++-8" +- "gcc-8" +- "git" +- "libtool" +- "patch" +- "pkg-config" +- "python3" +- "python3-pip" +# Cross compilation HOSTS: +# - arm-linux-gnueabihf +- "binutils-arm-linux-gnueabihf" +- "g++-8-arm-linux-gnueabihf" +# - aarch64-linux-gnu +- "binutils-aarch64-linux-gnu" +- "g++-8-aarch64-linux-gnu" +# - powerpc64-linux-gnu +- "binutils-powerpc64-linux-gnu" +- "g++-8-powerpc64-linux-gnu" +# - powerpc64le-linux-gnu +- "binutils-powerpc64le-linux-gnu" +- "g++-8-powerpc64le-linux-gnu" +# - riscv64-linux-gnu +- "binutils-riscv64-linux-gnu" +- "g++-8-riscv64-linux-gnu" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: [] script: | + set -e -o pipefail WRAP_DIR=$HOME/wrapped - HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" - CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" - FAKETIME_HOST_PROGS="" + HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu powerpc64-linux-gnu powerpc64le-linux-gnu riscv64-linux-gnu" + CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests --disable-fuzz-binary" + FAKETIME_HOST_PROGS="gcc g++" FAKETIME_PROGS="date ar ranlib nm" HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" - HOST_LDFLAGS=-static-libstdc++ + HOST_LDFLAGS_BASE="-static-libstdc++ -Wl,-O2" - 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` + export BUILD_DIR="$PWD" mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} @@ -55,13 +65,14 @@ script: | mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi + # Use $LIB in LD_PRELOAD to avoid hardcoding the dir (See `man ld.so`) function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do - echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + 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 LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} - echo "\$REAL \$@" >> $WRAP_DIR/${prog} + echo "exec \"\$REAL\" \"\$@\"" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } @@ -69,61 +80,38 @@ script: | function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do - echo '#!/bin/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} + if which ${i}-${prog}-8 + then + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog}-8 | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + if [ "${i:0:11}" = "powerpc64le" ]; then + echo "exec \"\$REAL\" -mcpu=power8 -mtune=power9 \"\$@\"" >> $WRAP_DIR/${i}-${prog} + elif [ "${i:0:9}" = "powerpc64" ]; then + echo "exec \"\$REAL\" -mcpu=970 -mtune=power9 \"\$@\"" >> $WRAP_DIR/${i}-${prog} + else + echo "exec \"\$REAL\" \"\$@\"" >> $WRAP_DIR/${i}-${prog} + fi + chmod +x ${WRAP_DIR}/${i}-${prog} + fi done done } + pip3 install lief==0.11.5 + # 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} - EXTRA_INCLUDES_BASE=$WRAP_DIR/extra_includes - mkdir -p $EXTRA_INCLUDES_BASE - - # x86 needs /usr/include/i386-linux-gnu/asm pointed to /usr/include/x86_64-linux-gnu/asm, - # but we can't write there. Instead, create a link here and force it to be included in the - # search paths by wrapping gcc/g++. - - mkdir -p $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu - rm -f $WRAP_DIR/extra_includes/i686-pc-linux-gnu/asm - ln -s /usr/include/x86_64-linux-gnu/asm $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu/asm - - for prog in gcc g++; do - rm -f ${WRAP_DIR}/${prog} - cat << EOF > ${WRAP_DIR}/${prog} - #!/bin/bash - REAL="`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1`" - for var in "\$@" - do - if [ "\$var" = "-m32" ]; then - export C_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" - export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" - break - fi - done - \$REAL \$@ - EOF - chmod +x ${WRAP_DIR}/${prog} - done - cd bitcoin - BASEPREFIX=`pwd`/depends + BASEPREFIX="${PWD}/depends" # Build dependencies for each host for i in $HOSTS; do - EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i" - if [ -d "$EXTRA_INCLUDES" ]; then - export HOST_ID_SALT="$EXTRA_INCLUDES" - fi - make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" - unset HOST_ID_SALT + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" CC=${i}-gcc-8 CXX=${i}-g++-8 done # Faketime for binaries @@ -132,54 +120,48 @@ script: | create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} - # Create the release tarball using (arbitrarily) the first host - ./autogen.sh - CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ - make dist - SOURCEDIST=`echo bitcoin-*.tar.gz` - DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` - # Correct tar file order - mkdir -p temp - pushd temp - tar xf ../$SOURCEDIST - find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST - popd + # Define DISTNAME variable. + # shellcheck source=contrib/gitian-descriptors/assign_DISTNAME + source contrib/gitian-descriptors/assign_DISTNAME + + GIT_ARCHIVE="${OUTDIR}/src/${DISTNAME}.tar.gz" + + # Create the source tarball + mkdir -p "$(dirname "$GIT_ARCHIVE")" + git archive --prefix="${DISTNAME}/" --output="$GIT_ARCHIVE" HEAD ORIGPATH="$PATH" - # Extract the release tarball into a dir for each host and build + # Extract the git archive into a dir for each host and build for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + if [ "${i}" = "powerpc64-linux-gnu" ]; then + # Workaround for https://bugs.launchpad.net/ubuntu/+source/gcc-8-cross-ports/+bug/1853740 + # TODO: remove this when no longer needed + HOST_LDFLAGS="${HOST_LDFLAGS_BASE} -Wl,-z,noexecstack" + else + HOST_LDFLAGS="${HOST_LDFLAGS_BASE}" + fi mkdir -p distsrc-${i} cd distsrc-${i} - INSTALLPATH=`pwd`/installed/${DISTNAME} + INSTALLPATH="${PWD}/installed/${DISTNAME}" mkdir -p ${INSTALLPATH} - tar --strip-components=1 -xf ../$SOURCEDIST + tar --strip-components=1 -xf "${GIT_ARCHIVE}" - CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" + ./autogen.sh + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" CC=${i}-gcc-8 CXX=${i}-g++-8 make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security - - #TODO: This is a quick hack that disables symbol checking for arm. - # Instead, we should investigate why these are popping up. - # For aarch64, we'll need to bump up the min GLIBC version, as the abi - # support wasn't introduced until 2.17. - case $i in - aarch64-*) : ;; - arm-*) : ;; - *) make ${MAKEOPTS} -C src check-symbols ;; - esac - + make ${MAKEOPTS} -C src check-symbols make install DESTDIR=${INSTALLPATH} cd installed find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - 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 + find ${DISTNAME}/bin -type f -executable -print0 | xargs -0 -n1 -I{} ../contrib/devtools/split-debug.sh {} {} {}.dbg + find ${DISTNAME}/lib -type f -print0 | xargs -0 -n1 -I{} ../contrib/devtools/split-debug.sh {} {} {}.dbg + cp ../README.md ${DISTNAME}/ + find ${DISTNAME} -not -name "*.dbg" | sort | tar --mtime="$REFERENCE_DATETIME" --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 --mtime="$REFERENCE_DATETIME" --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-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index f6e9414ab1..addad0a5d2 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -1,37 +1,53 @@ --- name: "bitcoin-dmg-signer" +distro: "ubuntu" suites: -- "trusty" +- "focal" architectures: - "amd64" packages: - "faketime" +- "xorriso" +- "python3-pip" remotes: - "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git" "dir": "signature" +- "url": "https://github.com/achow101/signapple.git" + "dir": "signapple" + "commit": "b084cbbf44d5330448ffce0c7d118f75781b64bd" files: - "bitcoin-osx-unsigned.tar.gz" script: | + set -e -o pipefail + WRAP_DIR=$HOME/wrapped mkdir -p ${WRAP_DIR} - export PATH=`pwd`:$PATH - FAKETIME_PROGS="dmg genisoimage" + export PATH="$PWD":$PATH + FAKETIME_PROGS="dmg xorrisofs" # Create global faketime wrappers for prog in ${FAKETIME_PROGS}; do - echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + 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 LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} - echo "\$REAL \$@" >> $WRAP_DIR/${prog} + echo "exec \"\$REAL\" \"\$@\"" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done - UNSIGNED=bitcoin-osx-unsigned.tar.gz + # Install signapple + cd signapple + python3 -m pip install -U pip setuptools + python3 -m pip install . + export PATH="$HOME/.local/bin":$PATH + cd .. + + UNSIGNED_TARBALL=bitcoin-osx-unsigned.tar.gz + UNSIGNED_APP=dist/Bitcoin-Qt.app SIGNED=bitcoin-osx-signed.dmg - tar -xf ${UNSIGNED} + tar -xf ${UNSIGNED_TARBALL} OSX_VOLNAME="$(cat osx_volname)" - ./detached-sig-apply.sh ${UNSIGNED} signature/osx - ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -apple -o uncompressed.dmg signed-app + ./detached-sig-apply.sh ${UNSIGNED_APP} signature/osx/dist + ${WRAP_DIR}/xorrisofs -D -l -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -o uncompressed.dmg signed-app ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index ef64891ebf..a39618adb7 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,15 +1,16 @@ --- -name: "bitcoin-osx-0.14" +name: "bitcoin-core-osx-22" enable_cache: true +distro: "ubuntu" suites: -- "trusty" +- "focal" architectures: - "amd64" packages: - "ca-certificates" - "curl" - "g++" -- "git-core" +- "git" - "pkg-config" - "autoconf" - "librsvg2-bin" @@ -20,31 +21,29 @@ packages: - "bsdmainutils" - "cmake" - "imagemagick" -- "libcap-dev" - "libz-dev" -- "libbz2-dev" -- "python" -- "python-dev" -- "python-setuptools" +- "python3" +- "python3-pip" +- "python3-setuptools" - "fonts-tuffy" +- "xorriso" +- "libtinfo5" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: -- "MacOSX10.11.sdk.tar.gz" +- "Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz" script: | + set -e -o pipefail + WRAP_DIR=$HOME/wrapped - HOSTS="x86_64-apple-darwin14" - CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage" + HOSTS="x86_64-apple-darwin18" + CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests --disable-fuzz-binary XORRISOFS=${WRAP_DIR}/xorrisofs DMG=${WRAP_DIR}/dmg" FAKETIME_HOST_PROGS="" - FAKETIME_PROGS="ar ranlib date dmg genisoimage" + FAKETIME_PROGS="ar ranlib date dmg xorrisofs" - 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` + export BUILD_DIR="$PWD" mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} @@ -54,13 +53,14 @@ script: | export ZERO_AR_DATE=1 + # Use $LIB in LD_PRELOAD to avoid hardcoding the dir (See `man ld.so`) function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do - echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + 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 LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} - echo "\$REAL \$@" >> $WRAP_DIR/${prog} + echo "exec \"\$REAL\" \"\$@\"" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } @@ -68,16 +68,18 @@ script: | function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do - echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} + 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 LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} - echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + echo "exec \"\$REAL\" \"\$@\"" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } + pip3 install lief==0.11.5 + # Faketime for depends so intermediate results are comparable export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" @@ -85,10 +87,10 @@ script: | export PATH=${WRAP_DIR}:${PATH} cd bitcoin - BASEPREFIX=`pwd`/depends + BASEPREFIX="${PWD}/depends" mkdir -p ${BASEPREFIX}/SDKs - tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz # Build dependencies for each host for i in $HOSTS; do @@ -101,59 +103,53 @@ script: | create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} - # Create the release tarball using (arbitrarily) the first host - ./autogen.sh - CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ - make dist - SOURCEDIST=`echo bitcoin-*.tar.gz` - DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + # Define DISTNAME variable. + # shellcheck source=contrib/gitian-descriptors/assign_DISTNAME + source contrib/gitian-descriptors/assign_DISTNAME - # Correct tar file order - mkdir -p temp - pushd temp - tar xf ../$SOURCEDIST - find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST - popd + GIT_ARCHIVE="${OUTDIR}/src/${DISTNAME}.tar.gz" + + # Create the source tarball + mkdir -p "$(dirname "$GIT_ARCHIVE")" + git archive --prefix="${DISTNAME}/" --output="$GIT_ARCHIVE" HEAD ORIGPATH="$PATH" - # Extract the release tarball into a dir for each host and build + # Extract the git archive 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} + INSTALLPATH="${PWD}/installed/${DISTNAME}" mkdir -p ${INSTALLPATH} - tar --strip-components=1 -xf ../$SOURCEDIST + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + ./autogen.sh CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security + make ${MAKEOPTS} -C src check-symbols make install-strip DESTDIR=${INSTALLPATH} make osx_volname make 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 + cp ${BASEPREFIX}/${i}/native/bin/dmg unsigned-app-${i} 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 + find . | sort | tar --mtime="$REFERENCE_DATETIME" --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 - make deploy - ${WRAP_DIR}/dmg dmg "${OSX_VOLNAME}.dmg" ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg + make deploy OSX_DMG="${OUTDIR}/${DISTNAME}-osx-unsigned.dmg" cd installed find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find ${DISTNAME} | 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} | sort | tar --mtime="$REFERENCE_DATETIME" --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-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml index 3c1e0214a0..c13c24c3cc 100644 --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -1,38 +1,42 @@ --- name: "bitcoin-win-signer" +distro: "ubuntu" suites: -- "trusty" +- "focal" architectures: - "amd64" packages: - "libssl-dev" - "autoconf" +- "automake" +- "libtool" +- "pkg-config" remotes: - "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git" "dir": "signature" files: -- "osslsigncode-1.7.1.tar.gz" -- "osslsigncode-Backports-to-1.7.1.patch" +- "osslsigncode-2.0.tar.gz" - "bitcoin-win-unsigned.tar.gz" script: | - BUILD_DIR=`pwd` + set -e -o pipefail + + BUILD_DIR="$PWD" SIGDIR=${BUILD_DIR}/signature/win UNSIGNED_DIR=${BUILD_DIR}/unsigned - echo "f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 osslsigncode-1.7.1.tar.gz" | sha256sum -c - echo "a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 osslsigncode-Backports-to-1.7.1.patch" | sha256sum -c + echo "5a60e0a4b3e0b4d655317b2f12a810211c50242138322b16e7e01c6fbb89d92f osslsigncode-2.0.tar.gz" | sha256sum -c mkdir -p ${UNSIGNED_DIR} tar -C ${UNSIGNED_DIR} -xf bitcoin-win-unsigned.tar.gz - tar xf osslsigncode-1.7.1.tar.gz - cd osslsigncode-1.7.1 - patch -p1 < ${BUILD_DIR}/osslsigncode-Backports-to-1.7.1.patch + tar xf osslsigncode-2.0.tar.gz + cd osslsigncode-2.0 + ./autogen.sh ./configure --without-gsf --without-curl --disable-dependency-tracking make find ${UNSIGNED_DIR} -name "*-unsigned.exe" | while read i; do - INFILE="`basename "${i}"`" - OUTFILE="`echo "${INFILE}" | sed s/-unsigned//`" + INFILE="$(basename "${i}")" + OUTFILE="${INFILE/-unsigned}" ./osslsigncode attach-signature -in "${i}" -out "${OUTDIR}/${OUTFILE}" -sigin "${SIGDIR}/${INFILE}.pem" done diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 754682d622..ffe228a032 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,14 +1,15 @@ --- -name: "bitcoin-win-0.14" +name: "bitcoin-core-win-22" enable_cache: true +distro: "ubuntu" suites: -- "trusty" +- "focal" architectures: - "amd64" packages: - "curl" - "g++" -- "git-core" +- "git" - "pkg-config" - "autoconf" - "libtool" @@ -20,26 +21,25 @@ packages: - "nsis" - "zip" - "ca-certificates" -- "python" +- "python3" +- "python3-pip" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: [] script: | + set -e -o pipefail + WRAP_DIR=$HOME/wrapped - HOSTS="i686-w64-mingw32 x86_64-w64-mingw32" - CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests" - FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip objcopy" + HOSTS="x86_64-w64-mingw32" + CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests --disable-fuzz-binary" + FAKETIME_HOST_PROGS="ar ranlib nm windres strip objcopy" FAKETIME_PROGS="date makensis zip" - HOST_CFLAGS="-O2 -g" - HOST_CXXFLAGS="-O2 -g" + HOST_CFLAGS="-O2 -g -fno-ident" + HOST_CXXFLAGS="-O2 -g -fno-ident" - 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` + export BUILD_DIR="$PWD" mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} @@ -47,13 +47,14 @@ script: | mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi + # Use $LIB in LD_PRELOAD to avoid hardcoding the dir (See `man ld.so`) function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do - echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + 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 LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} - echo "\$REAL \$@" >> $WRAP_DIR/${prog} + echo "exec \"\$REAL\" \"\$@\"" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done } @@ -61,49 +62,41 @@ script: | function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do - echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} + 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 LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} - echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + echo "exec \"\$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 + function create_per-host_compiler_wrapper { + # -posix variant is required for c++11 threading. for i in $HOSTS; do - mkdir -p ${WRAP_DIR}/${i} - for prog in collect2; do - echo '#!/bin/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 '#!/bin/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 '#!/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/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} + echo "exec \"\$REAL\" \"\$@\"" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done } + pip3 install lief==0.11.5 + # 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" + create_per-host_compiler_wrapper "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} cd bitcoin - BASEPREFIX=`pwd`/depends + BASEPREFIX="${PWD}/depends" # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" @@ -113,57 +106,52 @@ script: | export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" - create_per-host_linker_wrapper "${REFERENCE_DATETIME}" + create_per-host_compiler_wrapper "${REFERENCE_DATETIME}" export PATH=${WRAP_DIR}:${PATH} - # Create the release tarball using (arbitrarily) the first host - ./autogen.sh - CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ - make dist - SOURCEDIST=`echo bitcoin-*.tar.gz` - DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + # Define DISTNAME variable. + # shellcheck source=contrib/gitian-descriptors/assign_DISTNAME + source contrib/gitian-descriptors/assign_DISTNAME + + GIT_ARCHIVE="${OUTDIR}/src/${DISTNAME}.tar.gz" - # Correct tar file order - mkdir -p temp - pushd temp - tar xf ../$SOURCEDIST - find bitcoin-* | 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 + # Create the source tarball + mkdir -p "$(dirname "$GIT_ARCHIVE")" + git archive --prefix="${DISTNAME}/" --output="$GIT_ARCHIVE" HEAD ORIGPATH="$PATH" - # Extract the release tarball into a dir for each host and build + # Extract the git archive 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} + INSTALLPATH="${PWD}/installed/${DISTNAME}" mkdir -p ${INSTALLPATH} - tar --strip-components=1 -xf ../$SOURCEDIST + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + ./autogen.sh CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security - make deploy + make ${MAKEOPTS} -C src check-symbols + make deploy BITCOIN_WIN_INSTALLER="${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" make install DESTDIR=${INSTALLPATH} - cp -f bitcoin-*setup*.exe $OUTDIR/ cd installed mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/ find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - 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 + find ${DISTNAME}/bin -type f -executable -print0 | xargs -0 -n1 -I{} ../contrib/devtools/split-debug.sh {} {} {}.dbg + find ${DISTNAME}/lib -type f -print0 | xargs -0 -n1 -I{} ../contrib/devtools/split-debug.sh {} {} {}.dbg + cp ../doc/README_windows.txt ${DISTNAME}/readme.txt + find ${DISTNAME} -not -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i//x86_64-w64-mingw32/win64}.zip + find ${DISTNAME} -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i//x86_64-w64-mingw32/win64}-debug.zip cd ../../ rm -rf distsrc-${i} done - cd $OUTDIR - rename 's/-setup\.exe$/-setup-unsigned.exe/' *-setup.exe - 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 + + cp -rf contrib/windeploy $BUILD_DIR + cd $BUILD_DIR/windeploy + mkdir unsigned + cp ${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe unsigned/ + find . | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz diff --git a/contrib/gitian-keys/achow101-key.pgp b/contrib/gitian-keys/achow101-key.pgp deleted file mode 100644 index 030fd5cf3c..0000000000 --- a/contrib/gitian-keys/achow101-key.pgp +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -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 -Khvd4+XHE/ecjLOPvLweAg== -=+hz7 ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/aschildbach-key.pgp b/contrib/gitian-keys/aschildbach-key.pgp deleted file mode 100644 index df06e19fa4b109286dbbb7596c86d31fe0f1052f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1993 zcmbW%c|6mP9|!P{ZOo9Cp&a#Hj+h~m$T7F%D5emFVVEO+2vLrZIm;+aI~)yBmYO18 zM^Wx?Ie!|``qoy?2Z`m_FW=w!_wV2LAJ518db~=7Dj;UV-*xsu0D79G@N`E;@EF_j zZAyT=A6}Me4xPW&Zp@62nvj3y3W>K35PKZFfZuDmXq|S(ah3M;LE0BBZ_%unppxvE z-2O!dq)NG|QA``9kbCfqjX?){@c(@m5Pi`fQaaj3sn`;&V zH>t|DcOj<+8xrBh0DXw{<^xj|wD5hNC~0`1XF_|+KNBp7@MSR!c9sz7ShLc|Gl$|P zf-`KjZaloRozrKUMb*S*npiVtdxtM5_KY4kXlz^|o_0vIwO54ZckOAaXmWSvk-OC- zZjE!KoM37(gDdKmLQ9BqUdGC`f21afPMI`Abvw@3ltID^>pcg`lytE6?2(PL|iOYGZha+T6oFD=EmP47Oc zN{?Sla}(95`+d>k4vU|uH@xk*WqCLnMePprX7IC5WOLYeIVeFFlhIzAO*09I7}1@27zTjV6ZGm2y{pYv_Az9gTea( z(I0a%6MQ$01N0W~)Z8Qv7OBoq9-Iif$!%Js@c~-MeH*O&C%PIs$mN-Gx;<%1KMDGO z`BY2-7MLt}|8vq!kjnbh5L%;WNCBuC@;tH_EH^F>Oni`H8!4j_-Nz!@Lg2sp7ZC>8 z#91uv_Nn;{1yc9-nLeZn&|F^Jy;nM)>Y;Eyh?b~2EcRM= zVX36PXxoGTb?n-fUhFzsd%yL^O>OsZJ^?gyVSH(^Dd~j1j?qCQ$M^G&Jb^ku-!P}d zU;lukJM62bY19RJobOqu|ButYkiF}ySEirR0a=V134k()_^|R^MUZxZrJvnpbQ8BH zx=I9~9uDzXd#zGm+6XCMJW)SwI#$wB_{-V7%dfc{8@yJcW>`jIG5)&9pIcO&R{RR*Y2kKFW7ZXL1d8C7-X(qY_&B7?2zOptv~SYUWk z`{+o@{>>S=@w%tiTR-K`CgmzT>J~?{%=*DI+^Q7||K71;ZUe}q^h+SUSgJK}Nf#eE zlB8O+rmCr%gg5sYdqY$q@n>jQp*CGt5z`ETh;}G0*;J;mU-S>U!y5XA^dlq@h|Y!DG!^|uW(6C*RRUV!zEK@_uaxvlXRU1u1%Q>YD?PRa3J!oSxlHr$o)~YQ(&8r3(_S>uje8k>(j=DJ! zAC8U1=EQr=t4*~Jw-~^;^=)KMw@SJM54rul%c~=lWYfi5KD6;oz00Vo{OwI~@6>5` zmj6fbWB@D-6qP#5^rhmz#`8-N0jrP<(5ZU!j+H=P!F%cTpWH`n49o^A+ zGEuRA>2`AC?-wP=WnzdtnMwaVuv=mfLMDbhXgA+`_ZgSdkO1c_bV&bPE+L~O7*+$H zJY0CO8hO=L)isjminxmFFrL+Psx^W+3Y~sixVJ&!bC@2)+(~Qdn1o-SZl~^G<&9zq zsrbl1D&~hVvpiN#pts$YR5XgIAqX6PyK}K%>&8m-N_zDWp|h4VIkp(&RFQgwgj9s9 zd=Aa;M!cll?VfCWIUTp%dDG2HL~BXa-?D*s*KOD>R@ey2!nb0?HR!un_qG1b$6dwU)^ WIAcG~ygp)$8X5B=5Q?y`6#oH_l8)K{ diff --git a/contrib/gitian-keys/bluematt-key.pgp b/contrib/gitian-keys/bluematt-key.pgp deleted file mode 100644 index 2389d4657fb7f5f225f5d76e08841fd6e21d4be9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10324 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 YdwG{wk5UyOo}K#wKU;q@OV7XfKc-z}EdT%j diff --git a/contrib/gitian-keys/btcdrak-key.pgp b/contrib/gitian-keys/btcdrak-key.pgp deleted file mode 100644 index f00dc729d57a2e7b7848324177c605dac9dc8e45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4916 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 z%0A~L3i=9J@!9bPL-a_~P6?yyQ^#;Ueuj8FC``}0Ib;V^oHb59Bnms7y_T7j*p-N* zHm*69PEmN|ZOXs+g|^Q!DNa(IL1ocxSIXE6iDjOC_)7xFGJE9edBDs}?uVqS9!~-F zD-v7_pSLlWh>RqMl#pLn8C_&5v8jVW)wXHslcGlqtAiY=4m%FZ5;5R|#)~J$|@`l@Q|q<3T7-%PAwUe)Euk)_aMR#FWm(B5Be2!Oo=Wtu8P)xljzO$51+Qo)2q#JnRF4BS?3VBc^*b_IYas86K#@ehX`$WR{ZCpIaoi!bud%C9}kQ%82Y5A2tsDp`iC> zb@4$}Mqb#V(MlkvG<(~$31`-;bK!cs%a&56Ma!zU4rhB{4hZ-HXiNQs8)oM_lgMe> z6}`-BQRcv}n+3+b&|0AyLE={&o&V?YP(;2l0XuyF?eTNAN57Thv3738aa08D7mg`@ z5%Q7f54g;ycZ7Ejk?l)uJVm1?)XGVQwHqWn*h)av&&UWMyM(WpXJXJY;2KYh`jS zV`y?|b98B8Za`;kVQFkGV{dIfi2^tT69EDMA_W3fad_tf8v_Ol2?z%R0tOWb0tpHW z1Qr4V0RkQY0vCV)3JDPQLkCn64#M;c7Z3kx-Pw581T7xW@g#1KQEnw3E_{|`?3|VH zCUs0L`8XFlAbKALe*D14Qr4dZZ&t-R9GIdGBM8tk%epxx!vI2wGth+Q z=#p{WPr^cWf&;utQo)%Gok=z3f(mm0a|hkVF9ne4>5PQ1u5?NZ zHa4SJx7Q}F2`1oIvGZ9mUMjwmp@d5%?6S7SJ{=BoEfo|?-Wz!tVsWo-V;PTqGfnyZ zaOWp;La>x%(R3)4lz5ElXABaWNr^359~0-X1N;Irs(VW_EE=psd(3HIFvUWaBGwV_G7szr@U9|!ESX3NzsLKUI(keDDhlJHE=31U zC#VfBXqT7iV)=e2{1X`U@oF>X;VmdTefGB}M}Qu2xC*VKfh9{j=E-IpoU~^j^P5S+ z@-|e^y}Va`V#)*?9fMqV`n4EwBq_URg+Jk*gk9B(Tz=7nP*e`fIjVnay17-W9KeMs_E(tzi^)hMPj!I>-O3I9zg+ z#y68noBJdmL^Rz0SND^JeBD5vI^uMN&znN>?OIU0ZA*>*Vt^9ut}A6#u%l+2WQZ~ z+0xLtzJxu82{QH-AO+u{?~H4e%69Mc=zDJT%Lifcy!Kr{P3;f|YrPFDI4mH3gI>@k zu+mEOLpcm_hgIbqB`Uju^XZI&z#r?Qtakm-{`;U)zGZ!;&l#&~fU;=6xf^iSoc6!G zaNHq?Jq9+DA&$RX7h%?f5f0r7(c9eVdjBXybX*-D0duR|i|?M@nh6BsUxBcM{w)L_ zGX|8JniDyiUg7MixWAb6Xe?TcaUyNS${SEoNGHJAkvbI(?UrTNoGRffujC^}E~ymrhPt;SlGJn+;&7*pf2t+Wm^cz= Euvy_F$p8QV diff --git a/contrib/gitian-keys/centaur1-key.pgp b/contrib/gitian-keys/centaur1-key.pgp deleted file mode 100644 index 71a42e5148..0000000000 --- a/contrib/gitian-keys/centaur1-key.pgp +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (GNU/Linux) - -mQENBFTjy20BCAC7q/tpPQ9tdEALpDqe8kpVAT5ysOJDLDeFEE1J5O8NuDFuibiN -XYkb2nAt4Vdr23in9z0LAiTSgr7znndnab/rOSn6pXbXQfLTHrSnAeClTHVQVPSq -m5kNg1vWvNxFtIpZ/fGsc6LLmIHxdgeLn+NOpvNx7RzF/N5ctX51vMxMUeDq3daZ -tLneJVRj5tXHRJcjW62cyiNFasYAZ3JC8wjwzr0SOndc7kygbEVCTWNkTAGd1Lax -KSJW6TjhBPK7j+RljS5nfx/Tf+OG4AoA7/53593YL7Shfx8rwWVIeF4nS6efFnuf -eIj+aS5haGyFvNgw8DE7QUCrPiUxeA8wuXu7ABEBAAG0H2NlbnRhdXIgPGNlbnRh -dXJAcGhvbmVib29rLmNvbT6JATgEEwECACIFAlTjy20CGwMGCwkIBwMCBhUIAgkK -CwQWAgMBAh4BAheAAAoJEP+V+qlxaXQF8r4IAKnE8D9AOTdM/YvYxpCeI6ndEUUs -8NcotpbIBJ67vr1Dsot7Ee0PrmIYOiInA+T81lPUDecJYrnemVefhquiyJ5VJ4/d -z2zUKBfxjeOsj/PHgcowVxMco8fNEWQa2fZX6X8RVADIsUnIIwpRFVUcbssK/3xJ -k46vjWwYNQywht/ZgFBesOgywyz5GozmwrK6TixJxKk8M69GFz2fHhJjp1bxDZuk -Rs3YmWeOcCasoJ6GbvIboKQSPHGyEOCqIuiBL63YMa0n1FU0ooDteNZ04eRinIhc -fo9JC66fQrUFn8CmmRTtdZOrZ/efYjQtfLAunCkzSM3p6DE9u4Y7d8E5Ar65AQ0E -VOPLbQEIANhxtouZuQmw+k89toBWXw75s+csxKHKZuhw8QntaFyFYq3IOnIeV1sK -PRENkWsqDInjEM8k9eZ6pnS11EQ1rrFffss+mprTbL3I4S489tJETYZKHrmmox7h -ustRi5eXBEmGeKW0mqpb/9r4okpTaIfs+EJ4C9jj0ghWkqU0acyzanJiUY/0R46F -vPfGfHnhZ5TAl3eiL0H2JkF6taG8K1XOLemahdZHE9wJh0ZFWnDDkA1l6j2rtYga -jEi/ucOp5GkmumxbFiVgponDBqBpsscRrCV6SbZs9gz3dQNgqe5A3CKGZRuVCY6s -djRJelgqCF5+dV0fAT0oF3C/3E5KAgcAEQEAAYkBHwQYAQIACQUCVOPLbQIbDAAK -CRD/lfqpcWl0BUSxCACjEFwQSHcfZINWD+KdNMayxyHQlBwsEDX+xQkgnn+/Q3hW -9VI3SSSfFV3ustlUa3IaNHwuWzsrSqG6mLG47LAQ6vPAWVh723gVCpyJf42Oms/e -qeyn0f/PT/6RuNMXQeHbfddmRp4PFjyKOms5Bmf3oi4t4JSvOS4yABBBKzhDQYC9 -e+qv6Y1sDYpSiCxstQLzIHKiB5bfZ8Szfk09EyyLdqLGkiB0MFhHoXWwQxKiLVc+ -xNFj2a/jw0rQVgN5DZgHBWU5WqvS5CWIczi+2S9MFI26iBhCn3urZToaaQ/DObqC -qmekFrJ/GOj5vB1Mm014lWjG2X3EovLZ1XkgWI7W -=vtNZ ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/cfields-key.pgp b/contrib/gitian-keys/cfields-key.pgp deleted file mode 100644 index 6b0bd240ba..0000000000 --- a/contrib/gitian-keys/cfields-key.pgp +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (GNU/Linux) - -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 -MrD0ofsytfy1LQ== -=DE4h ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/devrandom-key.pgp b/contrib/gitian-keys/devrandom-key.pgp deleted file mode 100644 index 71898127ba0d6c9976ab7225d8c71ffc6380b0a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2213 zcmV;W2wL}<0u2OBj)Nls5CFeq*<7}>X;w`_QHIEVR4q2Fo2X;O&l+|Y;TUws#9s7$ zd$!N+kn-9yQpQGm&JE9u3t^!EbCB}GvGIX*t@O+-5I>MVonlJZ8CbfC{~;OJRT{mw ztV`wBL19Whs>{tw%bom4`3IkH)k;@IvdgYx#r%JEc4Iv9+y|x~7>q)-Gf7QmO|l0> z%p3{1c(pL4%-D1?*Bj3xD6kLFKan`|{XLUGrvT^QPVUUZXe)nJ{onV!YTP>L2j5i3 znsRJ7QINlj_#3^yyuOHxNQ6O*{udHvBdY*fUBfUHb<-L|1R&8j{$*KW%Pd7K*GRS}do|>CWV)=C?1yl0j#Oc!*3ZLK!X43t)T|FSh`*d9DI{;?& z%fO{fZnQogv6wuA8urEHoI{Z7z^>*7AJRif7biY7r>V5pp?de9km_gnc77F0QHqX_ zBI_EqjvLq$oUH&60RRECCPZa+AW~s&WN&RCJYz8~WMy`8VQyq^Z9r~mW^{RCZ+I?l zWpqA?0yqQ{0RjLb1p-ZugChbP0|pBT2nPcK1{DYb2?`4Y76JnS0v-VZ7k~f?2@sf{ zYcNQm7PX=n5B(jvxHK+fi6yms@Q;H38D5D~IjZ=a*#Auk)kmBND(QJf;rYTta!+9q zs0>2?RrQXb3;SDAnjJp(6{VsaC(BEgPF;n+OOV*l2P$^FJJl&8-;K+5uQbIs(03|0 z6f^JTiR=%A!_z}_Z6DADh-~~5z47oc?rX6guM>&`bq_TdX0Rfl z=38am)5*g+xZ8SKoTdW>1gx@GXj|d|IRBAQSHm7zVf>=^(~O!&JC4qFPN)zuaIQp>fi;T6i?2ghxf$V6r&{^f!XpSL!O=l3Lgw!(vlc<{zg1+ z<*qW?DsO;Tu=D|pm{J9u%;6>*H3hW(Lf7n3j0$zsy)vZMo%U|N-$>={H5@s=c|1X$ z$xND78b{RFJ8i0#6;}%Le>V`v*Ghhzr#c!(rPBg3&uQG#Egxn%h`Xa8e8r}s#;656pc^)9!C#|Yc_-)a~ zH4wQ14FpY&gChYD0JFQe^o}0)cr#z2`px-8SRuN`gxjWHFFG*Vq3!`U>IriQ+Te)0sDl*Q}C}-0-Z# zllWk$l=91f!GdFpWdW{llDrc<9$O3pNpzc2<>Fwt{xj3d_H;`Jl7DS*GcX~%h>u4L zD``9^W`~HzU6c1}Z|>FKe+7{|DRETtDh^JTwH;uM9Z-7Hz{kU-jF+Ai0O)zpx)+W& zvLHTvO*OIb)D0tF(Y#3IJ(!RPtq`A0-G{f;^+V3iE&Fo5L={LIlSW(*!Akx;sVqSw zAe1oCk@$PP@*h=>Xl8&Cv0NT|AY|pb#NsSO#1#US#)iuf=gsa8-9yQ=GB+H`ayluJ z>IQ8Un77!yesp%Xbv)s;Mnl)8w7xGxH){&z>n>$0@ z#21Qej|yd{Y!MYf(C=iw?;iBUunLjODY9v`;C!Wnwm2;`I=}S;Uw-4fo(EN0ymsN283-QAaPcFforDn)}=fHsTQx4>6G$zG{wlV)O5Y|`QGx=mZhBa#LAJt^5rWHwjAyb;G6Gc ztB1Zo*=UaxTiT+?vH>Mp%$2}T8C176(F7Ro8S;cmsre!_3q6oHbQ5zB*^G9#v339E z4i7E&OY%fJ|CR2jpANi}oO@9_U)8t&c5DuTh&aj*$+ZH$2+a;i>~)0$WMQh`W3(nk zvM;bJS>j!x5qx^K=A>j`39c9zcTF@aAG%)PhD5?`e#k!<5KgI~;>-CiJ7FtJeuIF=J{OfmAJwe%7wdp6VenJhZZ)8qOMfh$y<(Csx*nGs+~*m=)#QASGS9Fln9_adQ;CmY n(h-e<^sM=qCBIX6Njz5;XotHkz<0TM5Z~I@{aR97pyn9V^jsJC diff --git a/contrib/gitian-keys/erkmos.pgp b/contrib/gitian-keys/erkmos.pgp deleted file mode 100644 index 9d3f060627ee9cb4143e3b8945a261e90c39ba13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10205 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 diff --git a/contrib/gitian-keys/fanquake-key.pgp b/contrib/gitian-keys/fanquake-key.pgp deleted file mode 100644 index 9c03ff4522..0000000000 --- a/contrib/gitian-keys/fanquake-key.pgp +++ /dev/null @@ -1,63 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG/MacGPG2 v2.0.26 - -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 -XwbdK0Zpx/oDtRHpuDMGKJBV2LWAZYkEbFsmtg== -=3o2I ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/gavinandresen-key.pgp b/contrib/gitian-keys/gavinandresen-key.pgp deleted file mode 100644 index f81f44e874707837c13446858db2fed14ad5c501..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1176 zcmV;J1ZVr10ipyd+BPOXG1ZrDpv%iXyY*~=|+SlmVRJ2@d|5G=3lw%C&g;j0KvRW zG0RVD!3nRuh%R)pia&~L1FEOGx;eXR*K` zu*WO05N?XC!C+-X<8ovFvIpC&fxEyfX(2{j!G#JZ7?CU%mrw)$TSGNqq(L>S_EMhm z>C$tB193UkB)z)vhMWgbGCTvPxP}Kfdx0GIl8t06ZPII(&3kQCzEXv7#M)%vPj{EY zcen(gIU`UxU-nd2`Gon+|B_0Ff*@;+F`bIwREZv?xbmc4=-PL2hJnWpib2AUtPbc4=;5Ze((0b7gKoXKi6=Y%XJO zZ9a%*1QQVg044HzfCdW*2nPcK1Qh}Z0|XWV0|5da0Rk6*0162Z zb%-P{zBtpUe6IkY$jlON2g&-~!PtabhH%KRx;RqM0G%3)n>ot_(%$#C+gXU@atMHu zy_C5E4FpWQvb7Kh0Lyf?4-i~4^f3$`ga{Ay5*wreKf>2lV6ywp8d}7ENW=D%ux6^* zfe_#szOQ3V{y*tz7?DrDyfq@LWFCHCr%@-(h(6PCP!Kw9x74URPC$@TblGE?^C!T- zq8)?0%b0~_Ytjnul$QnT9RS<*D5dmu1n$x{uRAV*zh*N+8p9}Ho%Pe)*0 zMnEdZ`oH?%L4~7A1F_aQ|8Rcjri-TI9EL4W#QMcIXrNTVrH)rvOHg%{!T`G$1?>8K zRy|m)M}%VOrUsN$>#AQvZnPq$teX`yY;D;>tsyDHK5Qtj#S?asN{)W{exHw@bhzOU z9^1V{J3(+Kj{pM&2mgPBEamX!SrHwdYa^4uCaz(-f7?+0M)V2mw#6{WkHkn8b1R-^ zYDL+eN?p#i&&iBy&Go@UU6MyD*c7YSQ3wLLX`?CdU~}FpEb`VEVP6+=?&FSbCm=k@ z&d1&vM(f=F5d18_%WVyD>j@@JhkmOlWQELtPqF$CFI z6&Wk2#X|#%!_kOO1Q-zl01pKMOuVwS0vikk2`>HzfB*^!5Os(oFTOa_s4)oupKEmm q7ky6Gg$kN{t|V0xiYY!|8vvlVg5(~9gx$G(luB9`Z;BnEL2B3d)*1@{ diff --git a/contrib/gitian-keys/jl2012-key.pgp b/contrib/gitian-keys/jl2012-key.pgp deleted file mode 100644 index 984f555cb7..0000000000 --- a/contrib/gitian-keys/jl2012-key.pgp +++ /dev/null @@ -1,275 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: SKS 1.1.5 -Comment: Hostname: pgp.mit.edu - -mQINBFYhRd0BEAC+2VU+8+f9RTPLtl0C815oxaOCA9Tle13xNER8NjFrVwIuFQ64nO8Fbhd5 -KEEARuMS/lc5G6IV0QxBpDGE1sEjPQXrA6UnX8SDkNGhmoAsV07MP2XlglN9qqYUEoVD7ueh -7Cp3A9rFjg7wcMJCPQDP6lZY4cPgYlE1C31TCrEdAsVVTQg+xIYWnhB92VxOJhk0N0h6xtCQ -2MOtYDjYcBndQ5iK7L5jy5LI89YVRfbKtWqWZdwRlgj2JCLeXKauXBI1qbedCJrz5e8nXcdq -Zt9TXSHo/XhNlqvsLiqBq4aXNU3xRkrvfcweZ9jR9DjyQzefYFGaiCk37R4qLbaqQRm0luUi -zkCegIuTv44e/zig0im8yPAIWtGnmBPSy4MpvvWiVVb+jHikdQG1T7g9kF6gEmj4kj9UseWn -asiq+kkSNE67vLxbuZDfA3QhavRMJbCNEY49/IX6urIsiCLFbe6C7JVWvJ7d5l3MAHE8Sut+ -ytjX7z7OLFt7YD6loxGAdopEUZm50xs8PswKDajlzWGFXjDZdzQA1tb2CpHUtDkAInYDutR4 -qA29qtxaBswozzUYiDptGSkBqD1Nus7UAJYkwe2EjeszNPhmIAQXGWx2yWplPOJkZWDuhQtr -DXZikl70q0ekIJ7bxkpMO8xUuhsBCS3Wn6GAtySy0XTttmItfQARAQABtBVKb2huc29uIExh -dSA8akBpai5oaz6JAjcEEwEKACECGwEFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AFAle9oRAA -CgkQxSQqGrOTZRck4Q//W/uBcS6LuvlZsoVYA3jmJInzkQx5DektEa0kSYysV+bJptyYrYV8 -RsQoNLJCkEh6Nk2rSvA6+dcHFwHhCQdYkTKJuUT8fQXhMF4C7G8iXPIjwSVnK0wa0c0eYtr3 -m6YPFsxfb+VTI/eQlu40HP3fWf4JN7zDXlz2IarC/GAsFlfZaXVpuSmCszr1uX+ywz4DYB6e -X0FuZk9fVYp0VERg+iAybV4+dqM4ZQ0Vu1cxLzrIPH2LdLHICxg79OMzAD1MHYnzkqajO0eI -blaZCc/QPaVv2bSi42WTeJJIISN+WrpeTlz3aoqhz7eGwKIckJAygnfVhYSCX7TWcaBTW6SB -wubLTfGJM2/T+OrXvVfeGAxLDPcFwpDDLkzv2u3cDbUbhf4i2+X8Xh/51yPRhi8EwIhJlaAR -CesE+iMHHvFV+ifdrqK81U9B9uiqN2xS9UBcXcJKmp9zYkPvYWfvT+D6QmvWmQ9p+EQLm9dg -zOZM6sZjWV6WtKsJWsaLQpqjC/iVnqbJoUb5g8S/vLJTT1KaTc0aTxs0v2jBFbld/kAu7Gfe -8cGz6ZWZfIBydjHFAYxCqPG0TYoQvy7eA01Djly0SPJH9PhYPBfznU91ZcaqWCCxXlp0PgCy -woMUiwP2kvK+HWTb4dCgbQwFNChNPkZ8QAsZuxGyZd7VxdbLPYkW1IiJAjcEEwEKACEFAldF -2iMCGwEFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQxSQqGrOTZRfnZRAAtR16Ns89cP8T -AzEvw55RtjeaeSmb0mw66KT/Bzzis7aWfvebP3Yki55MygHJNu+Bb/LDBNpYlJCjAoMCdLTc -+aDYCYZkrWOLQXWBTqa6XFLeexKX+gpKrNB505n00CWvVDVGsHJZ0Ha8CDZATIlj3e4owKVQ -jMLWY70MNwT/uc7YkSd38/EW5BkA76eE/AhHanqB4cWKGSNIiaq8OJYBiGNfb81Bz4Ly4kmW -VGgshYJPQpnMQDq713WZINT9Sn/NDfCrdNjFjHHxJjymZ7RoE5teqYOw7bnbA744VFxmYMrG -DrWfrTb1FORqltr4VHJnRpFIXv61DY4+eoTi1Zd5aH+ehpfDH1G/3UhPxbmM9wBsfsgy6dMy -N2XLmL9V/eHs4lzbTCyQwuiCCu99Vsn9VWcqsXGtv2xxsR3C9PYmvkm4Z1KqasKPTvRvZ7BD -0Bsdg2eyBq1m7HTK/gzSh4aCt8H6HbIz6MwO+POaAuHiZPOiESmLk5gG7wmE+/It/5vfEwDl -zL8+5PCCZtoRWaW7lyiezpAYjUq81SEsVsAqlrtIyvJnG+wATCdUHRN6GNtfZ1aMp0i3Jei5 -ST7LGAqVF6MiLskTbmIGW+P8at69orUmpA3vcvGUiSqW5JXXiPJUwUZxNAPxvpOh4B98tXfp -8kxmSyzcHR0a2Crouh+STPq0FmpsMjAxMiA8amwyMDEyQHhidC5oaz6JARwEEAECAAYFAldF -tGoACgkQmE8QzHcWn9Kybgf8DVmGhfIlQNvMH7YIg8hGrA/Q13C+FiHG4k2RQsd8vD25Sehj -GHNEsh26TxaF1XNC/yANipXyUkfYRkweVwRyJ/OTTivCtZQ/Ct0hJA+lDSfLEWm8pdiRGdio -McFq3Uy+KGBTbdlGaSsMbfCb6hunlGnnSC36X8yxnGwGPduZDlnKxrxey+eYgAN/ivC3bmRi -gVBAgDJXOBszmINGqg1T98MSe2ph7NxvWF9mF9JenJne/juThFMf0khnalQB7NeagX0UmS8F -/i5k5JgB/YVP4zTWhiAeetzBIfiQ4GadHyW52bNT9P6Rz9kKFA7xT7Olod+KaRr4+f8/6MCS -rgvpnokBHAQQAQoABgUCV0SRKQAKCRB0gQsBI0bJpko6CAC6g9o1t+/ZexSQVGqVGyU4w22Y -+OmLlx0XFYPi5ftZ8jjUkhnujis0i/KS1oreBzg0U92Cs3pWe05eDwVcwyTGJbGR2DPRM53/ -q2ETdzBbOPrSaOjaGRrMljPgu32kaeSRQbtPt+OIhvPuHATVEaHdDbsbyAQzCgpDnA2yvLIZ -wqFPIpX+zkn4tv4DRLOHa8+2loFMX9B0dKBDy8JrUDDt8sZ7dzoxEagUxLWgDzlQ3SkIyYZz -1Kk9RCx/TxQbDSQsGGpPyhEU3MeyCRQo8klDIxzBI8jfASnaxMdn5hdFdj0/CoEMTlHr2FVR -Z1ECKgDslJ0GwDhZ4HFbXnWcNx5aiQGBBBMBCABrBQJWpym9BYMJZgGAXhSAAAAAABUAQGJs -b2NraGFzaEBiaXRjb2luLm9yZzAwMDAwMDAwMDAwMDAwMDAwNWJiZWZkNGM3Mzk5OTE0OGRm -ZDQ1MjA5ZjA2MTUwMTljMTNjMGVjOWUwYmQ4MzUACgkQf6sRQmfk+gQcZAgApPqnaIIE8Q5s -ruzua50RFRmmBtQys8sM95ciWYE4QaTXUnlhHl4QR4z/TQTRSBqXpdHQ9HBWrhFb6E0ykDEV -x9zdEt0fvtlhHx1ItrZetfiA4PwidnyoDKs//nt01RGreKSMDGInaQVEQxvEW+A0fwvcCdE8 -Mh3LcIydohfqUViB0c5zb7rUmize+2Kt4Uth9T+ooo+UE87pHSJcxlcPOv6Dc7KeoUicD8Dw -WdsT7oxAMk9jj/ut4UNxxOEp9Sa3sFN20tHMqyOZwnl22Py0y4ayJnceawpuka/bx7samg/2 -uUrO+dNKXObNtrebP83+8UFHOo7VGhesuawgwNjWW4kCHAQQAQIABgUCV0HjEgAKCRCGD+uA -TmaTILHhD/9tumyLLIMuVH0hgBPk/S3BxvQXfzgMt8xYyKw3kmGkJpble9RGYWTcT+D9Dagp -ISzGlxo9hh+I8fArryQjDuiLN3OMxDmN5ctatbVTSQyXPHOLZj6y5X8mA5gKfZb1EvcZpwoS -3sUdpb31oCrmxtRVfYv7G1PaBYGf/XILu8mwu62VimhYlK/RrNZHNeFb4mJiLFviVFtAN98s -uT3lFT+BA/RsLUO+ogNcJEPQ/2Hhg93qUuKssdHKC8q5hLozTLOxepG5JjrKUS8PIXjicsnv -ui54VPkrh+8Lez7ezh1n3SXIWySN4H2Z3uFNTkgheLA7F0NhwVKPl9TDsEaaJROrbRFVc6aE -l6IQ8Z+8Uw6IifDKg9FrKlPoL9+vBrjjK9mE6E1CdLE9kttK7dHRbtCIx7TaiWIKwq6ihmOT -Eo1Ht2aq6Jg2KMCTJMQQN0vFtgUrAJMzE+hb0q2nl8VUWe44z+WuN4JX9f7sVXn4Vw6q4hfJ -7J4hgv5SRNlGRjHZzyaJfP95VnDIzKq0V3+fRGziIvA4r3TVcIVF2bvKK7H66zdOczhB141k -UGNuDsIqTaY84uk9L7lvC2jymeqV+VZu6tgxrn6OdyYd91Oya9bdduj1oycqX21pNUySkCMj -cXbDHl8EMtQVdctS+zF/Zu1dyK3Jhu2B7VyrdlMigkFBTIkCHAQQAQIABgUCV0b2MAAKCRBr -4s7RSpkXvBw+D/wLaBkcs9iXyVMGsFZgBhJODxz9BWSHfmNOsbvLSoPHCVJtmyshDBXJSruU -dOpPST3fo0T2TLdrL7DnP3nW8BqRkAoVAExZenCpT0p1oPaQj2rV82AxVjxc6syI0e83Lmp2 -USAqM3CPEvPBUL6yzmQdajJWfNaOM9XtePSsRXPGuT3gH8rZojFH7Ay+pBbZ48du+Pfm8fJD -M0heKIBQ4bOR4YTiV9t9LxOFzzt+MtEEixoyBfA56YQUaNfvjGr0NGeGXcwbGvtj7gt+14M0 -KJI0TTZWYvWbXDkhgmY4bhLbEcH6a8v3428F56n8TAYYzqD6XvdqiC0tFZgSeEAalaiNIohy -ZY/nKvZI/0lpfVBN2ozAFGF5SVUFkLUDgUzxJTnTacTDom5iifU2jcDWccNtPMNJCoufAYEk -dTQ9g3qtLypAEwW3PY58Cvfu7a6SiBFvMprwgOHBa7JVPPOkup0Dc8F1vtzxG8gASd8dK+8h -+yE0vGP0aCDGLrOT0IgT61LsIbg+9I13EPdTLaS4TflEncoC7TNy9kyuwmiQ+ObEl/IcMj1N -uEF3zp8HNlUUURN9GTI5Xx+zHXO7G1PO+wkKCKUoHLLJxMyqCw1TFIFCcF8PnJaGSfgNgNjq -GOZzar9AJY9djlNBgp73mYc0noRgxn8qYnmPEZPrZdbZIGTqCIkCHAQSAQoABgUCVz+PLwAK -CRDAwHYTL/p2lVR8EACqVrrQOqc+5512G2TzTHw1IKasdViMVi5iKeULU3POL2bHpmGcVWmT -slPB7TNXgGj+fr/ni6P5MceyQ8kgVKfHRfH6zF+VYIAD8qkKESCbT/Wlmv+6ACKV/knl9HXs -F/Pa/b7wOqrvdF7qo/NYwzgMghu3W/FMFET1KdQ4VwvysYUe66xmXARClT4M7+Awo0yqsWHw -Rk3uTJLE/GeRX7pmQQRqX2ZbKswXvWE4ECR1IlSphN0ul59o2Lq5ruNzvptnajSMJx7HHczI -oOv8QvfsCWaVE330C7096nZJrxECo5va8JYLZaeWrc/BMnp8ozQ9GsyAtidWi6upO8mzxYNV -5NAUuvCU9KBg3DRUxgAvoY6IRyiEV1XnNt5fzoHXHQJ4wmR49UWJ/Nz9+ZT6ZO7SzgYJCASM -/6XGfvuIPb6FpGZFhsleExacgepOiVGMsZ0FYXOEVhgOCBSJkAPCqe/igDXlFCDugHOvQgFc -RPFZOFxgAicrafyFKZ8HmZKM6wxtUDtgNJg6ANUTUA74TJjs8lU2H4BRvF1bfeTdjn7LI+Nt -qmwN1PU2TGCLvrLTMWfVjoIGELkaeLhLCPAN9XSOQASzksFHKQ5AWJ38dZVtdLu08IW/AKHo -e3lzLb67C/yJKmHoKioIacOdFkDQ8dTlJ6iSk8KlAGXb+6wZcyHlKokCNwQTAQoAIQUCViFF -3QIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRDFJCoas5NlF7GyEACZ1w44RKCkiCyU -aym4PjFz90YcXP04V7uQvMoX2Kim5agmjTXxJq5Xq3CSiVTL42NLVU12KPARCZjTe50jSLLv -DYXifb12nDd164JDD7hYlMio/TxqUrDOkPDI09Ac3dKcaHZPoNFBI8jJLX7v906i7J6BTzrS -IzDpK/7gc2Z+XdAFyGUGwM+F2tswVvrkdzkl0UVwkSYwklhiHw19GIvxGvtwXvsvWzKg2t5z -1CxJFu/kTbsoy6+kMD2dPwaU0w3DOlYnNnWhTzuQdPqN8zzBZj3BHeJ0R0zzPQOUmibQvDIx -f/PZo4acRt7/EapKgnanTNnHs4v0+GA+I3MpxBd+mGtxrrnsMRGXIvzeckhuYBvGPvNFoHNX -vrDbbyH3x5N1o7tpDrzXAQNkwcN+lVwiVx0TkwOfgseJVMTpEEyaGElc8fOdlkulh3i4Nfl5 -w2b0+3IlSFdBMSUPQtVzjMIxTEbE1pfr35cZoAnhwiGq4ueycN4o+4IUQoHqi6exSFyuakiO -E8NnmoyaaEyj7MJWjupLzl7Wggx99BblYSmz8SCNNV4vwNgC7U5KQOpn539faK0I7/h8V/4s -FJaRzFMLLoaWUkGCMSL/wTkJ1w38OE3I5x7Kl2W6jc8xRIxrqzE5TlF+Cnkz7HHTi1KZztRT -OCSFcmxx34Qh/TKavjCMAokCOgQTAQoAJAIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAIZ -AQUCV72hEAAKCRDFJCoas5NlF+DZEACN2sYVaoY752e6NhbKz4IeD56/zEP1x4yaUPvcbx3g -93i2oimghVnJWvwqxESFU2MgoXsMiLeuTADOSP4iP+DeBpB8qSuesHyAdyDRFq/w1qT3pKvT -mwPNXpTha9pHQoD4+/+pBwL2pR4l6MZ5+4iXJQFQQtVOhLfq2KuGuaPro4yBiyQX2eKCim1a -dNk6qtyRkFYlOrJRPqZastfNEb2Yc0DDUFLTzjyNsRxhwUd3DdOtqO//5XMvI9q/fc5wpDSP -zNzLoSkJM4V8TTg2sS23wCh3AZB2C7wnmWK6EHGNosFL5hJ6jtW96O5KwL2b/cvIv/+v214S -AhVblvhxgJ4zSQD2UpkORfKLbyp3wwRe4PFzlJWAPM8tjnLfGU4ACa+3tubDaembPM+Ft8Id -j85+HgE0W0s/eEOBTqxkWZr7blSKeiH4u3b193aGMIGGjF2SgGAORES76er8KPlPk19XsXzK -msO84zRT9JckcM5eCYTza2o3c3ycNZN6dkEAmhs8vzDWIBzB/L4galO8M00Vtck+EIScXNKV -SgZYbFb71zcKYT8yI53ZS04/1R8VAMEblwmxiTYscrjBoCcfEKEghYgsuICXjazFyXndI+m+ -Qx+XcLbZb4ubala+GlD4YwGaAHBVCIWHpBHHSH12Z0nermU0WRB4rb0uvewxqNNXoYkCOgQT -AQoAJAIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAUCV0XfoQIZAQAKCRDFJCoas5NlF3+p -EACzVNajdKSJAdCgKf36HCQ0TwkYeYuR1lWwwYzw8SPwjUGukSgo4P/recCm9HyT+AKO1vBc -+vgHTPECH3trDjWFg7bcL9P/zleKqvPuKGUIYihnXZmLLsavPBuSBmu7L9OR9jgSNY18s3Rl -/uQ6boOEKIP6gKREpBTJi3EUKWx/lp9K/nlCwTGOUP3sU0vhQTM+p0XYH2lP9ZeXBhKv75dj -qXn1fF65oZMzo/mKUCsXahJZPBrobwtcI4bdDzlDlcC5pC6SngrCJIzceCgsAkfutFG/H2MR -TyArvswpuZMpdniBbgnQDLWZ2bkP6qWBak9Z/80cXlSYhO4uP+rdvKMGxiobZj3YQ4u+8zqt -GhI1P7nsOtnmEp+tVWjriVrCCrSiSWE9vYmUbxw/So+FKfdQxVJ6ER1tDYcQQf+6itykJulU -Hml3jFaXYMVK6MnsKNTUvB1dlmYnSuuNUMzcwVQCrcxgpkDt7A9sJK0+PI+3HmViiLEN6fFX -0y25mmCi7aUQdgtntiaM/BroHgA+qceKJFDQrCYVJ2ecbrAfEWo6TimRcC31V/DRKnuZAb+Y -NvaSFFO0UQojsnCtSBBfUFY6zg7vZB+hGccduqdsMCuUvrBBOYcSjY8jWOuxZgSgkqc7YqZ2 -ILPj+9Q+9H1DIwpmb6titNlijrYNItB2C1KodokEHAQRAQgABgUCV0UdVgAKCRC9ApQkIfSI -n34PH/9coCxhWRgFd7S57bMX4OeG8drxazbrq/uByZVlkejqrZU4qVgwGWe1XVZXmsoI3ISp -hNBCE1ut94+9GdRmxtXVAWS7owFLoJhXWV71vq0AsJQJAF1qIZgQqVv4JfIcaT3lPw5aSSuS -bD+NU9xVnkx7ngARNxmrCSGuXWBJXSz+Yr5mugFROJJn4mn5+Zov3Tx9OYR7ekB0ojVQfdIz -yWJefZ+pF5Owc66TpQMd5qVdHAvcO16WQSOY5YeQc0AWPPPaUc8SKzqzBMCQ+XBASrxJDmWR -MN3NagcpZDQpkvXOmgZLJagsNGxF/VTQrfg2etGnDYBelvKtNJ0IgcPCDF97mApo8/Mis7G1 -+fVZFEMSLx9zH1rudfbN3dBxy5FIm/iL1iDCA9bhXd5LV3eOqyWse7PvEE9gjoim6CVSvtWS -6vSUBGGuIpRvaF2ZhROja+n582TkGu4/9Xwp20Y+xVxoxum1uJgvooJkt71K/lFOLa/GmcR+ -fsLX0wsutyRZFQvGpps0JAxso8u9RjmR3t4n3/dSMw916GLdxO9dI4uo07ComVjZyT9mx5Vw -SngFFUJCLaMEKNYpKYGsL5pvQkr/aEFsK+PwYoBik+dSI7KAHeIhy8n+OrOUKAts688eULpH -GyFgYGDOQTWfeko3KZMfqdHIjhGRtn1Lopr7sbhDmSfF55C9FBJUo8cobMc7RCgYAKUjm7pL -L3tq8ui4ENuRdsgm8b8f8/T6t/Q7OQAdc5Zg4kYkt5Bre9BSB4expcEfqLeIwqvRPBMOYJwL -2AVwU6S+gYsBUmy5DcKU3+Eh+67+D9ITH428CIn/9bzRkwY9XfskdENZyT8ciUvtoG5u+GY/ -tCR0kej74nlX8fMmXOTsURG9G829djbIEy+vKNH+qPFAOiEyauJOuMdc0Bnb73WlvYHPUHMM -QpRu+7dZqDmnUX4QQWAFCAvZRrEy+9ZLwNDzFRptAiDgwrCge0ROwWamhYFv5b6uA54vTjdl -PgakBXGVwPklcrjRipGw52rIr33x3BYzaEGX1/bQDsDMT/jMDLaRvLc2c5JmuP1qQ7M9vE6l -cb/YUeJQP/K5n52xEuo0eJ3MDfgZ+YCHYChjiMaQJ1MnTHFM85YKY4QJeLViZfsdPktW8Z5B -4YxKtZh4a887EAX+fx49GK976U/S4FhWp9d35yOg6gBvElxP6rW6lU5sJnppu+OA+jAWgjSJ -oO7PfwAn9pbg6Sy5PKpNtoRkucp515w9oaHbrJefGFEAaTXsAry0XQfqJGUkEV6wqCagZQhQ -r5dsdN4ONhVb88qY312bPDNsRKMQ8d9GiTb6tkzK+KB0Z9ROpTXQTrPuaM+YjtHJvPUoEVnI -J+60uQGNBFYhRscBDADLqt7/e6v9+A18T3IqK+kGqaOrR5TmXeJPn2G8qvtL7oYdRr5i8T0E -GxrANIjhQgs1BfRgZPUtFrbSYLWiQFflIgSlbOhmHJtMxUzBLZkeRTI7pUECJ5RWiM/ddAcV -wMCIG9btFGEnYFT6/0MajzwcBiooQHzk/+L8T9rXFR9NaKIiEDwN38e/qnMgblC83xd+swhr -IvCk5XUboq8EglvPJRVS8vJDJKJk7INzOsDHNirtvWq/zHAcNTPJSXqyQ+pt7HVwVYh6Iwv0 -RjgOdn2XepvfUGGn4QfJ2/R6xyUzlcpCuJKD+Gyck4uUJLjnP9iGoY4KgPxDFdQnvU2EP8dB -H8C8bJMNw+vX9TUMnSUbvvzAI4R7U1p3Qb/ytykdJjrpFlH9Z/fXxLu4m3SZTDYky3UFHF9t -2AlqV5QCpiM1AAwNvwt887qOFCeZ/Sc3312l3OTBX92tVFwsMSe6kOuR4GyiRy6iHMTSBuNR -Phw1zQO5SwgQsxMCkbwpAKDMnL8AEQEAAYkDxAQYAQoADwIbAgUCVuLrvAUJAa7y7gGpwN0g -BBkBCgAGBQJWIUbHAAoJEO6eVSA0viTSpx4L/3XahwQPCK72SkEYJbQcP5VLIxWMtYyIKWT6 -M+eC80S3rdmRipGLLt/Cc+4mssWVovQTQksjB6KELkDI9IlPVDQuc7BuoIefWz71F8ih0b+/ -ozjwTPgZ9862ZjBb0qqiArvgXB0jH/A4hgN6HitPstFpYE1whc7wnX6//ze75XHpNYplOJkp -AwRXxU4lZ9KZMITodWBRi8sI8HoMj5fhpV5p3WRrIo5K5eUb+X3gHlEeUkH/FBdl3Ug3Ktl6 -1NnFjNkIGEhZpn+OLm+oWi3TFU1imVGRuDUxz3pf6HB57x6IH/JJJbFRX8MOQDlnO4TyfxEQ -SPOprOMw17nQ/tcpWD94ET5OmAIOWq/r12qc4XfbqbpPf4Uf8sM4eC5B8HulArGyK+KqM7ea -iUFLIwcvf1cVbK15VuBttJpNGSlf/9vt1CgUyJWGKBwzvyqjKYGLrJerCk3Xcmg240mEQ7B7 -Hl4QRQJWJsVF5SQGtigadZvC47GIs5HH8hu41g6+xMZgQAkQxSQqGrOTZRdZJxAAi8CASlCn -O4TUJYwFZwz+fiu5Ss5VN6jp1ilQY3UsjTvnzGbhUjjsjzA8TLikBt09yqho2cxwD82lJhre -FXSy9AMupP3qopOs3vU3WA0lr7nD4o2vB6/wxGmO7N71vh2fdq+zgv1/R+SnONLN7MrBVvuW -gVJmqAoBojRpKg5RN5z345TnKaCRg8QQXXbJ2TIzMvDIqu0SciqDBCmNhM3/c/XHsaSG/4Tw -vPTpNKBrzjJXLkjmA7UeSVzcxbQn2M8l7e4AtS0SHj0rEITat1shfthuTFZocd8r3wy733wh -ev/h5R5mF/YIsLZy65huTX+s5zE+Z4gkprpLk+VY5/djbItE7RUpyMPmlwbGIiagNVcLhUyH -O0JUt12NTvRzWS1IgFAG72CSk9wQKvONi2l4Bq85SCak//NDxfY0anr7mf1bCKK0CAHI0KDS -z4+pwBnG6nfhvdlj+3jvm0OUCYg6i8fXgBryD7Qp62P772s+maD2QaywaafiZUi0KVoDsv29 -lBAWdLGPJ8gIqxLEGGp153SWyKeXMF9cMSHc3p8ReHzX8aDMtSZOWSFwZoVemViqtQiWR070 -8PhHaHk/qVouErZ0B/ugpq9YdlCnTZhvmdUGINwqJVYoE/ie5ORZkIblH3rrClHUg5BDcvKR -J3lKy1xlfqJOm/g1mkLEjgJeloKJA8QEGAEKAA8CGwIFAle9oT8FCQN9jeYBqcDdIAQZAQoA -BgUCViFGxwAKCRDunlUgNL4k0qceC/912ocEDwiu9kpBGCW0HD+VSyMVjLWMiClk+jPngvNE -t63ZkYqRiy7fwnPuJrLFlaL0E0JLIweihC5AyPSJT1Q0LnOwbqCHn1s+9RfIodG/v6M48Ez4 -GffOtmYwW9KqogK74FwdIx/wOIYDeh4rT7LRaWBNcIXO8J1+v/83u+Vx6TWKZTiZKQMEV8VO -JWfSmTCE6HVgUYvLCPB6DI+X4aVead1kayKOSuXlG/l94B5RHlJB/xQXZd1INyrZetTZxYzZ -CBhIWaZ/ji5vqFot0xVNYplRkbg1Mc96X+hwee8eiB/ySSWxUV/DDkA5ZzuE8n8REEjzqazj -MNe50P7XKVg/eBE+TpgCDlqv69dqnOF326m6T3+FH/LDOHguQfB7pQKxsiviqjO3molBSyMH -L39XFWyteVbgbbSaTRkpX//b7dQoFMiVhigcM78qoymBi6yXqwpN13JoNuNJhEOwex5eEEUC -VibFReUkBrYoGnWbwuOxiLORx/IbuNYOvsTGYEAJEMUkKhqzk2UXmJYQAJ4fOk1J7qOUuMZj -gidORGCfejuuzKWT/dPboHeUzhfvZ01yn6hM4lLO2/pVQTJ//JWcHd9pCs9YiCMdOHiAV9h4 -+drXCcwENpwZqzk56TvfRRcKkWs5h6w4EAIKpNA7dRJiEl3FVDvZ8RW7Woydrxlpe3uszqg5 -ullPREj7Rn6kPX634iyx0FWYOaVO/jSRmdM7A9U/o0/VhHoENZ3st2ophAuGvnDcBwVU2oal -o+UOMvgJxyCcqeX2yOz/Zdbcgl6yMDlmxAD4ujCqnZ0bM3ClX1BCFPj0miLg39fx4TvIpD4V -8+da8H1jGOJZ+bzn0kNeurZ7FsdvPh/QsYz1MgxI0Y6NW/WhSLtWeq5J0ik+8HhblOBVKNlQ -zoLpIay6cUicax23kQF9zjjwvadkUved4YUWG2ndmo/8iwSrjDkM2GO+YWbTm3Ciw3s0ZK3p -RyeEKmPBU+C6keMBxxy6J/6ft9b5/1ZCDfnr/9feb006snkApbuh9AH+5U03fMN6x267sxot -Pey/FYN4/LaZqJD7+24jGIZdW3XPmtETzAqncnTIiOhLu+K0KoDQ+OCXLypRMJfURQ2XT5uD -M5mregBIAWbfC+AqF+R7QTmEaa/cZxzmeiMjj6C2VqiKUtyt52VXwL2F6te+5FSxaeigCZRf -g02/go5YdwJAeU0jB4V4iQPEBBgBCgAPBQJWIUbHAhsCBQkA7U4AAakJEMUkKhqzk2UXwN0g -BBkBCgAGBQJWIUbHAAoJEO6eVSA0viTSpx4L/3XahwQPCK72SkEYJbQcP5VLIxWMtYyIKWT6 -M+eC80S3rdmRipGLLt/Cc+4mssWVovQTQksjB6KELkDI9IlPVDQuc7BuoIefWz71F8ih0b+/ -ozjwTPgZ9862ZjBb0qqiArvgXB0jH/A4hgN6HitPstFpYE1whc7wnX6//ze75XHpNYplOJkp -AwRXxU4lZ9KZMITodWBRi8sI8HoMj5fhpV5p3WRrIo5K5eUb+X3gHlEeUkH/FBdl3Ug3Ktl6 -1NnFjNkIGEhZpn+OLm+oWi3TFU1imVGRuDUxz3pf6HB57x6IH/JJJbFRX8MOQDlnO4TyfxEQ -SPOprOMw17nQ/tcpWD94ET5OmAIOWq/r12qc4XfbqbpPf4Uf8sM4eC5B8HulArGyK+KqM7ea -iUFLIwcvf1cVbK15VuBttJpNGSlf/9vt1CgUyJWGKBwzvyqjKYGLrJerCk3Xcmg240mEQ7B7 -Hl4QRQJWJsVF5SQGtigadZvC47GIs5HH8hu41g6+xMZgQGxeD/9ynUFUsAd8UnpvHN2tTzPF -eKb1MPBzVaW0IfA8IYZKhtm4S5yp/dNpt/eQfTs74LkXN57i8576m72I5g2jarVtJG2mB9bv -5RQBrOerWT1LxQA2Q8SMOsazUIMJUU63LH//mSPHOAkTVZPFew9y9voiMYA31TcJriRYDJbI -jH3GuMRAEJYA8GiY7/HdZHnmDK0SfdOMIprQJEn6G+I7MwI8qCvb2eGLfAM2Dwq/OQ7GtLIE -fbJqI/aMPhxQHc1GsberuWYnBJMuMpScWVUJufigzpO2qQgr9VjJAAdPwgh5YfURGXHoa0IE -Sy5BnbYBcdkgq9eY3SwJUx4XhlduzEu3Z6imR0tcgaM6wIIyqCwlup0jo8rNWZ+NQmdI3cqs -IPqrKn3vRXXVT50Y12EiaWbbrd34fmKWYBNHguoEj9BEW5jP1axM43MAXzsMfuLQhJsabrF0 -JWXsJRV5gZW3iNl2D0H0fTKNqBCXeLqGPsrCnmm1m2qlvKvpJClwURC56f+X5BDq5lMvL76e -2FxPDUJNjE3UxzMQjOacRztiTst7xKIhPZEHVIQyw17bkDhxspavwU6gOsFwXKEuuwjCUyA0 -pLAH+dQzVzCRCRP2ltg92gjf2PtwdbwtiMg8t15Q3Hd/hb0EV6d+xdzYLPI8KhOe/8znmK+x -4weSvG7GdRvb+rkBjQRWIUhwAQwAx2hCVcoAXcFPNXOGMp8kzp1k2V/gUdxL0VudRnJ3746p -KoJpVjSxEyZLMEPPrNJoyhlZ8+HZHa+HFG1XoI/0re8M6DvpuZmCAzCX9Y/N1aOpU6PRSRc2 -3B62AvUUuzZEJg+6syc+CmP4dJ+bMxSAvyaWBAgTc2KyUHPJtpGYkpclECb3ufyOSYiOkJzN -MeJIsTXt9hiE5isPbNxNokX+sl1ZbKz6LjUt95T1yrb5jtWnu0fhvFXvgyQ7/ky8XHMtolPc -Ls+CN5NtPq5ZhMJNe33g4X5XoeUPqoyOL5GjXFxWuXKGRNB8lksALSz0jr9r1pLhXmJ3F0cs -4Pwrykee4vcJ6jMzUzLd2x2Nh3sxNd2x5Z+Qfyaq+IoYRUAajxvlGZRmEXwCOtDy4dsn7V+c -ZJvzzoi4BChe+v8iGSPMHD887qwIRWmQafPzFL9mSfzlE+K3RFVful564ozalQVPJn/ATC+Q -r48obFOvcn9Zr6Yi0K9+BTRHJyXpAxjyJPe3ABEBAAGJAiUEGAEKAA8CGwwFAlbi69AFCQGu -8VsACgkQxSQqGrOTZRfDTA/+IUaDihDRKveNGdIiYNEw70b0Z2iGLG53kUN8oNQxlSEPuER5 -s0HaTfTFtOUU0S6ibFtucnVsIe8tDv6AUY2qA0QJDEiMjqPxcvhPVlgZgMM3mAovdTMn3rSi -DqHK18aV1yp6LQBQzoFhhfCvi5Uwx/24jq3fH7YDlSVoc919OJmu8b09rUE6nxXW7RIrwPox -RMatzaNCKvgrbf3tB9nfZ6etknigVXaW8fcQHNrTyig0pfhcge5Y+QiufxSoaLZdmyYVVxE+ -PD+nvmxVcH0Tu6OPM7iuQiVW23Y4Wr0BoUKMX3nVtnZ/cu0KDKmslLlSIVCxP5Pst47CQVE+ -6eeu50nVBm3N7irdbHzymE3bBWx4k0ZbV5rCIr+Gxj7JW10rzkG5RTl1qwBNtgnSphs4ZRIh -Z274mQgpdARX+AsBFQSd6fS3KIq9ZfQLchyCBSN89Zpk8+BfQTG3urGjcAczvioePlEuTVf4 -ar8s9Gji5bW+inyPFhfJDmtQsQ48/w0x57zFjv3SDibirE4X7sWWat0dcNzt+kQfF8w0//DV -fOoH0MDdOzVs9a3cuOtHyt+hIziQ6pv+N+PwQ81ofE6pp0mphDcQU2yApljo/9uTNurQNkvc -3DyyR0xjAN8i90JQbY1mNrjaq+dXJ2R4DysQVs2kb3K2fpVKuRBvheCe6uaJAiUEGAEKAA8C -GwwFAle9oUoFCQN9jFgACgkQxSQqGrOTZRc0yQ/9Hk0ADSWmmggcisR+ONFze/3UWww+hVdc -5qvLaTvVayeoTqsDpECoZT1gvrLMwUZ24cWxgc8Xx6QuNaFX0nql+1iaGpuyfo1sgg1q7e6y -z+d/3MvnsfB1i9g1tlRSWsbziljaqH5B5mq5hhYm5rmjJr4KbXCtyWu1XlaVOFRcUNsUipnG -jdqrmHfbY4mMDhBlCcMly8eKoWyX+hSZ2TsK5ryApK8thtvv3bANJnmaKXD+5kdrXkaW2u/s -duVlW1ad1oTDEM5y7m1LqUMtVZUHdLn+f+XGi0t8EKMW2PQ+owkkEEiQrIrArXXouhl/b4fD -kqozjE15eoBCghQBauo68/HodTGDwOBUTFgKc32g3rKkumljIzfYtsZVUk7XkvT/D9bsiHqP -R7M6m8FU+PDXRX75c3z/fp927AgZpdd6sfQygLX7JDoSZa5iY8nk2MOr8aN7vBIIiRm3k6dY -jOlpiaNVNfVYIl7XJ3k9F5Kdf6g8rNnYezphmO6+HvnEWnHYa5T7jPhFFeQwRWYK1gLSXzft -hrFrYKkLBtfUefPFOUp6/dMeRMLoXGW0TxN9pGem3Ovf2ixM9ti0BfKPjcW+GEtxgU9DloLW -oezXNdQPoD80xdYZuCV4NsTstrP5IeUkTPefnxOUWS1XiwfEDhpv1oydL0MnWDYK+jXacpVT -4mCJAiUEGAEKAA8FAlYhSHACGwwFCQDtTgAACgkQxSQqGrOTZRfcZRAAvGiCvggMlw339PE6 -coJxLV/PWIAiwj7QPtjWXm9aswHSMK5mmQ5/RgfC/11oV9QBK3t3eknEGcKhJDkw4xAB3aYd -kp35+mC6CXtRnIKXb9vyznGqd6DW0+FyDYj9/1ynuwmKnJnAzSDr7j3rpYbxGkmVBGwLfK85 -psidexuiK+1chvNHFrT4bwzSX6lB6808SQYO80vddRgjiZySs8JxziKSFv1DhsrgL/QCSlwq -QKcImQLRHvVqF8hBTUwSMbvGhmLVHCyekayh/rNtAgDf2163BYRMZfXZXxIOoNsD/bCsJzir -BmhwDY/9WhO8VDY1JcSD8V7zH4mLE6QDLllLVhyV330zsn14gaV6GC+q9NBqlEdYlofGXluj -HHAbg4V5SbWMzeJjsMUQDSLuSLMEN1GX4bHiY7amHRv4fyEtGLyDp9WaT6wn5CHoFC92GOsK -NAxTJw/kIa0J1O5cnIuS1fbymQtt9itbmSUHNhLcoE9Vg1V5yl9000bFLhKK5zv6cWQtEP8U -thTSJGHtnZ/zGC+oDvDbtyaTfa8Cj80IuGO4CBojG3HKzt/ZI4g2Gi8fnkYLgI/tx2u/c0/2 -WzAP5sEsGyiq7MvcPBV87JVnzzJvgxm4+lO1DVD/QKQd/NtrVJ8jXcuc21DE5o704rnBLawU -f4U6Tde+ZZx9WgxvAMi5AY0EViFIrQEMAOQNgIVvQxcVbDNdOVhBKw9jbjNq77au3U8AKwRI -tinVpEhkLwhPcYMh/LuQBFsY/F1xxP637p1tHfaBe2fRWzrlftR0DgI+YUEFi1hxEcGeIDgK -hvGSgG7sE5aorXYlxD2YiWGUqtDV7Z4Mnk8e16s0EmrXxTiEC8yIsD0F19E7fiQdwdkjfw9j -T+67m830tgYNBK4VdtHzw5fGJaBCRX4/ZaRdGSZyeYV2D/RZeDKD5MgZBj6yT6KGeBalBRw4 -sJrbcz9QcxZcKQDxqSNDa5AXQZXxQLb4Y63ngeWeFWMLdcaqF4CPo2FwMaDJfq7ZChXVmqE+ -8B8KgwXgVmF6MlwNnWCGPFMdY3gwZ0RHJO72l4ZZ+s16jAEKMBPhfTkJ61oH/y6Dp+TGMbAQ -2PZjwDvLq8VAxPg6uNyQV5Uvo8mzDWVnbZGgayHXu3cPSE/BZ6fKRu/A5oD8ZkRR/UKMqU6j -Hwfse2bgdH5NbneLrd96i6O/AVmaFtB/vtdwm0pq2QARAQABiQIlBBgBCgAPAhsgBQJW4uvd -BQkBrvEqAAoJEMUkKhqzk2UXDUAQAJni9fFq+77ry+XckqGJlqhxbzPIEVMCBs2uXNw9vTWG -SXDyUUZHRgldiFxLlEji7Z4wDZEzNU1TDJ3rajUfFK8q+89146mC51cBqjj5xZ5ZBNs0t6Rv -ABhujscQYbhDL5MHHdbN7VlJSWEVotV4RI1WeSptqR7Fcb6F3iQlFbGvJ0l86hfIDi5uNPTR -TIipKfEDhoXhFeMlqx5MkotX1Xznax3wc7tpVJhxoEm5iSKS3CvnC9046Sfg5EjW54iNdyPx -GzzuFGouGt0GM+rLKWe1Mxf6Y2Ob+lqVl4lQeTz9mOQazFIFkZRcT2E3NyoiB1GFYiI1bUjr -FWkQhy/0mEav6h7Ot18ZcSiIYYpW0eDjvgryejf7xKUm8evUqpcYAwK2coN0EKnq5SxqUhYp -vYlpN0ARlrUPehJOq4yyzp+29+COm8V7X3DhKO4JdGNUxZHzqZ7FwHES661wqQIYAv7yEEUz -ChHAtfJI/72NeOA8Hn82AgYWyP6wkqIQKvGv84atkxPsZQmMvd9R1pVABsf4ZrP9KvikO9dm -YJOF8VxMeEWYr985fVKYenO0l8QDG/KNrz8wMXd0oTTp54PYQJfM5OTtUWT2ubudaaZDtRbC -fc429ir3YOGRAbSvIxE7/XJLqso/WJmWUkUUNnbo4PNbC0PQqzu1gdyBqcIfuJR0iQIlBBgB -CgAPAhsgBQJXvaFaBQkDfYwqAAoJEMUkKhqzk2UXy2cP/R9HTn+6b1WuvpZ7fK4zyFSM5DF1 -86pyLe8XKEzxOs5zSaJRs3bziVdWlTTYC4f5D3TQH6NjlD9KThpOqIX2W90dfLYiRUDVzZtk -Qs0gM0U9RGYoqP08oUhdoy+Qe19y/f3yaEsUgpZ5WEj3IaOBnwvsFWQr00t8eQLRPZxc65cY -JLkHuB/S+PyQy+BATFg1JepM5Ov4oddcRAyk6eD/fnIhb5hxZGipVpSCZiCCQbrXEKbCiWP+ -LJg+N9cmRJ901tx0eEKDH4JxKxtQybhHtAV7IqrFWxHNJWDiW2gcsaSMVRi+I3f7Tq88GJdc -VGjxwzRAySVZ529ZEJydQKfa144P20NL0HrIdOiHVgJgXrL19+uyaF+7wTqV+B8z8HNl61zh -ZZpwYchKkq7X73yaOIt6o7JuUCdpYqei1a8pdNrhKyqOyqzvXlUevaRlNO0uDoUKdpLOOWm7 -cHuksxl1ZyMRr5v0e9qtfekR9st2+9RQYW+8ZbY82G9XG9ywpOpjKYcUYg9yZDxHmLaGPozU -4GCln7sIwAkG0iQfQDWF6PrzOvlAXaqEm19Z/LFsyALTHl5cAE8K0a/5qQc6hnLS9Dm/rZug -mbxazVhVszVkOzC2g6qmaJOzou2x3LFzT5PUg+VapVnFcmpFDx5mJMfJ7a1AyVDiv3zj/9zF -JuP1GY+6iQIlBBgBCgAPBQJWIUitAhsgBQkA7U4AAAoJEMUkKhqzk2UXirwP/1V1gt3j6mFK -Uzx3GE+Mb+W4crfTJY+r2yYhgUEK/Eqmp3qUgtJGv+sRJjgi5LMwTBhyHCQCSVujSBT3rKz6 -e6eVVezcPEmCSMyCV07GIQ0AlAWbYS7/ENGZx4EHlA7dJBDVYnEoLKbKmRu+v1pFcK9jPrkK -DwhRGthDm8qod4WxWay/yhiNlxcikeajI7+0ON7kfTPHeogxGD3wXMby4kosNn6QlvzKFHsu -srfr8YdBxQ5lIXPZyqNTs58oDX/1bM/SyernTZRNGauSVFy+sKiH/LSMWJsfnOT2sZ1AbpRS -khWEIPUZjEWFFjh7vxO1T5MHPq95HSPv6bj8whU+7KOrIkMuDBoceemrzcTXmBMYc181FqCx -8RAad4CX/oKDD23HKQ7bO/lJYdhIQb+QCKVWjdOS+BbjdDanS2EyGog1V6AMWcR+WhPdzO1W -mNhk8D5mrUQysjd5JrAzZ1w2iw1I3e9o02Zex/zPSAUmpa00hzN8pIZezX1I1h1mXHqpYKP1 -EvVdUEFsshVmjRNAYsKflXFWRxqQGlL0PSK6vHGlN6ZvkoS4qHRYV8zoPBivIyTcGLuRORHG -sRlAsdtxbwFYKeVqd/Yw5cocrw1C7ja1OpBFdL8kEt2kzOTAwdAebvntf0GY8TEPA4dYUFmv -Ww8nn+QC38ITGK9hVF+eVkuR -=j8C/ ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/jonasschnelli-key.pgp b/contrib/gitian-keys/jonasschnelli-key.pgp deleted file mode 100644 index 8a9cc58c23..0000000000 --- a/contrib/gitian-keys/jonasschnelli-key.pgp +++ /dev/null @@ -1,110 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -mQINBFSBrDIBEACrZEqObmtlTf7fOKttE39qqisFfMg0VeEPS37uETMGYsgTEvzv -kfMsXCGsGFLQ78XsHqUeW4uQrtpJH3nUP/Sua1Q12K3lNKTSvVQyEpKoPJwXZahp -jm6GA1ApDxZ/KlmxyobR3X0urnMYNZobl5IKJXlxoKGl4OkGNeFlh42pCXZDnR9n -1Y17ZcDdybkWcqPbDAz8ilOQcFMhDBFg3Di3IVMAaDZP1uwWFb5vx60YB5NhkOpF -nZUH09NJx/7u7QdGPSHOdzW4Xo1HUYtYNDkdOvgZtxpbYEFIaBtVBURMUGwAFagA -3a6qaGnCBWEQftyISLiqcKqKqXudOg/cLa1CAiQFkz+IBhY9BCGDRnB8Dcae6EGI -Djt2lqZTuMSiheTWeNFMGBioHfPLedcwae8KflrIBC+hNS4ay6HJdIc03WMQ4JKK -At8Y8CRLym30/RlqZ2v8CHYqg9Ddlz3+g5JkRKaJTQwFRcX46/tAX+I2NZ8Ra1ea -rF5cRHuCk/oaw5ZXYhj4zJO74rjAoSewAARlrTMSM541atJU1u6aWT7rNiF9QKIj -i8vEufUxN0YfdmvDD3OXwbO7GnfWXS4sPklFIRACp+Y4ib+QnRY0/qGE0yh3RAG4 -r/dyIQ1m3z7Pc9eyPKAhE4S7SxAwoR4yOqQ5NAfZXgFuqWzkW51gkQgGzQARAQAB -tCtKb25hcyBTY2huZWxsaSA8am9uYXMuc2NobmVsbGlAaW5jbHVkZTcuY2g+iQI+ -BBMBAgAoBQJUgawyAhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK -CRAicOMMUic59iKUD/93DF04C3lptLjtrhyd4wgpBMJV8yzagGyG+Wk0UR7elQw4 -F1MIvEtIFpuGrcnNfKcqeGGmnnKFTeBjkmgcYvej2fW9XlRA1HgIS0t0ttDv8uVX -vy1xVj1qISB+17EiftxJjCOl2pZFEVpLQ7sSgqnVRMsCS45ag6rioGxtq1j3ifQN -TENnJWhzOXvwzZhLgsyWLjeYvTDbzfAQLpZFowAMibOwu6ObCkn4dhaW+lI3AnPu -76pLsrOljqGvXes6o2d28vjqMrlmsz2xVEJ4bnRPUbLv3bUl6t+19XpiMj94ZCZX -/kvepzSNAs+aYvoldFn0/8haU5wIDXO/zgXSlm4KnhaDf1zutVq/Ng6TGb66mZKc -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 -S5rowLE= -=ZVPf ------END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/contrib/gitian-keys/laanwj-key.pgp b/contrib/gitian-keys/laanwj-key.pgp deleted file mode 100644 index 559295109d..0000000000 --- a/contrib/gitian-keys/laanwj-key.pgp +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: SKS 1.1.0 - -mQENBE5UtMEBCADOUz2i9l/D8xYINCmfUDnxi+DXvX5LmZ39ZdvsoE+ugO0SRRGdIHEFO2is -0xezX50wXu9aneb+tEqM0BuiLo6VxaXpxrkxHpr6c4jf37SkE/H0qsi/txEUp7337y3+4HMG -lUjiuh802I72p1qusjsKBnmnnR0rwNouTcoDmGUDh7jpKCtzFv+2TR2dRthJn7vmmjq3+bG6 -PYfqoFY1yHrAGT1lrDBULZsQ/NBLI2+J4oo2LYv3GCq8GNnzrovqvTvui50VSROhLrOe58o2 -shE+sjQShAy5wYkPt1R1fQnpfx+5vf+TPnkxVwRb3h5GhCp0YL8XC/BXsd5vM4KlVH2rABEB -AAG0K1dsYWRpbWlyIEouIHZhbiBkZXIgTGFhbiA8bGFhbndqQGdtYWlsLmNvbT6JATgEEwEC -ACIFAk5UtMECGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEHSBCwEjRsmmy6YIAK09 -buNXyYQrJBsX16sXxEhx5QPKyF3uHJDFJv66SdnpvIkNoznsaPiRJkbTANop93FZmaGa6wVn -zGDiz7jPA8Dpxx5aAYPhIT+zPJAdXWM3wJ/Gio9besRNzniai8Lwi5MZ9R/5yFGBobm6/AcN -4sUoqA3NSV2U3I29R0Vwlzo8GVtmyi9ENSi6Oo7AcXNTRt69cxW4nAHkB+amwwDJlcAb31ex -bogYXPhScwqQZixRr+JBkKxBjkTXXnQypT4KI5SegYwQVYfyiZmDP7UHKe/u6pSKKbVphLg8 -xLB5spcXse8/a2+onrbNlw6y8TXiJ++Z54PE7zztWTXf2huakeG5AQ0ETlS0wQEIAMNO3OkP -xoPRKWzBLcI7JRITAW+HNaLTq3uN2+4WxA57DEjbL9EDoAv+7wTkDAL40f0T+xiu6GJcLFjw -GJZu/tYu7+mErHjrdo+K4suCQt7w5EXCBvOLjhW4tyYMzNx8hP+oqzOW9iEC+6VV91+DYeqt -EkJuyVXOI4vzBlTw8uGow8aMMsCq8XVvKUZFTPsjGl197Q5B3A+ZOFCR8xqiqdPjuz6MglVV -oFdDNu3EZn8zkGsQlovXoE9ndVeVzx/XMNmsxFaMYsReUs253RIf1FEfgExID0fg2OnyLCjS -2iFW1RgajS+/saIkKl+N1iuMzJA7wMAM0plhRueOG0MtZSsAEQEAAYkBHwQYAQIACQUCTlS0 -wQIbDAAKCRB0gQsBI0bJpmsDB/4waenn2CvSHXyomykfpwf5lMte1V5LvH3z5R2LY+1NopRv -LSz3iC39x69XWiTbhywDfgafnGPW4pWBOff2/bu5/A6z1Hnan1vyrRRD/hx1uMJ7S6q+bIvZ -iVIg1p0jH6tdIIhwX3cydhdRZHo7e9oSMgOUWsr6Ar59NRo9CENwGPE4U61HXfOnxWdrFWoA -XdwZczBeLxmUy6Vo6sKqv+gE4bqrtAM0sY/MsQ9cU95x+52ox/sq44lQMwd3ZBYUP7B1qbHI -hZSZuch6MLi5scLPeau0ZvCaljiaMeivP5+x0gWPRs0kI+9sZxInbqvrsJ6oOBJM3xYGhtn1 -zZ7qmZR7 -=si/k ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/luke-jr-key.pgp b/contrib/gitian-keys/luke-jr-key.pgp deleted file mode 100644 index a2d34e75e1c16c17cb721633038813800dbe45b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6518 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 S7kHs3GQ0tClS?I?0sJ4-*g3BN diff --git a/contrib/gitian-keys/marcofalke-key.pgp b/contrib/gitian-keys/marcofalke-key.pgp deleted file mode 100644 index ee626500a4..0000000000 --- a/contrib/gitian-keys/marcofalke-key.pgp +++ /dev/null @@ -1,69 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -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 -=GC3s ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/michagogo-key.pgp b/contrib/gitian-keys/michagogo-key.pgp deleted file mode 100644 index 47bc404554..0000000000 --- a/contrib/gitian-keys/michagogo-key.pgp +++ /dev/null @@ -1,59 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (GNU/Linux) - -mQENBFGeqJ4BCADb7SI3/+q93gIvN0AGRg9Mtz73OLIOzCHeeoyn+tp7JcYNzxkQ -9lfeXiEfn72Sh8gHkLtLIqr7HlIMo8DxSS8JPRVjlJGkNyAW4SeEwN2wNa5OV8k0 -N4jBa9a1csFyCyrEkPKvkUpBkQDvNXjNxyEhHwyZqPanKxy6NXIHOJji8ObOMQXI -T9HwJrpjRth3u4uKG968JBTEyAXAmkt0Zidl1Ykgzcedk4mJSE9uZCW8DjSv2wML -XcQz8+dYsoskT3KRdkowLHxAfj1BNyNc1+rKLghliM5vSQWi+Lbhi1Bxh4sY1UwA -lKnAGqrnAGyIvCtkwTq5QI6ufF2ZY44bvVgpABEBAAG0IU1pY2hhZ29nbyA8bWlj -aGFnb2dvQHNlcnZlci5mYWtlPokBOAQTAQIAIgUCUZ6ongIbAwYLCQgHAwIGFQgC -CQoLBBYCAwECHgECF4AACgkQgsXACWKOzwzMUAgAuqUmK10xE5C3lUym2f72z0t6 -a2NM5Wfjr9//Y1/okC36C5XAMEtN2UwckPzzJ5p5D5y5yzwfZq5Jd8Py29VQIMsV -7FbC1a0H3D+bCyX+JJ6FAmUbnWOQ/+mydYc74RvD8iwjePNT6kziZNv6dMGctJTl -0alwjtQYgyGkeYKnIxbcyjHX/IawLUrunb/6mSKun87T8+NM/omfFCTc3l8TakpM -0wyNYRiUkIfUBvB8sDUU3A80qKN/hqRKvlFu3+/kMiAc9ZYQrbmsB+sYWdmM+4zw -8NBw3yuYzWyPuoa4PR5ZmS9F11WLMR5vTRCdLudAqYsWu3LtV6vAIvlOUa2LMLRg -TWljaGFnb2dvIChSZWdpc3RlcmVkIG5pY2sgbWljaGFnb2dvIG9uIGZyZWVub2Rl -IGFzIG9mIE9jdG9iZXIgMTIsIDIwMTMpIDxtaWNoYWdvZ29Ac2VydmVyLmZha2U+ -iQE4BBMBAgAiBQJSWarzAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCC -xcAJYo7PDA7nB/91wAiaMlU5nHLUu0anhNQbGvUdFgKK1zO90S5KzUdJcY438jcS -UJW1az8l9U9JBRIfPRYVhz/Z1TAJ+dCzD7D8BXHFeGEr0zNOh87ly9aB5du7dpN2 -oSBD6wLcJpqxt4h+XjSS2CX98/2ZIJxXENE2KySaTXP39Xl3eNwvJTUBA4XlcMey -J8KMp/IERli4H0O7vRyLgu3yYpUArTqAonzG1g2lfB35PQJfeInrRSniQ336otnZ -A8qwJ63kfUtWVDRz0g1fnvtiLGPivDJaI5hyIaUeJPaXU1+sg7YNroDu60o2NGZh -F+0IjHlvRfzzA+F9Vw38rpSqR3BmCdjf6Sv3iQEcBBABAgAGBQJSWa9/AAoJEH+r -EUJn5PoE/hgH/1T2dAthVucA/hzY0nl4SMjbg+dzNlYBq00Qwx8DRKVjk5et8+kY -oPI3DGILcr+ELnxNekeMv9WQBBtJanUh1K5ohZ6ohoR7lG18LXf5HCdspflB5Me6 -LMA6iMryEP6gIs9GFuoGe2YQavm58YrkqhcPu34dGN7kdurfEXLvDfVlh5ZbKCsP -Gyd7Pbz04SpqykgK1udiTsLVjc70Xhv+jAMqeaCugDX6TLEwjVmZH/xsyKk2Uh3V -Oib5FXADAtKH+vSqqhFpXrw7R/NaBzvCbas8l61DFHiUg1/bo8vsV8MtGcyZmzXJ -C5Gm0njtGOil/g7JF9siUrpxs9Yyt/h+T2W0W01pY2hhZ29nbyAoVXNlciBhY2Nv -dW50IG1pY2hhZ29nbyBvbiBHaXRodWIgYXMgb2YgT2N0b2JlciAxMiwgMjAxMykg -PG1pY2hhZ29nb0BzZXJ2ZXIuZmFrZT6JATcEEwECACIFAlJZqxkCGwMGCwkIBwMC -BhUIAgkKCwQWAgMBAh4BAheAAAoJEILFwAlijs8M+1AH+IU78ARblqTnJeSl0iWH -mEsg4IBK30Q6/exDAcqOEm1Yc171uw2WnGmIvPYOQqxrRTvj3LoQ816dU6jrj6vY -s+XX0R2hxy7ILh17D/3UKnHcddu7rmc7pNEqZeBXaMughqQaPOWkAIe52+qK5tsl -sWllzTYE4jo29uZ3dAtDcKEJjBo/pIXnu1GOslE1+V4X1H9WDlwrS/JXHzyDQAjt -maPR+3gNesDanhrRmrnT3ZXW2ZVd3vGBibhia8PWUhU1uwOH23ySWXncgsHH0Zad -UMjd4w3YliZP/mLn2ghAxHB70IO7lgAgN3HYZeFoufP3pcK440A+CezfQiRcjHl/ -oIkBHAQQAQIABgUCUlmvfwAKCRB/qxFCZ+T6BOq9CACItsrUZPKGeWSTkMHknMrV -K5vxIXJVCBb+Tppc0Q/J5p4EkW/RFhTwIP2zw8NLDKMh5oO9md4LXhvfIZkqQJFo -6ZtLa3Vf+Kj7uyxezBo4QHA+G7tDsRGaMKVrEMiyLCwS1+hg9VaNzsf7zmQW7mYE -vTLMHp3cVaSU7Mh2Dl8rnAaM/DpTUZQwZ+32Qrb/Z4HSa4f278iqoFpjEbBE2KCr -vT5yEVvpCZ4lwSgA2a+uTlRTvVV6NA/kpsxU64tmhuEOjy+ToDqJ8wv4mqvWZxMv -C6OhfVaXBy3U9gG8aQV0ffXGs+TbCtv8ApHd6E1/AVk0oyZGJaBVrEl688bBIWd/ -uQENBFGeqJ4BCADFmgR7oEGkFFB5qXnuNYFq1nUGDAh0dLNtAD3J6EMxUZEXdmp+ -DQHJw6/eDRQaG9EbjNZheycbVUoI8K2Y/Z268HQueGuIEIJv6cZYXoXdWCbDD4fn -HMNUX2wNlpDqWxb7PNUEtfU9hI3gmHGlr5OiEh3iV06uiZg4n2rbWPbj45m5LJzv -wpCrUA+pLcl9Xjw2cajaSTjdXHk9gvXTCo6s2ZS3/3Q4l+xuzZp1MGNzPQHASMKs -wecSJKkYg6W8I5WsVlPd9a8oQCc/Nfz7BPw31MRVR/SF5FAMqaXx5uLwghVdHB2i -cLURsOtJlCfP8W06gB7yS+MH45Jq/oxBRiJBABEBAAGJAR8EGAECAAkFAlGeqJ4C -GwwACgkQgsXACWKOzwwT4wgAy6ICcnBZ9l2jSu+ldy57F6jf5kpKZgB9NV8V2mMA -NeY1wMQ4VTVpU4t3s4E2LYtGNJNkPQVHbt1Pf4dGPasvMPaHMamgwgyqgYixqs0x -D5PdKzVrfnjwTTr/ZAFdccSPmvy5/hbY0geQ/+mzdbL07+xaT58JIoG5nySDKhmC -VeOvhDZtXMVAhEWBDPEgh/H9sEuBgMgZrzfE1j3q802qiXeQs6WtadWlQ1RN9Iq1 -ZzIi6u9/BifEIRI0pO/WwKOZdXLTemFUoakoe7uT3A74N96t0G9LZVihYbEoO+Pc -5IaHPBV5VLeR3TB1LnnjHVf/Fwi8cnGy50kNWjcbMyEDag== -=jyQ4 ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/petertodd-key.pgp b/contrib/gitian-keys/petertodd-key.pgp deleted file mode 100644 index 5ee82a6f7e..0000000000 --- a/contrib/gitian-keys/petertodd-key.pgp +++ /dev/null @@ -1,1901 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -BSGsRbgvDNIR6RczbQ3j53l5j7ReYKP1yLnPwiNC3noPewqGephy6gH3BjYCtYZt -Vq4+OeNgCLi5fhy1xNCeqto6qQlbms7hw5YKB/x12QnsdgxGV9guuKYiJEOG37A0 -qdmYOBkHt3TfZWlLCDVRaHvb30eGSKS01aHmK4pJLAFYVgLw/ggBjegj6AxdnpT5 -NQM9uWCfwZ2qa3vBPaw7FYhjcB/nSvpZ9I4dC1F3lffLucgpg73p6OO5aU6w952M -hGDMKBGovbG2hvIaqs1RwaKZNtZZcBCXfIsQnGU11LYs/3w8cSyxWE/35HlveXW6 -+YBXHIaY8nrJCQHwLlmRj7w1RXVODBy75iUd6mYURPZyadpVfTKIpFkddIFPLKPl -6QkByMAno4dWS/p/2/xek9zBnhUhBjiQ+F9+rbF0K5LswiMK/BwzB8UXOXeueZXH -H1vDCDOBzrDit8bgxJy8j2YGT2Vq7ThMnhSLLC3hRcWJAz+0rSJ51OxWLS3CQGgQ -lmMOc2Wmz+K7JKvat3eZesBTQEZre6MpxXiebna53RnK/jFlEiqeZqPDWfry81ew -qzDnWaQ/m43L0V8QVVeJBLEEEgECAJsFAlGVbM6UGmh0dHA6Ly93d3cuamVuc2Vy -YXQuZGUvZmlsZXMvb3BlbnBncC9BNEZGMjI3OS1jZXJ0LXBvbGljeS0yMDEzLTA1 -LTE3LnR4dD9zaGE1MTJzdW09OGM4NTgyZjI1Mjk5MjRkZDY5Mjk3Yjc0YzM0MGEw -YTI5YTFjMWQ3NWIxODFiZmY2MDJmZGRkNzllN2YwNDk2NAAKCRBOH3mapP8ieSuD -H/90vmcaUOrfHXiDON3WzGU9lkk2K5GEauttX6p2gRRhzTqy47zUl5Wu8KWetkft -XOf/4yhPwDyFzCElArReLBg0gM4vgCAH+jeZqSWcMvgv9M11cA8rSF7aRLdpPfR6 -m4RwS8niwpvInNG4DNCQxqZqSBB6XDyrtmjJP6PNhJD6Nd24nMzImyJ7QB1JrSjK -lk539GS7fgEhhrBh5nKhVlvzzusvAc7MKysUCMduQrRYbkWQxw41OdIlIZMc6ErC -SGEEKgrVB4xFZR2DNTd93PDggjHTtvXKnydCZC1XL94qvvHMmSagXfk76QwtHBG8 -099QR60buDGLnZvyDbR7H5ts7UPbIwIRWA0v/p7hhT9PRRLLVuK1oLUa1gEN/IAf -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 -peBNXREPb4kkfF+RpT7HWD0u+i6sWb5+Yzt+vuRip7JkVu+7FDefLJ6ke0nEu6xJ -+HbAmZznOjnAg3o8M+XD9NIJT8Z5yB+ikQ3AZuZ1bJfNC85++oKGq14xJSvcA/4f -hLdGNmj05ijBMYLsdzDL+Wkdl/69sultxs4nD6mhlw2epZtiw5qj4dgbzz7p6O78 -3pZgXBvy5UFxgxx8hZsjDAayodfyebFNSLXC06uVjafFbtbQZc83UfJAxwaW0jF6 -cl0n7nquGPk1TNMVCHOd9VNCdhPlFJHctUbIv0+HNrzgWCrmN1JzP4BJZsIK/Oqs -j1SoFdGwxRWpSNwgO3WJASIEEAECAAwFAlKOadAFAwASdQAACgkQlxC4m8pXrXz8 -wQgAj0li8ga7DxoPNue6DzfKUbXw/LqjZUgs+d/MlHiEXS9hEMBDKLAnpDVIwSQl -Ldu7UvanjpWK5UVj4jTMnNKjJXHRlFc1WBRrehOFej6tob//cd3czFKDG+IewnQX -OLI7TA3uP5rg9PikGJOUW7wHUwunBdQl9XpLJe2XIhR7BAC4ppYl14OLDXM87f4J -grEDv8po/xdY+s2ysI31g8/v8mg2ROromZ12HMrsirqyVb+dyNFxcQi9U9ZC6h8V -00G4+duTjJt8YpQ/DYybVpMmVa40ePV+Z113OFZn9JdKs3p0kSi8csyLyItyJ62K -c3/yfspKE3ZDrd+FVJ/VJXUIXohGBBARAgAGBQJTGOluAAoJEHc3YWR7U2QV/1AA -n1bPtu6ZiSp+10U6yMmEvc9jWGlbAJ9tSDXgb9k3bFr1scJJ5kBsFJLGJYkCHAQQ -AQoABgUCUp+JYAAKCRCkTD3TpUjY4lRZEACqIACFZ0JHma1seks08qGrOYAIJxd7 -VS7Pgk4w8/kYaoXePs+F2Liaevnd06aCytJBxa32yR9fsgoPwoF2I4tRMCBn68Sn -lw/te9SU7M9Prrf8Rq02gEO7a2kqAH6ZNcUHdQDw2U0Rj4ArnZkHUh2Ey4TJwVUc -tZzeXxlpgqYRTBLNaJyyBP53N8A+nHtpcqJYdxDYMMdTYVNs8epvRMcRfO/dWnnR -lnco1ptge3cwm7E1/zX96/7GTPDwvtWseo0PF9W6wbaWTNm3c71iDXJbNbcVWdFt -BEJZBhHzciyN3sysHEI6IwGzmmpAKpQJ2foXpYhxy1LuHBT3kW7dq/mOnr1zyjkI -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 -TnaxBZk5kjROOetXQapW02twdC4k9tXLzuxjZ5w4zul9j0DFvXXIENHRMZVQDODr -e9SkkzfvYyhqLMB5hFMZK7bnY6LvtWWM+aLZRa1B/j+thWwhM0JnCyKtqOXS8sGK -rfpj7et2f66fi+i2yNhk/UBBHGwNlhYkeZG+ovcWTAtRjdGJASIEEAECAAwFAlQX -PQ4FAwASdQAACgkQlxC4m8pXrXyvNQgAq8NazgIJu3cuGoIkel7tDAdPjFtQuznc -pARNRSwVyG2jdZHOrNf76AoZK0NIqcenuKVyLe/o/U9+P4ufbBPajqnhSqEiu4f0 -mk1TWoJxWC2jW+Ew2ZLNu0adtoAqBE+FDCieAObUKF++4cxiU4r5npilADucQ4Fy -UGLTA5RUQy4j9w0rQJ4xCAhzxBT/SiULlKQgEpj2XdOOiHSMS76fbIkw991L8ECN -/1DiNDAzbExE2BwS0WwPb3KUiT0ookS91Q2i6mWaJbCa4iJUvK3i2YTxPpFb4N2e -YmCCvKMLT4RC/2JQlUSjEozMImdYbFh1c0snzXmRatWK9THyyFuXx9HTt9O1ARAA -AQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAQBIAEgAAP/bAEMAEAsMDgwKEA4N -DhIREBMYKRsYFhYYMiQmHik7ND49OjQ5OEFJXlBBRVlGODlSb1NZYWRpamk/T3N7 -cmZ6XmdpZf/bAEMBERISGBUYMBsbMGVDOUNlZWVlZWVlZWVlZWVlZWVlZWVlZWVl -ZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZf/AABEIASAA8AMBIgACEQEDEQH/ -xAAaAAACAwEBAAAAAAAAAAAAAAADBAABAgUG/8QAMBAAAgIBBAAGAQMFAAIDAAAA -AQIAAxEEEiExBRMiQVFhcRQygQYjQpGhFbEzUsH/xAAYAQEBAQEBAAAAAAAAAAAA -AAAAAQIDBP/EAB8RAQEBAQADAAIDAAAAAAAAAAABEQISITFBUQMiMv/aAAwDAQAC -EQMRAD8AyohAJSiEUTyuy1E2BIomgIRAJoCWBLAgQCXiSXAmJJckCSSSZgSSZZ1X -kkCZ8+v2YQCyTC2ofcTW4QLkkEuVEkxJJAkmJckDOJWJuTEKGRMkQuJREgERMkQp -EwRAERFr+RG2EXuEirUQiiZUTYEqNATYEoCaAgSalS4ElypCcQixMPYqD1HEV1Wq -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 -U2SsTgUAXL3GANeTM4N/XzzPXokCHAQQAQgABgUCUy3cVAAKCRBgtDFx2LpfQac8 -D/4kXKRRhtT8U+ViibJHXE8/MpGIqF373wbfs2y9S3D+kd/JOxC6ibnev2b+Wq29 -qdMk6BcyUaVzP0dxcnJj2CygYl2RD5dfIp8PzSilTHNfXGbJr9xPTcAjamXhUoJZ -p8/C1ODwf2y11EB8CLDVVZmqgtxUOJNfh6is3cfzbYF8O2CX9ai5x9UykV9g//// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -/////////////////////////////////////////////4kBHAQTAQIABgUCVK48 -ZgAKCRA82MB/C1zhTgoVB/9j6/khep6CXjyIoghxycm/4qhuCs2M8kM6G1B2W0sv -lkaeqha+A96lCS43YoaRWkto2k496rrHfoC5f/8Vb36nQS7hd59DYANbtr5KJzwf -yYsP/7+bkaiuC1E5SqmHjFiYYe7enQWdrcbsDfj420ScL9t2P0gO3vKJ5S8m7hkc -a4OdCmYJkdaYxJcHK7BC4vkJmbxfnmmyGJaEPP/oxNCeZiyL37Y62N4DqCQpDj5C -Ngk5w93+6H4oI8CIMzWEQZt9bZ2k9ipGobYhaLgVk5UMWkVJ8CuZESCgHLCuz7hG -gDoDmXTnz3zbp038QPusF9zb307DEsWq7XwJB33/ljm4uQENBE+Xo6MBCADB0197 -HdK48SqvipyPB49vlzfP6KHfcACZCg1JTqOt8KRJFwTP3PTi/GJuUvt4io1UVG29 -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 -IemulKZaOJ7LLNmKTjOZnj12+S76emwpNEduQajYMDXPtHnc1FpF2jo4tfOQBO5h -7z+UJzsGPO9O0pkYPxO3h/RS12R3uyvVE8Ej0w/8wiPFA29QgGf3zBRJ6GK2rAV+ -N/qhlMnE0agSy2+cmZzPDe33gtjLVZ7YmVp0YxbKa35DtvukhliGKH1cqkLKUt6Y -ytvzuckpEQPEtI/7KTYmCfaT2hlOo7uSfGn9FtV0xzlcVy0dMk24xKllyeyeennJ -jOuudVo5CQFRssnBDbkBDQRTG+drAQgAlo+QtN3XwYnuaRheTFnOLD7h9XBqZapO -DwqQbod7MXZqp4jEfGqfQKleL0Xs9Dh5I66Hhwr9GIuciVSQbSEcqBEznHJGM6n1 -ssG662b5a+W3WC11SUGpuZJOUgOEHVLgVqSe7td8w8bFD841kfPXRTYmtNgzki/K -RK7FFR1M5C5fBaQb7KGH/Cj/jUKKS9EwrMTW4jQxdcz881MFOGLM9hB4MCRXv+W4 -yUGqXurvFaEvYzVrYF1XNJFHheQ0Iw5GNUGxk0+F01kTBRNjJ+fnu/G/rIkHUYAc -E3VHqsd1l6NStMwn2o2a+po/xeS3CIdxsRBx4NYepBrZdRjUrRzNiQARAQABiQGE -BBgBCABuBQJTG+drXhSAAAAAABUAQGJsb2NraGFzaEBiaXRjb2luLm9yZzAwMDAw -MDAwMDAwMDAwMDBmNGY1YmEzMzQ3OTFhNDEwMjkxN2U0ZDNmMjJmNmFkN2YyYzRm -MTVkOTczMDdmZTICGyAFCQlmAYAACgkQf6sRQmfk+gTTNwf/XK8IGaPMASckFU1c -EHM8ruYAC4b1wzzAY2733geJJlIMd4pYVhPWcczwMozc2AWJrhHzMS6Ho/r+FmAQ -H+s0csYdhw0hL8w60bPXHSWu9wu6zlUJEY8G4pKjisEokYY7Aje/oEGfg8KJLHXA -hYrPauW++O/NFCZ6ZNimFf40JRSjSUGzTKuBYW0/25dfV017De1XZvD+Qd198CfA -9ojvBP2Rn7PYQkCMYA7xsViNz+tD0eC+BRdyO0cffCzoOOHHXy/1KSOnCry+JReA -jnpviOsUyfY2bqGsmOpxyo5VfZ3OoHOOV7nucBEmQojuhl/xvU+Lc2airaR6UIAm -jWDWrrkBjQRTG+GcAQwAk8T4liMdVQMjh6WFsmY38lEGu5FxirVSrMKjVQAq52XO -l0I2jc6zTdqzyinW0sEswcQhmkTANzCspaU2kIBr/QVbdtPxPakwysV3RsqHPlAI -rVQIdBU7ENnE9uzRzJtZfc5m+buknQ3MBjMdXlAceO4w7i+uhu5zXW4tSVwgKzhU -uy1IexvK7ni4EZHzsOAarFbZpHozUqNZol7ALJrWkpQWqjuJZEIN0vefgSf3AV/r -vGFlbI/PwEWDZlYlwDV9scuHRqqu0S1LArcLDmf78vnnclZYVUNl2kaVgRKmu2ra -CWCSctmkyC5rqM9Xj+6B0ZVxhXReqfCnRn06Zwf7WwJuMWMfbAfZjDbksIMgKWpT -/8UrH2RrI/6b4w5hXa7/C8zp8H109f7xcRgdLyj748P0bsrrVSfUWxMP+XRRGPY0 -4spkhNUVFlYc2BroIRXS+REKuI5WfWnUeSNWfAqbexaHRSgQQIydN2qp2sSxAe6Q -FE3aXZyCHC4DMqIlUml7ABEBAAGJA7IEGAEIAG4FAlMb4ZxeFIAAAAAAFQBAYmxv -Y2toYXNoQGJpdGNvaW4ub3JnMDAwMDAwMDAwMDAwMDAwMGY0ZjViYTMzNDc5MWE0 -MTAyOTE3ZTRkM2YyMmY2YWQ3ZjJjNGYxNWQ5NzMwN2ZlMgIbAgUJCWYBgAI4CRB/ -qxFCZ+T6BMFsIAQZAQgAlQUCUxvhnF4UgAAAAAAVAEBibG9ja2hhc2hAYml0Y29p -bi5vcmcwMDAwMDAwMDAwMDAwMDAwZjRmNWJhMzM0NzkxYTQxMDI5MTdlNGQzZjIy -ZjZhZDdmMmM0ZjE1ZDk3MzA3ZmUyLxSAAAAAABUAEXBrYS1hZGRyZXNzQGdudXBn -Lm9yZ3BldGVAcGV0ZXJ0b2Qub3JnAAoJEGJeboN5AaHKDGcL/R3/aZoKC3OgtAkb -o2g/ykbMt8pIko2cofAB/3zwl1p2qvwO3QV/vTVt6y4uEPEHItaFLiKTSH2KpTVl -YflOh4M2/LXwXQmOiixpyDY3w42R6AZqY4g6q2SLDpNQLWaxVOerPgvDpSkIbcwH -j8Fvai3Mrxtr2J+Jq3KW6TQnW9m5G/j4SqmQ2sRfkl6EEHiGcZp7pbKkE+qYGsmV -HEirfCjlf03N3c7zcs6Nic9AEq2ghcnLwRAqmyRU59wOvIHlbQtnpJ9TI2zaOp2n -U+4wOVkdolzN6TfPPLwATXsUFlQRS0ygarQXF4ifZ55MGZ56pc3GOR6fEH0FaUbr -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 -=BHZ+ ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/prab-key.pgp b/contrib/gitian-keys/prab-key.pgp deleted file mode 100644 index 0870c88b9b..0000000000 --- a/contrib/gitian-keys/prab-key.pgp +++ /dev/null @@ -1,81 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2 - -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 -RFdDYRHByRDDL1I= -=dOwX ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/sipa-key.pgp b/contrib/gitian-keys/sipa-key.pgp deleted file mode 100644 index a1930ddee905f688dcb3a189a88e1317e7006a0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137597 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 SyHEabV7`Cld{4jProgramArguments /usr/local/bin/bitcoind - -daemon RunAtLoad diff --git a/contrib/init/org.blackcoin.blackmored.plist b/contrib/init/org.blackcoin.blackmored.plist new file mode 100644 index 0000000000..fda090af52 --- /dev/null +++ b/contrib/init/org.blackcoin.blackmored.plist @@ -0,0 +1,14 @@ + + + + + Label + org.blackcoin.blackmored + ProgramArguments + + /usr/local/bin/blackmored + + RunAtLoad + + + diff --git a/contrib/install_db4.sh b/contrib/install_db4.sh new file mode 100755 index 0000000000..ce63d87df6 --- /dev/null +++ b/contrib/install_db4.sh @@ -0,0 +1,106 @@ +#!/bin/sh +# Copyright (c) 2017-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. + +# Install libdb4.8 (Berkeley DB). + +export LC_ALL=C +set -e + +if [ -z "${1}" ]; then + echo "Usage: $0 [ ...]" + echo + echo "Must specify a single argument: the directory in which db4 will be built." + echo "This is probably \`pwd\` if you're at the root of the litecoin repository." + exit 1 +fi + +expand_path() { + cd "${1}" && pwd -P +} + +BDB_PREFIX="$(expand_path ${1})/db4"; shift; +BDB_VERSION='db-4.8.30.NC' +BDB_HASH='12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef' +BDB_URL="https://download.oracle.com/berkeley-db/${BDB_VERSION}.tar.gz" + +check_exists() { + command -v "$1" >/dev/null +} + +sha256_check() { + # Args: + # + if check_exists sha256sum; then + echo "${1} ${2}" | sha256sum -c + elif check_exists sha256; then + if [ "$(uname)" = "FreeBSD" ]; then + sha256 -c "${1}" "${2}" + else + echo "${1} ${2}" | sha256 -c + fi + else + echo "${1} ${2}" | shasum -a 256 -c + fi +} + +http_get() { + # Args: + # + # It's acceptable that we don't require SSL here because we manually verify + # content hashes below. + # + if [ -f "${2}" ]; then + echo "File ${2} already exists; not downloading again" + elif check_exists curl; then + curl --insecure --retry 5 "${1}" -o "${2}" + else + wget --no-check-certificate "${1}" -O "${2}" + fi + + sha256_check "${3}" "${2}" +} + +mkdir -p "${BDB_PREFIX}" +http_get "${BDB_URL}" "${BDB_VERSION}.tar.gz" "${BDB_HASH}" +tar -xzvf ${BDB_VERSION}.tar.gz -C "$BDB_PREFIX" +cd "${BDB_PREFIX}/${BDB_VERSION}/" + +# Apply a patch necessary when building with clang and c++11 (see https://community.oracle.com/thread/3952592) +CLANG_CXX11_PATCH_URL='https://gist.githubusercontent.com/LnL7/5153b251fd525fe15de69b67e63a6075/raw/7778e9364679093a32dec2908656738e16b6bdcb/clang.patch' +CLANG_CXX11_PATCH_HASH='7a9a47b03fd5fb93a16ef42235fa9512db9b0829cfc3bdf90edd3ec1f44d637c' +http_get "${CLANG_CXX11_PATCH_URL}" clang.patch "${CLANG_CXX11_PATCH_HASH}" +patch -p2 < clang.patch + +# The packaged config.guess and config.sub are ancient (2009) and can cause build issues. +# Replace them with modern versions. +# See https://github.com/bitcoin/bitcoin/issues/16064 +CONFIG_GUESS_URL='https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=55eaf3e779455c4e5cc9f82efb5278be8f8f900b' +CONFIG_GUESS_HASH='2d1ff7bca773d2ec3c6217118129220fa72d8adda67c7d2bf79994b3129232c1' +CONFIG_SUB_URL='https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=55eaf3e779455c4e5cc9f82efb5278be8f8f900b' +CONFIG_SUB_HASH='3a4befde9bcdf0fdb2763fc1bfa74e8696df94e1ad7aac8042d133c8ff1d2e32' + +rm -f "dist/config.guess" +rm -f "dist/config.sub" + +http_get "${CONFIG_GUESS_URL}" dist/config.guess "${CONFIG_GUESS_HASH}" +http_get "${CONFIG_SUB_URL}" dist/config.sub "${CONFIG_SUB_HASH}" + +cd build_unix/ + +"${BDB_PREFIX}/${BDB_VERSION}/dist/configure" \ + --enable-cxx --disable-shared --disable-replication --with-pic --prefix="${BDB_PREFIX}" \ + "${@}" + +make install + +echo +echo "db4 build complete." +echo +# shellcheck disable=SC2016 +echo 'When compiling litecoind, run `./configure` in the following way:' +echo +echo " export BDB_PREFIX='${BDB_PREFIX}'" +# shellcheck disable=SC2016 +echo ' ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" ...' diff --git a/contrib/linearize/README.md b/contrib/linearize/README.md index 06f278f3b3..1448f79540 100644 --- a/contrib/linearize/README.md +++ b/contrib/linearize/README.md @@ -1,33 +1,54 @@ # Linearize -Construct a linear, no-fork, best version of the blockchain. +Construct a linear, no-fork, best version of the Litecoin blockchain. ## Step 1: Download hash list $ ./linearize-hashes.py linearize.cfg > hashlist.txt Required configuration file settings for linearize-hashes: -* RPC: rpcuser, rpcpassword +* RPC: `datadir` (Required if `rpcuser` and `rpcpassword` are not specified) +* RPC: `rpcuser`, `rpcpassword` (Required if `datadir` is not specified) Optional config file setting for linearize-hashes: -* RPC: host, port -* Block chain: min_height, max_height +* RPC: `host` (Default: `127.0.0.1`) +* RPC: `port` (Default: `9332`) +* Blockchain: `min_height`, `max_height` +* `rev_hash_bytes`: If true, the written block hash list will be +byte-reversed. (In other words, the hash returned by getblockhash will have its +bytes reversed.) False by default. Intended for generation of +standalone hash lists but safe to use with linearize-data.py, which will output +the same data no matter which byte format is chosen. + +The `linearize-hashes` script requires a connection, local or remote, to a +JSON-RPC server. Running `litecoind` or `litecoin-qt -server` will be sufficient. ## Step 2: Copy local block data $ ./linearize-data.py linearize.cfg Required configuration file settings: -* "input": bitcoind blocks/ directory containing blkNNNNN.dat -* "hashlist": text file containing list of block hashes, linearized-hashes.py -output. -* "output_file": bootstrap.dat +* `output_file`: The file that will contain the final blockchain. or -* "output": output directory for linearized blocks/blkNNNNN.dat output +* `output`: Output directory for linearized `blocks/blkNNNNN.dat` output. Optional config file setting for linearize-data: -* "netmagic": network magic number -* "max_out_sz": maximum output file size (default `1000*1000*1000`) -* "split_timestamp": Split files when a new month is first seen, in addition to -reaching a maximum file size. -* "file_timestamp": Set each file's last-modified time to that of the -most recent block in that file. +* `debug_output`: Some printouts may not always be desired. If true, such output +will be printed. +* `file_timestamp`: Set each file's last-accessed and last-modified times, +respectively, to the current time and to the timestamp of the most recent block +written to the script's blockchain. +* `genesis`: The hash of the genesis block in the blockchain. +* `input`: litecoind blocks/ directory containing blkNNNNN.dat +* `hashlist`: text file containing list of block hashes created by +linearize-hashes.py. +* `max_out_sz`: Maximum size for files created by the `output_file` option. +(Default: `1000*1000*1000 bytes`) +* `netmagic`: Network magic number. +* `out_of_order_cache_sz`: If out-of-order blocks are being read, the block can +be written to a cache so that the blockchain doesn't have to be sought again. +This option specifies the cache size. (Default: `100*1000*1000 bytes`) +* `rev_hash_bytes`: If true, the block hash list written by linearize-hashes.py +will be byte-reversed when read by linearize-data.py. See the linearize-hashes +entry for more information. +* `split_timestamp`: Split blockchain files when a new month is first seen, in +addition to reaching a maximum file size (`max_out_sz`). diff --git a/contrib/linearize/example-linearize.cfg b/contrib/linearize/example-linearize.cfg index 38da02e66c..f3ce69ff50 100644 --- a/contrib/linearize/example-linearize.cfg +++ b/contrib/linearize/example-linearize.cfg @@ -1,10 +1,20 @@ - -# bitcoind RPC settings (linearize-hashes) +# litecoind RPC settings (linearize-hashes) rpcuser=someuser rpcpassword=somepassword +#datadir=~/.litecoin host=127.0.0.1 -port=8332 -#port=18332 + +#mainnet default +port=9332 + +#testnet default +#port=19332 + +#regtest default +#port=19443 + +#signet default +#port=38332 # bootstrap.dat hashlist settings (linearize-hashes) max_height=313000 @@ -12,18 +22,42 @@ max_height=313000 # bootstrap.dat input/output settings (linearize-data) # mainnet -netmagic=f9beb4d9 -genesis=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f -input=/home/example/.bitcoin/blocks +netmagic=fbc0b6db +genesis=12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2 +input=/home/example/.litecoin/blocks # testnet -#netmagic=0b110907 -#genesis=000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 -#input=/home/example/.bitcoin/testnet3/blocks +#netmagic=fdd2c8f1 +#genesis=4966625a4b2851d9fdee139e56211a0d88575f59ed816ff5e6a63deb4e3e29a0 +#input=/home/example/.litecoin/testnet3/blocks +# regtest +#netmagic=fabfb5da +#genesis=0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206 +#input=/home/example/.bitcoin/regtest/blocks + +# signet +#netmagic=0a03cf40 +#genesis=00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6 +#input=/home/example/.bitcoin/signet/blocks + +# "output" option causes blockchain files to be written to the given location, +# with "output_file" ignored. If not used, "output_file" is used instead. +# output=/home/example/blockchain_directory output_file=/home/example/Downloads/bootstrap.dat hashlist=hashlist.txt -split_year=1 -# Maxmimum size in bytes of out-of-order blocks cache in memory +# Maximum size in bytes of out-of-order blocks cache in memory out_of_order_cache_sz = 100000000 + +# Do we want the reverse the hash bytes coming from getblockhash? +rev_hash_bytes = False + +# On a new month, do we want to set the access and modify times of the new +# blockchain file? +file_timestamp = 0 +# Do we want to split the blockchain files given a new month or specific height? +split_timestamp = 0 + +# Do we want debug printouts? +debug_output = False diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index 0f6fde2a6e..73f54cd488 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -1,303 +1,350 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # linearize-data.py: Construct a linear, no-fork version of the chain. # -# Copyright (c) 2013-2014 The Bitcoin Core developers +# Copyright (c) 2013-2020 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -from __future__ import print_function, division -import json import struct import re import os import os.path -import base64 -import httplib import sys import hashlib import datetime import time +import glob from collections import namedtuple +from binascii import unhexlify settings = {} +def hex_switchEndian(s): + """ Switches the endianness of a hex string (in pairs of hex chars) """ + pairList = [s[i:i+2].encode() for i in range(0, len(s), 2)] + return b''.join(pairList[::-1]).decode() + def uint32(x): - return x & 0xffffffffL + return x & 0xffffffff def bytereverse(x): - return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | - (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )) + return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | + (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )) def bufreverse(in_buf): - out_words = [] - for i in range(0, len(in_buf), 4): - word = struct.unpack('@I', in_buf[i:i+4])[0] - out_words.append(struct.pack('@I', bytereverse(word))) - return ''.join(out_words) + out_words = [] + for i in range(0, len(in_buf), 4): + word = struct.unpack('@I', in_buf[i:i+4])[0] + out_words.append(struct.pack('@I', bytereverse(word))) + return b''.join(out_words) def wordreverse(in_buf): - out_words = [] - for i in range(0, len(in_buf), 4): - out_words.append(in_buf[i:i+4]) - out_words.reverse() - return ''.join(out_words) + out_words = [] + for i in range(0, len(in_buf), 4): + out_words.append(in_buf[i:i+4]) + out_words.reverse() + return b''.join(out_words) def calc_hdr_hash(blk_hdr): - hash1 = hashlib.sha256() - hash1.update(blk_hdr) - hash1_o = hash1.digest() + hash1 = hashlib.sha256() + hash1.update(blk_hdr) + hash1_o = hash1.digest() - hash2 = hashlib.sha256() - hash2.update(hash1_o) - hash2_o = hash2.digest() + hash2 = hashlib.sha256() + hash2.update(hash1_o) + hash2_o = hash2.digest() - return hash2_o + return hash2_o def calc_hash_str(blk_hdr): - hash = calc_hdr_hash(blk_hdr) - hash = bufreverse(hash) - hash = wordreverse(hash) - hash_str = hash.encode('hex') - return hash_str + hash = calc_hdr_hash(blk_hdr) + hash = bufreverse(hash) + hash = wordreverse(hash) + hash_str = hash.hex() + return hash_str def get_blk_dt(blk_hdr): - members = struct.unpack(" self.maxOutSz): - self.outF.close() - if self.setFileTime: - os.utime(outFname, (int(time.time()), highTS)) - self.outF = None - self.outFname = None - self.outFn = self.outFn + 1 - self.outsz = 0 - - (blkDate, blkTS) = get_blk_dt(blk_hdr) - if self.timestampSplit and (blkDate > self.lastDate): - print("New month " + blkDate.strftime("%Y-%m") + " @ " + hash_str) - lastDate = blkDate - if outF: - outF.close() - if setFileTime: - os.utime(outFname, (int(time.time()), highTS)) - self.outF = None - self.outFname = None - self.outFn = self.outFn + 1 - self.outsz = 0 - - if not self.outF: - if self.fileOutput: - outFname = self.settings['output_file'] - else: - outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn) - print("Output file " + outFname) - self.outF = open(outFname, "wb") - - self.outF.write(inhdr) - self.outF.write(blk_hdr) - self.outF.write(rawblock) - self.outsz = self.outsz + len(inhdr) + len(blk_hdr) + len(rawblock) - - self.blkCountOut = self.blkCountOut + 1 - if blkTS > self.highTS: - self.highTS = blkTS - - if (self.blkCountOut % 1000) == 0: - print('%i blocks scanned, %i blocks written (of %i, %.1f%% complete)' % - (self.blkCountIn, self.blkCountOut, len(self.blkindex), 100.0 * self.blkCountOut / len(self.blkindex))) - - def inFileName(self, fn): - return os.path.join(self.settings['input'], "blk%05d.dat" % fn) - - def fetchBlock(self, extent): - '''Fetch block contents from disk given extents''' - with open(self.inFileName(extent.fn), "rb") as f: - f.seek(extent.offset) - return f.read(extent.size) - - def copyOneBlock(self): - '''Find the next block to be written in the input, and copy it to the output.''' - extent = self.blockExtents.pop(self.blkCountOut) - if self.blkCountOut in self.outOfOrderData: - # If the data is cached, use it from memory and remove from the cache - rawblock = self.outOfOrderData.pop(self.blkCountOut) - self.outOfOrderSize -= len(rawblock) - else: # Otherwise look up data on disk - rawblock = self.fetchBlock(extent) - - self.writeBlock(extent.inhdr, extent.blkhdr, rawblock) - - def run(self): - while self.blkCountOut < len(self.blkindex): - if not self.inF: - fname = self.inFileName(self.inFn) - print("Input file " + fname) - try: - self.inF = open(fname, "rb") - except IOError: - print("Premature end of block data") - return - - inhdr = self.inF.read(8) - if (not inhdr or (inhdr[0] == "\0")): - self.inF.close() - self.inF = None - self.inFn = self.inFn + 1 - continue - - inMagic = inhdr[:4] - if (inMagic != self.settings['netmagic']): - print("Invalid magic: " + inMagic.encode('hex')) - return - inLenLE = inhdr[4:] - su = struct.unpack(" self.maxOutSz): + self.outF.close() + if self.setFileTime: + os.utime(self.outFname, (int(time.time()), self.highTS)) + self.outF = None + self.outFname = None + self.outFn = self.outFn + 1 + self.outsz = 0 + + (blkDate, blkTS) = get_blk_dt(blk_hdr) + if self.timestampSplit and (blkDate > self.lastDate): + print("New month " + blkDate.strftime("%Y-%m") + " @ " + self.hash_str) + self.lastDate = blkDate + if self.outF: + self.outF.close() + if self.setFileTime: + os.utime(self.outFname, (int(time.time()), self.highTS)) + self.outF = None + self.outFname = None + self.outFn = self.outFn + 1 + self.outsz = 0 + + if not self.outF: + if self.fileOutput: + self.outFname = self.settings['output_file'] + else: + self.outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn) + print("Output file " + self.outFname) + self.outF = open(self.outFname, "wb") + + self.outF.write(inhdr) + self.outF.write(blk_hdr) + self.outF.write(rawblock) + self.outsz = self.outsz + len(inhdr) + len(blk_hdr) + len(rawblock) + + self.blkCountOut = self.blkCountOut + 1 + if blkTS > self.highTS: + self.highTS = blkTS + + if (self.blkCountOut % 1000) == 0: + print('%i blocks scanned, %i blocks written (of %i, %.1f%% complete)' % + (self.blkCountIn, self.blkCountOut, len(self.blkindex), 100.0 * self.blkCountOut / len(self.blkindex))) + + def inFileName(self, fn): + return os.path.join(self.settings['input'], "blk%05d.dat" % fn) + + def fetchBlock(self, extent): + '''Fetch block contents from disk given extents''' + with open(self.inFileName(extent.fn), "rb") as f: + f.seek(extent.offset) + return f.read(extent.size) + + def copyOneBlock(self): + '''Find the next block to be written in the input, and copy it to the output.''' + extent = self.blockExtents.pop(self.blkCountOut) + if self.blkCountOut in self.outOfOrderData: + # If the data is cached, use it from memory and remove from the cache + rawblock = self.outOfOrderData.pop(self.blkCountOut) + self.outOfOrderSize -= len(rawblock) + else: # Otherwise look up data on disk + rawblock = self.fetchBlock(extent) + + self.writeBlock(extent.inhdr, extent.blkhdr, rawblock) + + def run(self): + while self.blkCountOut < len(self.blkindex): + if not self.inF: + fname = self.inFileName(self.inFn) + print("Input file " + fname) + try: + self.inF = open(fname, "rb") + except IOError: + print("Premature end of block data") + return + + inhdr = self.inF.read(8) + if (not inhdr or (inhdr[0] == "\0")): + self.inF.close() + self.inF = None + self.inFn = self.inFn + 1 + continue + + inMagic = inhdr[:4] + if (inMagic != self.settings['netmagic']): + # Seek backwards 7 bytes (skipping the first byte in the previous search) + # and continue searching from the new position if the magic bytes are not + # found. + self.inF.seek(-7, os.SEEK_CUR) + continue + inLenLE = inhdr[4:] + su = struct.unpack(" " @@ -22,35 +22,6 @@ if [ -z "$SIGNATURE" ]; then exit 1 fi -rm -rf ${TEMPDIR} && mkdir -p ${TEMPDIR} -tar -C ${TEMPDIR} -xf ${UNSIGNED} -cp -rf "${SIGNATURE}"/* ${TEMPDIR} - -if [ -z "${PAGESTUFF}" ]; then - PAGESTUFF=${TEMPDIR}/pagestuff -fi - -if [ -z "${CODESIGN_ALLOCATE}" ]; then - CODESIGN_ALLOCATE=${TEMPDIR}/codesign_allocate -fi - -find ${TEMPDIR} -name "*.sign" | while read i; do - SIZE=`stat -c %s "${i}"` - TARGET_FILE="`echo "${i}" | sed 's/\.sign$//'`" - - echo "Allocating space for the signature of size ${SIZE} in ${TARGET_FILE}" - ${CODESIGN_ALLOCATE} -i "${TARGET_FILE}" -a ${ARCH} ${SIZE} -o "${i}.tmp" - - OFFSET=`${PAGESTUFF} "${i}.tmp" -p | tail -2 | grep offset | sed 's/[^0-9]*//g'` - if [ -z ${QUIET} ]; then - echo "Attaching signature at offset ${OFFSET}" - fi - - dd if="$i" of="${i}.tmp" bs=1 seek=${OFFSET} count=${SIZE} 2>/dev/null - mv "${i}.tmp" "${TARGET_FILE}" - rm "${i}" - echo "Success." -done -mv ${TEMPDIR}/${ROOTDIR} ${OUTDIR} -rm -rf ${TEMPDIR} +${SIGNAPPLE} apply ${UNSIGNED} ${SIGNATURE} +mv ${ROOTDIR} ${OUTDIR} echo "Signed: ${OUTDIR}" diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh index 0f5ccfe56c..f69f45cc48 100755 --- a/contrib/macdeploy/detached-sig-create.sh +++ b/contrib/macdeploy/detached-sig-create.sh @@ -1,50 +1,28 @@ #!/bin/sh -# Copyright (c) 2014-2015 The Bitcoin Core developers +# Copyright (c) 2014-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. +export LC_ALL=C set -e ROOTDIR=dist BUNDLE="${ROOTDIR}/Blackmore-Qt.app" -CODESIGN=codesign +SIGNAPPLE=signapple TEMPDIR=sign.temp -TEMPLIST=${TEMPDIR}/signatures.txt -OUT=signature.tar.gz -OUTROOT=osx +OUT=signature-osx.tar.gz +OUTROOT=osx/dist -if [ ! -n "$1" ]; then - echo "usage: $0 " - echo "example: $0 -s MyIdentity" +if [ -z "$1" ]; then + echo "usage: $0 " + echo "example: $0 " exit 1 fi -rm -rf ${TEMPDIR} ${TEMPLIST} +rm -rf ${TEMPDIR} mkdir -p ${TEMPDIR} -${CODESIGN} -f --file-list ${TEMPLIST} "$@" "${BUNDLE}" - -grep -v CodeResources < "${TEMPLIST}" | while read i; do - TARGETFILE="${BUNDLE}/`echo "${i}" | sed "s|.*${BUNDLE}/||"`" - SIZE=`pagestuff "$i" -p | tail -2 | grep size | sed 's/[^0-9]*//g'` - OFFSET=`pagestuff "$i" -p | tail -2 | grep offset | sed 's/[^0-9]*//g'` - SIGNFILE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}.sign" - DIRNAME="`dirname "${SIGNFILE}"`" - mkdir -p "${DIRNAME}" - echo "Adding detached signature for: ${TARGETFILE}. Size: ${SIZE}. Offset: ${OFFSET}" - dd if="$i" of="${SIGNFILE}" bs=1 skip=${OFFSET} count=${SIZE} 2>/dev/null -done - -grep CodeResources < "${TEMPLIST}" | while read i; do - TARGETFILE="${BUNDLE}/`echo "${i}" | sed "s|.*${BUNDLE}/||"`" - RESOURCE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}" - DIRNAME="`dirname "${RESOURCE}"`" - mkdir -p "${DIRNAME}" - echo "Adding resource for: "${TARGETFILE}"" - cp "${i}" "${RESOURCE}" -done - -rm ${TEMPLIST} +${SIGNAPPLE} sign -f --detach "${TEMPDIR}/${OUTROOT}" "$@" "${BUNDLE}" tar -C "${TEMPDIR}" -czf "${OUT}" . rm -rf "${TEMPDIR}" diff --git a/contrib/macdeploy/gen-sdk b/contrib/macdeploy/gen-sdk new file mode 100755 index 0000000000..457d8f5e64 --- /dev/null +++ b/contrib/macdeploy/gen-sdk @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +import argparse +import plistlib +import pathlib +import sys +import tarfile +import gzip +import os +import contextlib + +@contextlib.contextmanager +def cd(path): + """Context manager that restores PWD even if an exception was raised.""" + old_pwd = os.getcwd() + os.chdir(str(path)) + try: + yield + finally: + os.chdir(old_pwd) + +def run(): + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawTextHelpFormatter) + + parser.add_argument('xcode_app', metavar='XCODEAPP', nargs=1) + parser.add_argument("-o", metavar='OUTSDKTGZ', nargs=1, dest='out_sdktgz', required=False) + + args = parser.parse_args() + + xcode_app = pathlib.Path(args.xcode_app[0]).resolve() + assert xcode_app.is_dir(), "The supplied Xcode.app path '{}' either does not exist or is not a directory".format(xcode_app) + + xcode_app_plist = xcode_app.joinpath("Contents/version.plist") + with xcode_app_plist.open('rb') as fp: + pl = plistlib.load(fp) + xcode_version = pl['CFBundleShortVersionString'] + xcode_build_id = pl['ProductBuildVersion'] + print("Found Xcode (version: {xcode_version}, build id: {xcode_build_id})".format(xcode_version=xcode_version, xcode_build_id=xcode_build_id)) + + sdk_dir = xcode_app.joinpath("Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk") + sdk_plist = sdk_dir.joinpath("System/Library/CoreServices/SystemVersion.plist") + with sdk_plist.open('rb') as fp: + pl = plistlib.load(fp) + sdk_version = pl['ProductVersion'] + sdk_build_id = pl['ProductBuildVersion'] + print("Found MacOSX SDK (version: {sdk_version}, build id: {sdk_build_id})".format(sdk_version=sdk_version, sdk_build_id=sdk_build_id)) + + out_name = "Xcode-{xcode_version}-{xcode_build_id}-extracted-SDK-with-libcxx-headers".format(xcode_version=xcode_version, xcode_build_id=xcode_build_id) + + xcode_libcxx_dir = xcode_app.joinpath("Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1") + assert xcode_libcxx_dir.is_dir() + + if args.out_sdktgz: + out_sdktgz_path = pathlib.Path(args.out_sdktgz_path) + else: + # Construct our own out_sdktgz if not specified on the command line + out_sdktgz_path = pathlib.Path("./{}.tar.gz".format(out_name)) + + def tarfp_add_with_base_change(tarfp, dir_to_add, alt_base_dir): + """Add all files in dir_to_add to tarfp, but prepent MEMBERPREFIX to the files' + names + + e.g. if the only file under /root/bazdir is /root/bazdir/qux, invoking: + + tarfp_add_with_base_change(tarfp, "foo/bar", "/root/bazdir") + + would result in the following members being added to tarfp: + + foo/bar/ -> corresponding to /root/bazdir + foo/bar/qux -> corresponding to /root/bazdir/qux + + """ + def change_tarinfo_base(tarinfo): + if tarinfo.name and tarinfo.name.startswith("./"): + tarinfo.name = str(pathlib.Path(alt_base_dir, tarinfo.name)) + if tarinfo.linkname and tarinfo.linkname.startswith("./"): + tarinfo.linkname = str(pathlib.Path(alt_base_dir, tarinfo.linkname)) + return tarinfo + with cd(dir_to_add): + tarfp.add(".", recursive=True, filter=change_tarinfo_base) + + print("Creating output .tar.gz file...") + with out_sdktgz_path.open("wb") as fp: + with gzip.GzipFile(fileobj=fp, compresslevel=9, mtime=0) as gzf: + with tarfile.open(mode="w", fileobj=gzf) as tarfp: + print("Adding MacOSX SDK {} files...".format(sdk_version)) + tarfp_add_with_base_change(tarfp, sdk_dir, out_name) + print("Adding libc++ headers...") + tarfp_add_with_base_change(tarfp, xcode_libcxx_dir, "{}/usr/include/c++/v1".format(out_name)) + print("Done! Find the resulting gzipped tarball at:") + print(out_sdktgz_path.resolve()) + +if __name__ == '__main__': + run() diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index e673b8e18e..7b26a05074 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -1,5 +1,4 @@ -#!/usr/bin/env python -from __future__ import division, print_function, unicode_literals +#!/usr/bin/env python3 # # Copyright (C) 2011 Patrick "p2k" Schneider # @@ -17,9 +16,13 @@ from __future__ import division, print_function, unicode_literals # along with this program. If not, see . # -import subprocess, sys, re, os, shutil, stat, os.path, time -from string import Template +import sys, re, os, shutil, stat, os.path from argparse import ArgumentParser +from ds_store import DSStore +from mac_alias import Alias +from pathlib import Path +from subprocess import PIPE, run +from typing import List, Optional # This is ported from the original macdeployqt with modifications @@ -49,28 +52,18 @@ class FrameworkInfo(object): return False def __str__(self): - return """ Framework name: %s - Framework directory: %s - Framework path: %s - Binary name: %s - Binary directory: %s - Binary path: %s - Version: %s - Install name: %s - Deployed install name: %s - Source file Path: %s - Deployed Directory (relative to bundle): %s -""" % (self.frameworkName, - self.frameworkDirectory, - self.frameworkPath, - self.binaryName, - self.binaryDirectory, - self.binaryPath, - self.version, - self.installName, - self.deployedInstallName, - self.sourceFilePath, - self.destinationDirectory) + return f""" Framework name: {self.frameworkName} + Framework directory: {self.frameworkDirectory} + Framework path: {self.frameworkPath} + Binary name: {self.binaryName} + Binary directory: {self.binaryDirectory} + Binary path: {self.binaryPath} + Version: {self.version} + Install name: {self.installName} + Deployed install name: {self.deployedInstallName} + Source file Path: {self.sourceFilePath} + Deployed Directory (relative to bundle): {self.destinationDirectory} +""" def isDylib(self): return self.frameworkName.endswith(".dylib") @@ -86,18 +79,18 @@ class FrameworkInfo(object): bundleBinaryDirectory = "Contents/MacOS" @classmethod - def fromOtoolLibraryLine(cls, line): + def fromOtoolLibraryLine(cls, line: str) -> Optional['FrameworkInfo']: # Note: line must be trimmed if line == "": return None - # Don't deploy system libraries (exception for libQtuitools and libQtlucene). - if line.startswith("/System/Library/") or line.startswith("@executable_path") or (line.startswith("/usr/lib/") and "libQt" not in line): + # Don't deploy system libraries + if line.startswith("/System/Library/") or line.startswith("@executable_path") or line.startswith("/usr/lib/"): return None m = cls.reOLine.match(line) if m is None: - raise RuntimeError("otool line could not be parsed: " + line) + raise RuntimeError(f"otool line could not be parsed: {line}") path = m.group(1) @@ -117,7 +110,7 @@ class FrameworkInfo(object): info.version = "-" info.installName = path - info.deployedInstallName = "@executable_path/../Frameworks/" + info.binaryName + info.deployedInstallName = f"@executable_path/../Frameworks/{info.binaryName}" info.sourceFilePath = path info.destinationDirectory = cls.bundleFrameworkDirectory else: @@ -129,7 +122,7 @@ class FrameworkInfo(object): break i += 1 if i == len(parts): - raise RuntimeError("Could not find .framework or .dylib in otool line: " + line) + raise RuntimeError(f"Could not find .framework or .dylib in otool line: {line}") info.frameworkName = parts[i] info.frameworkDirectory = "/".join(parts[:i]) @@ -140,25 +133,24 @@ class FrameworkInfo(object): info.binaryPath = os.path.join(info.binaryDirectory, info.binaryName) info.version = parts[i+2] - info.deployedInstallName = "@executable_path/../Frameworks/" + os.path.join(info.frameworkName, info.binaryPath) + info.deployedInstallName = f"@executable_path/../Frameworks/{os.path.join(info.frameworkName, info.binaryPath)}" info.destinationDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, info.binaryDirectory) info.sourceResourcesDirectory = os.path.join(info.frameworkPath, "Resources") info.sourceContentsDirectory = os.path.join(info.frameworkPath, "Contents") info.sourceVersionContentsDirectory = os.path.join(info.frameworkPath, "Versions", info.version, "Contents") info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources") - info.destinationContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Contents") info.destinationVersionContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Versions", info.version, "Contents") return info class ApplicationBundleInfo(object): - def __init__(self, path): + def __init__(self, path: str): self.path = path - appName = "Blackmore-Qt" - self.binaryPath = os.path.join(path, "Contents", "MacOS", appName) + # for backwards compatibility reasons, this must remain as Blackmore-Qt + self.binaryPath = os.path.join(path, "Contents", "MacOS", "Blackmore-Qt") if not os.path.exists(self.binaryPath): - raise RuntimeError("Could not find bundle binary for " + path) + raise RuntimeError(f"Could not find bundle binary for {path}") self.resourcesPath = os.path.join(path, "Contents", "Resources") self.pluginPath = os.path.join(path, "Contents", "PlugIns") @@ -168,17 +160,11 @@ class DeploymentInfo(object): self.pluginPath = None self.deployedFrameworks = [] - def detectQtPath(self, frameworkDirectory): + def detectQtPath(self, frameworkDirectory: str): parentDir = os.path.dirname(frameworkDirectory) if os.path.exists(os.path.join(parentDir, "translations")): # Classic layout, e.g. "/usr/local/Trolltech/Qt-4.x.x" self.qtPath = parentDir - elif os.path.exists(os.path.join(parentDir, "share", "qt4", "translations")): - # MacPorts layout, e.g. "/opt/local/share/qt4" - self.qtPath = os.path.join(parentDir, "share", "qt4") - elif os.path.exists(os.path.join(os.path.dirname(parentDir), "share", "qt4", "translations")): - # Newer Macports layout - self.qtPath = os.path.join(os.path.dirname(parentDir), "share", "qt4") else: self.qtPath = os.getenv("QTDIR", None) @@ -187,31 +173,27 @@ class DeploymentInfo(object): if os.path.exists(pluginPath): self.pluginPath = pluginPath - def usesFramework(self, name): - nameDot = "%s." % name - libNameDot = "lib%s." % name + def usesFramework(self, name: str) -> bool: for framework in self.deployedFrameworks: if framework.endswith(".framework"): - if framework.startswith(nameDot): + if framework.startswith(f"{name}."): return True elif framework.endswith(".dylib"): - if framework.startswith(libNameDot): + if framework.startswith(f"lib{name}."): return True return False -def getFrameworks(binaryPath, verbose): - if verbose >= 3: - print("Inspecting with otool: " + binaryPath) +def getFrameworks(binaryPath: str, verbose: int) -> List[FrameworkInfo]: + if verbose: + print(f"Inspecting with otool: {binaryPath}") otoolbin=os.getenv("OTOOL", "otool") - otool = subprocess.Popen([otoolbin, "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - o_stdout, o_stderr = otool.communicate() + otool = run([otoolbin, "-L", binaryPath], stdout=PIPE, stderr=PIPE, universal_newlines=True) if otool.returncode != 0: - if verbose >= 1: - sys.stderr.write(o_stderr) - sys.stderr.flush() - raise RuntimeError("otool failed with return code %d" % otool.returncode) + sys.stderr.write(otool.stderr) + sys.stderr.flush() + raise RuntimeError(f"otool failed with return code {otool.returncode}") - otoolLines = o_stdout.decode().split("\n") + otoolLines = otool.stdout.split("\n") otoolLines.pop(0) # First line is the inspected binary if ".framework" in binaryPath or binaryPath.endswith(".dylib"): otoolLines.pop(0) # Frameworks and dylibs list themselves as a dependency. @@ -221,50 +203,50 @@ def getFrameworks(binaryPath, verbose): line = line.replace("@loader_path", os.path.dirname(binaryPath)) info = FrameworkInfo.fromOtoolLibraryLine(line.strip()) if info is not None: - if verbose >= 3: + if verbose: print("Found framework:") print(info) libraries.append(info) return libraries -def runInstallNameTool(action, *args): +def runInstallNameTool(action: str, *args): installnametoolbin=os.getenv("INSTALLNAMETOOL", "install_name_tool") - subprocess.check_call([installnametoolbin, "-"+action] + list(args)) + run([installnametoolbin, "-"+action] + list(args), check=True) -def changeInstallName(oldName, newName, binaryPath, verbose): - if verbose >= 3: +def changeInstallName(oldName: str, newName: str, binaryPath: str, verbose: int): + if verbose: print("Using install_name_tool:") print(" in", binaryPath) print(" change reference", oldName) print(" to", newName) runInstallNameTool("change", oldName, newName, binaryPath) -def changeIdentification(id, binaryPath, verbose): - if verbose >= 3: +def changeIdentification(id: str, binaryPath: str, verbose: int): + if verbose: print("Using install_name_tool:") print(" change identification in", binaryPath) print(" to", id) runInstallNameTool("id", id, binaryPath) -def runStrip(binaryPath, verbose): +def runStrip(binaryPath: str, verbose: int): stripbin=os.getenv("STRIP", "strip") - if verbose >= 3: + if verbose: print("Using strip:") print(" stripped", binaryPath) - subprocess.check_call([stripbin, "-x", binaryPath]) + run([stripbin, "-x", binaryPath], check=True) -def copyFramework(framework, path, verbose): +def copyFramework(framework: FrameworkInfo, path: str, verbose: int) -> Optional[str]: if framework.sourceFilePath.startswith("Qt"): #standard place for Nokia Qt installer's frameworks - fromPath = "/Library/Frameworks/" + framework.sourceFilePath + fromPath = f"/Library/Frameworks/{framework.sourceFilePath}" else: fromPath = framework.sourceFilePath toDir = os.path.join(path, framework.destinationDirectory) toPath = os.path.join(toDir, framework.binaryName) if not os.path.exists(fromPath): - raise RuntimeError("No file at " + fromPath) + raise RuntimeError(f"No file at {fromPath}") if os.path.exists(toPath): return None # Already there @@ -273,7 +255,7 @@ def copyFramework(framework, path, verbose): os.makedirs(toDir) shutil.copy2(fromPath, toPath) - if verbose >= 3: + if verbose: print("Copied:", fromPath) print(" to:", toPath) @@ -287,13 +269,12 @@ def copyFramework(framework, path, verbose): linkto = framework.version if not os.path.exists(linkfrom): os.symlink(linkto, linkfrom) - if verbose >= 2: - print("Linked:", linkfrom, "->", linkto) + print("Linked:", linkfrom, "->", linkto) fromResourcesDir = framework.sourceResourcesDirectory if os.path.exists(fromResourcesDir): toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory) shutil.copytree(fromResourcesDir, toResourcesDir, symlinks=True) - if verbose >= 3: + if verbose: print("Copied resources:", fromResourcesDir) print(" to:", toResourcesDir) fromContentsDir = framework.sourceVersionContentsDirectory @@ -302,22 +283,13 @@ def copyFramework(framework, path, verbose): if os.path.exists(fromContentsDir): toContentsDir = os.path.join(path, framework.destinationVersionContentsDirectory) shutil.copytree(fromContentsDir, toContentsDir, symlinks=True) - contentslinkfrom = os.path.join(path, framework.destinationContentsDirectory) - if verbose >= 3: + if verbose: print("Copied Contents:", fromContentsDir) print(" to:", toContentsDir) - elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout) - qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib") - qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib") - if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath): - shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath, symlinks=True) - if verbose >= 3: - print("Copied for libQtGui:", qtMenuNibSourcePath) - print(" to:", qtMenuNibDestinationPath) return toPath -def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploymentInfo=None): +def deployFrameworks(frameworks: List[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo: if deploymentInfo is None: deploymentInfo = DeploymentInfo() @@ -325,22 +297,20 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym framework = frameworks.pop(0) deploymentInfo.deployedFrameworks.append(framework.frameworkName) - if verbose >= 2: - print("Processing", framework.frameworkName, "...") + print("Processing", framework.frameworkName, "...") # Get the Qt path from one of the Qt frameworks if deploymentInfo.qtPath is None and framework.isQtFramework(): deploymentInfo.detectQtPath(framework.frameworkDirectory) if framework.installName.startswith("@executable_path") or framework.installName.startswith(bundlePath): - if verbose >= 2: - print(framework.frameworkName, "already deployed, skipping.") + print(framework.frameworkName, "already deployed, skipping.") continue # install_name_tool the new id into the binary changeInstallName(framework.installName, framework.deployedInstallName, binaryPath, verbose) - # Copy farmework to app bundle. + # Copy framework to app bundle. deployedBinaryPath = copyFramework(framework, bundlePath, verbose) # Skip the rest if already was deployed. if deployedBinaryPath is None: @@ -363,88 +333,34 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym return deploymentInfo -def deployFrameworksForAppBundle(applicationBundle, strip, verbose): +def deployFrameworksForAppBundle(applicationBundle: ApplicationBundleInfo, strip: bool, verbose: int) -> DeploymentInfo: frameworks = getFrameworks(applicationBundle.binaryPath, verbose) - if len(frameworks) == 0 and verbose >= 1: - print("Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle.path)) + if len(frameworks) == 0: + print(f"Warning: Could not find any external frameworks to deploy in {applicationBundle.path}.") return DeploymentInfo() else: return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) -def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): - # Lookup available plugins, exclude unneeded +def deployPlugins(appBundleInfo: ApplicationBundleInfo, deploymentInfo: DeploymentInfo, strip: bool, verbose: int): plugins = [] if deploymentInfo.pluginPath is None: return for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath): pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath) - if pluginDirectory == "designer": - # Skip designer plugins + + if pluginDirectory not in ['styles', 'platforms']: continue - elif pluginDirectory == "phonon" or pluginDirectory == "phonon_backend": - # Deploy the phonon plugins only if phonon is in use - if not deploymentInfo.usesFramework("phonon"): - continue - elif pluginDirectory == "sqldrivers": - # Deploy the sql plugins only if QtSql is in use - if not deploymentInfo.usesFramework("QtSql"): - continue - elif pluginDirectory == "script": - # Deploy the script plugins only if QtScript is in use - if not deploymentInfo.usesFramework("QtScript"): - continue - elif pluginDirectory == "qmltooling" or pluginDirectory == "qml1tooling": - # Deploy the qml plugins only if QtDeclarative is in use - if not deploymentInfo.usesFramework("QtDeclarative"): - continue - elif pluginDirectory == "bearer": - # Deploy the bearer plugins only if QtNetwork is in use - if not deploymentInfo.usesFramework("QtNetwork"): - continue - elif pluginDirectory == "position": - # Deploy the position plugins only if QtPositioning is in use - if not deploymentInfo.usesFramework("QtPositioning"): - continue - elif pluginDirectory == "sensors" or pluginDirectory == "sensorgestures": - # Deploy the sensor plugins only if QtSensors is in use - if not deploymentInfo.usesFramework("QtSensors"): - continue - elif pluginDirectory == "audio" or pluginDirectory == "playlistformats": - # Deploy the audio plugins only if QtMultimedia is in use - if not deploymentInfo.usesFramework("QtMultimedia"): - continue - elif pluginDirectory == "mediaservice": - # Deploy the mediaservice plugins only if QtMultimediaWidgets is in use - if not deploymentInfo.usesFramework("QtMultimediaWidgets"): - continue for pluginName in filenames: pluginPath = os.path.join(pluginDirectory, pluginName) - if pluginName.endswith("_debug.dylib"): - # Skip debug plugins + + if pluginName.split('.')[0] not in ['libqminimal', 'libqcocoa', 'libqmacstyle']: continue - elif pluginPath == "imageformats/libqsvg.dylib" or pluginPath == "iconengines/libqsvgicon.dylib": - # Deploy the svg plugins only if QtSvg is in use - if not deploymentInfo.usesFramework("QtSvg"): - continue - elif pluginPath == "accessible/libqtaccessiblecompatwidgets.dylib": - # Deploy accessibility for Qt3Support only if the Qt3Support is in use - if not deploymentInfo.usesFramework("Qt3Support"): - continue - elif pluginPath == "graphicssystems/libqglgraphicssystem.dylib": - # Deploy the opengl graphicssystem plugin only if QtOpenGL is in use - if not deploymentInfo.usesFramework("QtOpenGL"): - continue - elif pluginPath == "accessible/libqtaccessiblequick.dylib": - # Deploy the accessible qtquick plugin only if QtQuick is in use - if not deploymentInfo.usesFramework("QtQuick"): - continue plugins.append((pluginDirectory, pluginName)) for pluginDirectory, pluginName in plugins: - if verbose >= 2: - print("Processing plugin", os.path.join(pluginDirectory, pluginName), "...") + print("Processing plugin", os.path.join(pluginDirectory, pluginName), "...") sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName) destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory) @@ -453,7 +369,7 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): destinationPath = os.path.join(destinationDirectory, pluginName) shutil.copy2(sourcePath, destinationPath) - if verbose >= 3: + if verbose: print("Copied:", sourcePath) print(" to:", destinationPath) @@ -469,147 +385,53 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): if dependency.frameworkName not in deploymentInfo.deployedFrameworks: deployFrameworks([dependency], appBundleInfo.path, destinationPath, strip, verbose, deploymentInfo) -qt_conf="""[Paths] -Translations=Resources -Plugins=PlugIns -""" - ap = ArgumentParser(description="""Improved version of macdeployqt. Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file. Note, that the "dist" folder will be deleted before deploying on each run. -Optionally, Qt translation files (.qm) and additional resources can be added to the bundle. - -Also optionally signs the .app bundle; set the CODESIGNARGS environment variable to pass arguments -to the codesign tool. -E.g. CODESIGNARGS='--sign "Developer ID Application: ..." --keychain /encrypted/foo.keychain'""") +Optionally, Qt translation files (.qm) can be added to the bundle.""") ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed") -ap.add_argument("-verbose", type=int, nargs=1, default=[1], metavar="<0-3>", help="0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug") +ap.add_argument("appname", nargs=1, metavar="appname", help="name of the app being deployed") +ap.add_argument("-verbose", nargs="?", const=True, help="Output additional debugging information") ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment") ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries") -ap.add_argument("-sign", dest="sign", action="store_true", default=False, help="sign .app bundle with codesign tool") -ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image; if basename is not specified, a camel-cased version of the app name is used") -ap.add_argument("-fancy", nargs=1, metavar="plist", default=[], help="make a fancy looking disk image using the given plist file with instructions; requires -dmg to work") -ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's ressources; the language list must be separated with commas, not with whitespace") -ap.add_argument("-translations-dir", nargs=1, metavar="path", default=None, help="Path to Qt's translation files") -ap.add_argument("-add-resources", nargs="+", metavar="path", default=[], help="list of additional files or folders to be copied into the bundle's resources; must be the last argument") -ap.add_argument("-volname", nargs=1, metavar="volname", default=[], help="custom volume name for dmg") +ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image") +ap.add_argument("-translations-dir", nargs=1, metavar="path", default=None, help="Path to Qt's translations. Base translations will automatically be added to the bundle's resources.") config = ap.parse_args() -verbose = config.verbose[0] +verbose = config.verbose # ------------------------------------------------ app_bundle = config.app_bundle[0] +appname = config.appname[0] if not os.path.exists(app_bundle): - if verbose >= 1: - sys.stderr.write("Error: Could not find app bundle \"%s\"\n" % (app_bundle)) + sys.stderr.write(f"Error: Could not find app bundle \"{app_bundle}\"\n") sys.exit(1) -app_bundle_name = os.path.splitext(os.path.basename(app_bundle))[0] - -# ------------------------------------------------ -translations_dir = None -if config.translations_dir and config.translations_dir[0]: - if os.path.exists(config.translations_dir[0]): - translations_dir = config.translations_dir[0] - else: - if verbose >= 1: - sys.stderr.write("Error: Could not find translation dir \"%s\"\n" % (translations_dir)) - sys.exit(1) -# ------------------------------------------------ - -for p in config.add_resources: - if verbose >= 3: - print("Checking for \"%s\"..." % p) - if not os.path.exists(p): - if verbose >= 1: - sys.stderr.write("Error: Could not find additional resource file \"%s\"\n" % (p)) - sys.exit(1) - -# ------------------------------------------------ - -if len(config.fancy) == 1: - if verbose >= 3: - print("Fancy: Importing plistlib...") - try: - import plistlib - except ImportError: - if verbose >= 1: - sys.stderr.write("Error: Could not import plistlib which is required for fancy disk images.\n") - sys.exit(1) - - p = config.fancy[0] - if verbose >= 3: - print("Fancy: Loading \"%s\"..." % p) - if not os.path.exists(p): - if verbose >= 1: - sys.stderr.write("Error: Could not find fancy disk image plist at \"%s\"\n" % (p)) - sys.exit(1) - - try: - with open(p, 'rb') as fp: - fancy = plistlib.load(fp, fmt=plistlib.FMT_XML) - except: - if verbose >= 1: - sys.stderr.write("Error: Could not parse fancy disk image plist at \"%s\"\n" % (p)) - sys.exit(1) - - try: - assert "window_bounds" not in fancy or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4) - assert "background_picture" not in fancy or isinstance(fancy["background_picture"], str) - assert "icon_size" not in fancy or isinstance(fancy["icon_size"], int) - assert "applications_symlink" not in fancy or isinstance(fancy["applications_symlink"], bool) - if "items_position" in fancy: - assert isinstance(fancy["items_position"], dict) - for key, value in fancy["items_position"].items(): - assert isinstance(value, list) and len(value) == 2 and isinstance(value[0], int) and isinstance(value[1], int) - except: - if verbose >= 1: - sys.stderr.write("Error: Bad format of fancy disk image plist at \"%s\"\n" % (p)) - sys.exit(1) - - if "background_picture" in fancy: - bp = fancy["background_picture"] - if verbose >= 3: - print("Fancy: Resolving background picture \"%s\"..." % bp) - if not os.path.exists(bp): - bp = os.path.join(os.path.dirname(p), bp) - if not os.path.exists(bp): - if verbose >= 1: - sys.stderr.write("Error: Could not find background picture at \"%s\" or \"%s\"\n" % (fancy["background_picture"], bp)) - sys.exit(1) - else: - fancy["background_picture"] = bp -else: - fancy = None - # ------------------------------------------------ if os.path.exists("dist"): - if verbose >= 2: - print("+ Removing old dist folder +") - + print("+ Removing existing dist folder +") shutil.rmtree("dist") -# ------------------------------------------------ +if os.path.exists(appname + ".dmg"): + print("+ Removing existing DMG +") + os.unlink(appname + ".dmg") -if len(config.volname) == 1: - volname = config.volname[0] -else: - volname = app_bundle_name +if os.path.exists(appname + ".temp.dmg"): + os.unlink(appname + ".temp.dmg") # ------------------------------------------------ target = os.path.join("dist", "Blackmore-Qt.app") -if verbose >= 2: - print("+ Copying source bundle +") -if verbose >= 3: +print("+ Copying source bundle +") +if verbose: print(app_bundle, "->", target) os.mkdir("dist") @@ -619,274 +441,154 @@ applicationBundle = ApplicationBundleInfo(target) # ------------------------------------------------ -if verbose >= 2: - print("+ Deploying frameworks +") +print("+ Deploying frameworks +") try: deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose) if deploymentInfo.qtPath is None: deploymentInfo.qtPath = os.getenv("QTDIR", None) if deploymentInfo.qtPath is None: - if verbose >= 1: - sys.stderr.write("Warning: Could not detect Qt's path, skipping plugin deployment!\n") + sys.stderr.write("Warning: Could not detect Qt's path, skipping plugin deployment!\n") config.plugins = False except RuntimeError as e: - if verbose >= 1: - sys.stderr.write("Error: %s\n" % str(e)) + sys.stderr.write(f"Error: {str(e)}\n") sys.exit(1) # ------------------------------------------------ if config.plugins: - if verbose >= 2: - print("+ Deploying plugins +") + print("+ Deploying plugins +") try: deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose) except RuntimeError as e: - if verbose >= 1: - sys.stderr.write("Error: %s\n" % str(e)) + sys.stderr.write(f"Error: {str(e)}\n") sys.exit(1) # ------------------------------------------------ -if len(config.add_qt_tr) == 0: - add_qt_tr = [] -else: - if translations_dir is not None: - qt_tr_dir = translations_dir - else: - if deploymentInfo.qtPath is not None: - qt_tr_dir = os.path.join(deploymentInfo.qtPath, "translations") - else: - sys.stderr.write("Error: Could not find Qt translation path\n") - sys.exit(1) - add_qt_tr = ["qt_%s.qm" % lng for lng in config.add_qt_tr[0].split(",")] - for lng_file in add_qt_tr: - p = os.path.join(qt_tr_dir, lng_file) - if verbose >= 3: - print("Checking for \"%s\"..." % p) - if not os.path.exists(p): - if verbose >= 1: - sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file)) - sys.exit(1) - -# ------------------------------------------------ +if config.translations_dir: + if not Path(config.translations_dir[0]).exists(): + sys.stderr.write(f"Error: Could not find translation dir \"{config.translations_dir[0]}\"\n") + sys.exit(1) -if verbose >= 2: - print("+ Installing qt.conf +") +print("+ Adding Qt translations +") -f = open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") -f.write(qt_conf.encode()) -f.close() +translations = Path(config.translations_dir[0]) -# ------------------------------------------------ +regex = re.compile('qt_[a-z]*(.qm|_[A-Z]*.qm)') -if len(add_qt_tr) > 0 and verbose >= 2: - print("+ Adding Qt translations +") +lang_files = [x for x in translations.iterdir() if regex.match(x.name)] -for lng_file in add_qt_tr: - if verbose >= 3: - print(os.path.join(qt_tr_dir, lng_file), "->", os.path.join(applicationBundle.resourcesPath, lng_file)) - shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(applicationBundle.resourcesPath, lng_file)) +for file in lang_files: + if verbose: + print(file.as_posix(), "->", os.path.join(applicationBundle.resourcesPath, file.name)) + shutil.copy2(file.as_posix(), os.path.join(applicationBundle.resourcesPath, file.name)) # ------------------------------------------------ -if len(config.add_resources) > 0 and verbose >= 2: - print("+ Adding additional resources +") +print("+ Installing qt.conf +") -for p in config.add_resources: - t = os.path.join(applicationBundle.resourcesPath, os.path.basename(p)) - if verbose >= 3: - print(p, "->", t) - if os.path.isdir(p): - shutil.copytree(p, t, symlinks=True) - else: - shutil.copy2(p, t) +qt_conf="""[Paths] +Translations=Resources +Plugins=PlugIns +""" + +with open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") as f: + f.write(qt_conf.encode()) # ------------------------------------------------ -if config.sign and 'CODESIGNARGS' not in os.environ: - print("You must set the CODESIGNARGS environment variable. Skipping signing.") -elif config.sign: - if verbose >= 1: - print("Code-signing app bundle %s"%(target,)) - subprocess.check_call("codesign --force %s %s"%(os.environ['CODESIGNARGS'], target), shell=True) +print("+ Generating .DS_Store +") + +output_file = os.path.join("dist", ".DS_Store") + +ds = DSStore.open(output_file, 'w+') + +ds['.']['bwsp'] = { + 'WindowBounds': '{{300, 280}, {500, 343}}', + 'PreviewPaneVisibility': False, +} + +icvp = { + 'gridOffsetX': 0.0, + 'textSize': 12.0, + 'viewOptionsVersion': 1, + 'backgroundImageAlias': b'\x00\x00\x00\x00\x02\x1e\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x94\\\xb0H+\x00\x05\x00\x00\x00\x98\x0fbackground.tiff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\xd19\xb0\xf8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x10\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x11\x00\x08\x00\x00\xd19\xb0\xf8\x00\x00\x00\x01\x00\x04\x00\x00\x00\x98\x00\x0e\x00 \x00\x0f\x00b\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00.\x00t\x00i\x00f\x00f\x00\x0f\x00\x02\x00\x00\x00\x12\x00\x1c/.background/background.tiff\x00\x14\x01\x06\x00\x00\x00\x00\x01\x06\x00\x02\x00\x00\x0cMacintosh HD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x97\xab\xc3H+\x00\x00\x01\x88[\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02u\xab\x8d\xd1\x94\\\xb0devrddsk\xff\xff\xff\xff\x00\x00\t \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07bitcoin\x00\x00\x10\x00\x08\x00\x00\xce\x97\xab\xc3\x00\x00\x00\x11\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x01\x00\x14\x01\x88[\x88\x00\x16\xa9\t\x00\x08\xfaR\x00\x08\xfaQ\x00\x02d\x8e\x00\x0e\x00\x02\x00\x00\x00\x0f\x00\x1a\x00\x0c\x00M\x00a\x00c\x00i\x00n\x00t\x00o\x00s\x00h\x00 \x00H\x00D\x00\x13\x00\x01/\x00\x00\x15\x00\x02\x00\x14\xff\xff\x00\x00\xff\xff\x00\x00', + 'backgroundColorBlue': 1.0, + 'iconSize': 96.0, + 'backgroundColorGreen': 1.0, + 'arrangeBy': 'none', + 'showIconPreview': True, + 'gridSpacing': 100.0, + 'gridOffsetY': 0.0, + 'showItemInfo': False, + 'labelOnBottom': True, + 'backgroundType': 2, + 'backgroundColorRed': 1.0 +} +alias = Alias().from_bytes(icvp['backgroundImageAlias']) +alias.volume.name = appname +alias.volume.posix_path = '/Volumes/' + appname +icvp['backgroundImageAlias'] = alias.to_bytes() +ds['.']['icvp'] = icvp + +ds['.']['vSrn'] = ('long', 1) + +ds['Applications']['Iloc'] = (370, 156) +ds['Blackmore-Qt.app']['Iloc'] = (128, 156) + +ds.flush() +ds.close() # ------------------------------------------------ if config.dmg is not None: - #Patch in check_output for Python 2.6 - if "check_output" not in dir( subprocess ): - def f(*popenargs, **kwargs): - if 'stdout' in kwargs: - raise ValueError('stdout argument not allowed, it will be overridden.') - process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) - output, unused_err = process.communicate() - retcode = process.poll() - if retcode: - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - raise CalledProcessError(retcode, cmd) - return output - subprocess.check_output = f - - def runHDIUtil(verb, image_basename, **kwargs): - hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"] - if "capture_stdout" in kwargs: - del kwargs["capture_stdout"] - run = subprocess.check_output - else: - if verbose < 2: - hdiutil_args.append("-quiet") - elif verbose >= 3: - hdiutil_args.append("-verbose") - run = subprocess.check_call - - for key, value in kwargs.items(): - hdiutil_args.append("-" + key) - if not value is True: - hdiutil_args.append(str(value)) - - return run(hdiutil_args) - - if verbose >= 2: - if fancy is None: - print("+ Creating .dmg disk image +") - else: - print("+ Preparing .dmg disk image +") - - if config.dmg != "": - dmg_name = config.dmg - else: - spl = app_bundle_name.split(" ") - dmg_name = spl[0] + "".join(p.capitalize() for p in spl[1:]) - - if fancy is None: - try: - runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname=volname, ov=True) - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - else: - if verbose >= 3: - print("Determining size of \"dist\"...") - size = 0 - for path, dirs, files in os.walk("dist"): - for file in files: - size += os.path.getsize(os.path.join(path, file)) - size += int(size * 0.15) - - if verbose >= 3: - print("Creating temp image for modification...") - try: - runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=volname, ov=True) - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - - if verbose >= 3: - print("Attaching temp image...") - try: - output = runHDIUtil("attach", dmg_name + ".temp", readwrite=True, noverify=True, noautoopen=True, capture_stdout=True) - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - - m = re.search("/Volumes/(.+$)", output.decode()) - disk_root = m.group(0) - disk_name = m.group(1) - - if verbose >= 2: - print("+ Applying fancy settings +") - - if "background_picture" in fancy: - bg_path = os.path.join(disk_root, ".background", os.path.basename(fancy["background_picture"])) - os.mkdir(os.path.dirname(bg_path)) - if verbose >= 3: - print(fancy["background_picture"], "->", bg_path) - shutil.copy2(fancy["background_picture"], bg_path) - else: - bg_path = None - - if fancy.get("applications_symlink", False): - os.symlink("/Applications", os.path.join(disk_root, "Applications")) - - # The Python appscript package broke with OSX 10.8 and isn't being fixed. - # So we now build up an AppleScript string and use the osascript command - # to make the .dmg file pretty: - appscript = Template( """ - on run argv - tell application "Finder" - tell disk "$disk" - open - set current view of container window to icon view - set toolbar visible of container window to false - set statusbar visible of container window to false - set the bounds of container window to {$window_bounds} - set theViewOptions to the icon view options of container window - set arrangement of theViewOptions to not arranged - set icon size of theViewOptions to $icon_size - $background_commands - $items_positions - close -- close/reopen works around a bug... - open - update without registering applications - delay 5 - eject - end tell - end tell - end run - """) - - itemscript = Template('set position of item "${item}" of container window to {${position}}') - items_positions = [] - if "items_position" in fancy: - for name, position in fancy["items_position"].items(): - params = { "item" : name, "position" : ",".join([str(p) for p in position]) } - items_positions.append(itemscript.substitute(params)) - - params = { - "disk" : volname, - "window_bounds" : "300,300,800,620", - "icon_size" : "96", - "background_commands" : "", - "items_positions" : "\n ".join(items_positions) - } - if "window_bounds" in fancy: - params["window_bounds"] = ",".join([str(p) for p in fancy["window_bounds"]]) - if "icon_size" in fancy: - params["icon_size"] = str(fancy["icon_size"]) - if bg_path is not None: - # Set background file, then call SetFile to make it invisible. - # (note: making it invisible first makes set background picture fail) - bgscript = Template("""set background picture of theViewOptions to file ".background:$bgpic" - do shell script "SetFile -a V /Volumes/$disk/.background/$bgpic" """) - params["background_commands"] = bgscript.substitute({"bgpic" : os.path.basename(bg_path), "disk" : params["disk"]}) - - s = appscript.substitute(params) - if verbose >= 2: - print("Running AppleScript:") - print(s) - - p = subprocess.Popen(['osascript', '-'], stdin=subprocess.PIPE) - p.communicate(input=s.encode('utf-8')) - if p.returncode: - print("Error running osascript.") - - if verbose >= 2: - print("+ Finalizing .dmg disk image +") - time.sleep(5) - - try: - runHDIUtil("convert", dmg_name + ".temp", format="UDBZ", o=dmg_name + ".dmg", ov=True) - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - - os.unlink(dmg_name + ".temp.dmg") + print("+ Preparing .dmg disk image +") + + if verbose: + print("Determining size of \"dist\"...") + size = 0 + for path, dirs, files in os.walk("dist"): + for file in files: + size += os.path.getsize(os.path.join(path, file)) + size += int(size * 0.15) + + if verbose: + print("Creating temp image for modification...") + + tempname: str = appname + ".temp.dmg" + + run(["hdiutil", "create", tempname, "-srcfolder", "dist", "-format", "UDRW", "-size", str(size), "-volname", appname], check=True, universal_newlines=True) + + if verbose: + print("Attaching temp image...") + output = run(["hdiutil", "attach", tempname, "-readwrite"], check=True, universal_newlines=True, stdout=PIPE).stdout + + m = re.search(r"/Volumes/(.+$)", output) + disk_root = m.group(0) + + print("+ Applying fancy settings +") + + bg_path = os.path.join(disk_root, ".background", os.path.basename('background.tiff')) + os.mkdir(os.path.dirname(bg_path)) + if verbose: + print('background.tiff', "->", bg_path) + shutil.copy2('background.tiff', bg_path) + + os.symlink("/Applications", os.path.join(disk_root, "Applications")) + + print("+ Finalizing .dmg disk image +") + + run(["hdiutil", "detach", f"/Volumes/{appname}"], universal_newlines=True) + + run(["hdiutil", "convert", tempname, "-format", "UDZO", "-o", appname, "-imagekey", "zlib-level=9"], check=True, universal_newlines=True) + + os.unlink(tempname) # ------------------------------------------------ -if verbose >= 2: - print("+ Done +") +print("+ Done +") sys.exit(0) diff --git a/contrib/message-capture/message-capture-docs.md b/contrib/message-capture/message-capture-docs.md new file mode 100644 index 0000000000..7301968461 --- /dev/null +++ b/contrib/message-capture/message-capture-docs.md @@ -0,0 +1,25 @@ +# Per-Peer Message Capture + +## Purpose + +This feature allows for message capture on a per-peer basis. It answers the simple question: "Can I see what messages my node is sending and receiving?" + +## Usage and Functionality + +* Run `bitcoind` with the `-capturemessages` option. +* Look in the `message_capture` folder in your datadir. + * Typically this will be `~/.bitcoin/message_capture`. + * See that there are many folders inside, one for each peer names with its IP address and port. + * Inside each peer's folder there are two `.dat` files: one is for received messages (`msgs_recv.dat`) and the other is for sent messages (`msgs_sent.dat`). +* Run `contrib/message-capture/message-capture-parser.py` with the proper arguments. + * See the `-h` option for help. + * To see all messages, both sent and received, for all peers use: + ``` + ./contrib/message-capture/message-capture-parser.py -o out.json \ + ~/.bitcoin/message_capture/**/*.dat + ``` + * Note: The messages in the given `.dat` files will be interleaved in chronological order. So, giving both received and sent `.dat` files (as above with `*.dat`) will result in all messages being interleaved in chronological order. + * If an output file is not provided (i.e. the `-o` option is not used), then the output prints to `stdout`. +* View the resulting output. + * The output file is `JSON` formatted. + * Suggestion: use `jq` to view the output, with `jq . out.json` diff --git a/contrib/message-capture/message-capture-parser.py b/contrib/message-capture/message-capture-parser.py new file mode 100755 index 0000000000..9988478f1b --- /dev/null +++ b/contrib/message-capture/message-capture-parser.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Parse message capture binary files. To be used in conjunction with -capturemessages.""" + +import argparse +import os +import shutil +import sys +from io import BytesIO +import json +from pathlib import Path +from typing import Any, List, Optional + +sys.path.append(os.path.join(os.path.dirname(__file__), '../../test/functional')) + +from test_framework.messages import ser_uint256 # noqa: E402 +from test_framework.p2p import MESSAGEMAP # noqa: E402 + +TIME_SIZE = 8 +LENGTH_SIZE = 4 +MSGTYPE_SIZE = 12 + +# The test framework classes stores hashes as large ints in many cases. +# These are variables of type uint256 in core. +# There isn't a way to distinguish between a large int and a large int that is actually a blob of bytes. +# As such, they are itemized here. +# Any variables with these names that are of type int are actually uint256 variables. +# (These can be easily found by looking for calls to deser_uint256, deser_uint256_vector, and uint256_from_str in messages.py) +HASH_INTS = [ + "blockhash", + "block_hash", + "hash", + "hashMerkleRoot", + "hashPrevBlock", + "hashstop", + "prev_header", + "sha256", + "stop_hash", +] + +HASH_INT_VECTORS = [ + "hashes", + "headers", + "vHave", + "vHash", +] + + +class ProgressBar: + def __init__(self, total: float): + self.total = total + self.running = 0 + + def set_progress(self, progress: float): + cols = shutil.get_terminal_size()[0] + if cols <= 12: + return + max_blocks = cols - 9 + num_blocks = int(max_blocks * progress) + print('\r[ {}{} ] {:3.0f}%' + .format('#' * num_blocks, + ' ' * (max_blocks - num_blocks), + progress * 100), + end ='') + + def update(self, more: float): + self.running += more + self.set_progress(self.running / self.total) + + +def to_jsonable(obj: Any) -> Any: + if hasattr(obj, "__dict__"): + return obj.__dict__ + elif hasattr(obj, "__slots__"): + ret = {} # type: Any + for slot in obj.__slots__: + val = getattr(obj, slot, None) + if slot in HASH_INTS and isinstance(val, int): + ret[slot] = ser_uint256(val).hex() + elif slot in HASH_INT_VECTORS and isinstance(val[0], int): + ret[slot] = [ser_uint256(a).hex() for a in val] + else: + ret[slot] = to_jsonable(val) + return ret + elif isinstance(obj, list): + return [to_jsonable(a) for a in obj] + elif isinstance(obj, bytes): + return obj.hex() + else: + return obj + + +def process_file(path: str, messages: List[Any], recv: bool, progress_bar: Optional[ProgressBar]) -> None: + with open(path, 'rb') as f_in: + if progress_bar: + bytes_read = 0 + + while True: + if progress_bar: + # Update progress bar + diff = f_in.tell() - bytes_read - 1 + progress_bar.update(diff) + bytes_read = f_in.tell() - 1 + + # Read the Header + tmp_header_raw = f_in.read(TIME_SIZE + LENGTH_SIZE + MSGTYPE_SIZE) + if not tmp_header_raw: + break + tmp_header = BytesIO(tmp_header_raw) + time = int.from_bytes(tmp_header.read(TIME_SIZE), "little") # type: int + msgtype = tmp_header.read(MSGTYPE_SIZE).split(b'\x00', 1)[0] # type: bytes + length = int.from_bytes(tmp_header.read(LENGTH_SIZE), "little") # type: int + + # Start converting the message to a dictionary + msg_dict = {} + msg_dict["direction"] = "recv" if recv else "sent" + msg_dict["time"] = time + msg_dict["size"] = length # "size" is less readable here, but more readable in the output + + msg_ser = BytesIO(f_in.read(length)) + + # Determine message type + if msgtype not in MESSAGEMAP: + # Unrecognized message type + try: + msgtype_tmp = msgtype.decode() + if not msgtype_tmp.isprintable(): + raise UnicodeDecodeError + msg_dict["msgtype"] = msgtype_tmp + except UnicodeDecodeError: + msg_dict["msgtype"] = "UNREADABLE" + msg_dict["body"] = msg_ser.read().hex() + msg_dict["error"] = "Unrecognized message type." + messages.append(msg_dict) + print(f"WARNING - Unrecognized message type {msgtype} in {path}", file=sys.stderr) + continue + + # Deserialize the message + msg = MESSAGEMAP[msgtype]() + msg_dict["msgtype"] = msgtype.decode() + + try: + msg.deserialize(msg_ser) + except KeyboardInterrupt: + raise + except Exception: + # Unable to deserialize message body + msg_ser.seek(0, os.SEEK_SET) + msg_dict["body"] = msg_ser.read().hex() + msg_dict["error"] = "Unable to deserialize message." + messages.append(msg_dict) + print(f"WARNING - Unable to deserialize message in {path}", file=sys.stderr) + continue + + # Convert body of message into a jsonable object + if length: + msg_dict["body"] = to_jsonable(msg) + messages.append(msg_dict) + + if progress_bar: + # Update the progress bar to the end of the current file + # in case we exited the loop early + f_in.seek(0, os.SEEK_END) # Go to end of file + diff = f_in.tell() - bytes_read - 1 + progress_bar.update(diff) + + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, + epilog="EXAMPLE \n\t{0} -o out.json /message_capture/**/*.dat".format(sys.argv[0]), + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument( + "capturepaths", + nargs='+', + help="binary message capture files to parse.") + parser.add_argument( + "-o", "--output", + help="output file. If unset print to stdout") + parser.add_argument( + "-n", "--no-progress-bar", + action='store_true', + help="disable the progress bar. Automatically set if the output is not a terminal") + args = parser.parse_args() + capturepaths = [Path.cwd() / Path(capturepath) for capturepath in args.capturepaths] + output = Path.cwd() / Path(args.output) if args.output else False + use_progress_bar = (not args.no_progress_bar) and sys.stdout.isatty() + + messages = [] # type: List[Any] + if use_progress_bar: + total_size = sum(capture.stat().st_size for capture in capturepaths) + progress_bar = ProgressBar(total_size) + else: + progress_bar = None + + for capture in capturepaths: + process_file(str(capture), messages, "recv" in capture.stem, progress_bar) + + messages.sort(key=lambda msg: msg['time']) + + if use_progress_bar: + progress_bar.set_progress(1) + + jsonrep = json.dumps(messages) + if output: + with open(str(output), 'w+', encoding="utf8") as f_out: + f_out.write(jsonrep) + else: + print(jsonrep) + +if __name__ == "__main__": + main() diff --git a/contrib/qos/README.md b/contrib/qos/README.md index 5e0a975fc6..2bb2a13db3 100644 --- a/contrib/qos/README.md +++ b/contrib/qos/README.md @@ -1,5 +1,5 @@ -### Qos ### +### QoS (Quality of service) ### -This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitcoin network. It limits outbound TCP traffic with a source or destination port of 8333, but not if the destination IP is within a LAN (defined as 192.168.x.x). +This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Blackcoin network. It limits outbound TCP traffic with a source or destination port of 15714, but not if the destination IP is within a LAN (defined as 192.168.x.x). -This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it. +This means one can have an always-on blackmored instance running, and another local blackmored/blackmore-qt instance which connects to this node and receives blocks from it. diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh index aaf5e1fa11..bc9c9e0502 100644 --- a/contrib/qos/tc.sh +++ b/contrib/qos/tc.sh @@ -1,17 +1,22 @@ -# Copyright (c) 2013 The Bitcoin Core developers +#!/usr/bin/env bash +# +# Copyright (c) 2017-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. +export LC_ALL=C #network interface on which to limit traffic IF="eth0" #limit of the network interface in question LINKCEIL="1gbit" #limit outbound Bitcoin protocol traffic to this rate LIMIT="160kbit" -#defines the address space for which you wish to disable rate limiting -LOCALNET="192.168.0.0/16" +#defines the IPv4 address space for which you wish to disable rate limiting +LOCALNET_V4="192.168.0.0/16" +#defines the IPv6 address space for which you wish to disable rate limiting +LOCALNET_V6="fe80::/10" -#delete existing rules +#delete existing rules ('Error: Cannot delete qdisc with handle of zero.' means there weren't any.) tc qdisc del dev ${IF} root #add root class @@ -28,6 +33,12 @@ tc class add dev ${IF} parent 1:1 classid 1:11 htb rate ${LIMIT} ceil ${LIMIT} p tc filter add dev ${IF} parent 1: protocol ip prio 1 handle 1 fw classid 1:10 tc filter add dev ${IF} parent 1: protocol ip prio 2 handle 2 fw classid 1:11 +if [ -n "${LOCALNET_V6}" ] ; then + # v6 cannot have the same priority value as v4 + tc filter add dev ${IF} parent 1: protocol ipv6 prio 3 handle 1 fw classid 1:10 + tc filter add dev ${IF} parent 1: protocol ipv6 prio 4 handle 2 fw classid 1:11 +fi + #delete any existing rules #disable for now #ret=0 @@ -37,9 +48,15 @@ tc filter add dev ${IF} parent 1: protocol ip prio 2 handle 2 fw classid 1:11 #done #limit outgoing traffic to and from port 8333. but not when dealing with a host on the local network -# (defined by $LOCALNET) -# --set-mark marks packages matching these criteria with the number "2" -# these packages are filtered by the tc filter with "handle 2" +# (defined by $LOCALNET_V4 and $LOCALNET_V6) +# --set-mark marks packages matching these criteria with the number "2" (v4) +# --set-mark marks packages matching these criteria with the number "4" (v6) +# these packets are filtered by the tc filter with "handle 2" # this filter sends the packages into the 1:11 class, and this class is limited to ${LIMIT} -iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET} -j MARK --set-mark 0x2 -iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET} -j MARK --set-mark 0x2 +iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 15714 ! -d ${LOCALNET_V4} -j MARK --set-mark 0x2 +iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 15714 ! -d ${LOCALNET_V4} -j MARK --set-mark 0x2 + +if [ -n "${LOCALNET_V6}" ] ; then + ip6tables -t mangle -A OUTPUT -p tcp -m tcp --dport 15714 ! -d ${LOCALNET_V6} -j MARK --set-mark 0x4 + ip6tables -t mangle -A OUTPUT -p tcp -m tcp --sport 15714 ! -d ${LOCALNET_V6} -j MARK --set-mark 0x4 +fi diff --git a/contrib/rpm/README.md b/contrib/rpm/README.md deleted file mode 100644 index aecb3ba84f..0000000000 --- a/contrib/rpm/README.md +++ /dev/null @@ -1,185 +0,0 @@ -RPM Spec File Notes -------------------- - -The RPM spec file provided here is for Bitcoin-Core 0.12.0 and builds on CentOS -7 with either the CentOS provided OpenSSL library or with LibreSSL as packaged -at [LibreLAMP.com](https://librelamp.com/). It should hopefully not be too -difficult to port the RPM spec file to most RPM based Linux distributions. - -When porting the spec file to build for a particular distribution, there are -some important notes. - -## Sources - -It is considered good form for all sources to reference a URL where the source -can be downloaded. - -Sources 0-9 should be reserved for source code tarballs. `Source0` should -reference the release tarball available from https://bitcoin.org/bin/ and -`Source1` should reference the BerkeleyDB source. - -Sources 10-99 are for source files that are maintained in the -[Bitcoin git repository](https://github.com/bitcoin/bitcoin) but are not part of -the release tarball. Most of these will reside in the `contrib` sub-directory. - -Sources 10-19 should be reserved for miscellaneous configuration files. -Currently only `Source10` is used, for the example `bitcoin.conf` file. - -Sources 20-29 should be reserved for man pages. Currently only `Source20` -through `Source23` are used. - -Sources 30-39 should be reserved for SELinux related files. Currently only -`Source30` through `Source32` are used. Until those files are in a tagged -release, the full URL specified in the RPM spec file will not work. You can get -them from the git ropository where you retrieved this file. - -Sources 100+ are for files that are not source tarballs and are not maintained -in the bitcoin git repository. At present only an SVG version of the Bitcoin -icon is used. - -## Patches - -In general, patches should be avoided. When a packager feels a patch is -necessary, the packager should bring the problem to the attention of the bitcoin -developers so that an official fix to the issue can make it into the next -release. - -### Patch0 bitcoin-0.12.0-libressl.patch - -This patch is only needed if building against LibreSSL. LibreSSL is not the -standard TLS library on most Linux distributions. The patch will likely not be -needed when 0.12.1 is released, a proper fix is already in the Bitcoin git -master branch. - -## BuildRequires - -The packages specified in the `BuildRequires` are specified according to the -package naming convention currently used in CentOS 7 and EPEL for CentOS 7. You -may need to change some of the package names for other distributions. This is -most likely to be the case with the Qt packages. - -## BerkeleyDB - -The `build-unix.md` file recommends building against BerkeleyDB 4.8.30. Even if -that is the version your Linux distribution ships with, it probably is a good -idea to build Bitcoin Core against a static version of that library compiled -according to the instructions in the `build-unix.md` file so that any changes -the distribution may make in the future will not result in a problem for users. - -The problem that can exist, clients built against different versions of -BerkeleyDB may not be able read each other's `wallet.dat` file which can make it -difficult for a user to recover from backup in the event of a system failure. - -## Graphical User Interface and Qt Version - -The RPM spec file will by default build the GUI client linked against the Qt5 -libraries. If you wish instead to link against the Qt4 libraries you need to -pass the switch `-D '_use_qt4 1'` at build time to the `rpmbuild` or `mock` -command used to build the packages. - -If you would prefer not to build the GUI at all, you can pass the switch -`-D '_no_gui 1'` to the `rpmbuild` or `mock` build command. - -## Desktop and KDE Files - -The desktop and KDE meta files are created in the spec file itself with the -`cat` command. This is done to allow easy distribution specific changes without -needing to use any patches. A specific time stamp is given to the files so that -it does not they do not appear to have been updated every time the package is -built. If you do make changes to them, you probably should update time stamp -assigned to them in the `touch` command that specifies the time stamp. - -## SVG, PNG, and XPM Icons - -The `bitcoin.svg` file is from the source listed as `Source100`. It is used as -the source for the PNG and XPM files. The generated PNG and XPM files are given -the same time stamp as the source SVG file as a means of indicating they are -derived from it. - -## Systemd - -This spec file assumes the target distribution uses systemd. That really only -matters for the `bitcoin-server` package. At this point, most RPM based -distributions that still receive vendor updates do in fact use systemd. - -The files to control the service are created in the RPM spec file itself using -the `cat` command. This is done to make it easy to modify for other -distributions that may implement things differently without needing to patch -source. A specific time stamp is given to the files so that they do not appear -to have been updated every time the package is built. If you do make changes to -them, you probably should update the time stamp assigned to them in the `touch` -command that specifies the time stamp. - -## SELinux - -The `bitcoin-server` package should have SELinux support. How to properly do -that *may* vary by distribution and version of distribution. - -The SELinux stuff in this RPM spec file *should* be correct for CentOS, RHEL, -and Fedora but it would be a good idea to review it before building the package -on other distributions. - -## Tests - -The `%check` section takes a very long time to run. If your build system has a -time limit for package build, you may need to make an exception for this -package. On CentOS 7 the `%check` section completes successfully with both -OpenSSL and LibreSSL, a failure really does mean something is wrong. - -## LibreSSL Build Notes - -To build against LibreSSL you will need to pass the switch -`-D '_use_libressl 1'` to the `rpmbuild` or `mock` command or the spec file will -want the OpenSSL development files. - -### LibreSSL and Boost - -LibreSSL (and some newer builds of OpenSSL) do not have support for SSLv3. This -can cause issues with the Boost package if the Boost package has not been -patched accordingly. On those distributions, you will either need to build -Bitcoin-Core against OpenSSL or use a patched version of Boost in the build -system. - -As SSLv3 is no longer safe, distributions that have not patched Boost to work -with TLS libraries that do not support SSLv3 should have bug reports filed -against the Boost package. This bug report has already been filed for RHEL 7 but -it may need to be filed for other distributions. - -A patch for Boost: https://github.com/boostorg/asio/pull/23/files - -## ZeroMQ - -At this time, this RPM spec file does not support the ZeroMQ build options. A -suitable version of ZeroMQ is not available for the platform this spec file was -developed on (CentOS 7). - -## Legacy Credit - -This RPM spec file is largely based upon the work of Michael Hampton at -[Ringing Liberty](https://www.ringingliberty.com/bitcoin/). He has been -packaging Bitcoin for Fedora at least since 2012. - -Most of the differences between his packaging and this package are stylistic in -nature. The major differences: - -1. He builds from a github tagged release rather than a release tarball. This -should not result in different source code. - -2. He does not build BerkeleyDB but instead uses the BerkeleyDB provided by the -Linux distribution. For the distributions he packages for, they currently all -use the same version of BerkeleyDB so that difference is *probably* just -academic. - -3. As of his 10.11.2 package he did not allow for building against LibreSSL, -specifying a build without the Qt GUI, or specifying which version of the Qt -libraries to use. - -4. I renamed the `bitcoin` package that contains the Qt GUI to `bitcoin-core` as -that appears to be how the general population refers to it, in contrast to -`bitcoin-xt` or `bitcoin-classic`. I wanted to make sure the general population -knows what they are getting when installing the GUI package. - -As far as minor differences, I generally prefer to assign the file permissions -in the `%files` portion of an RPM spec file rather than specifying the -permissions of a file during `%install` and other minor things like that that -are largely just cosmetic. diff --git a/contrib/rpm/bitcoin-0.12.0-libressl.patch b/contrib/rpm/bitcoin-0.12.0-libressl.patch deleted file mode 100644 index 555614a06d..0000000000 --- a/contrib/rpm/bitcoin-0.12.0-libressl.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -ur bitcoin-0.12.0.orig/src/init.cpp bitcoin-0.12.0/src/init.cpp ---- bitcoin-0.12.0.orig/src/init.cpp 2015-12-31 16:00:00.000000000 -0800 -+++ bitcoin-0.12.0/src/init.cpp 2016-02-23 06:03:47.133227757 -0800 -@@ -1075,7 +1075,7 @@ - if (fPrintToDebugLog) - OpenDebugLog(); - --#if (OPENSSL_VERSION_NUMBER < 0x10100000L) -+#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L) - LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); - #else - LogPrintf("Using OpenSSL version %s\n", OpenSSL_version(OPENSSL_VERSION)); -diff -ur bitcoin-0.12.0.orig/src/qt/rpcconsole.cpp bitcoin-0.12.0/src/qt/rpcconsole.cpp ---- bitcoin-0.12.0.orig/src/qt/rpcconsole.cpp 2015-12-31 16:00:00.000000000 -0800 -+++ bitcoin-0.12.0/src/qt/rpcconsole.cpp 2016-02-23 15:09:42.881126841 -0800 -@@ -264,7 +264,7 @@ - - // set library version labels - --#if (OPENSSL_VERSION_NUMBER < 0x10100000L) -+#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L) - ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); - #else - ui->openSSLVersion->setText(OpenSSL_version(OPENSSL_VERSION)); diff --git a/contrib/rpm/bitcoin.fc b/contrib/rpm/bitcoin.fc deleted file mode 100644 index 6f5eef6375..0000000000 --- a/contrib/rpm/bitcoin.fc +++ /dev/null @@ -1,8 +0,0 @@ -/usr/bin/bitcoin-cli -- gen_context(system_u:object_r:bitcoin_exec_t,s0) -/usr/sbin/bitcoind -- gen_context(system_u:object_r:bitcoin_exec_t,s0) -/usr/lib(64)?/bitcoin/bitcoind -- gen_context(system_u:object_r:bitcoin_exec_t,s0) - -/etc/bitcoin(/.*)? gen_context(system_u:object_r:bitcoin_conf_t,s0) -/var/lib/bitcoin(/.*)? gen_context(system_u:object_r:bitcoin_var_lib_t,s0) - -(/var)?/run/bitcoind(/.*)? gen_context(system_u:object_r:bitcoin_var_run_t,s0) diff --git a/contrib/rpm/bitcoin.if b/contrib/rpm/bitcoin.if deleted file mode 100644 index 2b096c24dc..0000000000 --- a/contrib/rpm/bitcoin.if +++ /dev/null @@ -1,157 +0,0 @@ - -## policy for bitcoin - - -######################################## -## -## Transition to bitcoin. -## -## -## -## Domain allowed to transition. -## -## -# -interface(`bitcoin_domtrans',` - gen_require(` - type bitcoin_t, bitcoin_exec_t; - ') - - corecmd_search_bin($1) - domtrans_pattern($1, bitcoin_exec_t, bitcoin_t) -') - - -######################################## -## -## Execute bitcoin server in the bitcoin domain. -## -## -## -## Domain allowed access. -## -## -# -interface(`bitcoin_initrc_domtrans',` - gen_require(` - type bitcoin_initrc_exec_t; - ') - - init_labeled_script_domtrans($1, bitcoin_initrc_exec_t) -') - - -######################################## -## -## Search bitcoin lib directories. -## -## -## -## Domain allowed access. -## -## -# -interface(`bitcoin_search_lib',` - gen_require(` - type bitcoin_var_lib_t; - ') - - allow $1 bitcoin_var_lib_t:dir search_dir_perms; - files_search_var_lib($1) -') - -######################################## -## -## Read bitcoin lib files. -## -## -## -## Domain allowed access. -## -## -# -interface(`bitcoin_read_lib_files',` - gen_require(` - type bitcoin_var_lib_t; - ') - - files_search_var_lib($1) - read_files_pattern($1, bitcoin_var_lib_t, bitcoin_var_lib_t) -') - -######################################## -## -## Manage bitcoin lib files. -## -## -## -## Domain allowed access. -## -## -# -interface(`bitcoin_manage_lib_files',` - gen_require(` - type bitcoin_var_lib_t; - ') - - files_search_var_lib($1) - manage_files_pattern($1, bitcoin_var_lib_t, bitcoin_var_lib_t) -') - -######################################## -## -## Manage bitcoin lib directories. -## -## -## -## Domain allowed access. -## -## -# -interface(`bitcoin_manage_lib_dirs',` - gen_require(` - type bitcoin_var_lib_t; - ') - - files_search_var_lib($1) - manage_dirs_pattern($1, bitcoin_var_lib_t, bitcoin_var_lib_t) -') - - -######################################## -## -## All of the rules required to administrate -## an bitcoin environment -## -## -## -## Domain allowed access. -## -## -## -## -## Role allowed access. -## -## -## -# -interface(`bitcoin_admin',` - gen_require(` - type bitcoin_t; - type bitcoin_initrc_exec_t; - type bitcoin_var_lib_t; - ') - - allow $1 bitcoin_t:process { ptrace signal_perms }; - ps_process_pattern($1, bitcoin_t) - - bitcoin_initrc_domtrans($1) - domain_system_change_exemption($1) - role_transition $2 bitcoin_initrc_exec_t system_r; - allow $2 system_r; - - files_search_var_lib($1) - admin_pattern($1, bitcoin_var_lib_t) - -') - diff --git a/contrib/rpm/bitcoin.spec b/contrib/rpm/bitcoin.spec deleted file mode 100644 index 38ae038180..0000000000 --- a/contrib/rpm/bitcoin.spec +++ /dev/null @@ -1,444 +0,0 @@ -%define bdbv 4.8.30 -%global selinux_variants mls strict targeted - -%if 0%{?_no_gui:1} -%define _buildqt 0 -%define buildargs --with-gui=no -%else -%define _buildqt 1 -%if 0%{?_use_qt4} -%define buildargs --with-qrencode --with-gui=qt4 -%else -%define buildargs --with-qrencode --with-gui=qt5 -%endif -%endif - -Name: bitcoin -Version: 0.12.0 -Release: 2%{?dist} -Summary: Peer to Peer Cryptographic Currency - -Group: Applications/System -License: MIT -URL: https://bitcoin.org/ -Source0: https://bitcoin.org/bin/bitcoin-core-%{version}/bitcoin-%{version}.tar.gz -Source1: http://download.oracle.com/berkeley-db/db-%{bdbv}.NC.tar.gz - -Source10: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/examples/bitcoin.conf - -#man pages -Source20: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/manpages/bitcoind.1 -Source21: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/manpages/bitcoin-cli.1 -Source22: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/manpages/bitcoin-qt.1 -Source23: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/manpages/bitcoin.conf.5 - -#selinux -Source30: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.te -# Source31 - what about bitcoin-tx and bench_bitcoin ??? -Source31: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.fc -Source32: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.if - -Source100: https://upload.wikimedia.org/wikipedia/commons/4/46/Bitcoin.svg - -%if 0%{?_use_libressl:1} -BuildRequires: libressl-devel -%else -BuildRequires: openssl-devel -%endif -BuildRequires: boost-devel -BuildRequires: miniupnpc-devel -BuildRequires: autoconf automake libtool -BuildRequires: libevent-devel - - -Patch0: bitcoin-0.12.0-libressl.patch - - -%description -Bitcoin is a digital cryptographic currency that uses peer-to-peer technology to -operate with no central authority or banks; managing transactions and the -issuing of bitcoins is carried out collectively by the network. - -%if %{_buildqt} -%package core -Summary: Peer to Peer Cryptographic Currency -Group: Applications/System -Obsoletes: %{name} < %{version}-%{release} -Provides: %{name} = %{version}-%{release} -%if 0%{?_use_qt4} -BuildRequires: qt-devel -%else -BuildRequires: qt5-qtbase-devel -# for /usr/bin/lrelease-qt5 -BuildRequires: qt5-linguist -%endif -BuildRequires: protobuf-devel -BuildRequires: qrencode-devel -BuildRequires: %{_bindir}/desktop-file-validate -# for icon generation from SVG -BuildRequires: %{_bindir}/inkscape -BuildRequires: %{_bindir}/convert - -%description core -Bitcoin is a digital cryptographic currency that uses peer-to-peer technology to -operate with no central authority or banks; managing transactions and the -issuing of bitcoins is carried out collectively by the network. - -This package contains the Qt based graphical client and node. If you are looking -to run a Bitcoin wallet, this is probably the package you want. -%endif - - -%package libs -Summary: Bitcoin shared libraries -Group: System Environment/Libraries - -%description libs -This package provides the bitcoinconsensus shared libraries. These libraries -may be used by third party software to provide consensus verification -functionality. - -Unless you know need this package, you probably do not. - -%package devel -Summary: Development files for bitcoin -Group: Development/Libraries -Requires: %{name}-libs = %{version}-%{release} - -%description devel -This package contains the header files and static library for the -bitcoinconsensus shared library. If you are developing or compiling software -that wants to link against that library, then you need this package installed. - -Most people do not need this package installed. - -%package server -Summary: The bitcoin daemon -Group: System Environment/Daemons -Requires: bitcoin-utils = %{version}-%{release} -Requires: selinux-policy policycoreutils-python -Requires(pre): shadow-utils -Requires(post): %{_sbindir}/semodule %{_sbindir}/restorecon %{_sbindir}/fixfiles %{_sbindir}/sestatus -Requires(postun): %{_sbindir}/semodule %{_sbindir}/restorecon %{_sbindir}/fixfiles %{_sbindir}/sestatus -BuildRequires: systemd -BuildRequires: checkpolicy -BuildRequires: %{_datadir}/selinux/devel/Makefile - -%description server -This package provides a stand-alone bitcoin-core daemon. For most users, this -package is only needed if they need a full-node without the graphical client. - -Some third party wallet software will want this package to provide the actual -bitcoin-core node they use to connect to the network. - -If you use the graphical bitcoin-core client then you almost certainly do not -need this package. - -%package utils -Summary: Bitcoin utilities -Group: Applications/System - -%description utils -This package provides several command line utilities for interacting with a -bitcoin-core daemon. - -The bitcoin-cli utility allows you to communicate and control a bitcoin daemon -over RPC, the bitcoin-tx utility allows you to create a custom transaction, and -the bench_bitcoin utility can be used to perform some benchmarks. - -This package contains utilities needed by the bitcoin-server package. - - -%prep -%setup -q -%patch0 -p1 -b .libressl -cp -p %{SOURCE10} ./bitcoin.conf.example -tar -zxf %{SOURCE1} -cp -p db-%{bdbv}.NC/LICENSE ./db-%{bdbv}.NC-LICENSE -mkdir db4 SELinux -cp -p %{SOURCE30} %{SOURCE31} %{SOURCE32} SELinux/ - - -%build -CWD=`pwd` -cd db-%{bdbv}.NC/build_unix/ -../dist/configure --enable-cxx --disable-shared --with-pic --prefix=${CWD}/db4 -make install -cd ../.. - -./autogen.sh -%configure LDFLAGS="-L${CWD}/db4/lib/" CPPFLAGS="-I${CWD}/db4/include/" --with-miniupnpc --enable-glibc-back-compat %{buildargs} -make %{?_smp_mflags} - -pushd SELinux -for selinuxvariant in %{selinux_variants}; do - make NAME=${selinuxvariant} -f %{_datadir}/selinux/devel/Makefile - mv bitcoin.pp bitcoin.pp.${selinuxvariant} - make NAME=${selinuxvariant} -f %{_datadir}/selinux/devel/Makefile clean -done -popd - - -%install -make install DESTDIR=%{buildroot} - -mkdir -p -m755 %{buildroot}%{_sbindir} -mv %{buildroot}%{_bindir}/bitcoind %{buildroot}%{_sbindir}/bitcoind - -# systemd stuff -mkdir -p %{buildroot}%{_tmpfilesdir} -cat < %{buildroot}%{_tmpfilesdir}/bitcoin.conf -d /run/bitcoind 0750 bitcoin bitcoin - -EOF -touch -a -m -t 201504280000 %{buildroot}%{_tmpfilesdir}/bitcoin.conf - -mkdir -p %{buildroot}%{_sysconfdir}/sysconfig -cat < %{buildroot}%{_sysconfdir}/sysconfig/bitcoin -# Provide options to the bitcoin daemon here, for example -# OPTIONS="-testnet -disable-wallet" - -OPTIONS="" - -# System service defaults. -# Don't change these unless you know what you're doing. -CONFIG_FILE="%{_sysconfdir}/bitcoin/bitcoin.conf" -DATA_DIR="%{_localstatedir}/lib/bitcoin" -PID_FILE="/run/bitcoind/bitcoind.pid" -EOF -touch -a -m -t 201504280000 %{buildroot}%{_sysconfdir}/sysconfig/bitcoin - -mkdir -p %{buildroot}%{_unitdir} -cat < %{buildroot}%{_unitdir}/bitcoin.service -[Unit] -Description=Bitcoin daemon -After=syslog.target network.target - -[Service] -Type=forking -ExecStart=%{_sbindir}/bitcoind -daemon -conf=\${CONFIG_FILE} -datadir=\${DATA_DIR} -pid=\${PID_FILE} \$OPTIONS -EnvironmentFile=%{_sysconfdir}/sysconfig/bitcoin -User=bitcoin -Group=bitcoin - -Restart=on-failure -PrivateTmp=true -TimeoutStopSec=120 -TimeoutStartSec=60 -StartLimitInterval=240 -StartLimitBurst=5 - -[Install] -WantedBy=multi-user.target -EOF -touch -a -m -t 201504280000 %{buildroot}%{_unitdir}/bitcoin.service -#end systemd stuff - -mkdir %{buildroot}%{_sysconfdir}/bitcoin -mkdir -p %{buildroot}%{_localstatedir}/lib/bitcoin - -#SELinux -for selinuxvariant in %{selinux_variants}; do - install -d %{buildroot}%{_datadir}/selinux/${selinuxvariant} - install -p -m 644 SELinux/bitcoin.pp.${selinuxvariant} %{buildroot}%{_datadir}/selinux/${selinuxvariant}/bitcoin.pp -done - -%if %{_buildqt} -# qt icons -install -D -p share/pixmaps/bitcoin.ico %{buildroot}%{_datadir}/pixmaps/bitcoin.ico -install -p share/pixmaps/nsis-header.bmp %{buildroot}%{_datadir}/pixmaps/ -install -p share/pixmaps/nsis-wizard.bmp %{buildroot}%{_datadir}/pixmaps/ -install -p %{SOURCE100} %{buildroot}%{_datadir}/pixmaps/bitcoin.svg -%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin16.png -w16 -h16 -%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin32.png -w32 -h32 -%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin64.png -w64 -h64 -%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin128.png -w128 -h128 -%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin256.png -w256 -h256 -%{_bindir}/convert -resize 16x16 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin16.xpm -%{_bindir}/convert -resize 32x32 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin32.xpm -%{_bindir}/convert -resize 64x64 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin64.xpm -%{_bindir}/convert -resize 128x128 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin128.xpm -%{_bindir}/convert %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin256.xpm -touch %{buildroot}%{_datadir}/pixmaps/*.png -r %{SOURCE100} -touch %{buildroot}%{_datadir}/pixmaps/*.xpm -r %{SOURCE100} - -# Desktop File - change the touch timestamp if modifying -mkdir -p %{buildroot}%{_datadir}/applications -cat < %{buildroot}%{_datadir}/applications/bitcoin-core.desktop -[Desktop Entry] -Encoding=UTF-8 -Name=Bitcoin -Comment=Bitcoin P2P Cryptocurrency -Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair -Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi -Exec=bitcoin-qt %u -Terminal=false -Type=Application -Icon=bitcoin128 -MimeType=x-scheme-handler/bitcoin; -Categories=Office;Finance; -EOF -# change touch date when modifying desktop -touch -a -m -t 201511100546 %{buildroot}%{_datadir}/applications/bitcoin-core.desktop -%{_bindir}/desktop-file-validate %{buildroot}%{_datadir}/applications/bitcoin-core.desktop - -# KDE protocol - change the touch timestamp if modifying -mkdir -p %{buildroot}%{_datadir}/kde4/services -cat < %{buildroot}%{_datadir}/kde4/services/bitcoin-core.protocol -[Protocol] -exec=bitcoin-qt '%u' -protocol=bitcoin -input=none -output=none -helper=true -listing= -reading=false -writing=false -makedir=false -deleting=false -EOF -# change touch date when modifying protocol -touch -a -m -t 201511100546 %{buildroot}%{_datadir}/kde4/services/bitcoin-core.protocol -%endif - -# man pages -install -D -p %{SOURCE20} %{buildroot}%{_mandir}/man1/bitcoind.1 -install -p %{SOURCE21} %{buildroot}%{_mandir}/man1/bitcoin-cli.1 -%if %{_buildqt} -install -p %{SOURCE22} %{buildroot}%{_mandir}/man1/bitcoin-qt.1 -%endif -install -D -p %{SOURCE23} %{buildroot}%{_mandir}/man5/bitcoin.conf.5 - -# nuke these, we do extensive testing of binaries in %%check before packaging -rm -f %{buildroot}%{_bindir}/test_* - -%check -make check -pushd src -srcdir=. test/bitcoin-util-test.py -popd -qa/pull-tester/rpc-tests.py -extended - -%post libs -p /sbin/ldconfig - -%postun libs -p /sbin/ldconfig - -%pre server -getent group bitcoin >/dev/null || groupadd -r bitcoin -getent passwd bitcoin >/dev/null || - useradd -r -g bitcoin -d /var/lib/bitcoin -s /sbin/nologin \ - -c "Bitcoin wallet server" bitcoin -exit 0 - -%post server -%systemd_post bitcoin.service -# SELinux -if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then -for selinuxvariant in %{selinux_variants}; do - %{_sbindir}/semodule -s ${selinuxvariant} -i %{_datadir}/selinux/${selinuxvariant}/bitcoin.pp &> /dev/null || : -done -%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 8332 -%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 8333 -%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 18332 -%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 18333 -%{_sbindir}/fixfiles -R bitcoin-server restore &> /dev/null || : -%{_sbindir}/restorecon -R %{_localstatedir}/lib/bitcoin || : -fi - -%posttrans server -%{_bindir}/systemd-tmpfiles --create - -%preun server -%systemd_preun bitcoin.service - -%postun server -%systemd_postun bitcoin.service -# SELinux -if [ $1 -eq 0 ]; then - if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then - %{_sbindir}/semanage port -d -p tcp 8332 - %{_sbindir}/semanage port -d -p tcp 8333 - %{_sbindir}/semanage port -d -p tcp 18332 - %{_sbindir}/semanage port -d -p tcp 18333 - for selinuxvariant in %{selinux_variants}; do - %{_sbindir}/semodule -s ${selinuxvariant} -r bitcoin &> /dev/null || : - done - %{_sbindir}/fixfiles -R bitcoin-server restore &> /dev/null || : - [ -d %{_localstatedir}/lib/bitcoin ] && \ - %{_sbindir}/restorecon -R %{_localstatedir}/lib/bitcoin &> /dev/null || : - fi -fi - -%clean -rm -rf %{buildroot} - -%if %{_buildqt} -%files core -%defattr(-,root,root,-) -%license COPYING db-%{bdbv}.NC-LICENSE -%doc COPYING bitcoin.conf.example doc/README.md doc/bips.md doc/files.md doc/multiwallet-qt.md doc/reduce-traffic.md doc/release-notes.md doc/tor.md -%attr(0755,root,root) %{_bindir}/bitcoin-qt -%attr(0644,root,root) %{_datadir}/applications/bitcoin-core.desktop -%attr(0644,root,root) %{_datadir}/kde4/services/bitcoin-core.protocol -%attr(0644,root,root) %{_datadir}/pixmaps/*.ico -%attr(0644,root,root) %{_datadir}/pixmaps/*.bmp -%attr(0644,root,root) %{_datadir}/pixmaps/*.svg -%attr(0644,root,root) %{_datadir}/pixmaps/*.png -%attr(0644,root,root) %{_datadir}/pixmaps/*.xpm -%attr(0644,root,root) %{_mandir}/man1/bitcoin-qt.1* -%endif - -%files libs -%defattr(-,root,root,-) -%license COPYING -%doc COPYING doc/README.md doc/shared-libraries.md -%{_libdir}/lib*.so.* - -%files devel -%defattr(-,root,root,-) -%license COPYING -%doc COPYING doc/README.md doc/developer-notes.md doc/shared-libraries.md -%attr(0644,root,root) %{_includedir}/*.h -%{_libdir}/*.so -%{_libdir}/*.a -%{_libdir}/*.la -%attr(0644,root,root) %{_libdir}/pkgconfig/*.pc - -%files server -%defattr(-,root,root,-) -%license COPYING db-%{bdbv}.NC-LICENSE -%doc COPYING bitcoin.conf.example doc/README.md doc/REST-interface.md doc/bips.md doc/dnsseed-policy.md doc/files.md doc/reduce-traffic.md doc/release-notes.md doc/tor.md -%attr(0755,root,root) %{_sbindir}/bitcoind -%attr(0644,root,root) %{_tmpfilesdir}/bitcoin.conf -%attr(0644,root,root) %{_unitdir}/bitcoin.service -%dir %attr(0750,bitcoin,bitcoin) %{_sysconfdir}/bitcoin -%dir %attr(0750,bitcoin,bitcoin) %{_localstatedir}/lib/bitcoin -%config(noreplace) %attr(0600,root,root) %{_sysconfdir}/sysconfig/bitcoin -%attr(0644,root,root) %{_datadir}/selinux/*/*.pp -%attr(0644,root,root) %{_mandir}/man1/bitcoind.1* -%attr(0644,root,root) %{_mandir}/man5/bitcoin.conf.5* - -%files utils -%defattr(-,root,root,-) -%license COPYING -%doc COPYING bitcoin.conf.example doc/README.md -%attr(0755,root,root) %{_bindir}/bitcoin-cli -%attr(0755,root,root) %{_bindir}/bitcoin-tx -%attr(0755,root,root) %{_bindir}/bench_bitcoin -%attr(0644,root,root) %{_mandir}/man1/bitcoin-cli.1* -%attr(0644,root,root) %{_mandir}/man5/bitcoin.conf.5* - - - -%changelog -* Fri Feb 26 2016 Alice Wonder - 0.12.0-2 -- Rename Qt package from bitcoin to bitcoin-core -- Make building of the Qt package optional -- When building the Qt package, default to Qt5 but allow building -- against Qt4 -- Only run SELinux stuff in post scripts if it is not set to disabled - -* Wed Feb 24 2016 Alice Wonder - 0.12.0-1 -- Initial spec file for 0.12.0 release - -# This spec file is written from scratch but a lot of the packaging decisions are directly -# based upon the 0.11.2 package spec file from https://www.ringingliberty.com/bitcoin/ diff --git a/contrib/rpm/bitcoin.te b/contrib/rpm/bitcoin.te deleted file mode 100644 index d6231c591a..0000000000 --- a/contrib/rpm/bitcoin.te +++ /dev/null @@ -1,81 +0,0 @@ -policy_module(bitcoin, 1.100.1) - -######################################## -# -# Declarations -# - -type bitcoin_t; -type bitcoin_exec_t; -init_daemon_domain(bitcoin_t, bitcoin_exec_t) - -permissive bitcoin_t; - -type bitcoin_initrc_exec_t; -init_script_file(bitcoin_initrc_exec_t) - -type bitcoin_conf_t; -files_type(bitcoin_conf_t) - -type bitcoin_var_lib_t; -files_type(bitcoin_var_lib_t) - -type bitcoin_var_run_t; -files_type(bitcoin_var_run_t) - -type bitcoin_port_t; -corenet_port(bitcoin_port_t) - -######################################## -# -# bitcoin local policy -# -allow bitcoin_t self:process { fork }; - -allow bitcoin_t self:fifo_file rw_fifo_file_perms; -allow bitcoin_t self:unix_stream_socket create_stream_socket_perms; - -manage_dirs_pattern(bitcoin_t, bitcoin_conf_t, bitcoin_conf_t) -manage_files_pattern(bitcoin_t, bitcoin_conf_t, bitcoin_conf_t) - -manage_dirs_pattern(bitcoin_t, bitcoin_var_lib_t, bitcoin_var_lib_t) -manage_files_pattern(bitcoin_t, bitcoin_var_lib_t, bitcoin_var_lib_t) -files_var_lib_filetrans(bitcoin_t, bitcoin_var_lib_t, { dir file }) - -manage_dirs_pattern(bitcoin_t, bitcoin_var_run_t, bitcoin_var_run_t) -manage_files_pattern(bitcoin_t, bitcoin_var_run_t, bitcoin_var_run_t) - -sysnet_dns_name_resolve(bitcoin_t) -corenet_all_recvfrom_unlabeled(bitcoin_t) - -allow bitcoin_t self:tcp_socket create_stream_socket_perms; -corenet_tcp_sendrecv_generic_if(bitcoin_t) -corenet_tcp_sendrecv_generic_node(bitcoin_t) -corenet_tcp_sendrecv_all_ports(bitcoin_t) -corenet_tcp_bind_generic_node(bitcoin_t) - -gen_require(` - type bitcoin_port_t; -') -allow bitcoin_t bitcoin_port_t:tcp_socket name_bind; - -gen_require(` - type bitcoin_port_t; -') -allow bitcoin_t bitcoin_port_t:tcp_socket name_connect; - -domain_use_interactive_fds(bitcoin_t) - -files_read_etc_files(bitcoin_t) - -miscfiles_read_localization(bitcoin_t) - -sysnet_dns_name_resolve(bitcoin_t) - -allow bitcoin_t bitcoin_exec_t:file execute_no_trans; -allow bitcoin_t self:process setsched; -corecmd_exec_ls(bitcoin_t) -corenet_tcp_connect_http_port(bitcoin_t) -dev_read_urand(bitcoin_t) -fs_getattr_xattr_fs(bitcoin_t) -kernel_read_system_state(bitcoin_t) diff --git a/contrib/seeds/.gitignore b/contrib/seeds/.gitignore new file mode 100644 index 0000000000..e4a39d6093 --- /dev/null +++ b/contrib/seeds/.gitignore @@ -0,0 +1 @@ +seeds_main.txt diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt index be3ae9da6d..27f35f3c8d 100644 --- a/contrib/seeds/nodes_main.txt +++ b/contrib/seeds/nodes_main.txt @@ -1,43 +1,46 @@ # List of fixed seed nodes for main network # IPv4 nodes -85.144.252.98 -72.216.145.112 +77.251.84.75 +95.217.78.81 +188.126.6.32 +42.192.85.218 +161.97.80.103 +213.114.228.96 +70.173.238.229 +152.228.187.235 +89.142.64.85 +45.95.65.173 +69.173.197.127 73.53.78.243 -164.68.105.69 +58.104.41.118 +81.69.250.50 +94.130.176.201 +199.241.187.130 116.203.82.109 -166.70.54.40 +72.66.45.15 +81.162.122.67 +103.243.173.214 103.243.173.210 -37.72.70.152 -94.130.176.201 -178.254.1.135 -76.171.209.195 -78.56.242.6 -89.142.77.30 -95.217.78.81 -89.22.251.238 -178.254.32.145 -207.148.13.250 -67.193.26.71 -108.173.237.207 -84.254.43.119 -203.213.94.242 -175.36.186.152 -83.78.240.202 -94.226.129.128 -76.17.131.175 -188.126.6.32 -202.142.52.235 -46.10.52.145 -24.245.110.168 -82.217.127.4 -144.91.84.145 +51.9.245.110 +162.157.171.12 +94.231.253.146 +178.254.34.173 +95.43.111.139 +98.250.175.53 +60.108.92.175 +84.249.4.71 +123.243.225.37 +161.81.69.13 +71.211.77.89 +88.207.82.15 # IPv6 nodes -[2a01:4f9:4a:1dee::2] -[2603:7000:ac40:1a6a:9535:aeeb:7135:eb4] -[2a01:d0:ffff:7094::2] -[2603:7000:ac40:1a6a:ec26:13df:e973:b124] +2a10:3781:525:6::11 +2a10:3781:525:6::12 +2a10:3781:525:6::190 +2a01:4f9:4a:1dee::2 +2001:b011:7004:88f2:987e:30b4:53c:21b # Onion nodes vtrlmv3zqqqnfwfy.onion diff --git a/contrib/seeds/nodes_test.txt b/contrib/seeds/nodes_test.txt index 93a6f17834..b94b654510 100644 --- a/contrib/seeds/nodes_test.txt +++ b/contrib/seeds/nodes_test.txt @@ -1,9 +1,11 @@ # List of fixed seed nodes for testnet # IPv4 nodes -85.144.252.98 -51.15.112.23 -97.113.73.134 +45.95.65.173 +161.97.80.10 +173.249.22.241 +164.68.105.69 # IPv6 nodes -[2a01:4f9:4a:1dee::2] \ No newline at end of file +2a10:3781:525:6::11 +2a10:3781:525:6::12 \ No newline at end of file diff --git a/contrib/shell/git-utils.bash b/contrib/shell/git-utils.bash new file mode 100644 index 0000000000..37bac1f38d --- /dev/null +++ b/contrib/shell/git-utils.bash @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +git_root() { + git rev-parse --show-toplevel 2> /dev/null +} + +git_head_version() { + local recent_tag + if recent_tag="$(git describe --exact-match HEAD 2> /dev/null)"; then + echo "${recent_tag#v}" + else + git rev-parse --short=12 HEAD + fi +} diff --git a/contrib/shell/realpath.bash b/contrib/shell/realpath.bash new file mode 100644 index 0000000000..389b77b562 --- /dev/null +++ b/contrib/shell/realpath.bash @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# Based on realpath.sh written by Michael Kropat +# Found at: https://github.com/mkropat/sh-realpath/blob/65512368b8155b176b67122aa395ac580d9acc5b/realpath.sh + +bash_realpath() { + canonicalize_path "$(resolve_symlinks "$1")" +} + +resolve_symlinks() { + _resolve_symlinks "$1" +} + +_resolve_symlinks() { + _assert_no_path_cycles "$@" || return + + local dir_context path + if path=$(readlink -- "$1"); then + dir_context=$(dirname -- "$1") + _resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@" + else + printf '%s\n' "$1" + fi +} + +_prepend_dir_context_if_necessary() { + if [ "$1" = . ]; then + printf '%s\n' "$2" + else + _prepend_path_if_relative "$1" "$2" + fi +} + +_prepend_path_if_relative() { + case "$2" in + /* ) printf '%s\n' "$2" ;; + * ) printf '%s\n' "$1/$2" ;; + esac +} + +_assert_no_path_cycles() { + local target path + + target=$1 + shift + + for path in "$@"; do + if [ "$path" = "$target" ]; then + return 1 + fi + done +} + +canonicalize_path() { + if [ -d "$1" ]; then + _canonicalize_dir_path "$1" + else + _canonicalize_file_path "$1" + fi +} + +_canonicalize_dir_path() { + (cd "$1" 2>/dev/null && pwd -P) +} + +_canonicalize_file_path() { + local dir file + dir=$(dirname -- "$1") + file=$(basename -- "$1") + (cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file") +} diff --git a/contrib/spendfrom/spendfrom.py b/contrib/spendfrom/spendfrom.py index 086b91b267..d15799a0fc 100755 --- a/contrib/spendfrom/spendfrom.py +++ b/contrib/spendfrom/spendfrom.py @@ -10,7 +10,7 @@ # spendfrom.py # Lists available funds # spendfrom.py --from=ADDRESS --to=ADDRESS --amount=11.00 # -# Assumes it will talk to a bitcoind or Bitcoin-Qt running +# Assumes it will talk to a bitcoind or Blackmore-Qt running # on localhost. # # Depends on jsonrpc diff --git a/contrib/testgen/gen_key_io_test_vectors.py b/contrib/testgen/gen_key_io_test_vectors.py new file mode 100755 index 0000000000..87ca5fa314 --- /dev/null +++ b/contrib/testgen/gen_key_io_test_vectors.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python3 +# Copyright (c) 2012-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. +''' +Generate valid and invalid base58/bech32(m) address and private key test vectors. + +Usage: + PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py valid 70 > ../../src/test/data/key_io_valid.json + PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py invalid 70 > ../../src/test/data/key_io_invalid.json +''' +# 2012 Wladimir J. van der Laan +# Released under MIT License +import os +from itertools import islice +from base58 import b58encode_chk, b58decode_chk, b58chars, convertbits, CHARSET, Encoding +import random + +# key types +PUBKEY_ADDRESS = 48 +SCRIPT_ADDRESS = 5 +SCRIPT_ADDRESS2 = 50 +PUBKEY_ADDRESS_TEST = 111 +SCRIPT_ADDRESS_TEST = 196 +SCRIPT_ADDRESS_TEST2 = 58 +PUBKEY_ADDRESS_REGTEST = 111 +SCRIPT_ADDRESS_REGTEST = 196 +PRIVKEY = 176 +PRIVKEY_TEST = 239 +PRIVKEY_REGTEST = 239 + +# script +OP_0 = 0x00 +OP_1 = 0x51 +OP_2 = 0x52 +OP_3 = 0x53 +OP_16 = 0x60 +OP_DUP = 0x76 +OP_EQUAL = 0x87 +OP_EQUALVERIFY = 0x88 +OP_HASH160 = 0xa9 +OP_CHECKSIG = 0xac +pubkey_prefix = (OP_DUP, OP_HASH160, 20) +pubkey_suffix = (OP_EQUALVERIFY, OP_CHECKSIG) +script_prefix = (OP_HASH160, 20) +script_suffix = (OP_EQUAL,) +p2wpkh_prefix = (OP_0, 20) +p2wsh_prefix = (OP_0, 32) +p2tr_prefix = (OP_1, 32) + +metadata_keys = ['isPrivkey', 'chain', 'isCompressed', 'tryCaseFlip'] +# templates for valid sequences +templates = [ + # prefix, payload_size, suffix, metadata, output_prefix, output_suffix + # None = N/A + ((PUBKEY_ADDRESS,), 20, (), (False, 'main', None, None), pubkey_prefix, pubkey_suffix), + ((SCRIPT_ADDRESS,), 20, (), (False, 'main', None, None), script_prefix, script_suffix), + ((SCRIPT_ADDRESS2,), 20, (), (False, 'main', None, None), script_prefix, script_suffix), + ((PUBKEY_ADDRESS_TEST,), 20, (), (False, 'test', None, None), pubkey_prefix, pubkey_suffix), + ((SCRIPT_ADDRESS_TEST,), 20, (), (False, 'test', None, None), script_prefix, script_suffix), + ((SCRIPT_ADDRESS_TEST2,), 20, (), (False, 'test', None, None), script_prefix, script_suffix), + ((PUBKEY_ADDRESS_TEST,), 20, (), (False, 'signet', None, None), pubkey_prefix, pubkey_suffix), + ((SCRIPT_ADDRESS_TEST,), 20, (), (False, 'signet', None, None), script_prefix, script_suffix), + ((PUBKEY_ADDRESS_REGTEST,), 20, (), (False, 'regtest', None, None), pubkey_prefix, pubkey_suffix), + ((SCRIPT_ADDRESS_REGTEST,), 20, (), (False, 'regtest', None, None), script_prefix, script_suffix), + ((PRIVKEY,), 32, (), (True, 'main', False, None), (), ()), + ((PRIVKEY,), 32, (1,), (True, 'main', True, None), (), ()), + ((PRIVKEY_TEST,), 32, (), (True, 'test', False, None), (), ()), + ((PRIVKEY_TEST,), 32, (1,), (True, 'test', True, None), (), ()), + ((PRIVKEY_TEST,), 32, (), (True, 'signet', False, None), (), ()), + ((PRIVKEY_TEST,), 32, (1,), (True, 'signet', True, None), (), ()), + ((PRIVKEY_REGTEST,), 32, (), (True, 'regtest', False, None), (), ()), + ((PRIVKEY_REGTEST,), 32, (1,), (True, 'regtest', True, None), (), ()) +] +# templates for valid bech32 sequences +bech32_templates = [ + # hrp, version, witprog_size, metadata, encoding, output_prefix + ('ltc', 0, 20, (False, 'main', None, True), Encoding.BECH32, p2wpkh_prefix), + ('ltc', 0, 32, (False, 'main', None, True), Encoding.BECH32, p2wsh_prefix), + ('ltc', 1, 32, (False, 'main', None, True), Encoding.BECH32M, p2tr_prefix), + ('ltc', 2, 2, (False, 'main', None, True), Encoding.BECH32M, (OP_2, 2)), + ('tltc', 0, 20, (False, 'test', None, True), Encoding.BECH32, p2wpkh_prefix), + ('tltc', 0, 32, (False, 'test', None, True), Encoding.BECH32, p2wsh_prefix), + ('tltc', 1, 32, (False, 'test', None, True), Encoding.BECH32M, p2tr_prefix), + ('tltc', 3, 16, (False, 'test', None, True), Encoding.BECH32M, (OP_3, 16)), + ('tltc', 0, 20, (False, 'signet', None, True), Encoding.BECH32, p2wpkh_prefix), + ('tltc', 0, 32, (False, 'signet', None, True), Encoding.BECH32, p2wsh_prefix), + ('tltc', 1, 32, (False, 'signet', None, True), Encoding.BECH32M, p2tr_prefix), + ('tltc', 3, 32, (False, 'signet', None, True), Encoding.BECH32M, (OP_3, 32)), + ('rltc', 0, 20, (False, 'regtest', None, True), Encoding.BECH32, p2wpkh_prefix), + ('rltc', 0, 32, (False, 'regtest', None, True), Encoding.BECH32, p2wsh_prefix), + ('rltc', 1, 32, (False, 'regtest', None, True), Encoding.BECH32M, p2tr_prefix), + ('rltc', 16, 40, (False, 'regtest', None, True), Encoding.BECH32M, (OP_16, 40)) +] +# templates for invalid bech32 sequences +bech32_ng_templates = [ + # hrp, version, witprog_size, encoding, invalid_bech32, invalid_checksum, invalid_char + ('tc', 0, 20, Encoding.BECH32, False, False, False), + ('bt', 1, 32, Encoding.BECH32M, False, False, False), + ('tltc', 17, 32, Encoding.BECH32M, False, False, False), + ('rltc', 3, 1, Encoding.BECH32M, False, False, False), + ('ltc', 15, 41, Encoding.BECH32M, False, False, False), + ('tltc', 0, 16, Encoding.BECH32, False, False, False), + ('rltc', 0, 32, Encoding.BECH32, True, False, False), + ('ltc', 0, 16, Encoding.BECH32, True, False, False), + ('tltc', 0, 32, Encoding.BECH32, False, True, False), + ('rltc', 0, 20, Encoding.BECH32, False, False, True), + ('ltc', 0, 20, Encoding.BECH32M, False, False, False), + ('tltc', 0, 32, Encoding.BECH32M, False, False, False), + ('rltc', 0, 20, Encoding.BECH32M, False, False, False), + ('ltc', 1, 32, Encoding.BECH32, False, False, False), + ('tltc', 2, 16, Encoding.BECH32, False, False, False), + ('rltc', 16, 20, Encoding.BECH32, False, False, False), +] + +def gen_valid_base58_vector(template): + '''Generate valid base58 vector''' + prefix = bytearray(template[0]) + payload = bytearray(os.urandom(template[1])) + suffix = bytearray(template[2]) + dst_prefix = bytearray(template[4]) + dst_suffix = bytearray(template[5]) + rv = b58encode_chk(prefix + payload + suffix) + return rv, dst_prefix + payload + dst_suffix + +def gen_invalid_base58_vector(template): + '''Generate possibly invalid vector''' + # kinds of invalid vectors: + # invalid prefix + # invalid payload length + # invalid (randomized) suffix (add random data) + # corrupt checksum + corrupt_prefix = randbool(0.2) + randomize_payload_size = randbool(0.2) + corrupt_suffix = randbool(0.2) + + if corrupt_prefix: + prefix = os.urandom(1) + else: + prefix = bytearray(template[0]) + + if randomize_payload_size: + payload = os.urandom(max(int(random.expovariate(0.5)), 50)) + else: + payload = os.urandom(template[1]) + + if corrupt_suffix: + suffix = os.urandom(len(template[2])) + else: + suffix = bytearray(template[2]) + + val = b58encode_chk(prefix + payload + suffix) + if random.randint(0,10)<1: # line corruption + if randbool(): # add random character to end + val += random.choice(b58chars) + else: # replace random character in the middle + n = random.randint(0, len(val)) + val = val[0:n] + random.choice(b58chars) + val[n+1:] + + return val + +def gen_invalid_bech32_vector(template): + '''Generate possibly invalid bech32 vector''' + no_data = randbool(0.1) + to_upper = randbool(0.1) + hrp = template[0] + witver = template[1] + witprog = bytearray(os.urandom(template[2])) + encoding = template[3] + + if template[5]: + i = len(rv) - random.randrange(1, 7) + rv = rv[:i] + random.choice(CHARSET.replace(rv[i], '')) + rv[i + 1:] + if template[6]: + i = len(hrp) + 1 + random.randrange(0, len(rv) - len(hrp) - 4) + rv = rv[:i] + rv[i:i + 4].upper() + rv[i + 4:] + + if to_upper: + rv = rv.swapcase() + + return rv + +def randbool(p = 0.5): + '''Return True with P(p)''' + return random.random() < p + + data = list(islice(uiter(), count)) + json.dump(data, sys.stdout, sort_keys=True, indent=4) + sys.stdout.write('\n') + diff --git a/contrib/tidy_datadir.sh b/contrib/tidy_datadir.sh deleted file mode 100755 index 8960f8811d..0000000000 --- a/contrib/tidy_datadir.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# Copyright (c) 2013 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -if [ -d "$1" ]; then - cd "$1" -else - echo "Usage: $0 " >&2 - echo "Removes obsolete Bitcoin database files" >&2 - exit 1 -fi - -LEVEL=0 -if [ -f wallet.dat -a -f addr.dat -a -f blkindex.dat -a -f blk0001.dat ]; then LEVEL=1; fi -if [ -f wallet.dat -a -f peers.dat -a -f blkindex.dat -a -f blk0001.dat ]; then LEVEL=2; fi -if [ -f wallet.dat -a -f peers.dat -a -f coins/CURRENT -a -f blktree/CURRENT -a -f blocks/blk00000.dat ]; then LEVEL=3; fi -if [ -f wallet.dat -a -f peers.dat -a -f chainstate/CURRENT -a -f blocks/index/CURRENT -a -f blocks/blk00000.dat ]; then LEVEL=4; fi - -case $LEVEL in - 0) - echo "Error: no Bitcoin datadir detected." - exit 1 - ;; - 1) - echo "Detected old Bitcoin datadir (before 0.7)." - echo "Nothing to do." - exit 0 - ;; - 2) - echo "Detected Bitcoin 0.7 datadir." - ;; - 3) - echo "Detected Bitcoin pre-0.8 datadir." - ;; - 4) - echo "Detected Bitcoin 0.8 datadir." - ;; -esac - -FILES="" -DIRS="" - -if [ $LEVEL -ge 3 ]; then FILES=$(echo $FILES blk????.dat blkindex.dat); fi -if [ $LEVEL -ge 2 ]; then FILES=$(echo $FILES addr.dat); fi -if [ $LEVEL -ge 4 ]; then DIRS=$(echo $DIRS coins blktree); fi - -for FILE in $FILES; do - if [ -f $FILE ]; then - echo "Deleting: $FILE" - rm -f $FILE - fi -done - -for DIR in $DIRS; do - if [ -d $DIR ]; then - echo "Deleting: $DIR/" - rm -rf $DIR - fi -done - -echo "Done." diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp new file mode 100644 index 0000000000..ece02dc24e --- /dev/null +++ b/contrib/valgrind.supp @@ -0,0 +1,185 @@ +# This valgrind suppressions file includes known Valgrind warnings in our +# dependencies that cannot be fixed in-tree. +# +# Example use: +# $ valgrind --suppressions=contrib/valgrind.supp src/test/test_bitcoin +# $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ +# --show-leak-kinds=all src/test/test_bitcoin +# +# To create suppressions for found issues, use the --gen-suppressions=all option: +# $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ +# --show-leak-kinds=all --gen-suppressions=all --show-reachable=yes \ +# --error-limit=no src/test/test_bitcoin +# +# Note that suppressions may depend on OS and/or library versions. +# Tested on: +# * aarch64 (Ubuntu 20.04 system libs, without gui) +# * x86_64 (Ubuntu 18.04 system libs, without gui) +{ + Suppress libstdc++ warning - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65434 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + obj:*/libstdc++.* + fun:call_init.part.0 + fun:call_init + fun:_dl_init + obj:*/ld-*.so +} +{ + Suppress libdb warning - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=662917 + Memcheck:Cond + obj:*/libdb_cxx-*.so + fun:__log_put +} +{ + Suppress libdb warning + Memcheck:Param + pwrite64(buf) + fun:pwrite + fun:__os_io +} +{ + Suppress libdb warning + Memcheck:Cond + fun:__log_putr.isra.1 +} +{ + Suppress libdb warning + Memcheck:Param + pwrite64(buf) + ... + obj:*/libdb_cxx-*.so +} +{ + Suppress uninitialized bytes warning in compat code + Memcheck:Param + ioctl(TCSET{S,SW,SF}) + fun:tcsetattr +} +{ + Suppress libdb warning + Memcheck:Leak + fun:malloc + ... + obj:*/libdb_cxx-*.so +} +{ + Suppress leaks on init + Memcheck:Leak + ... + fun:_Z11AppInitMainR11NodeContext +} +{ + Suppress leaks on shutdown + Memcheck:Leak + ... + fun:_Z8ShutdownR11NodeContext +} +{ + Ignore GUI warning + Memcheck:Leak + ... + obj:/usr/lib64/libgdk-3.so.0.2404.7 +} +{ + Suppress leveldb warning (leveldb::InitModule()) - https://github.com/google/leveldb/issues/113 + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN7leveldbL10InitModuleEv +} +{ + Suppress leveldb warning (leveldb::Env::Default()) - https://github.com/google/leveldb/issues/113 + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + ... + fun:_ZN7leveldbL14InitDefaultEnvEv +} +{ + Suppress leveldb leak + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + ... + fun:_ZN7leveldb6DBImpl14BackgroundCallEv +} +{ + Suppress leveldb leak + Memcheck:Leak + fun:_Znwm + ... + fun:GetCoin +} +{ + Suppress wcsnrtombs glibc SSE4 warning (could be related: https://stroika.atlassian.net/browse/STK-626) + Memcheck:Addr16 + fun:__wcsnlen_sse4_1 + fun:wcsnrtombs +} +{ + Suppress wcsnrtombs warning (remove after removing boost::fs) + Memcheck:Cond + ... + fun:_ZN5boost10filesystem6detail11unique_pathERKNS0_4pathEPNS_6system10error_codeE +} +{ + Suppress boost warning + Memcheck:Leak + fun:_Znwm + ... + fun:_ZN5boost9unit_test9framework5state17execute_test_treeEmjPKNS2_23random_generator_helperE + fun:_ZN5boost9unit_test9framework3runEmb + fun:_ZN5boost9unit_test14unit_test_mainEPFbvEiPPc + fun:main +} +{ + Suppress boost::filesystem warning (fixed in boost 1.70: https://github.com/boostorg/filesystem/commit/bbe9d1771e5d679b3f10c42a58fc81f7e8c024a9) + Memcheck:Cond + fun:_ZN5boost10filesystem6detail28directory_iterator_incrementERNS0_18directory_iteratorEPNS_6system10error_codeE + ... + obj:*/libboost_filesystem.so.* +} +{ + Suppress boost::filesystem warning (could be related: https://stackoverflow.com/questions/9830182/function-boostfilesystemcomplete-being-reported-as-possible-memory-leak-by-v) + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + ... + fun:_ZN5boost10filesystem8absoluteERKNS0_4pathES3_ +} +{ + Suppress boost still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + ... + fun:_M_construct_aux + fun:_M_construct + fun:basic_string + fun:path +} +{ + Suppress LogInstance still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_Z11LogInstancev +} +{ + Suppress secp256k1_context_create still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:secp256k1_context_create +} +{ + Suppress BCLog::Logger::StartLogging() still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:_ZN5BCLog6Logger12StartLoggingEv +} diff --git a/contrib/verify-commits/allow-incorrect-sha512-commits b/contrib/verify-commits/allow-incorrect-sha512-commits new file mode 100644 index 0000000000..c572806f26 --- /dev/null +++ b/contrib/verify-commits/allow-incorrect-sha512-commits @@ -0,0 +1,2 @@ +f8feaa4636260b599294c7285bcf1c8b7737f74e +8040ae6fc576e9504186f2ae3ff2c8125de1095c diff --git a/contrib/verify-commits/allow-unclean-merge-commits b/contrib/verify-commits/allow-unclean-merge-commits new file mode 100644 index 0000000000..7aab274b9a --- /dev/null +++ b/contrib/verify-commits/allow-unclean-merge-commits @@ -0,0 +1,4 @@ +6052d509105790a26b3ad5df43dd61e7f1b24a12 +3798e5de334c3deb5f71302b782f6b8fbd5087f1 +326ffed09bfcc209a2efd6a2ebc69edf6bd200b5 +97d83739db0631be5d4ba86af3616014652c00ec diff --git a/contrib/verify-commits/trusted-sha512-root-commit b/contrib/verify-commits/trusted-sha512-root-commit new file mode 100644 index 0000000000..7d41f90ad7 --- /dev/null +++ b/contrib/verify-commits/trusted-sha512-root-commit @@ -0,0 +1 @@ +309bf16257b2395ce502017be627186b749ee749 diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py new file mode 100755 index 0000000000..7e46c6fd47 --- /dev/null +++ b/contrib/verify-commits/verify-commits.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018-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. +"""Verify commits against a trusted keys list.""" +import argparse +import hashlib +import logging +import os +import subprocess +import sys +import time + +GIT = os.getenv('GIT', 'git') + +def tree_sha512sum(commit='HEAD'): + """Calculate the Tree-sha512 for the commit. + + This is copied from github-merge.py. See https://github.com/bitcoin-core/bitcoin-maintainer-tools.""" + + # request metadata for entire tree, recursively + files = [] + blob_by_name = {} + for line in subprocess.check_output([GIT, 'ls-tree', '--full-tree', '-r', commit]).splitlines(): + name_sep = line.index(b'\t') + metadata = line[:name_sep].split() # perms, 'blob', blobid + assert metadata[1] == b'blob' + name = line[name_sep + 1:] + files.append(name) + blob_by_name[name] = metadata[2] + + files.sort() + # open connection to git-cat-file in batch mode to request data for all blobs + # this is much faster than launching it per file + p = subprocess.Popen([GIT, 'cat-file', '--batch'], stdout=subprocess.PIPE, stdin=subprocess.PIPE) + overall = hashlib.sha512() + for f in files: + blob = blob_by_name[f] + # request blob + p.stdin.write(blob + b'\n') + p.stdin.flush() + # read header: blob, "blob", size + reply = p.stdout.readline().split() + assert reply[0] == blob and reply[1] == b'blob' + size = int(reply[2]) + # hash the blob data + intern = hashlib.sha512() + ptr = 0 + while ptr < size: + bs = min(65536, size - ptr) + piece = p.stdout.read(bs) + if len(piece) == bs: + intern.update(piece) + else: + raise IOError('Premature EOF reading git cat-file output') + ptr += bs + dig = intern.hexdigest() + assert p.stdout.read(1) == b'\n' # ignore LF that follows blob data + # update overall hash with file hash + overall.update(dig.encode("utf-8")) + overall.update(" ".encode("utf-8")) + overall.update(f) + overall.update("\n".encode("utf-8")) + p.stdin.close() + if p.wait(): + raise IOError('Non-zero return value executing git cat-file') + return overall.hexdigest() + +def main(): + + # Enable debug logging if running in CI + if 'CI' in os.environ and os.environ['CI'].lower() == "true": + logging.getLogger().setLevel(logging.DEBUG) + + # Parse arguments + parser = argparse.ArgumentParser(usage='%(prog)s [options] [commit id]') + parser.add_argument('--disable-tree-check', action='store_false', dest='verify_tree', help='disable SHA-512 tree check') + parser.add_argument('--clean-merge', type=float, dest='clean_merge', default=float('inf'), help='Only check clean merge after days ago (default: %(default)s)', metavar='NUMBER') + parser.add_argument('commit', nargs='?', default='HEAD', help='Check clean merge up to commit ') + args = parser.parse_args() + + # get directory of this program and read data files + dirname = os.path.dirname(os.path.abspath(__file__)) + print("Using verify-commits data from " + dirname) + verified_root = open(dirname + "/trusted-git-root", "r", encoding="utf8").read().splitlines()[0] + verified_sha512_root = open(dirname + "/trusted-sha512-root-commit", "r", encoding="utf8").read().splitlines()[0] + revsig_allowed = open(dirname + "/allow-revsig-commits", "r", encoding="utf-8").read().splitlines() + unclean_merge_allowed = open(dirname + "/allow-unclean-merge-commits", "r", encoding="utf-8").read().splitlines() + incorrect_sha512_allowed = open(dirname + "/allow-incorrect-sha512-commits", "r", encoding="utf-8").read().splitlines() + + # Set commit and branch and set variables + current_commit = args.commit + if ' ' in current_commit: + print("Commit must not contain spaces", file=sys.stderr) + sys.exit(1) + verify_tree = args.verify_tree + no_sha1 = True + prev_commit = "" + initial_commit = current_commit + branch = subprocess.check_output([GIT, 'show', '-s', '--format=%H', initial_commit]).decode('utf8').splitlines()[0] + + # Iterate through commits + while True: + + # Log a message to prevent Travis from timing out + logging.debug("verify-commits: [in-progress] processing commit {}".format(current_commit[:8])) + + if current_commit == verified_root: + print('There is a valid path from "{}" to {} where all commits are signed!'.format(initial_commit, verified_root)) + sys.exit(0) + if current_commit == verified_sha512_root: + if verify_tree: + print("All Tree-SHA512s matched up to {}".format(verified_sha512_root), file=sys.stderr) + verify_tree = False + no_sha1 = False + + os.environ['BITCOIN_VERIFY_COMMITS_ALLOW_SHA1'] = "0" if no_sha1 else "1" + os.environ['BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG'] = "1" if current_commit in revsig_allowed else "0" + + # Check that the commit (and parents) was signed with a trusted key + if subprocess.call([GIT, '-c', 'gpg.program={}/gpg.sh'.format(dirname), 'verify-commit', current_commit], stdout=subprocess.DEVNULL): + if prev_commit != "": + print("No parent of {} was signed with a trusted key!".format(prev_commit), file=sys.stderr) + print("Parents are:", file=sys.stderr) + parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', prev_commit]).decode('utf8').splitlines()[0].split(' ') + for parent in parents: + subprocess.call([GIT, 'show', '-s', parent], stdout=sys.stderr) + else: + print("{} was not signed with a trusted key!".format(current_commit), file=sys.stderr) + sys.exit(1) + + # Check the Tree-SHA512 + if (verify_tree or prev_commit == "") and current_commit not in incorrect_sha512_allowed: + tree_hash = tree_sha512sum(current_commit) + if ("Tree-SHA512: {}".format(tree_hash)) not in subprocess.check_output([GIT, 'show', '-s', '--format=format:%B', current_commit]).decode('utf8').splitlines(): + print("Tree-SHA512 did not match for commit " + current_commit, file=sys.stderr) + sys.exit(1) + + # Merge commits should only have two parents + parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', current_commit]).decode('utf8').splitlines()[0].split(' ') + if len(parents) > 2: + print("Commit {} is an octopus merge".format(current_commit), file=sys.stderr) + sys.exit(1) + + # Check that the merge commit is clean + commit_time = int(subprocess.check_output([GIT, 'show', '-s', '--format=format:%ct', current_commit]).decode('utf8').splitlines()[0]) + check_merge = commit_time > time.time() - args.clean_merge * 24 * 60 * 60 # Only check commits in clean_merge days + allow_unclean = current_commit in unclean_merge_allowed + if len(parents) == 2 and check_merge and not allow_unclean: + current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit]).decode('utf8').splitlines()[0] + subprocess.call([GIT, 'checkout', '--force', '--quiet', parents[0]]) + subprocess.call([GIT, 'merge', '--no-ff', '--quiet', '--no-gpg-sign', parents[1]], stdout=subprocess.DEVNULL) + recreated_tree = subprocess.check_output([GIT, 'show', '--format=format:%T', 'HEAD']).decode('utf8').splitlines()[0] + if current_tree != recreated_tree: + print("Merge commit {} is not clean".format(current_commit), file=sys.stderr) + subprocess.call([GIT, 'diff', current_commit]) + subprocess.call([GIT, 'checkout', '--force', '--quiet', branch]) + sys.exit(1) + subprocess.call([GIT, 'checkout', '--force', '--quiet', branch]) + + prev_commit = current_commit + current_commit = parents[0] + +if __name__ == '__main__': + main() diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh deleted file mode 100755 index cfe4f11a0b..0000000000 --- a/contrib/verify-commits/verify-commits.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh -# Copyright (c) 2014-2016 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# Not technically POSIX-compliant due to use of "local", but almost every -# shell anyone uses today supports it, so its probably fine - -DIR=$(dirname "$0") -[ "/${DIR#/}" != "$DIR" ] && DIR=$(dirname "$(pwd)/$0") - -VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root") -REVSIG_ALLOWED=$(cat "${DIR}/allow-revsig-commits") - -HAVE_FAILED=false -IS_SIGNED () { - if [ $1 = $VERIFIED_ROOT ]; then - return 0; - fi - if [ "${REVSIG_ALLOWED#*$1}" != "$REVSIG_ALLOWED" ]; then - export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=1 - else - export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=0 - fi - if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then - return 1; - fi - local PARENTS - PARENTS=$(git show -s --format=format:%P $1) - for PARENT in $PARENTS; do - if IS_SIGNED $PARENT > /dev/null; then - return 0; - fi - done - if ! "$HAVE_FAILED"; then - echo "No parent of $1 was signed with a trusted key!" > /dev/stderr - echo "Parents are:" > /dev/stderr - for PARENT in $PARENTS; do - git show -s $PARENT > /dev/stderr - done - HAVE_FAILED=true - fi - return 1; -} - -if [ x"$1" = "x" ]; then - TEST_COMMIT="HEAD" -else - TEST_COMMIT="$1" -fi - -IS_SIGNED "$TEST_COMMIT" -RES=$? -if [ "$RES" = 1 ]; then - if ! "$HAVE_FAILED"; then - echo "$TEST_COMMIT was not signed with a trusted key!" - fi -else - echo "There is a valid path from $TEST_COMMIT to $VERIFIED_ROOT where all commits are signed!" -fi - -exit $RES diff --git a/contrib/windeploy/detached-sig-create.sh b/contrib/windeploy/detached-sig-create.sh new file mode 100644 index 0000000000..31720e72e7 --- /dev/null +++ b/contrib/windeploy/detached-sig-create.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# Copyright (c) 2014-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. + +export LC_ALL=C +if [ -z "$OSSLSIGNCODE" ]; then + OSSLSIGNCODE=osslsigncode +fi + +if [ -z "$1" ]; then + echo "usage: $0 " + echo "example: $0 -key codesign.key" + exit 1 +fi + +OUT=signature-win.tar.gz +SRCDIR=unsigned +WORKDIR=./.tmp +OUTDIR="${WORKDIR}/out" +OUTSUBDIR="${OUTDIR}/win" +TIMESERVER=http://timestamp.comodoca.com +CERTFILE="win-codesign.cert" + +mkdir -p "${OUTSUBDIR}" +basename -a $(ls -1 "${SRCDIR}"/*-unsigned.exe) | while read UNSIGNED; do + echo Signing "${UNSIGNED}" + "${OSSLSIGNCODE}" sign -certs "${CERTFILE}" -t "${TIMESERVER}" -in "${SRCDIR}/${UNSIGNED}" -out "${WORKDIR}/${UNSIGNED}" "$@" + "${OSSLSIGNCODE}" extract-signature -pem -in "${WORKDIR}/${UNSIGNED}" -out "${OUTSUBDIR}/${UNSIGNED}.pem" && rm "${WORKDIR}/${UNSIGNED}" +done + +rm -f "${OUT}" +tar -C "${OUTDIR}" -czf "${OUT}" . +rm -rf "${WORKDIR}" +echo "Created ${OUT}" diff --git a/contrib/windeploy/win-codesign.cert b/contrib/windeploy/win-codesign.cert new file mode 100644 index 0000000000..5828389e05 --- /dev/null +++ b/contrib/windeploy/win-codesign.cert @@ -0,0 +1,42 @@ +Bag Attributes + localKeyID: 01 00 00 00 +subject=C = SG, postalCode = 179098, L = Singapore, street = 111 North Bridge Road Peninsula Plaza #08-19, O = Litecoin Foundation Limited, CN = Litecoin Foundation Limited + +issuer=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Code Signing CA + +-----BEGIN CERTIFICATE----- +MIIGTzCCBTegAwIBAgIRAIlhNAlbwcXgVwHXoiv/WEMwDQYJKoZIhvcNAQELBQAw +fDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYDVQQD +ExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcgQ0EwHhcNMjEwMjE1MDAwMDAwWhcN +MjQwMjE1MjM1OTU5WjCBtTELMAkGA1UEBhMCU0cxDzANBgNVBBEMBjE3OTA5ODES +MBAGA1UEBwwJU2luZ2Fwb3JlMTUwMwYDVQQJDCwxMTEgTm9ydGggQnJpZGdlIFJv +YWQgUGVuaW5zdWxhIFBsYXphICMwOC0xOTEkMCIGA1UECgwbTGl0ZWNvaW4gRm91 +bmRhdGlvbiBMaW1pdGVkMSQwIgYDVQQDDBtMaXRlY29pbiBGb3VuZGF0aW9uIExp +bWl0ZWQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCrVPOgx0wD3Pp1 +Z5xqhpYQYy0w7igidlFn/LEJtZYR5lp2fLpxxc6f4UAcNohULvMiEkMQIETnV6by +T6r+YN+/qAMqQGW7R+9AwZ5k2kFsM1gnYagyP53+eZVXRmrgv9nrags2/36uRDwc +MzsW1Fg39sw/dsbpew9kBJkxuSRCfDS+6Y2oyiulVpQuZ0GK9LtXysarRbwzl2vl +I1Obp/D4iA5wo+ny6cmzxFcLHwqAm3Gi35wwADPEVAgsEObjgzsbLWuwN/3z5VqJ +5hi5iQ0qnDK3hddLsIGdwkrMnVSm5ccdw1ZKUcm2BgrWMSLCa5inzlV+PwRd0dAP +WCQ9pA4inZ4Cf6iZtkneRqOM+P/HkI0l5QvBp6sqrteLrEsZxbNZGIDdpjhAJ2QQ +6CMySjt8VWxoMXDnrrOd8UKSNq9cx394Au7lWI8L18L9Sg28v8qdklvD+ufkUQlf ++HnpcgcG3bCkKrjurbNT23+xANlXk6w7tjjju7xQOtBnuyBRuNh5ZZL8Et/DHRB7 +wT5yt3vFzdnK7JiNWTfj0AjstxHAGjD3n7ABM1AGE0BJoSahqq0pMv9W1Oh+L19M +P2rxjHbc07LSly6uzIEehcNRiKNEq9ffggueclc0UQ4rhWNet4QPBT6mtUaDosMn +WE/Vd+nLz3TDI+au7vNmaCySckAMjQIDAQABo4IBkDCCAYwwHwYDVR0jBBgwFoAU +DuE6qFM6MdWKvsG7rWcaA4WtNA4wHQYDVR0OBBYEFDq5MytoU983xcFtYTmvpAq8 +Pf77MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG +AQUFBwMDMBEGCWCGSAGG+EIBAQQEAwIEEDBKBgNVHSAEQzBBMDUGDCsGAQQBsjEB +AgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAIBgZn +gQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5zZWN0aWdvLmNvbS9T +ZWN0aWdvUlNBQ29kZVNpZ25pbmdDQS5jcmwwcwYIKwYBBQUHAQEEZzBlMD4GCCsG +AQUFBzAChjJodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29SU0FDb2RlU2ln +bmluZ0NBLmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20w +DQYJKoZIhvcNAQELBQADggEBAGXFCIipnE37NM4l4MDRFoaMAi4cJiqMnTN0bIxO +b8uf1EX5pI5Y1ch1Rdg4m3l05JDR/dVuTpeGktal4JZGh/N9UOrxNi6rF8VLmy/g +VCRzCj+UQHmBPBkZSZalYfWPDlOvjWGn5XccqlIo/EpcjGqPEkFx3qqOyuC+jkkX +aE49Tt6kv7IMrcp9b7nC2/eP8JmCQqH6Z1sSxZtSqGEZjdiJvU/NfzZ90qx0t3xf +xbL69R9cdrUZHscm32RE6VJhRuhF1u+Wo5dn3lPSPRtwgl30lKhuCm+1pajdyT4l +im0TGh85wn5vIMl6sEAKgLgO2D0YhYWdEjpgiW4nHMfT3+Y= +-----END CERTIFICATE----- diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 3dea5e3c14..4c4bbf93e3 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,44 +1,90 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2016 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-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. -import array +""" + ZMQ example using python3's asyncio + + Litecoind should be started with the command line arguments: + litecoind -testnet -daemon \ + -zmqpubrawtx=tcp://127.0.0.1:28332 \ + -zmqpubrawblock=tcp://127.0.0.1:28332 \ + -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubhashblock=tcp://127.0.0.1:28332 \ + -zmqpubsequence=tcp://127.0.0.1:28332 + + We use the asyncio library here. `self.handle()` installs itself as a + future at the end of the function. Since it never returns with the event + loop having an empty stack of futures, this creates an infinite loop. An + alternative is to wrap the contents of `handle` inside `while True`. + + A blocking example using python 2.7 can be obtained from the git history: + https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py +""" + import binascii +import asyncio import zmq +import zmq.asyncio +import signal import struct +import sys + +if (sys.version_info.major, sys.version_info.minor) < (3, 5): + print("This example only works with Python 3.5 and greater") + sys.exit(1) port = 28332 -zmqContext = zmq.Context() -zmqSubSocket = zmqContext.socket(zmq.SUB) -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawblock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawtx") -zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) - -try: - while True: - msg = zmqSubSocket.recv_multipart() - topic = str(msg[0]) - body = msg[1] - sequence = "Unknown"; - if len(msg[-1]) == 4: - msgSequence = struct.unpack('/dev/null) -build_id_string+=$(shell $(build_AR) --version 2>/dev/null) -build_id_string+=$(shell $(build_CXX) --version 2>/dev/null) -build_id_string+=$(shell $(build_RANLIB) --version 2>/dev/null) -build_id_string+=$(shell $(build_STRIP) --version 2>/dev/null) - -$(host_arch)_$(host_os)_id_string:=$(HOST_ID_SALT) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_CC) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_AR) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) - -ifneq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -build_id_string+=system_clang -$(host_arch)_$(host_os)_id_string+=system_clang -endif +# Previously, we directly invoked the well-known programs using $(shell ...) +# to contruct build_id_string. However, that was problematic because: +# +# 1. When invoking a shell, GNU Make special-cases exit code 127 (command not +# found) by not capturing the output but instead passing it through. This is +# not done for any other exit code. +# +# 2. Characters like '#' (from these programs' output) would end up in make +# variables like build_id_string, which would be wrongly interpreted by make +# when these variables were used. +# +# Therefore, we should avoid having arbitrary strings in make variables where +# possible. The gen_id script used here hashes the output to construct a +# "make-safe" id. +# +# Also note that these lines need to be: +# +# 1. After including {hosts,builders}/*.mk, since they rely on the tool +# variables (e.g. build_CC, host_STRIP, etc.) to be set. +# +# 2. Before including packages/*.mk (excluding packages/packages.mk), since +# they rely on the build_id variables +# +build_id:=$(shell env CC='$(build_CC)' CXX='$(build_CXX)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))') +$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' CXX='$(host_CXX)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' ./gen_id '$(HOST_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))') qrencode_packages_$(NO_QR) = $(qrencode_packages) @@ -159,12 +166,6 @@ $(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) include funcs.mk -binutils_path=$($($(host_arch)_$(host_os)_native_binutils)_prefixbin) -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin) -else -toolchain_path= -endif final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) @@ -175,15 +176,39 @@ $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) $(AT)cd $(@D); $(foreach package,$^, tar xf $($(package)_cached); ) $(AT)touch $@ +# $PATH is not preserved between ./configure and make by convention. Its +# modification and overriding at ./configure time is (as I understand it) +# supposed to be captured by the AC_{PROG_{,OBJ}CXX,PATH_{PROG,TOOL}} macros, +# which will expand the program names to their full absolute paths. The notable +# exception is command line overriding: ./configure CC=clang, which skips the +# program name expansion step, and works because the user implicitly indicates +# with CC=clang that clang will be available in $PATH at all times, and is most +# likely part of the user's system. +# +# Therefore, when we "seed the autoconf cache"/"override well-known program +# vars" by setting AR= in our config.site, either one of two things needs +# to be true for the build system to work correctly: +# +# 1. If we refer to the program by name (e.g. AR=riscv64-gnu-linux-ar), the +# tool needs to be available in $PATH at all times. +# +# 2. If the tool is _**not**_ expected to be available in $PATH at all times +# (such as is the case for our native_cctools binutils tools), it needs to +# be referred to by its absolute path, such as would be output by the +# AC_PATH_{PROG,TOOL} macros. +# +# Minor note: it is also okay to refer to tools by their absolute path even if +# we expect them to be available in $PATH at all times, more specificity does +# not hurt. $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id) $(AT)@mkdir -p $(@D) $(AT)sed -e 's|@HOST@|$(host)|' \ - -e 's|@CC@|$(toolchain_path)$(host_CC)|' \ - -e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \ - -e 's|@AR@|$(binutils_path)$(host_AR)|' \ - -e 's|@RANLIB@|$(binutils_path)$(host_RANLIB)|' \ - -e 's|@NM@|$(binutils_path)$(host_NM)|' \ - -e 's|@STRIP@|$(binutils_path)$(host_STRIP)|' \ + -e 's|@CC@|$(host_CC)|' \ + -e 's|@CXX@|$(host_CXX)|' \ + -e 's|@AR@|$(host_AR)|' \ + -e 's|@RANLIB@|$(host_RANLIB)|' \ + -e 's|@NM@|$(host_NM)|' \ + -e 's|@STRIP@|$(host_STRIP)|' \ -e 's|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ @@ -236,9 +261,9 @@ install: check-packages $(host_prefix)/share/config.site download-one: check-sources $(all_sources) download-osx: - @$(MAKE) -s HOST=x86_64-apple-darwin16 download-one + @$(MAKE) -s HOST=x86_64-apple-darwin download-one download-linux: - @$(MAKE) -s HOST=x86_64-linux-gnu download-one + @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one download-win: @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one download: download-osx download-linux download-win @@ -246,3 +271,4 @@ download: download-osx download-linux download-win $(foreach package,$(all_packages),$(eval $(call ext_add_stages,$(package)))) .PHONY: install cached clean clean-all download-one download-osx download-linux download-win download check-packages check-sources +.PHONY: FORCE diff --git a/depends/README.md b/depends/README.md index f37181ca84..84674a4616 100644 --- a/depends/README.md +++ b/depends/README.md @@ -12,20 +12,23 @@ For example: make HOST=x86_64-w64-mingw32 -j4 -**Bitcoin Core's configure script by default will ignore the depends output.** In +**Bitcoin Core's `configure` script by default will ignore the depends output.** In order for it to pick up libraries, tools, and settings from the depends build, -you must point it at the appropriate `--prefix` directory generated by the -build. In the above example, a prefix dir named x86_64-w64-mingw32 will be -created. To use it for Bitcoin: +you must set the `CONFIG_SITE` environment variable to point to a `config.site` settings file. +In the above example, a file named `depends/x86_64-w64-mingw32/share/config.site` will be +created. To use it during compilation: - ./configure --prefix=$PWD/depends/x86_64-w64-mingw32 + CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure -Common `host-platform-triplets` for cross compilation are: +The default install prefix when using `config.site` is `--prefix=depends/`, +so depends build outputs will be installed in that location. + +Common `host-platform-triplet`s for cross compilation are: - `i686-pc-linux-gnu` for Linux 32 bit - `x86_64-pc-linux-gnu` for x86 Linux - `x86_64-w64-mingw32` for Win64 -- `x86_64-apple-darwin16` for macOS +- `x86_64-apple-darwin18` for macOS - `arm-linux-gnueabihf` for Linux ARM 32 bit - `aarch64-linux-gnu` for Linux ARM 64 bit - `powerpc64-linux-gnu` for Linux POWER 64-bit (big endian) @@ -44,7 +47,12 @@ The paths are automatically configured and no other options are needed unless ta #### For macOS cross compilation - sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools libtinfo5 + sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools libtinfo5 xorriso ninja-build + +Note: You must obtain the macOS SDK before proceeding with a cross-compile. +Under the depends directory, create a subdirectory named `SDKs`. +Then, place the extracted SDK under this new directory. +For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-extraction). #### For Win64 cross compilation @@ -54,7 +62,7 @@ The paths are automatically configured and no other options are needed unless ta Common linux dependencies: - sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch + sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch bison For linux ARM cross compilation: @@ -79,7 +87,16 @@ For linux S390X cross compilation: sudo apt-get install g++-s390x-linux-gnu binutils-s390x-linux-gnu +### Install the required dependencies: M1-based macOS + +To be able to build the `qt` package, ensure that Rosetta 2 is installed: + +``` +softwareupdate --install-rosetta +``` + ### Dependency Options + The following can be set when running make: `make FOO=bar`
diff --git a/depends/SDKs/.gitignore b/depends/SDKs/.gitignore new file mode 100644 index 0000000000..d7685001b6 --- /dev/null +++ b/depends/SDKs/.gitignore @@ -0,0 +1 @@ +Xcode* diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index f4103fc1f2..001c928424 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -1,5 +1,5 @@ -build_darwin_CC:=$(shell xcrun -f clang) --sysroot $(shell xcrun --show-sdk-path) -build_darwin_CXX:=$(shell xcrun -f clang++) --sysroot $(shell xcrun --show-sdk-path) +build_darwin_CC:=$(shell xcrun -f clang) -isysroot$(shell xcrun --show-sdk-path) +build_darwin_CXX:=$(shell xcrun -f clang++) -isysroot$(shell xcrun --show-sdk-path) build_darwin_AR:=$(shell xcrun -f ar) build_darwin_RANLIB:=$(shell xcrun -f ranlib) build_darwin_STRIP:=$(shell xcrun -f strip) @@ -10,8 +10,8 @@ build_darwin_SHA256SUM=shasum -a 256 build_darwin_DOWNLOAD=curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o #darwin host on darwin builder. overrides darwin host preferences. -darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(shell xcrun --show-sdk-path) -darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -stdlib=libc++ --sysroot $(shell xcrun --show-sdk-path) +darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) -isysroot$(shell xcrun --show-sdk-path) +darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -stdlib=libc++ -isysroot$(shell xcrun --show-sdk-path) darwin_AR:=$(shell xcrun -f ar) darwin_RANLIB:=$(shell xcrun -f ranlib) darwin_STRIP:=$(shell xcrun -f strip) diff --git a/depends/config.guess b/depends/config.guess index 7f9ebbe310..dc0a6b2997 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2019 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2019-09-10' +timestamp='2021-05-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -27,12 +27,12 @@ timestamp='2019-09-10' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2019 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -99,9 +99,11 @@ tmp= trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039 - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } @@ -129,16 +131,14 @@ if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown +UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown +UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown +UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown -case "$UNAME_SYSTEM" in +case $UNAME_SYSTEM in Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu + LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" @@ -147,24 +147,36 @@ Linux|GNU|GNU/*) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc - #else + #elif defined(__GLIBC__) LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')" - # If ldd exists, use it to detect musl libc. - if command -v ldd >/dev/null && \ - ldd --version 2>&1 | grep -q ^musl - then - LIBC=musl + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -176,27 +188,27 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - "/sbin/$sysctl" 2>/dev/null || \ - "/usr/sbin/$sysctl" 2>/dev/null || \ - echo unknown)` - case "$UNAME_MACHINE_ARCH" in + UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)) + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,') + endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p') machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; @@ -217,10 +229,10 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in ;; esac # Determine ABI tags. - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") ;; esac # The OS release @@ -228,12 +240,12 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "$UNAME_VERSION" in + case $UNAME_VERSION in Debian*) release='-gnu' ;; *) - release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: @@ -242,15 +254,19 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//') echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=$(arch | sed 's/SecBSD.//') + echo "$UNAME_MACHINE_ARCH"-unknown-secbsd"$UNAME_RELEASE" + exit ;; *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//') echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) @@ -284,20 +300,22 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 case $UNAME_RELEASE in *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}') ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}') ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in + ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1) + case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") @@ -334,11 +352,8 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; + echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)" + exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; @@ -368,7 +383,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then + if test "$( (/bin/universe) 2>/dev/null)" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd @@ -381,17 +396,17 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in + case $(/usr/bin/uname -p) in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" @@ -402,7 +417,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null @@ -410,30 +425,30 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in SUN_ARCH=x86_64 fi fi - echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case $(/usr/bin/arch -k) in Series*|S4*) - UNAME_RELEASE=`uname -v` + UNAME_RELEASE=$(uname -v) ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null) test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case "`/bin/arch`" in + case $(/bin/arch) in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; @@ -513,8 +528,8 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`"$dummy" "$dummyarg"` && + dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') && + SYSTEM_NAME=$("$dummy" "$dummyarg") && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; @@ -541,11 +556,11 @@ EOF exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + UNAME_PROCESSOR=$(/usr/bin/uname -p) + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ - [ "$TARGET_BINARY_INTERFACE"x = x ] + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then echo m88k-dg-dgux"$UNAME_RELEASE" else @@ -569,17 +584,17 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if test -x /usr/bin/oslevel ; then + IBM_REV=$(/usr/bin/oslevel) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi @@ -599,7 +614,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") then echo "$SYSTEM_NAME" else @@ -612,15 +627,15 @@ EOF fi exit ;; *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }') if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + if test -x /usr/bin/lslpp ; then + IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi @@ -648,26 +663,26 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` - case "$UNAME_MACHINE" in + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') + case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "$sc_cpu_version" in + if test -x /usr/bin/getconf; then + sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null) + sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null) + case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "$sc_kernel_bits" in + case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "$HP_ARCH" = "" ]; then + if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" @@ -702,11 +717,11 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy") test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ "$HP_ARCH" = hppa2.0w ] + if test "$HP_ARCH" = hppa2.0w then set_cc_for_build @@ -730,7 +745,7 @@ EOF echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) @@ -760,7 +775,7 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; @@ -780,7 +795,7 @@ EOF echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then + if test -x /usr/sbin/sysversion ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 @@ -829,14 +844,14 @@ EOF echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/') echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/') echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -849,25 +864,25 @@ EOF echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; arm:FreeBSD:*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi else - echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf fi exit ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case "$UNAME_PROCESSOR" in + UNAME_PROCESSOR=$(/usr/bin/uname -p) + case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin @@ -885,7 +900,7 @@ EOF echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case "$UNAME_MACHINE" in + case $UNAME_MACHINE in x86) echo i586-pc-interix"$UNAME_RELEASE" exit ;; @@ -903,15 +918,15 @@ EOF echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; *:GNU:*:*) # the GNU system - echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC" exit ;; *:Minix:*:*) echo "$UNAME_MACHINE"-unknown-minix @@ -924,7 +939,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -937,7 +952,7 @@ EOF if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; - arc:Linux:*:* | arceb:Linux:*:*) + arc:Linux:*:* | arceb:Linux:*:* | arc64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) @@ -983,6 +998,9 @@ EOF k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; @@ -1033,7 +1051,7 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) @@ -1053,7 +1071,7 @@ EOF exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; @@ -1071,7 +1089,7 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) @@ -1093,7 +1111,17 @@ EOF echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi + fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1133,7 +1161,7 @@ EOF echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) - UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//') if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else @@ -1142,7 +1170,7 @@ EOF exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in + case $(/bin/uname -X | grep "^Machine") in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; @@ -1151,10 +1179,10 @@ EOF exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //')) (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 @@ -1204,7 +1232,7 @@ EOF 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1215,7 +1243,7 @@ EOF NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1248,7 +1276,7 @@ EOF exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=$( (uname -p) 2>/dev/null) echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv @@ -1282,7 +1310,7 @@ EOF echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then + if test -d /usr/nec; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" @@ -1330,8 +1358,11 @@ EOF *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" + exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac @@ -1344,7 +1375,7 @@ EOF else set_cc_for_build fi - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null @@ -1368,7 +1399,7 @@ EOF echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc @@ -1406,10 +1437,9 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - # shellcheck disable=SC2154 - if test "$cputype" = 386; then + if test "${cputype-}" = 386; then UNAME_MACHINE=i386 - else + elif test "x${cputype-}" != x; then UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 @@ -1436,11 +1466,11 @@ EOF echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "$UNAME_MACHINE" in + UNAME_MACHINE=$( (uname -p) 2>/dev/null) + case $UNAME_MACHINE in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1449,13 +1479,13 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; - i*86:AROS:*:*) - echo "$UNAME_MACHINE"-pc-aros + *:AROS:*:*) + echo "$UNAME_MACHINE"-unknown-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx @@ -1507,7 +1537,7 @@ main () #define __ARCHITECTURE__ "m68k" #endif int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null); if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else @@ -1599,7 +1629,7 @@ main () } EOF -$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. @@ -1607,7 +1637,7 @@ test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 -case "$UNAME_MACHINE:$UNAME_SYSTEM" in +case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` +uname -m = $( (uname -m) 2>/dev/null || echo unknown) +uname -r = $( (uname -r) 2>/dev/null || echo unknown) +uname -s = $( (uname -s) 2>/dev/null || echo unknown) +uname -v = $( (uname -v) 2>/dev/null || echo unknown) -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` +/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null) +/bin/uname -X = $( (/bin/uname -X) 2>/dev/null) -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` +hostinfo = $( (hostinfo) 2>/dev/null) +/bin/universe = $( (/bin/universe) 2>/dev/null) +/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null) +/bin/arch = $( (/bin/arch) 2>/dev/null) +/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null) +/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null) UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF +fi exit 1 diff --git a/depends/config.site.in b/depends/config.site.in index d2a2776bdf..8f75fecb97 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -8,72 +8,71 @@ true # Dummy command because shellcheck treats all directives before first # See: https://github.com/koalaman/shellcheck/wiki/Directive # shellcheck disable=SC2154 -depends_prefix="$(cd "$(dirname ${ac_site_file})/.." && pwd)" +depends_prefix="$(cd "$(dirname "$ac_site_file")/.." && pwd)" cross_compiling=maybe -host_alias=@HOST@ -ac_tool_prefix=${host_alias}- +host_alias="@HOST@" +ac_tool_prefix="${host_alias}-" -if test -z $with_boost; then - with_boost=$depends_prefix +if test -z "$with_boost"; then + with_boost="$depends_prefix" fi -if test -z $with_qt_plugindir; then - with_qt_plugindir=$depends_prefix/plugins +if test -z "$with_qt_plugindir"; then + with_qt_plugindir="${depends_prefix}/plugins" fi -if test -z $with_qt_translationdir; then - with_qt_translationdir=$depends_prefix/translations +if test -z "$with_qt_translationdir"; then + with_qt_translationdir="${depends_prefix}/translations" fi -if test -z $with_qt_bindir && test -z "@no_qt@"; then - with_qt_bindir=$depends_prefix/native/bin +if test -z "$with_qt_bindir" && test -z "@no_qt@"; then + with_qt_bindir="${depends_prefix}/native/bin" fi -if test -z $with_qrencode && test -n "@no_qr@"; then +if test -z "$with_qrencode" && test -n "@no_qr@"; then with_qrencode=no fi -if test -z $enable_wallet && test -n "@no_wallet@"; then +if test -z "$enable_wallet" && test -n "@no_wallet@"; then enable_wallet=no fi -if test -z $with_miniupnpc && test -n "@no_upnp@"; then +if test -z "$with_bdb" && test -n "@no_bdb@"; then + with_bdb=no +fi + +if test -z "$with_miniupnpc" && test -n "@no_upnp@"; then with_miniupnpc=no fi -if test -z $with_gui && test -n "@no_qt@"; then +if test -z "$with_gui" && test -n "@no_qt@"; then with_gui=no fi -if test -z $enable_zmq && test -n "@no_zmq@"; then +if test -n "@debug@" && test -z "@no_qt@" && test "x$with_gui" != xno; then + with_gui=qt5_debug +fi + +if test -z "$enable_zmq" && test -n "@no_zmq@"; then enable_zmq=no fi -if test x@host_os@ = xdarwin; then +if test "@host_os@" = darwin; then BREW=no PORT=no fi -if test x@host_os@ = xmingw32; then - if test -z $with_qt_incdir; then - with_qt_incdir=$depends_prefix/include - fi - if test -z $with_qt_libdir; then - with_qt_libdir=$depends_prefix/lib - fi -fi - -PATH=$depends_prefix/native/bin:$PATH +PATH="${depends_prefix}/native/bin:${PATH}" PKG_CONFIG="$(which pkg-config) --static" # These two need to remain exported because pkg-config does not see them # otherwise. That means they must be unexported at the end of configure.ac to # avoid ruining the cache. Sigh. -export PKG_CONFIG_PATH=$depends_prefix/share/pkgconfig:$depends_prefix/lib/pkgconfig +export PKG_CONFIG_PATH="${depends_prefix}/share/pkgconfig:${depends_prefix}/lib/pkgconfig" if test -z "@allow_host_packages@"; then - export PKG_CONFIG_LIBDIR=$depends_prefix/lib/pkgconfig + export PKG_CONFIG_LIBDIR="${depends_prefix}/lib/pkgconfig" fi -CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS" -LDFLAGS="-L$depends_prefix/lib $LDFLAGS" +CPPFLAGS="-I${depends_prefix}/include/ ${CPPFLAGS}" +LDFLAGS="-L${depends_prefix}/lib ${LDFLAGS}" if test -n "@CC@" -a -z "${CC}"; then CC="@CC@" @@ -84,18 +83,18 @@ fi PYTHONPATH="${depends_prefix}/native/lib/python3/dist-packages${PYTHONPATH:+${PATH_SEPARATOR}}${PYTHONPATH}" if test -n "@AR@"; then - AR=@AR@ - ac_cv_path_ac_pt_AR=${AR} + AR="@AR@" + ac_cv_path_ac_pt_AR="${AR}" fi if test -n "@RANLIB@"; then - RANLIB=@RANLIB@ - ac_cv_path_ac_pt_RANLIB=${RANLIB} + RANLIB="@RANLIB@" + ac_cv_path_ac_pt_RANLIB="${RANLIB}" fi if test -n "@NM@"; then - NM=@NM@ - ac_cv_path_ac_pt_NM=${NM} + NM="@NM@" + ac_cv_path_ac_pt_NM="${NM}" fi if test -n "@debug@"; then @@ -103,14 +102,14 @@ if test -n "@debug@"; then fi if test -n "@CFLAGS@"; then - CFLAGS="@CFLAGS@ $CFLAGS" + CFLAGS="@CFLAGS@ ${CFLAGS}" fi if test -n "@CXXFLAGS@"; then - CXXFLAGS="@CXXFLAGS@ $CXXFLAGS" + CXXFLAGS="@CXXFLAGS@ ${CXXFLAGS}" fi if test -n "@CPPFLAGS@"; then - CPPFLAGS="@CPPFLAGS@ $CPPFLAGS" + CPPFLAGS="@CPPFLAGS@ ${CPPFLAGS}" fi if test -n "@LDFLAGS@"; then - LDFLAGS="@LDFLAGS@ $LDFLAGS" + LDFLAGS="@LDFLAGS@ ${LDFLAGS}" fi diff --git a/depends/config.sub b/depends/config.sub index a318a46868..7384e9198b 100755 --- a/depends/config.sub +++ b/depends/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2019 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2019-06-30' +timestamp='2021-04-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ timestamp='2019-06-30' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -50,7 +50,7 @@ timestamp='2019-06-30' # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2019 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -124,28 +124,27 @@ case $1 in ;; *-*-*-*) basic_machine=$field1-$field2 - os=$field3-$field4 + basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ - | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ + nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 - os=$maybe_os + basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown - os=linux-android + basic_os=linux-android ;; *) basic_machine=$field1-$field2 - os=$field3 + basic_os=$field3 ;; esac ;; @@ -154,7 +153,7 @@ case $1 in case $field1-$field2 in decstation-3100) basic_machine=mips-dec - os= + basic_os= ;; *-*) # Second component is usually, but not always the OS @@ -162,7 +161,7 @@ case $1 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 - os=$field2 + basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ @@ -175,11 +174,11 @@ case $1 in | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 - os= + basic_os= ;; *) basic_machine=$field1 - os=$field2 + basic_os=$field2 ;; esac ;; @@ -191,447 +190,451 @@ case $1 in case $field1 in 386bsd) basic_machine=i386-pc - os=bsd + basic_os=bsd ;; a29khif) basic_machine=a29k-amd - os=udi + basic_os=udi ;; adobe68k) basic_machine=m68010-adobe - os=scout + basic_os=scout ;; alliant) basic_machine=fx80-alliant - os= + basic_os= ;; altos | altos3068) basic_machine=m68k-altos - os= + basic_os= ;; am29k) basic_machine=a29k-none - os=bsd + basic_os=bsd ;; amdahl) basic_machine=580-amdahl - os=sysv + basic_os=sysv ;; amiga) basic_machine=m68k-unknown - os= + basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown - os=amigaos + basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown - os=sysv4 + basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo - os=sysv + basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo - os=bsd + basic_os=bsd ;; aros) basic_machine=i386-pc - os=aros + basic_os=aros ;; aux) basic_machine=m68k-apple - os=aux + basic_os=aux ;; balance) basic_machine=ns32k-sequent - os=dynix + basic_os=dynix ;; blackfin) basic_machine=bfin-unknown - os=linux + basic_os=linux ;; cegcc) basic_machine=arm-unknown - os=cegcc + basic_os=cegcc ;; convex-c1) basic_machine=c1-convex - os=bsd + basic_os=bsd ;; convex-c2) basic_machine=c2-convex - os=bsd + basic_os=bsd ;; convex-c32) basic_machine=c32-convex - os=bsd + basic_os=bsd ;; convex-c34) basic_machine=c34-convex - os=bsd + basic_os=bsd ;; convex-c38) basic_machine=c38-convex - os=bsd + basic_os=bsd ;; cray) basic_machine=j90-cray - os=unicos + basic_os=unicos ;; crds | unos) basic_machine=m68k-crds - os= + basic_os= ;; da30) basic_machine=m68k-da30 - os= + basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec - os= + basic_os= ;; delta88) basic_machine=m88k-motorola - os=sysv3 + basic_os=sysv3 ;; dicos) basic_machine=i686-pc - os=dicos + basic_os=dicos ;; djgpp) basic_machine=i586-pc - os=msdosdjgpp + basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd - os=ebmon + basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson - os=ose + basic_os=ose ;; gmicro) basic_machine=tron-gmicro - os=sysv + basic_os=sysv ;; go32) basic_machine=i386-pc - os=go32 + basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi - os=hms + basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi - os=xray + basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi - os=hms + basic_os=hms ;; harris) basic_machine=m88k-harris - os=sysv3 + basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp - os=hpux + basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp - os=bsd + basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp - os=osf + basic_os=osf ;; hppro) basic_machine=hppa1.1-hp - os=proelf + basic_os=proelf ;; i386mach) basic_machine=i386-mach - os=mach + basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi - os=sysv + basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown - os=linux + basic_os=linux ;; magnum | m3230) basic_machine=mips-mips - os=sysv + basic_os=sysv ;; merlin) basic_machine=ns32k-utek - os=sysv + basic_os=sysv ;; mingw64) basic_machine=x86_64-pc - os=mingw64 + basic_os=mingw64 ;; mingw32) basic_machine=i686-pc - os=mingw32 + basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown - os=mingw32ce + basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k - os=coff + basic_os=coff ;; morphos) basic_machine=powerpc-unknown - os=morphos + basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown - os=moxiebox + basic_os=moxiebox ;; msdos) basic_machine=i386-pc - os=msdos + basic_os=msdos ;; msys) basic_machine=i686-pc - os=msys + basic_os=msys ;; mvs) basic_machine=i370-ibm - os=mvs + basic_os=mvs ;; nacl) basic_machine=le32-unknown - os=nacl + basic_os=nacl ;; ncr3000) basic_machine=i486-ncr - os=sysv4 + basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc - os=netbsd + basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel - os=linux + basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony - os=newsos + basic_os=newsos ;; news1000) basic_machine=m68030-sony - os=newsos + basic_os=newsos ;; necv70) basic_machine=v70-nec - os=sysv + basic_os=sysv ;; nh3000) basic_machine=m68k-harris - os=cxux + basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris - os=cxux + basic_os=cxux ;; nindy960) basic_machine=i960-intel - os=nindy + basic_os=nindy ;; mon960) basic_machine=i960-intel - os=mon960 + basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq - os=nonstopux + basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm - os=os400 + basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson - os=ose + basic_os=ose ;; os68k) basic_machine=m68k-none - os=os68k + basic_os=os68k ;; paragon) basic_machine=i860-intel - os=osf + basic_os=osf ;; parisc) basic_machine=hppa-unknown - os=linux + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp ;; pw32) basic_machine=i586-unknown - os=pw32 + basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc - os=rdos + basic_os=rdos ;; rdos32) basic_machine=i386-pc - os=rdos + basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k - os=coff + basic_os=coff ;; sa29200) basic_machine=a29k-amd - os=udi + basic_os=udi ;; sei) basic_machine=mips-sei - os=seiux + basic_os=seiux ;; sequent) basic_machine=i386-sequent - os= + basic_os= ;; sps7) basic_machine=m68k-bull - os=sysv2 + basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem - os= + basic_os= ;; stratus) basic_machine=i860-stratus - os=sysv4 + basic_os=sysv4 ;; sun2) basic_machine=m68000-sun - os= + basic_os= ;; sun2os3) basic_machine=m68000-sun - os=sunos3 + basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun - os=sunos4 + basic_os=sunos4 ;; sun3) basic_machine=m68k-sun - os= + basic_os= ;; sun3os3) basic_machine=m68k-sun - os=sunos3 + basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun - os=sunos4 + basic_os=sunos4 ;; sun4) basic_machine=sparc-sun - os= + basic_os= ;; sun4os3) basic_machine=sparc-sun - os=sunos3 + basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun - os=sunos4 + basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun - os=solaris2 + basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun - os= + basic_os= ;; sv1) basic_machine=sv1-cray - os=unicos + basic_os=unicos ;; symmetry) basic_machine=i386-sequent - os=dynix + basic_os=dynix ;; t3e) basic_machine=alphaev5-cray - os=unicos + basic_os=unicos ;; t90) basic_machine=t90-cray - os=unicos + basic_os=unicos ;; toad1) basic_machine=pdp10-xkl - os=tops20 + basic_os=tops20 ;; tpf) basic_machine=s390x-ibm - os=tpf + basic_os=tpf ;; udi29k) basic_machine=a29k-amd - os=udi + basic_os=udi ;; ultra3) basic_machine=a29k-nyu - os=sym1 + basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec - os=none + basic_os=none ;; vaxv) basic_machine=vax-dec - os=sysv + basic_os=sysv ;; vms) basic_machine=vax-dec - os=vms + basic_os=vms ;; vsta) basic_machine=i386-pc - os=vsta + basic_os=vsta ;; vxworks960) basic_machine=i960-wrs - os=vxworks + basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs - os=vxworks + basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs - os=vxworks + basic_os=vxworks ;; xbox) basic_machine=i686-pc - os=mingw32 + basic_os=mingw32 ;; ymp) basic_machine=ymp-cray - os=unicos + basic_os=unicos ;; *) basic_machine=$1 - os= + basic_os= ;; esac ;; @@ -683,17 +686,17 @@ case $basic_machine in bluegene*) cpu=powerpc vendor=ibm - os=cnk + basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec - os=tops10 + basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec - os=tops20 + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) @@ -703,7 +706,7 @@ case $basic_machine in dpx2*) cpu=m68k vendor=bull - os=sysv3 + basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k @@ -712,7 +715,7 @@ case $basic_machine in elxsi) cpu=elxsi vendor=elxsi - os=${os:-bsd} + basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 @@ -725,7 +728,7 @@ case $basic_machine in h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi - os=hiuxwe2 + basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 @@ -766,38 +769,38 @@ case $basic_machine in vendor=hp ;; i*86v32) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv32 + basic_os=sysv32 ;; i*86v4*) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv4 + basic_os=sysv4 ;; i*86v) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv + basic_os=sysv ;; i*86sol2) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=solaris2 + basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray - os=${os:-unicos} + basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi - case $os in + case $basic_os in irix*) ;; *) - os=irix4 + basic_os=irix4 ;; esac ;; @@ -808,26 +811,26 @@ case $basic_machine in *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari - os=mint + basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony - os=newsos + basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next - case $os in + case $basic_os in openstep*) ;; nextstep*) ;; ns2*) - os=nextstep2 + basic_os=nextstep2 ;; *) - os=nextstep3 + basic_os=nextstep3 ;; esac ;; @@ -838,12 +841,12 @@ case $basic_machine in op50n-* | op60c-*) cpu=hppa1.1 vendor=oki - os=proelf + basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi - os=hiuxwe2 + basic_os=hiuxwe2 ;; pbd) cpu=sparc @@ -880,12 +883,12 @@ case $basic_machine in sde) cpu=mipsisa32 vendor=sde - os=${os:-elf} + basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs - os=vxworks + basic_os=vxworks ;; tower | tower-32) cpu=m68k @@ -902,7 +905,7 @@ case $basic_machine in w89k-*) cpu=hppa1.1 vendor=winbond - os=proelf + basic_os=proelf ;; none) cpu=none @@ -914,7 +917,7 @@ case $basic_machine in ;; leon-*|leon[3-9]-*) cpu=sparc - vendor=`echo "$basic_machine" | sed 's/-.*//'` + vendor=$(echo "$basic_machine" | sed 's/-.*//') ;; *-*) @@ -955,11 +958,11 @@ case $cpu-$vendor in # some cases the only manufacturer, in others, it is the most popular. craynv-unknown) vendor=cray - os=${os:-unicosmp} + basic_os=${basic_os:-unicosmp} ;; c90-unknown | c90-cray) vendor=cray - os=${os:-unicos} + basic_os=${Basic_os:-unicos} ;; fx80-unknown) vendor=alliant @@ -1003,7 +1006,7 @@ case $cpu-$vendor in dpx20-unknown | dpx20-bull) cpu=rs6000 vendor=bull - os=${os:-bosx} + basic_os=${basic_os:-bosx} ;; # Here we normalize CPU types irrespective of the vendor @@ -1012,7 +1015,7 @@ case $cpu-$vendor in ;; blackfin-*) cpu=bfin - os=linux + basic_os=linux ;; c54x-*) cpu=tic54x @@ -1025,7 +1028,7 @@ case $cpu-$vendor in ;; e500v[12]-*) cpu=powerpc - os=$os"spe" + basic_os=${basic_os}"spe" ;; mips3*-*) cpu=mips64 @@ -1035,7 +1038,7 @@ case $cpu-$vendor in ;; m68knommu-*) cpu=m68k - os=linux + basic_os=linux ;; m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) cpu=s12z @@ -1045,7 +1048,7 @@ case $cpu-$vendor in ;; parisc-*) cpu=hppa - os=linux + basic_os=linux ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 @@ -1081,7 +1084,7 @@ case $cpu-$vendor in cpu=mipsisa64sb1el ;; sh5e[lb]-*) - cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` + cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/') ;; spur-*) cpu=spur @@ -1099,13 +1102,16 @@ case $cpu-$vendor in cpu=x86_64 ;; xscale-* | xscalee[bl]-*) - cpu=`echo "$cpu" | sed 's/^xscale/arm/'` + cpu=$(echo "$cpu" | sed 's/^xscale/arm/') + ;; + arm64-*) + cpu=aarch64 ;; # Recognize the canonical CPU Types that limit and/or modify the # company names they are paired with. cr16-*) - os=${os:-elf} + basic_os=${basic_os:-elf} ;; crisv32-* | etraxfs*-*) cpu=crisv32 @@ -1116,7 +1122,7 @@ case $cpu-$vendor in vendor=axis ;; crx-*) - os=${os:-elf} + basic_os=${basic_os:-elf} ;; neo-tandem) cpu=neo @@ -1138,16 +1144,12 @@ case $cpu-$vendor in cpu=nsx vendor=tandem ;; - s390-*) - cpu=s390 - vendor=ibm - ;; - s390x-*) - cpu=s390x - vendor=ibm + mipsallegrexel-sony) + cpu=mipsallegrexel + vendor=sony ;; tile*-*) - os=${os:-linux-gnu} + basic_os=${basic_os:-linux-gnu} ;; *) @@ -1163,8 +1165,8 @@ case $cpu-$vendor in | alphapca5[67] | alpha64pca5[67] \ | am33_2.0 \ | amdgcn \ - | arc | arceb \ - | arm | arm[lb]e | arme[lb] | armv* \ + | arc | arceb | arc64 \ + | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ | asmjs \ | ba \ @@ -1183,6 +1185,7 @@ case $cpu-$vendor in | k1om \ | le32 | le64 \ | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ @@ -1201,9 +1204,13 @@ case $cpu-$vendor in | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r3 | mipsisa32r3el \ + | mipsisa32r5 | mipsisa32r5el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r3 | mipsisa64r3el \ + | mipsisa64r5 | mipsisa64r5el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ @@ -1227,8 +1234,9 @@ case $cpu-$vendor in | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ | pru \ | pyramid \ - | riscv | riscv32 | riscv64 \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ | score \ | sh | shl \ | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ @@ -1238,6 +1246,7 @@ case $cpu-$vendor in | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ | spu \ | tahoe \ + | thumbv7* \ | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ | tron \ | ubicom32 \ @@ -1275,8 +1284,47 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x$os != x ] +if test x$basic_os != x then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|') + ;; + os2-emx) + kernel=os2 + os=$(echo $basic_os | sed -e 's|os2-emx|emx|') + ;; + nto-qnx*) + kernel=nto + os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|') + ;; + *-*) + # shellcheck disable=SC2162 + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1528,6 +1503,7 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. +kernel= case $cpu-$vendor in score-*) os=elf @@ -1539,7 +1515,8 @@ case $cpu-$vendor in os=riscix1.2 ;; arm*-rebel) - os=linux + kernel=linux + os=gnu ;; arm*-semi) os=aout @@ -1705,84 +1682,178 @@ case $cpu-$vendor in os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + musl* | newlib* | uclibc*) + ;; + # Likewise for "kernel-abi" + eabi* | gnueabi*) + ;; + # VxWorks passes extra cpu info in the 4th filed. + simlinux | simwindows | spe) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* | serenity* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) - case $os in - riscix*) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - sunos*) + *-sunos*) vendor=sun ;; - cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - beos*) + *-beos*) vendor=be ;; - hpux*) + *-hpux*) vendor=hp ;; - mpeix*) + *-mpeix*) vendor=hp ;; - hiux*) + *-hiux*) vendor=hitachi ;; - unos*) + *-unos*) vendor=crds ;; - dgux*) + *-dgux*) vendor=dg ;; - luna*) + *-luna*) vendor=omron ;; - genix*) + *-genix*) vendor=ns ;; - clix*) + *-clix*) vendor=intergraph ;; - mvs* | opened*) + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) vendor=ibm ;; - os400*) + s390-* | s390x-*) vendor=ibm ;; - ptx*) + *-ptx*) vendor=sequent ;; - tpf*) + *-tpf*) vendor=ibm ;; - vxsim* | vxworks* | windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - aux*) + *-aux*) vendor=apple ;; - hms*) + *-hms*) vendor=hitachi ;; - mpw* | macos*) + *-mpw* | *-macos*) vendor=apple ;; - *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - vos*) + *-vos*) vendor=stratus ;; esac ;; esac -echo "$cpu-$vendor-$os" +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: diff --git a/depends/funcs.mk b/depends/funcs.mk index 58d882eb05..34a030fab7 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -1,17 +1,23 @@ define int_vars #Set defaults for vars which may be overridden per-package -$(1)_cc=$($($(1)_type)_CC) -$(1)_cxx=$($($(1)_type)_CXX) -$(1)_objc=$($($(1)_type)_OBJC) -$(1)_objcxx=$($($(1)_type)_OBJCXX) -$(1)_ar=$($($(1)_type)_AR) -$(1)_ranlib=$($($(1)_type)_RANLIB) -$(1)_libtool=$($($(1)_type)_LIBTOOL) -$(1)_nm=$($($(1)_type)_NM) -$(1)_cflags=$($($(1)_type)_CFLAGS) $($($(1)_type)_$(release_type)_CFLAGS) -$(1)_cxxflags=$($($(1)_type)_CXXFLAGS) $($($(1)_type)_$(release_type)_CXXFLAGS) -$(1)_ldflags=$($($(1)_type)_LDFLAGS) $($($(1)_type)_$(release_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib -$(1)_cppflags=$($($(1)_type)_CPPFLAGS) $($($(1)_type)_$(release_type)_CPPFLAGS) -I$($($(1)_type)_prefix)/include +$(1)_cc=$$($$($(1)_type)_CC) +$(1)_cxx=$$($$($(1)_type)_CXX) +$(1)_objc=$$($$($(1)_type)_OBJC) +$(1)_objcxx=$$($$($(1)_type)_OBJCXX) +$(1)_ar=$$($$($(1)_type)_AR) +$(1)_ranlib=$$($$($(1)_type)_RANLIB) +$(1)_libtool=$$($$($(1)_type)_LIBTOOL) +$(1)_nm=$$($$($(1)_type)_NM) +$(1)_cflags=$$($$($(1)_type)_CFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CFLAGS) +$(1)_cxxflags=$$($$($(1)_type)_CXXFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CXXFLAGS) +$(1)_ldflags=$$($$($(1)_type)_LDFLAGS) \ + $$($$($(1)_type)_$$(release_type)_LDFLAGS) \ + -L$$($($(1)_type)_prefix)/lib +$(1)_cppflags=$$($$($(1)_type)_CPPFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CPPFLAGS) \ + -I$$($$($(1)_type)_prefix)/include $(1)_recipe_hash:= endef @@ -43,7 +49,7 @@ define int_get_build_id $(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies)) $(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($($(1)_type)_native_binutils) $($(1)_dependencies))) $(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash))) -$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id_string)) +$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id)) $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) final_build_id_long+=$($(package)_build_id_long) @@ -134,7 +140,13 @@ $(1)_config_env+=CMAKE_MODULE_PATH=$($($(1)_type)_prefix)/lib/cmake $(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH) -$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" + +# Setting a --build type that differs from --host will explicitly enable +# cross-compilation mode. Note that --build defaults to the output of +# config.guess, which is what we set it too here. This also quells autoconf +# warnings, "If you wanted to set the --build type, don't use --host.", +# when using versions older than 2.70. +$(1)_autoconf=./configure --build=$(BUILD) --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" ifneq ($($(1)_nm),) $(1)_autoconf += NM="$$($(1)_nm)" endif @@ -163,7 +175,9 @@ $(1)_cmake=env CC="$$($(1)_cc)" \ CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \ LDFLAGS="$$($(1)_ldflags)" \ cmake -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" -ifneq ($($(1)_type),build) +ifeq ($($(1)_type),build) +$(1)_cmake += -DCMAKE_INSTALL_RPATH:PATH="$$($($(1)_type)_prefix)/lib" +else ifneq ($(host),$(build)) $(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system) $(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host) diff --git a/depends/gen_id b/depends/gen_id new file mode 100755 index 0000000000..ac69ca7ee1 --- /dev/null +++ b/depends/gen_id @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# Usage: env [ CC=... ] [ CXX=... ] [ AR=... ] [ RANLIB=... ] [ STRIP=... ] \ +# [ DEBUG=... ] ./build-id [ID_SALT]... +# +# Prints to stdout a SHA256 hash representing the current toolset, used by +# depends/Makefile as a build id for caching purposes (detecting when the +# toolset has changed and the cache needs to be invalidated). +# +# If the DEBUG environment variable is non-empty and the system has `tee` +# available in its $PATH, the pre-image to the SHA256 hash will be printed to +# stderr. This is to help developers debug caching issues in depends. + +# This script explicitly does not `set -e` because id determination is mostly +# opportunistic: it is fine that things fail, as long as they fail consistently. + +# Command variables (CC/CXX/AR) which can be blank are invoked with `bash -c`, +# because the "command not found" error message printed by shells often include +# the line number, like so: +# +# ./depends/gen_id: line 43: --version: command not found +# +# By invoking with `bash -c`, we ensure that the line number is always 1 + +( + # Redirect stderr to stdout + exec 2>&1 + + echo "BEGIN ALL" + + # Include any ID salts supplied via command line + echo "BEGIN ID SALT" + echo "$@" + echo "END ID SALT" + + # GCC only prints COLLECT_LTO_WRAPPER when invoked with just "-v", but we want + # the information from "-v -E -" as well, so just include both. + echo "BEGIN CC" + bash -c "${CC} -v" + bash -c "${CC} -v -E -xc -o /dev/null - < /dev/null" + bash -c "${CC} -v -E -xobjective-c -o /dev/null - < /dev/null" + echo "END CC" + + echo "BEGIN CXX" + bash -c "${CXX} -v" + bash -c "${CXX} -v -E -xc++ -o /dev/null - < /dev/null" + bash -c "${CXX} -v -E -xobjective-c++ -o /dev/null - < /dev/null" + echo "END CXX" + + echo "BEGIN AR" + bash -c "${AR} --version" + env | grep '^AR_' + echo "ZERO_AR_DATE=${ZERO_AR_DATE}" + echo "END AR" + + echo "BEGIN RANLIB" + bash -c "${RANLIB} --version" + env | grep '^RANLIB_' + echo "END RANLIB" + + echo "BEGIN STRIP" + bash -c "${STRIP} --version" + env | grep '^STRIP_' + echo "END STRIP" + + echo "END ALL" +) | if [ -n "$DEBUG" ] && command -v tee > /dev/null 2>&1; then + # When debugging and `tee` is available, output the preimage to stderr + # in addition to passing through stdin to stdout + tee >(cat 1>&2) + else + # Otherwise, passthrough stdin to stdout + cat + fi | ${SHA256SUM} - | cut -d' ' -f1 diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index af5e78b304..5a7ae2df9a 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,12 +1,53 @@ - -OSX_MIN_VERSION=10.12 -OSX_SDK_VERSION=10.15.1 -XCODE_VERSION=11.3.1 -XCODE_BUILD_ID=11C505 -LD64_VERSION=530 +OSX_MIN_VERSION=10.14 +OSX_SDK_VERSION=10.15.6 +XCODE_VERSION=12.1 +XCODE_BUILD_ID=12A7403 +LD64_VERSION=609 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers +darwin_native_binutils=native_cctools + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +# FORCE_USE_SYSTEM_CLANG is empty, so we use our depends-managed, pinned clang +# from llvm.org + +# Clang is a dependency of native_cctools when FORCE_USE_SYSTEM_CLANG is empty +darwin_native_toolchain=native_cctools + +clang_prog=$(build_prefix)/bin/clang +clangxx_prog=$(clang_prog)++ + +clang_resource_dir=$(build_prefix)/lib/clang/$(native_clang_version) +else +# FORCE_USE_SYSTEM_CLANG is non-empty, so we use the clang from the user's +# system + +darwin_native_toolchain= + +# We can't just use $(shell command -v clang) because GNU Make handles builtins +# in a special way and doesn't know that `command` is a POSIX-standard builtin +# prior to 1af314465e5dfe3e8baa839a32a72e83c04f26ef, first released in v4.2.90. +# At the time of writing, GNU Make v4.2.1 is still being used in supported +# distro releases. +# +# Source: https://lists.gnu.org/archive/html/bug-make/2017-11/msg00017.html +clang_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang") +clangxx_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") + +clang_resource_dir=$(shell clang -print-resource-dir) +endif + +cctools_TOOLS=AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL + +# Make-only lowercase function +lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) + +# For well-known tools provided by cctools, make sure that their well-known +# variable is set to the full path of the tool, just like how AC_PATH_{TOO,PROG} +# would. +$(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$(host)-$(call lc,$(TOOL)))) + # Flag explanations: # # -mlinker-version @@ -19,18 +60,54 @@ OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with- # Explicitly point to our binaries (e.g. cctools) so that they are # ensured to be found and preferred over other possibilities. # -# -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 +# -stdlib=libc++ -stdlib++-isystem$(OSX_SDK)/usr/include/c++/v1 # # Forces clang to use the libc++ headers from our SDK and completely # forget about the libc++ headers from the standard directories # -# TODO: Once we start requiring a clang version that has the -# -stdlib++-isystem flag first introduced here: -# https://reviews.llvm.org/D64089, we should use that instead. Read the -# differential summary there for more details. +# -Xclang -*system \ +# -Xclang -*system \ +# -Xclang -*system ... +# +# Adds path_a, path_b, and path_c to the bottom of clang's list of +# include search paths. This is used to explicitly specify the list of +# system include search paths and its ordering, rather than rely on +# clang's autodetection routine. This routine has been shown to: +# 1. Fail to pickup libc++ headers in $SYSROOT/usr/include/c++/v1 +# when clang was built manually (see: https://github.com/bitcoin/bitcoin/pull/17919#issuecomment-656785034) +# 2. Fail to pickup C headers in $SYSROOT/usr/include when +# C_INCLUDE_DIRS was specified at configure time (see: https://gist.github.com/dongcarl/5cdc6990b7599e8a5bf6d2a9c70e82f9) +# +# Talking directly to cc1 with -Xclang here grants us access to specify +# more granular categories for these system include search paths, and we +# can use the correct categories that these search paths would have been +# placed in if the autodetection routine had worked correctly. (see: +# https://gist.github.com/dongcarl/5cdc6990b7599e8a5bf6d2a9c70e82f9#the-treatment) +# +# Furthermore, it places these search paths after any "non-Xclang" +# specified search paths. This prevents any additional clang options or +# environment variables from coming after or in between these system +# include search paths, as that would be wrong in general but would also +# break #include_next's. # -darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin -darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -stdlib=libc++ -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 +darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ + -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ + -u LIBRARY_PATH \ + $(clang_prog) --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ + -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ + -isysroot$(OSX_SDK) \ + -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ + -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include +darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ + -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ + -u LIBRARY_PATH \ + $(clangxx_prog) --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ + -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ + -isysroot$(OSX_SDK) \ + -stdlib=libc++ \ + -stdlib++-isystem$(OSX_SDK)/usr/include/c++/v1 \ + -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ + -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) @@ -41,11 +118,4 @@ darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) darwin_debug_CFLAGS=-O1 darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) -darwin_native_binutils=native_cctools -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -darwin_native_toolchain=native_cctools -else -darwin_native_toolchain= -endif - -darwin_cmake_system=Darwin \ No newline at end of file +darwin_cmake_system=Darwin diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index 8ab448ce5f..07da752492 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -7,7 +7,7 @@ linux_release_CXXFLAGS=$(linux_release_CFLAGS) linux_debug_CFLAGS=-O1 linux_debug_CXXFLAGS=$(linux_debug_CFLAGS) -linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC +linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_LIBCPP_DEBUG=1 ifeq (86,$(findstring 86,$(build_arch))) i686_linux_CC=gcc -m32 diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index d6204df6bb..85a067cf34 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -8,20 +8,21 @@ $(package)_build_subdir=build_unix define $(package)_set_vars $(package)_config_opts=--disable-shared --enable-cxx --disable-replication --enable-option-checking $(package)_config_opts_mingw32=--enable-mingw -$(package)_config_opts_mingw64=--enable-mingw $(package)_config_opts_linux=--with-pic $(package)_config_opts_freebsd=--with-pic ifneq ($(build_os),darwin) $(package)_config_opts_darwin=--disable-atomicsupport endif $(package)_config_opts_aarch64=--disable-atomicsupport -$(package)_cxxflags=-std=c++11 +$(package)_cflags+=-Wno-error=implicit-function-declaration +$(package)_cxxflags=-std=c++17 $(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef define $(package)_preprocess_cmds sed -i.old 's/WinIoCtl.h/winioctl.h/g' src/dbinc/win_db.h && \ - sed -i.old 's/atomic_init/atomic_init_db/' src/dbinc/atomic.h src/mp/mp_region.c src/mp/mp_mvcc.c src/mp/mp_fget.c src/mutex/mut_method.c src/mutex/mut_tas.c + sed -i.old 's/atomic_init/atomic_init_db/' src/dbinc/atomic.h src/mp/mp_region.c src/mp/mp_mvcc.c src/mp/mp_fget.c src/mutex/mut_method.c src/mutex/mut_tas.c && \ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub dist endef define $(package)_config_cmds diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 0717a55e09..2a10f1fee0 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,45 +1,46 @@ package=boost -$(package)_version=1_70_0 -$(package)_download_path=https://dl.bintray.com/boostorg/release/1.70.0/source/ +$(package)_version=1_71_0 +$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/ $(package)_file_name=boost_$($(package)_version).tar.bz2 -$(package)_sha256_hash=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 -$(package)_patches=unused_var_in_process.patch +$(package)_sha256_hash=d73a8da01e8bf8c7eda40b4c84915071a8c8a0df4a6734537ddde4a8580524ee +$(package)_dependencies=native_b2 define $(package)_set_vars $(package)_config_opts_release=variant=release $(package)_config_opts_debug=variant=debug $(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam -$(package)_config_opts+=threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1 +$(package)_config_opts+=threading=multi link=static -sNO_COMPRESSION=1 $(package)_config_opts_linux=target-os=linux threadapi=pthread runtime-link=shared $(package)_config_opts_darwin=target-os=darwin runtime-link=shared $(package)_config_opts_mingw32=target-os=windows binary-format=pe threadapi=win32 runtime-link=static -$(package)_config_opts_x86_64_mingw32=address-model=64 -$(package)_config_opts_i686_mingw32=address-model=32 -$(package)_config_opts_i686_linux=address-model=32 architecture=x86 -$(package)_toolset_$(host_os)=gcc -$(package)_toolset_darwin=clang +$(package)_config_opts_x86_64=architecture=x86 address-model=64 +$(package)_config_opts_i686=architecture=x86 address-model=32 +$(package)_config_opts_aarch64=address-model=64 +$(package)_config_opts_armv7a=address-model=32 ifneq (,$(findstring clang,$($(package)_cxx))) - $(package)_toolset_$(host_os)=clang +$(package)_toolset_$(host_os)=clang +else +$(package)_toolset_$(host_os)=gcc endif -$(package)_archiver_$(host_os)=$($(package)_ar) -$(package)_config_libraries=chrono,filesystem,program_options,system,thread,test -$(package)_cxxflags=-std=c++11 -fvisibility=hidden +$(package)_config_libraries=chrono,filesystem,program_options,system,thread,test,random +$(package)_cxxflags=-std=c++17 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC +$(package)_cxxflags_android=-fPIC +$(package)_cxxflags_x86_64_darwin=-fcf-protection=full endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/unused_var_in_process.patch && \ - echo "using $($(package)_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cxxflags) $($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$($(package)_archiver_$(host_os))\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam + echo "using $($(package)_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cflags)\" \"$($(package)_cxxflags)\" \"$($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$($(package)_ar)\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam endef define $(package)_config_cmds - ./bootstrap.sh --without-icu --with-libraries=$($(package)_config_libraries) --with-toolset=$($(package)_toolset_$(host_os)) + ./bootstrap.sh --without-icu --with-libraries=$($(package)_config_libraries) --with-toolset=$($(package)_toolset_$(host_os)) --with-bjam=b2 endef define $(package)_build_cmds - ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) stage + b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) stage endef define $(package)_stage_cmds - ./b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) install + b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) install endef diff --git a/depends/packages/capnp.mk b/depends/packages/capnp.mk new file mode 100644 index 0000000000..abeb26545f --- /dev/null +++ b/depends/packages/capnp.mk @@ -0,0 +1,18 @@ +package=capnp +$(package)_version=$(native_$(package)_version) +$(package)_download_path=$(native_$(package)_download_path) +$(package)_file_name=$(native_$(package)_file_name) +$(package)_sha256_hash=$(native_$(package)_sha256_hash) +$(package)_dependencies=native_$(package) + +define $(package)_config_cmds + $($(package)_autoconf) --with-external-capnp +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/dbus.mk b/depends/packages/dbus.mk index a0aae3d769..25732b2da5 100644 --- a/depends/packages/dbus.mk +++ b/depends/packages/dbus.mk @@ -1,8 +1,8 @@ package=dbus -$(package)_version=1.12.20 +$(package)_version=1.13.20 $(package)_download_path=https://dbus.freedesktop.org/releases/dbus -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=F77620140ECB4CDC67F37FB444F8A6BEA70B5B6461F12F1CBE2CEC60FA7DE5FE +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=a9c4b7bad9f49ffa4f199a12aedcdad5d5dcef875d794829fd1378153e072963 $(package)_dependencies=expat define $(package)_set_vars diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 90e875f61f..902fe43be2 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -5,7 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=cbc9102f4a31a8dafd42d642e9a3aa31e79a0aedaa1f6efd2795ebc83174ec18 define $(package)_set_vars - $(package)_config_opts=--disable-shared --without-docbook + $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic endef diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index 244185cae7..5da5871c0a 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -1,14 +1,14 @@ package=libXau -$(package)_version=1.0.8 +$(package)_version=1.0.9 $(package)_download_path=https://xorg.freedesktop.org/releases/individual/lib/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=fdd477320aeb5cdd67272838722d6b7d544887dfe7de46e1e7cc0c27c2bea4f2 +$(package)_sha256_hash=ccf8cbf0dbf676faa2ea0a6d64bcc3b6746064722b606c8c52917ed00dcb73ec $(package)_dependencies=xproto # When updating this package, check the default value of # --disable-xthreads. It is currently enabled. define $(package)_set_vars - $(package)_config_opts=--disable-shared + $(package)_config_opts=--disable-shared --disable-lint-library --without-lint $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index b75b7c3cf4..0af5412d94 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -1,14 +1,8 @@ package=libevent -$(package)_version=2.1.11-stable -$(package)_download_path=https://github.com/libevent/libevent/archive/ -$(package)_file_name=release-$($(package)_version).tar.gz -$(package)_sha256_hash=229393ab2bf0dc94694f21836846b424f3532585bac3468738b7bf752c03901e -$(package)_patches=0001-fix-windows-getaddrinfo.patch - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/0001-fix-windows-getaddrinfo.patch && \ - ./autogen.sh -endef +$(package)_version=2.1.12-stable +$(package)_download_path=https://github.com/libevent/libevent/releases/download/release-$($(package)_version)/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb # When building for Windows, we set _WIN32_WINNT to target the same Windows # version as we do in configure. Due to quirks in libevents build system, this @@ -18,9 +12,14 @@ define $(package)_set_vars $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_release=--disable-debug-mode $(package)_config_opts_linux=--with-pic + $(package)_config_opts_android=--with-pic $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 endef +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux +endef + define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/packages/libmultiprocess.mk b/depends/packages/libmultiprocess.mk new file mode 100644 index 0000000000..3e5cf5f160 --- /dev/null +++ b/depends/packages/libmultiprocess.mk @@ -0,0 +1,18 @@ +package=libmultiprocess +$(package)_version=$(native_$(package)_version) +$(package)_download_path=$(native_$(package)_download_path) +$(package)_file_name=$(native_$(package)_file_name) +$(package)_sha256_hash=$(native_$(package)_sha256_hash) +$(package)_dependencies=native_$(package) boost capnp + +define $(package)_config_cmds + $($(package)_cmake) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index e6fd89014a..7911f8d0f7 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -1,14 +1,13 @@ package=libxcb -$(package)_version=1.10 +$(package)_version=1.14 $(package)_download_path=https://xcb.freedesktop.org/dist -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c3f2d5b5 +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=2c7fcddd1da34d9b238c9caeda20d3bd7486456fc50b3cc6567185dbd5b0ad02 $(package)_dependencies=xcb_proto libXau xproto define $(package)_set_vars $(package)_config_opts=--disable-static $(package)_config_opts += --disable-dependency-tracking --enable-option-checking - # Because we pass -qt-xcb to Qt, it will compile in a set of xcb helper libraries and extensions, # so we skip building all of the extensions here. # More info is available from: https://doc.qt.io/qt-5.9/linux-requirements.html @@ -16,15 +15,15 @@ $(package)_config_opts += --disable-composite --disable-damage --disable-dpms $(package)_config_opts += --disable-dri2 --disable-dri3 --disable-glx $(package)_config_opts += --disable-present --disable-randr --disable-record $(package)_config_opts += --disable-render --disable-resource --disable-screensaver -$(package)_config_opts += --disable-shape --disable-shm --disable-sync +$(package)_config_opts += --disable-shape --disable-sync $(package)_config_opts += --disable-xevie --disable-xfixes --disable-xfree86-dri -$(package)_config_opts += --disable-xinerama --disable-xinput --disable-xkb +$(package)_config_opts += --disable-xinerama --disable-xinput $(package)_config_opts += --disable-xprint --disable-selinux --disable-xtest $(package)_config_opts += --disable-xv --disable-xvmc endef define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux &&\ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux && \ sed "s/pthread-stubs//" -i configure endef diff --git a/depends/packages/libxkbcommon.mk b/depends/packages/libxkbcommon.mk new file mode 100644 index 0000000000..8c6c56545f --- /dev/null +++ b/depends/packages/libxkbcommon.mk @@ -0,0 +1,32 @@ +package=libxkbcommon +$(package)_version=0.8.4 +$(package)_download_path=https://xkbcommon.org/download/ +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=60ddcff932b7fd352752d51a5c4f04f3d0403230a584df9a2e0d5ed87c486c8b +$(package)_dependencies=libxcb + +define $(package)_set_vars +$(package)_config_opts = --enable-option-checking --disable-dependency-tracking +$(package)_config_opts += --disable-static --disable-docs +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef + diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 49a584e462..99f5b0a8db 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,9 +1,9 @@ package=miniupnpc -$(package)_version=2.0.20180203 +$(package)_version=2.2.2 $(package)_download_path=https://miniupnp.tuxfamily.org/files/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=90dda8c7563ca6cd4a83e23b3c66dbbea89603a1675bfdb852897c2c9cc220b7 -$(package)_patches=dont_use_wingen.patch +$(package)_sha256_hash=888fb0976ba61518276fe1eda988589c700a3f2a69d71089260d75562afd3687 +$(package)_patches=dont_leak_info.patch define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" @@ -13,9 +13,7 @@ $(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$ endef define $(package)_preprocess_cmds - mkdir dll && \ - sed -e 's|MINIUPNPC_VERSION_STRING \"version\"|MINIUPNPC_VERSION_STRING \"$($(package)_version)\"|' -e 's|OS/version|$(host)|' miniupnpcstrings.h.in > miniupnpcstrings.h && \ - patch -p1 < $($(package)_patch_dir)/dont_use_wingen.patch + patch -p1 < $($(package)_patch_dir)/dont_leak_info.patch endef define $(package)_build_cmds diff --git a/depends/packages/native_b2.mk b/depends/packages/native_b2.mk new file mode 100644 index 0000000000..aaa37cdcfa --- /dev/null +++ b/depends/packages/native_b2.mk @@ -0,0 +1,20 @@ +package=native_b2 +$(package)_version=$(boost_version) +$(package)_download_path=$(boost_download_path) +$(package)_file_name=$(boost_file_name) +$(package)_sha256_hash=$(boost_sha256_hash) +$(package)_build_subdir=tools/build/src/engine +ifneq (,$(findstring clang,$($(package)_cxx))) +$(package)_toolset_$(host_os)=clang +else +$(package)_toolset_$(host_os)=gcc +endif + +define $(package)_build_cmds + CXX="$($(package)_cxx)" CXXFLAGS="$($(package)_cxxflags)" ./build.sh "$($(package)_toolset_$(host_os))" +endef + +define $(package)_stage_cmds + mkdir -p "$($(package)_staging_prefix_dir)"/bin/ && \ + cp b2 "$($(package)_staging_prefix_dir)"/bin/ +endef diff --git a/depends/packages/native_capnp.mk b/depends/packages/native_capnp.mk new file mode 100644 index 0000000000..ed5a6deee2 --- /dev/null +++ b/depends/packages/native_capnp.mk @@ -0,0 +1,18 @@ +package=native_capnp +$(package)_version=0.7.0 +$(package)_download_path=https://capnproto.org/ +$(package)_download_file=capnproto-c++-$($(package)_version).tar.gz +$(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz +$(package)_sha256_hash=c9a4c0bd88123064d483ab46ecee777f14d933359e23bff6fb4f4dbd28b4cd41 + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk index c7655c4c3d..b098455c44 100644 --- a/depends/packages/native_ccache.mk +++ b/depends/packages/native_ccache.mk @@ -1,8 +1,8 @@ package=native_ccache -$(package)_version=3.5 +$(package)_version=3.6 $(package)_download_path=https://samba.org/ftp/ccache $(package)_file_name=ccache-$($(package)_version).tar.bz2 -$(package)_sha256_hash=3a4c81a05b6c98d4e671e00b15f09718da6afabfbeeace9030b067aee1395e66 +$(package)_sha256_hash=c23ecf1253e0d12c9da9dda9567a88a606d46f93d9982b8b1a423d6f238bd435 define $(package)_set_vars $(package)_config_opts= diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index 62aef0aabb..d169eb6723 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,85 +1,23 @@ package=native_cctools -$(package)_version=4da2f3b485bcf4cef526f30c0b8c0bcda99cdbb4 +$(package)_version=2ef2e931cf641547eb8a68cfebde61003587c9fd $(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=a2d491c0981cef72fee2b833598f20f42a6c44a7614a61c439bda93d56446fec +$(package)_sha256_hash=6b73269efdf5c58a070e7357b66ee760501388549d6a12b423723f45888b074b $(package)_build_subdir=cctools -$(package)_patches=ld64_disable_threading.patch - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -$(package)_clang_version=8.0.0 -$(package)_clang_download_path=https://releases.llvm.org/$($(package)_clang_version) -$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-16.04.tar.xz -$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-16.04.tar.xz -$(package)_clang_sha256_hash=87b88d620284d1f0573923e6f7cc89edccf11d19ebaec1cfb83b4f09ac5db09c -endif - -$(package)_libtapi_version=3efb201881e7a76a21e0554906cf306432539cef -$(package)_libtapi_download_path=https://github.com/tpoechtrager/apple-libtapi/archive -$(package)_libtapi_download_file=$($(package)_libtapi_version).tar.gz -$(package)_libtapi_file_name=$($(package)_libtapi_version).tar.gz -$(package)_libtapi_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3 - -$(package)_extra_sources=$($(package)_libtapi_file_name) -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -$(package)_extra_sources += $($(package)_clang_file_name) -endif - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) -endef -else -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) -endef -endif - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_clang_sha256_hash) $($(package)_source_dir)/$($(package)_clang_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p toolchain/bin toolchain/lib/clang/$($(package)_clang_version)/include && \ - mkdir -p libtapi && \ - tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ - tar --no-same-owner --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ - rm -f toolchain/lib/libc++abi.so* && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -endef -else -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p libtapi && \ - tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -endef -endif +$(package)_dependencies=native_libtapi define $(package)_set_vars - $(package)_config_opts=--target=$(host) --disable-lto-support --with-libtapi=$($(package)_extract_dir) + $(package)_config_opts=--target=$(host) $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) - $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang - $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ - else - $(package)_cc=clang - $(package)_cxx=clang++ + $(package)_config_opts+=--enable-lto-support --with-llvm-config=$(build_prefix)/bin/llvm-config endif + $(package)_cc=$(clang_prog) + $(package)_cxx=$(clangxx_prog) endef define $(package)_preprocess_cmds - CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/build.sh && \ - CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/install.sh && \ - patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub cctools endef define $(package)_config_cmds @@ -90,26 +28,10 @@ define $(package)_build_cmds $(MAKE) endef -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir) && \ - cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir)/toolchain && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \ - mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ - cp bin/clang $($(package)_staging_prefix_dir)/bin/ &&\ - cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ - cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ - cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \ - cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil + $(MAKE) DESTDIR=$($(package)_staging_dir) install endef -else -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir) && \ - cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ + +define $(package)_postprocess_cmds + rm -rf share endef -endif diff --git a/depends/packages/native_clang.mk b/depends/packages/native_clang.mk new file mode 100644 index 0000000000..25ac77c1a3 --- /dev/null +++ b/depends/packages/native_clang.mk @@ -0,0 +1,32 @@ +package=native_clang +$(package)_version=10.0.1 +$(package)_download_path=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) +ifneq (,$(findstring aarch64,$(BUILD))) +$(package)_download_file=clang+llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz +$(package)_file_name=clang+llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz +$(package)_sha256_hash=90dc69a4758ca15cd0ffa45d07fbf5bf4309d47d2c7745a9f0735ecffde9c31f +else +$(package)_download_file=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-16.04.tar.xz +$(package)_file_name=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-16.04.tar.xz +$(package)_sha256_hash=48b83ef827ac2c213d5b64f5ad7ed082c8bcb712b46644e0dc5045c6f462c231 +endif + +define $(package)_preprocess_cmds + rm -f $($(package)_extract_dir)/lib/libc++abi.so* +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_version)/include && \ + mkdir -p $($(package)_staging_prefix_dir)/bin && \ + mkdir -p $($(package)_staging_prefix_dir)/include && \ + cp bin/clang $($(package)_staging_prefix_dir)/bin/ && \ + cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ && \ + cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ + cp bin/llvm-config $($(package)_staging_prefix_dir)/bin/ && \ + cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ + cp -rf lib/clang/$($(package)_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_version)/include/ +endef + +define $(package)_postprocess_cmds + rmdir include +endef diff --git a/depends/packages/native_ds_store.mk b/depends/packages/native_ds_store.mk index f99b689ecd..44108925a4 100644 --- a/depends/packages/native_ds_store.mk +++ b/depends/packages/native_ds_store.mk @@ -1,10 +1,9 @@ package=native_ds_store -$(package)_version=1.1.2 +$(package)_version=1.3.0 $(package)_download_path=https://github.com/al45tair/ds_store/archive/ $(package)_file_name=v$($(package)_version).tar.gz -$(package)_sha256_hash=3b3ecb7bf0a5157f5b6010bc3af7c141fb0ad3527084e63336220d22744bc20c +$(package)_sha256_hash=76b3280cd4e19e5179defa23fb594a9dd32643b0c80d774bd3108361d94fb46d $(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages -$(package)_dependencies=native_biplist define $(package)_build_cmds python3 setup.py build diff --git a/depends/packages/native_libdmg-hfsplus.mk b/depends/packages/native_libdmg-hfsplus.mk index 6e83d030e3..c7c8adef41 100644 --- a/depends/packages/native_libdmg-hfsplus.mk +++ b/depends/packages/native_libdmg-hfsplus.mk @@ -12,17 +12,13 @@ define $(package)_preprocess_cmds endef define $(package)_config_cmds - cmake -GNinja -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix) -DCMAKE_C_FLAGS="-Wl,--build-id=none" .. + $($(package)_cmake) -DCMAKE_C_FLAGS="$$($(1)_cflags) -Wl,--build-id=none" -DCMAKE_SKIP_RPATH="ON" -DCMAKE_EXE_LINKER_FLAGS="-static" -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" .. endef define $(package)_build_cmds - ninja dmg + $(MAKE) -C dmg endef -# Older versions of cmake do not generate install target properly, but we -# need to support them because that's what is in xenial and we use xenial -# for reproducible builds. So we just fallback on installing everything. define $(package)_stage_cmds - DESTDIR=$($(package)_staging_dir) ninja dmg/install || \ - DESTDIR=$($(package)_staging_dir) ninja install + $(MAKE) DESTDIR=$($(package)_staging_dir) -C dmg install endef diff --git a/depends/packages/native_libmultiprocess.mk b/depends/packages/native_libmultiprocess.mk new file mode 100644 index 0000000000..c50fdc3f6b --- /dev/null +++ b/depends/packages/native_libmultiprocess.mk @@ -0,0 +1,18 @@ +package=native_libmultiprocess +$(package)_version=5741d750a04e644a03336090d8979c6d033e32c0 +$(package)_download_path=https://github.com/chaincodelabs/libmultiprocess/archive +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=ac848db49a6ed53e423c62d54bd87f1f08cbb0326254a8667e10bbfe5bf032a4 +$(package)_dependencies=native_capnp + +define $(package)_config_cmds + $($(package)_cmake) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/native_libtapi.mk b/depends/packages/native_libtapi.mk new file mode 100644 index 0000000000..60b898da5f --- /dev/null +++ b/depends/packages/native_libtapi.mk @@ -0,0 +1,20 @@ +package=native_libtapi +$(package)_version=664b8414f89612f2dfd35a9b679c345aa5389026 +$(package)_download_path=https://github.com/tpoechtrager/apple-libtapi/archive +$(package)_download_file=$($(package)_version).tar.gz +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=62e419c12d1c9fad67cc1cd523132bc00db050998337c734c15bc8d73cc02b61 + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +$(package)_dependencies=native_clang +endif + +define $(package)_build_cmds + CC=$(clang_prog) CXX=$(clangxx_prog) INSTALLPREFIX=$($(package)_staging_prefix_dir) ./build.sh +endef + +define $(package)_stage_cmds + ./install.sh && \ + mkdir -p $($(package)_staging_prefix_dir)/include/llvm-c && \ + cp src/llvm/include/llvm-c/lto.h $($(package)_staging_prefix_dir)/include/llvm-c +endef diff --git a/depends/packages/native_mac_alias.mk b/depends/packages/native_mac_alias.mk index e60b99dccc..783f87ca7c 100644 --- a/depends/packages/native_mac_alias.mk +++ b/depends/packages/native_mac_alias.mk @@ -1,8 +1,8 @@ package=native_mac_alias -$(package)_version=2.0.7 +$(package)_version=2.2.0 $(package)_download_path=https://github.com/al45tair/mac_alias/archive/ $(package)_file_name=v$($(package)_version).tar.gz -$(package)_sha256_hash=6f606d3b6bccd2112aeabf1a063f5b5ece87005a5d7e97c8faca23b916e88838 +$(package)_sha256_hash=421e6d7586d1f155c7db3e7da01ca0dacc9649a509a253ad7077b70174426499 $(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages define $(package)_build_cmds diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk index ce50b366fa..0daa0a62bd 100644 --- a/depends/packages/native_protobuf.mk +++ b/depends/packages/native_protobuf.mk @@ -1,11 +1,13 @@ package=native_protobuf -$(package)_version=2.6.1 -$(package)_download_path=https://github.com/google/protobuf/releases/download/v$($(package)_version) -$(package)_file_name=protobuf-$($(package)_version).tar.bz2 -$(package)_sha256_hash=ee445612d544d885ae240ffbcbf9267faa9f593b7b101f21d58beceb92661910 +$(package)_version=3.6.1 +$(package)_download_path=https://github.com/protocolbuffers/protobuf/releases/download/v$($(package)_version)/ +$(package)_file_name=protobuf-cpp-$($(package)_version).tar.gz +$(package)_sha256_hash=b3732e471a9bb7950f090fd0457ebd2536a9ba0891b7f3785919c654fe2a2529 +$(package)_cxxflags=-std=c++11 define $(package)_set_vars -$(package)_config_opts=--disable-shared + $(package)_config_opts=--disable-shared --prefix=$(build_prefix) + $(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds @@ -13,13 +15,13 @@ define $(package)_config_cmds endef define $(package)_build_cmds - $(MAKE) -C src protoc + $(MAKE) -C src endef define $(package)_stage_cmds - $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install-strip + $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install endef define $(package)_postprocess_cmds - rm -rf lib include + rm lib/libprotoc.a endef diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index 26bdb695e2..61c3e7c95f 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -1,8 +1,8 @@ package=openssl -$(package)_version=1.0.2u +$(package)_version=1.1.1m $(package)_download_path=https://www.openssl.org/source $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=ecd0c6ffb493dd06707d38b14bb4d8c2288bb7033735606569d8f90f89669d16 +$(package)_sha256_hash=f89199be8b23ca45fc7cb9f1d8d3ee67312318286ad030f5316aca6462db6c96 define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" @@ -12,48 +12,38 @@ $(package)_config_opts+=no-dso $(package)_config_opts+=no-dtls1 $(package)_config_opts+=no-ec_nistp_64_gcc_128 $(package)_config_opts+=no-gost -$(package)_config_opts+=no-gmp $(package)_config_opts+=no-heartbeats -$(package)_config_opts+=no-jpake -$(package)_config_opts+=no-krb5 -$(package)_config_opts+=no-libunbound $(package)_config_opts+=no-md2 $(package)_config_opts+=no-rc5 $(package)_config_opts+=no-rdrand $(package)_config_opts+=no-rfc3779 -$(package)_config_opts+=no-rsax $(package)_config_opts+=no-sctp -$(package)_config_opts+=no-sha0 $(package)_config_opts+=no-shared $(package)_config_opts+=no-ssl-trace $(package)_config_opts+=no-ssl2 $(package)_config_opts+=no-ssl3 -$(package)_config_opts+=no-static_engine -$(package)_config_opts+=no-store $(package)_config_opts+=no-unit-test $(package)_config_opts+=no-weak-ssl-ciphers -$(package)_config_opts+=no-zlib -$(package)_config_opts+=no-zlib-dynamic $(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) $(package)_config_opts_linux=-fPIC -Wa,--noexecstack +$(package)_config_opts_freebsd=-fPIC -Wa,--noexecstack $(package)_config_opts_x86_64_linux=linux-x86_64 $(package)_config_opts_i686_linux=linux-generic32 $(package)_config_opts_arm_linux=linux-generic32 -$(package)_config_opts_armv7l_linux=linux-generic32 $(package)_config_opts_aarch64_linux=linux-generic64 +$(package)_config_opts_riscv64_linux=linux-generic64 $(package)_config_opts_mipsel_linux=linux-generic32 $(package)_config_opts_mips_linux=linux-generic32 $(package)_config_opts_powerpc_linux=linux-generic32 -$(package)_config_opts_riscv32_linux=linux-generic32 -$(package)_config_opts_riscv64_linux=linux-generic64 $(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc $(package)_config_opts_x86_64_mingw32=mingw64 $(package)_config_opts_i686_mingw32=mingw +$(package)_config_opts_x86_64_freebsd=BSD-x86_64 endef define $(package)_preprocess_cmds - sed -i.old "/define DATE/d" util/mkbuildinf.pl && \ - sed -i.old "s|engines apps test|engines|" Makefile.org + sed -i.old 's|"engines", "apps", "test", "util", "tools", "fuzz"|"engines", "tools"|' Configure && \ + sed -i -e 's|cflags --sysroot.*",|cflags",|' Configurations/15-android.conf endef define $(package)_config_cmds @@ -65,7 +55,7 @@ define $(package)_build_cmds endef define $(package)_stage_cmds - $(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw + $(MAKE) DESTDIR=$($(package)_staging_dir) -j1 install_sw endef define $(package)_postprocess_cmds diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index b2ea5e423e..687c957a82 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,5 +1,4 @@ packages:=boost openssl libevent -native_packages := native_ccache protobuf_native_packages = native_protobuf protobuf_packages = protobuf @@ -8,7 +7,8 @@ qt_packages = zlib qrencode_packages = qrencode -qt_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans +qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon dbus libX11 xextproto libXext xtrans +qt_android_packages=qt qt_darwin_packages=qt qt_mingw32_packages=qt @@ -19,8 +19,15 @@ zmq_packages=zeromq upnp_packages=miniupnpc -darwin_native_packages = native_biplist native_ds_store native_mac_alias +darwin_native_packages = native_ds_store native_mac_alias + +$(host_arch)_$(host_os)_native_packages += native_b2 ifneq ($(build_os),darwin) -darwin_native_packages += native_cctools native_cdrkit native_libdmg-hfsplus +darwin_native_packages += native_cctools native_libtapi native_libdmg-hfsplus + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +darwin_native_packages+= native_clang +endif + endif diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk index 3661a16631..af07943773 100644 --- a/depends/packages/protobuf.mk +++ b/depends/packages/protobuf.mk @@ -7,15 +7,10 @@ $(package)_dependencies=native_$(package) $(package)_cxxflags=-std=c++11 define $(package)_set_vars - $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc --disable-dependency-tracking + $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc $(package)_config_opts_linux=--with-pic endef -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . &&\ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub gtest/build-aux -endef - define $(package)_config_cmds $($(package)_autoconf) endef @@ -30,5 +25,6 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm lib/libprotoc.a lib/*.la + rm lib/libprotoc.a &&\ + rm lib/*.la endef diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index 21570726ff..d1687883bc 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -9,6 +9,7 @@ $(package)_config_opts=--disable-shared --without-tools --without-tests --disabl $(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic +$(package)_config_opts_android=--with-pic endef define $(package)_preprocess_cmds diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 858f4bc7ff..57a457e28d 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,50 +1,55 @@ PACKAGE=qt -$(package)_version=5.9.9 -$(package)_download_path=https://download.qt.io/official_releases/qt/5.9/$($(package)_version)/submodules -$(package)_suffix=opensource-src-$($(package)_version).tar.xz +$(package)_version=5.12.11 +$(package)_download_path=https://download.qt.io/official_releases/qt/5.12/$($(package)_version)/submodules +$(package)_suffix=everywhere-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=d5a97381b9339c0fbaf13f0c05d599a5c999dcf94145044058198987183fed65 -$(package)_dependencies=openssl zlib -$(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext -$(package)_build_subdir=qtbase +$(package)_sha256_hash=1c1b4e33137ca77881074c140d54c3c9747e845a31338cfe8680f171f0bc3a39 +$(package)_dependencies=openssl +$(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon libX11 xproto libXext $(package)_qt_libs=corelib network widgets gui plugins testlib -$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch -$(package)_patches+= fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch no-xlib.patch dont_hardcode_pwd.patch -$(package)_patches+= freetype_back_compat.patch drop_lrelease_dependency.patch +$(package)_linguist_tools = lrelease lupdate lconvert +$(package)_patches = qt.pro qttools_src.pro +$(package)_patches += dont_hardcode_pwd.patch +$(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch +$(package)_patches += no_sdk_version_check.patch +$(package)_patches += fix_lib_paths.patch +$(package)_patches += qtbase-moc-ignore-gcc-macro.patch fix_limits_header.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=f7474f260a1382549720081bf2359a3d425ec3bf7d31976c512834303d30d73b +$(package)_qttranslations_sha256_hash=577b0668a777eb2b451c61e8d026d79285371597ce9df06b6dee6c814164b7c3 $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=fce6e0fd39a40bcef880c669080087dba94af1ec442296222210472e0852bf98 +$(package)_qttools_sha256_hash=98b2aaca230458f65996f3534fd471d2ffd038dd58ac997c0589c06dc2385b4f $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) define $(package)_set_vars $(package)_config_opts_release = -release +$(package)_config_opts_release += -silent $(package)_config_opts_debug = -debug +$(package)_config_opts_debug += -optimized-tools $(package)_config_opts += -bindir $(build_prefix)/bin -$(package)_config_opts += -c++std c++11 +$(package)_config_opts += -c++std c++1z $(package)_config_opts += -confirm-license -$(package)_config_opts += -dbus-runtime $(package)_config_opts += -hostprefix $(build_prefix) $(package)_config_opts += -no-compile-examples $(package)_config_opts += -no-cups $(package)_config_opts += -no-egl $(package)_config_opts += -no-eglfs $(package)_config_opts += -no-freetype -$(package)_config_opts += -no-gif $(package)_config_opts += -no-glib $(package)_config_opts += -no-icu -$(package)_config_opts += -no-iconv $(package)_config_opts += -no-kms $(package)_config_opts += -no-linuxfb +$(package)_config_opts += -no-libproxy $(package)_config_opts += -no-libudev $(package)_config_opts += -no-mtdev +$(package)_config_opts += -openssl-linked $(package)_config_opts += -no-openvg $(package)_config_opts += -no-reduce-relocations -$(package)_config_opts += -no-qml-debug +$(package)_config_opts += -no-sctp +$(package)_config_opts += -no-securetransport $(package)_config_opts += -no-sql-db2 $(package)_config_opts += -no-sql-ibase $(package)_config_opts += -no-sql-oci @@ -54,59 +59,54 @@ $(package)_config_opts += -no-sql-odbc $(package)_config_opts += -no-sql-psql $(package)_config_opts += -no-sql-sqlite $(package)_config_opts += -no-sql-sqlite2 +$(package)_config_opts += -no-system-proxies $(package)_config_opts += -no-use-gold-linker -$(package)_config_opts += -no-xinput2 $(package)_config_opts += -nomake examples $(package)_config_opts += -nomake tests +$(package)_config_opts += -nomake tools $(package)_config_opts += -opensource -$(package)_config_opts += -optimized-tools -$(package)_config_opts += -openssl-linked -$(package)_config_opts += -optimized-qmake -$(package)_config_opts += -pch $(package)_config_opts += -pkg-config $(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng $(package)_config_opts += -qt-libjpeg $(package)_config_opts += -qt-pcre $(package)_config_opts += -qt-harfbuzz -$(package)_config_opts += -system-zlib +$(package)_config_opts += -qt-zlib $(package)_config_opts += -static -$(package)_config_opts += -silent $(package)_config_opts += -v -$(package)_config_opts += -no-feature-dial -$(package)_config_opts += -no-feature-ftp -$(package)_config_opts += -no-feature-lcdnumber -$(package)_config_opts += -no-feature-pdf -$(package)_config_opts += -no-feature-printer $(package)_config_opts += -no-feature-printdialog -$(package)_config_opts += -no-feature-concurrent -$(package)_config_opts += -no-feature-sql -$(package)_config_opts += -no-feature-statemachine -$(package)_config_opts += -no-feature-syntaxhighlighter -$(package)_config_opts += -no-feature-textbrowser -$(package)_config_opts += -no-feature-textodfwriter -$(package)_config_opts += -no-feature-udpsocket -$(package)_config_opts += -no-feature-wizard -$(package)_config_opts += -no-feature-xml +$(package)_config_opts += -no-feature-printer +$(package)_config_opts += -no-feature-printpreviewdialog +$(package)_config_opts += -no-feature-printpreviewwidget +$(package)_config_opts += -no-feature-sqlmodel $(package)_config_opts_darwin = -no-dbus $(package)_config_opts_darwin += -no-opengl +$(package)_config_opts_darwin += -pch +$(package)_config_opts_darwin += -no-feature-corewlan +$(package)_config_opts_darwin += QMAKE_MACOSX_DEPLOYMENT_TARGET=$(OSX_MIN_VERSION) ifneq ($(build_os),darwin) $(package)_config_opts_darwin += -xplatform macx-clang-linux $(package)_config_opts_darwin += -device-option MAC_SDK_PATH=$(OSX_SDK) $(package)_config_opts_darwin += -device-option MAC_SDK_VERSION=$(OSX_SDK_VERSION) $(package)_config_opts_darwin += -device-option CROSS_COMPILE="$(host)-" -$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) $(package)_config_opts_darwin += -device-option MAC_TARGET=$(host) +$(package)_config_opts_darwin += -device-option XCODE_VERSION=$(XCODE_VERSION) endif -$(package)_config_opts_linux = -qt-xkbcommon-x11 -$(package)_config_opts_linux += -qt-xcb +# for macOS on Apple Silicon (ARM) see https://bugreports.qt.io/browse/QTBUG-85279 +$(package)_config_opts_aarch64_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS=arm64 + +$(package)_config_opts_linux = -qt-xcb +$(package)_config_opts_linux += -no-xcb-xlib +$(package)_config_opts_linux += -no-feature-xlib $(package)_config_opts_linux += -system-freetype -$(package)_config_opts_linux += -no-feature-sessionmanager $(package)_config_opts_linux += -fontconfig $(package)_config_opts_linux += -no-opengl +$(package)_config_opts_linux += -no-feature-vulkan +$(package)_config_opts_linux += -dbus-runtime +$(package)_config_opts_linux += OPENSSL_LIBS="-lssl -lcrypto -lpthread -ldl" $(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitcoin-linux-g++ $(package)_config_opts_i686_linux = -xplatform linux-g++-32 $(package)_config_opts_x86_64_linux = -xplatform linux-g++-64 @@ -118,11 +118,13 @@ $(package)_config_opts_s390x_linux = -platform linux-g++ -xplatform bitcoin-linu $(package)_config_opts_mingw32 = -no-opengl $(package)_config_opts_mingw32 += -no-dbus +$(package)_config_opts_mingw32 += OPENSSL_LIBS="-lssl -lcrypto -luser32 -lcrypt32 -lws2_32 -lgdi32" $(package)_config_opts_mingw32 += -xplatform win32-g++ +$(package)_config_opts_mingw32 += "QMAKE_CFLAGS = '$($(package)_cflags) $($(package)_cppflags)'" +$(package)_config_opts_mingw32 += "QMAKE_CXXFLAGS = '$($(package)_cflags) $($(package)_cppflags)'" +$(package)_config_opts_mingw32 += "QMAKE_LFLAGS = '$($(package)_ldflags)'" $(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-" - -$(package)_build_env = QT_RCC_TEST=1 -$(package)_build_env += QT_RCC_SOURCE_DATE_OVERRIDE=1 +$(package)_config_opts_mingw32 += -pch endef define $(package)_fetch_cmds @@ -145,69 +147,67 @@ define $(package)_extract_cmds tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools endef +# Preprocessing steps work as follows: +# +# 1. Apply our patches to the extracted source. See each patch for more info. +# +# 2. Create a macOS-Clang-Linux mkspec using our mac-qmake.conf. +# +# 3. After making a copy of the mkspec for the linux-arm-gnueabi host, named +# bitcoin-linux-g++, replace instances of linux-arm-gnueabi with $(host). This +# way we can generically support hosts like riscv64-linux-gnu, which Qt doesn't +# ship a mkspec for. See it's usage in config_opts_* above. +# +# 4. Put our C, CXX and LD FLAGS into gcc-base.conf. Only used for non-host builds. +# +# 5. Do similar for the win32-g++ mkspec. +# +# 6. In clang.conf, swap out clang & clang++, for our compiler + flags. See #17466. +# +# 7. Adjust a regex in toolchain.prf, to accommodate Guix's usage of +# CROSS_LIBRARY_PATH. See #15277. define $(package)_preprocess_cmds - patch -p1 -i $($(package)_patch_dir)/freetype_back_compat.patch && \ - sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ - patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \ - patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch &&\ + cp $($(package)_patch_dir)/qt.pro qt.pro && \ + cp $($(package)_patch_dir)/qttools_src.pro qttools/src/src.pro && \ + patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \ + patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ + patch -p1 -i $($(package)_patch_dir)/qtbase-moc-ignore-gcc-macro.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ - cp -f qtbase/mkspecs/macx-clang/Info.plist.lib qtbase/mkspecs/macx-clang-linux/ &&\ - cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ cp -r qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/bitcoin-linux-g++ && \ sed -i.old "s/arm-linux-gnueabi-/$(host)-/g" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ - patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch &&\ - patch -p1 -i $($(package)_patch_dir)/fix_configure_mac.patch &&\ - patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch &&\ - patch -p1 -i $($(package)_patch_dir)/fix_rcc_determinism.patch &&\ - patch -p1 -i $($(package)_patch_dir)/xkb-default.patch &&\ echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - patch -p1 -i $($(package)_patch_dir)/fix_riscv64_arch.patch &&\ - echo "QMAKE_LINK_OBJECT_MAX = 10" >> qtbase/mkspecs/win32-g++/qmake.conf &&\ - echo "QMAKE_LINK_OBJECT_SCRIPT = object_script" >> qtbase/mkspecs/win32-g++/qmake.conf &&\ - sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_CC = clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ - sed -i.old "s|QMAKE_CXX = clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s|QMAKE_CC = \$$$$\$$$${CROSS_COMPILE}clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s|QMAKE_CXX = \$$$$\$$$${CROSS_COMPILE}clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf endef define $(package)_config_cmds export PKG_CONFIG_SYSROOT_DIR=/ && \ export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \ - export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \ - ./configure $($(package)_config_opts) && \ - echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ - echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ - $(MAKE) sub-src-clean && \ - cd ../qttranslations && ../qtbase/bin/qmake qttranslations.pro -o Makefile && \ - cd translations && ../../qtbase/bin/qmake translations.pro -o Makefile && cd ../.. && \ - cd qttools/src/linguist/lrelease/ && ../../../../qtbase/bin/qmake lrelease.pro -o Makefile && \ - cd ../lupdate/ && ../../../../qtbase/bin/qmake lupdate.pro -o Makefile && cd ../../../.. + export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \ + cd qtbase && \ + ./configure -top-level $($(package)_config_opts) endef define $(package)_build_cmds - $(MAKE) -C src $(addprefix sub-,$($(package)_qt_libs)) && \ - $(MAKE) -C ../qttools/src/linguist/lrelease && \ - $(MAKE) -C ../qttools/src/linguist/lupdate && \ - $(MAKE) -C ../qttranslations + $(MAKE) endef define $(package)_stage_cmds - $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && cd .. && \ - $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttools/src/linguist/lupdate INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets && \ - if `test -f qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a`; then \ - cp qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a $($(package)_staging_prefix_dir)/lib; \ - fi + $(MAKE) -C qtbase/src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && \ + $(MAKE) -C qttools/src/linguist INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_linguist_tools))) && \ + $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets endef define $(package)_postprocess_cmds rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \ - rm -f lib/lib*.la lib/*.prl plugins/*/*.prl + rm -f lib/lib*.la endef diff --git a/depends/packages/sqlite.mk b/depends/packages/sqlite.mk new file mode 100644 index 0000000000..5b3a61b239 --- /dev/null +++ b/depends/packages/sqlite.mk @@ -0,0 +1,26 @@ +package=sqlite +$(package)_version=3320100 +$(package)_download_path=https://sqlite.org/2020/ +$(package)_file_name=sqlite-autoconf-$($(package)_version).tar.gz +$(package)_sha256_hash=486748abfb16abd8af664e3a5f03b228e5f124682b0c942e157644bf6fff7d10 + +define $(package)_set_vars +$(package)_config_opts=--disable-shared --disable-readline --disable-dynamic-extensions --enable-option-checking +$(package)_config_opts_linux=--with-pic +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) libsqlite3.la +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-includeHEADERS install-pkgconfigDATA +endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk index 44110394bd..4798124a74 100644 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -1,13 +1,8 @@ package=xcb_proto -$(package)_version=1.10 +$(package)_version=1.14 $(package)_download_path=https://xcb.freedesktop.org/dist -$(package)_file_name=xcb-proto-$($(package)_version).tar.bz2 -$(package)_sha256_hash=7ef40ddd855b750bc597d2a435da21e55e502a0fefa85b274f2c922800baaf05 - -define $(package)_set_vars - $(package)_config_opts=--disable-shared - $(package)_config_opts_linux=--with-pic -endef +$(package)_file_name=xcb-proto-$($(package)_version).tar.gz +$(package)_sha256_hash=1c3fa23d091fb5e4f1e9bf145a902161cec00d260fabf880a7a248b02ab27031 define $(package)_config_cmds $($(package)_autoconf) diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index 23ad5ffa10..7a43c52faf 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -1,11 +1,12 @@ package=xproto -$(package)_version=7.0.26 +$(package)_version=7.0.31 $(package)_download_path=https://xorg.freedesktop.org/releases/individual/proto $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f +$(package)_sha256_hash=c6f9747da0bd3a95f86b17fb8dd5e717c8f3ab7f0ece3ba1b247899ec1ef7747 define $(package)_set_vars -$(package)_config_opts=--disable-shared +$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking endef define $(package)_preprocess_cmds diff --git a/depends/packages/xtrans.mk b/depends/packages/xtrans.mk index 67d2d976c4..b289203427 100644 --- a/depends/packages/xtrans.mk +++ b/depends/packages/xtrans.mk @@ -1,8 +1,8 @@ package=xtrans -$(package)_version=1.3.4 +$(package)_version=1.4.0 $(package)_download_path=https://xorg.freedesktop.org/releases/individual/lib/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=054d4ee3efd52508c753e9f7bc655ef185a29bd2850dd9e2fc2ccc33544f583a +$(package)_sha256_hash=377c4491593c417946efcd2c7600d1e62639f7a8bbca391887e2c4679807d773 $(package)_dependencies= define $(package)_set_vars diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 41fb9e4c74..d0497c6962 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,8 +1,8 @@ package=zeromq -$(package)_version=4.3.1 +$(package)_version=4.3.4 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d835cd21eb +$(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336295c3e5 $(package)_patches=remove_libstd_link.patch define $(package)_set_vars @@ -11,7 +11,8 @@ define $(package)_set_vars $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov --disable-dependency-tracking $(package)_config_opts += --disable-Werror --disable-drafts --enable-option-checking $(package)_config_opts_linux=--with-pic - $(package)_cxxflags=-std=c++11 + $(package)_config_opts_android=--with-pic + $(package)_cxxflags=-std=c++17 endef define $(package)_preprocess_cmds diff --git a/depends/patches/bdb/winioctl.patch b/depends/patches/bdb/winioctl.patch deleted file mode 100644 index adf41caa57..0000000000 --- a/depends/patches/bdb/winioctl.patch +++ /dev/null @@ -1,19 +0,0 @@ -commit b2c9b538fed1aa1d65b85b372f7a49f1878e9e3b -Author: Fabien -Date: Mon Oct 5 11:45:28 2020 +0200 - - Fix winioctl.h case for MinGw - -diff --git a/dbinc/win_db.h b/dbinc/win_db.h -index 6544558..6cb6878 100644 ---- a/dbinc/win_db.h -+++ b/dbinc/win_db.h -@@ -46,7 +46,7 @@ - #include - #include - #ifndef DB_WINCE --#include -+#include - #endif - - #ifdef HAVE_GETADDRINFO diff --git a/depends/patches/boost/unused_var_in_process.patch b/depends/patches/boost/unused_var_in_process.patch deleted file mode 100644 index 722f7bb5ea..0000000000 --- a/depends/patches/boost/unused_var_in_process.patch +++ /dev/null @@ -1,22 +0,0 @@ -commit dbd95cdaefdea95307d004f019a1c394cf9389f0 -Author: fanquake -Date: Mon Aug 17 20:15:17 2020 +0800 - - Remove unused variable in Boost Process - - This causes issues with our linters / CI. - - Can be removed once depends Boost is 1.71.0 or later. - -diff --git a/boost/process/detail/posix/wait_group.hpp b/boost/process/detail/posix/wait_group.hpp -index 9dc249803..2502d9772 100644 ---- a/boost/process/detail/posix/wait_group.hpp -+++ b/boost/process/detail/posix/wait_group.hpp -@@ -137,7 +137,6 @@ inline bool wait_until( - - do - { -- int ret_sig = 0; - int status; - if ((::waitpid(timeout_pid, &status, WNOHANG) != 0) - && (WIFEXITED(status) || WIFSIGNALED(status))) diff --git a/depends/patches/fontconfig/gperf_header_regen.patch b/depends/patches/fontconfig/gperf_header_regen.patch index 7401b83d84..3ffd1674e0 100644 --- a/depends/patches/fontconfig/gperf_header_regen.patch +++ b/depends/patches/fontconfig/gperf_header_regen.patch @@ -2,7 +2,7 @@ commit 7b6eb33ecd88768b28c67ce5d2d68a7eed5936b6 Author: fanquake Date: Tue Aug 25 14:34:53 2020 +0800 - Remove rule that causes inadvertant header regeneration + Remove rule that causes inadvertent header regeneration Otherwise the makefile will needlessly attempt to re-generate the headers with gperf. This can be dropped once the upstream build is fixed. diff --git a/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch b/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch deleted file mode 100644 index a98cd90bd5..0000000000 --- a/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -ur libevent-2.1.8-stable.orig/configure.ac libevent-2.1.8-stable/configure.ac ---- libevent-2.1.8-stable.orig/configure.ac 2017-01-29 17:51:00.000000000 +0000 -+++ libevent-2.1.8-stable/configure.ac 2020-03-07 01:11:16.311335005 +0000 -@@ -389,6 +389,10 @@ - #ifdef HAVE_NETDB_H - #include - #endif -+#ifdef _WIN32 -+#include -+#include -+#endif - ]], - [[ - getaddrinfo; -Only in libevent-2.1.8-stable: configure.ac~ diff --git a/depends/patches/miniupnpc/dont_leak_info.patch b/depends/patches/miniupnpc/dont_leak_info.patch new file mode 100644 index 0000000000..512f9c50ea --- /dev/null +++ b/depends/patches/miniupnpc/dont_leak_info.patch @@ -0,0 +1,32 @@ +commit 8815452257437ba36607d0e2381c01142d1c7bb0 +Author: fanquake +Date: Thu Nov 19 10:51:19 2020 +0800 + + Don't leak OS and miniupnpc version info in User-Agent + +diff --git a//minisoap.c b/minisoap.c +index 7860667..775580b 100644 +--- a/minisoap.c ++++ b/minisoap.c +@@ -90,7 +90,7 @@ int soapPostSubmit(SOCKET fd, + headerssize = snprintf(headerbuf, sizeof(headerbuf), + "POST %s HTTP/%s\r\n" + "Host: %s%s\r\n" +- "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" ++ "User-Agent: " UPNP_VERSION_STRING "\r\n" + "Content-Length: %d\r\n" + "Content-Type: text/xml\r\n" + "SOAPAction: \"%s\"\r\n" +diff --git a/miniwget.c b/miniwget.c +index d5b7970..05aeb9c 100644 +--- a/miniwget.c ++++ b/miniwget.c +@@ -444,7 +444,7 @@ miniwget3(const char * host, + "GET %s HTTP/%s\r\n" + "Host: %s:%d\r\n" + "Connection: Close\r\n" +- "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" ++ "User-Agent: " UPNP_VERSION_STRING "\r\n" + + "\r\n", + path, httpversion, host, port); diff --git a/depends/patches/miniupnpc/dont_use_wingen.patch b/depends/patches/miniupnpc/dont_use_wingen.patch deleted file mode 100644 index a1cc9b50d1..0000000000 --- a/depends/patches/miniupnpc/dont_use_wingen.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit e8077044df239bcf0d9e9980b0e1afb9f1f5c446 -Author: fanquake -Date: Tue Aug 18 20:50:19 2020 +0800 - - Don't use wingenminiupnpcstrings when generating miniupnpcstrings.h - - The wingenminiupnpcstrings tool is used on Windows to generate version - information. This information is irrelevant for us, and trying to use - wingenminiupnpcstrings would cause builds to fail, so just don't use it. - - We should be able to drop this once we are using 2.1 or later. See - upstream commit: 9663c55c61408fdcc39a82987d2243f816b22932. - -diff --git a/Makefile.mingw b/Makefile.mingw -index 574720e..fcc17bb 100644 ---- a/Makefile.mingw -+++ b/Makefile.mingw -@@ -74,7 +74,7 @@ wingenminiupnpcstrings: wingenminiupnpcstrings.o - - wingenminiupnpcstrings.o: wingenminiupnpcstrings.c - --miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings -+miniupnpcstrings.h: miniupnpcstrings.h.in - wingenminiupnpcstrings $< $@ - - minixml.o: minixml.c minixml.h diff --git a/depends/patches/native_cctools/ld64_disable_threading.patch b/depends/patches/native_cctools/ld64_disable_threading.patch deleted file mode 100644 index d6c58c102f..0000000000 --- a/depends/patches/native_cctools/ld64_disable_threading.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit 584668415039adeed073decee7e04de28248afd3 -Author: fanquake -Date: Tue Aug 18 01:20:24 2020 +0000 - - Disable threading to fix non-determinism - - A bug in the file parser can cause dependencies to be calculated - differently based on which files have already been parsed. This is more - likely to occur on systems with more CPUs. - - Just disable threading for now. There is no noticable slowdown. - - See #9891. - -diff --git a/cctools/ld64/src/ld/InputFiles.h b/cctools/ld64/src/ld/InputFiles.h -index ef9c756..90a70b6 100644 ---- a/cctools/ld64/src/ld/InputFiles.h -+++ b/cctools/ld64/src/ld/InputFiles.h -@@ -25,7 +25,6 @@ - #ifndef __INPUT_FILES_H__ - #define __INPUT_FILES_H__ - --#define HAVE_PTHREADS 1 - - #include - #include diff --git a/depends/patches/qt/drop_lrelease_dependency.patch b/depends/patches/qt/drop_lrelease_dependency.patch deleted file mode 100644 index f6b2c9fc80..0000000000 --- a/depends/patches/qt/drop_lrelease_dependency.patch +++ /dev/null @@ -1,20 +0,0 @@ -commit 67b3ed7406e1d0762188dbad2c44a06824ba0778 -Author: fanquake -Date: Tue Aug 18 15:24:01 2020 +0800 - - Drop dependency on lrelease - - Qts buildsystem insists on using the installed lrelease, but gets - confused about how to find it. Since we manually control the build - order, just drop the dependency. - - See #9469 - -diff --git a/qttranslations/translations/translations.pro b/qttranslations/translations/translations.pro -index 694544c..eff339d 100644 ---- a/qttranslations/translations/translations.pro -+++ b/qttranslations/translations/translations.pro -@@ -109,3 +109,2 @@ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} - silent:updateqm.commands = @echo lrelease ${QMAKE_FILE_IN} && $$updateqm.commands --updateqm.depends = $$LRELEASE_EXE - updateqm.name = LRELEASE ${QMAKE_FILE_IN} diff --git a/depends/patches/qt/fix-cocoahelpers-macos.patch b/depends/patches/qt/fix-cocoahelpers-macos.patch deleted file mode 100644 index 381b79c9f5..0000000000 --- a/depends/patches/qt/fix-cocoahelpers-macos.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0707260a4f8e64dfadf1df5f935e74cabb7c7d27 Mon Sep 17 00:00:00 2001 -From: Jake Petroules -Date: Sun, 1 Oct 2017 21:48:17 -0700 -Subject: [PATCH] Fix build error with macOS 10.13 SDK -MIME-Version: 1.0 -Content-Type: text/plain; charset=utf8 -Content-Transfer-Encoding: 8bit - -Several of these variables/macros are no longer defined. We didn't -validate the preconditions on iOS, tvOS, or watchOS, so no -need to bother validating them on macOS either. Nor did we check the -OSStatus result on any platform anyways. - -Task-number: QTBUG-63401 -Change-Id: Ife64dff767cf6d3f4b839fc53ec486181c176bf3 -(cherry-picked from 861544583511d4e6f7745d2339b26ff1cd44132b) -Reviewed-by: Timur Pocheptsov -Reviewed-by: Tor Arne Vestbø ---- - src/plugins/platforms/cocoa/qcocoahelpers.h | 2 +- - src/plugins/platforms/cocoa/qcocoahelpers.mm | 13 +------------ - 2 files changed, 2 insertions(+), 13 deletions(-) - -diff --git old/qtbase/src/plugins/platforms/cocoa/qcocoahelpers.h new/qtbase/src/plugins/platforms/cocoa/qcocoahelpers.h -index bbb3793..74371d5 100644 ---- old/qtbase/src/plugins/platforms/cocoa/qcocoahelpers.h -+++ new/qtbase/src/plugins/platforms/cocoa/qcocoahelpers.h -@@ -80,7 +80,7 @@ QColor qt_mac_toQColor(CGColorRef color); - // Creates a mutable shape, it's the caller's responsibility to release. - HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion); - --OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); -+void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); - - NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); - NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); -diff --git old/qtbase/src/plugins/platforms/cocoa/qcocoahelpers.mm new/qtbase/src/plugins/platforms/cocoa/qcocoahelpers.mm -index cd73148..3f8429e 100644 ---- old/qtbase/src/plugins/platforms/cocoa/qcocoahelpers.mm -+++ new/qtbase/src/plugins/platforms/cocoa/qcocoahelpers.mm -@@ -544,15 +544,8 @@ NSRect qt_mac_flipRect(const QRect &rect) - return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height()); - } - --OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) -+void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) - { -- // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev) -- OSStatus err = noErr; -- -- require_action(inContext != NULL, InvalidContext, err = paramErr); -- require_action(inBounds != NULL, InvalidBounds, err = paramErr); -- require_action(inImage != NULL, InvalidImage, err = paramErr); -- - CGContextSaveGState( inContext ); - CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds)); - CGContextScaleCTM(inContext, 1, -1); -@@ -560,10 +553,6 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm - CGContextDrawImage(inContext, *inBounds, inImage); - - CGContextRestoreGState(inContext); --InvalidImage: --InvalidBounds: --InvalidContext: -- return err; - } - - Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) --- -2.7.4 diff --git a/depends/patches/qt/fix_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch index 2f6ff00f40..a186aeb8f6 100644 --- a/depends/patches/qt/fix_android_jni_static.patch +++ b/depends/patches/qt/fix_android_jni_static.patch @@ -1,6 +1,6 @@ --- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp +++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp -@@ -890,6 +890,14 @@ +@@ -898,6 +898,14 @@ __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } diff --git a/depends/patches/qt/fix_android_pch.patch b/depends/patches/qt/fix_android_pch.patch new file mode 100644 index 0000000000..bed6e4bb63 --- /dev/null +++ b/depends/patches/qt/fix_android_pch.patch @@ -0,0 +1,10 @@ +--- old/qtbase/mkspecs/common/android-base-head.conf ++++ new/qtbase/mkspecs/common/android-base-head.conf +@@ -73,6 +73,6 @@ CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX- + QMAKE_PCH_OUTPUT_EXT = .gch + + QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +-QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE} ++QMAKE_CFLAGS_USE_PRECOMPILE = -include-pch ${QMAKE_PCH_OUTPUT} + QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} + QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE diff --git a/depends/patches/qt/fix_android_qmake_conf.patch b/depends/patches/qt/fix_android_qmake_conf.patch index 13bfff9776..3a8753fd1d 100644 --- a/depends/patches/qt/fix_android_qmake_conf.patch +++ b/depends/patches/qt/fix_android_qmake_conf.patch @@ -1,20 +1,10 @@ --- old/qtbase/mkspecs/android-clang/qmake.conf +++ new/qtbase/mkspecs/android-clang/qmake.conf -@@ -30,7 +30,7 @@ - QMAKE_CFLAGS += -target mips64el-none-linux-android +@@ -47,7 +47,7 @@ ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so + ANDROID_USE_LLVM = true - QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH --QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -+QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -nostdlib++ - QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \ - -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \ - -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \ -@@ -40,7 +40,7 @@ - ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH - - ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so --ANDROID_CXX_STL_LIBS = -lc++ -+ANDROID_CXX_STL_LIBS = -lc++_shared - - QMAKE_ARM_CFLAGS_RELEASE = -Oz - QMAKE_ARM_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Oz + exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \ +- ANDROID_CXX_STL_LIBS = -lc++ ++ ANDROID_CXX_STL_LIBS = -lc++_shared + else: \ + ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "") diff --git a/depends/patches/qt/fix_configure_mac.patch b/depends/patches/qt/fix_configure_mac.patch deleted file mode 100644 index 0d7dd647de..0000000000 --- a/depends/patches/qt/fix_configure_mac.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- old/qtbase/mkspecs/features/mac/sdk.prf 2018-02-08 10:24:48.000000000 -0800 -+++ new/qtbase/mkspecs/features/mac/sdk.prf 2018-03-23 10:38:56.000000000 -0700 -@@ -8,21 +8,21 @@ - defineReplace(xcodeSDKInfo) { - info = $$1 - equals(info, "Path"): \ -- info = --show-sdk-path -+ infoarg = --show-sdk-path - equals(info, "PlatformPath"): \ -- info = --show-sdk-platform-path -+ infoarg = --show-sdk-platform-path - equals(info, "SDKVersion"): \ -- info = --show-sdk-version -+ infoarg = --show-sdk-version - sdk = $$2 - isEmpty(sdk): \ - sdk = $$QMAKE_MAC_SDK - - isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}) { -- QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$info 2>/dev/null") -+ QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$infoarg 2>/dev/null") - # --show-sdk-platform-path won't work for Command Line Tools; this is fine - # only used by the XCTest backend to testlib -- isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(info, "--show-sdk-platform-path")): \ -- error("Could not resolve SDK $$info for \'$$sdk\'") -+ isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(infoarg, "--show-sdk-platform-path")): \ -+ error("Could not resolve SDK $$info for \'$$sdk\' using $$infoarg") - cache(QMAKE_MAC_SDK.$${sdk}.$${info}, set stash, QMAKE_MAC_SDK.$${sdk}.$${info}) - } - ---- old/qtbase/configure 2018-02-08 10:24:48.000000000 -0800 -+++ new/qtbase/configure 2018-03-23 05:42:29.000000000 -0700 -@@ -232,8 +232,13 @@ - - sdk=$(getSingleQMakeVariable "QMAKE_MAC_SDK" "$1") - if [ -z "$sdk" ]; then echo "QMAKE_MAC_SDK must be set when building on Mac" >&2; exit 1; fi -- sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null) -- if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi -+ sysroot=$(getSingleQMakeVariable "QMAKE_MAC_SDK_PATH" "$1") -+ -+ echo "sysroot pre-configured as $sysroot"; -+ if [ -z "$sysroot" ]; then -+ sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null) -+ if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi -+ fi - - case "$sdk" in - macosx*) - - diff --git a/depends/patches/qt/fix_lib_paths.patch b/depends/patches/qt/fix_lib_paths.patch new file mode 100644 index 0000000000..d1a15373f4 --- /dev/null +++ b/depends/patches/qt/fix_lib_paths.patch @@ -0,0 +1,193 @@ +--- old/qtbase/mkspecs/common/mac.conf ++++ new/qtbase/mkspecs/common/mac.conf +@@ -14,7 +14,6 @@ + + QMAKE_RESOURCE = /Developer/Tools/Rez + QMAKE_EXTENSION_SHLIB = dylib +-QMAKE_EXTENSIONS_AUX_SHLIB = tbd + QMAKE_LIBDIR = + + # sdk.prf will prefix the proper SDK sysroot + +--- old/qtbase/mkspecs/features/qmake_use.prf ++++ new/qtbase/mkspecs/features/qmake_use.prf +@@ -22,6 +22,8 @@ + !defined(QMAKE_LIBS_$$nu, var): \ + error("Library '$$lower($$replace(nu, _, -))' is not defined.") + ++ QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu) ++ + debug: \ + LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) + else: \ + +--- old/qtbase/mkspecs/features/qt_configure.prf ++++ new/qtbase/mkspecs/features/qt_configure.prf +@@ -526,98 +526,23 @@ + return($$sysrootified) + } + +-# libs-var, libs, in-paths, out-paths-var ++# libs-var, libs, in-paths + defineTest(qtConfResolveLibs) { +- ret = true +- paths = $$3 +- out = +- copy = false +- for (l, 2) { +- $$copy { +- copy = false +- out += $$l +- } else: equals(l, "-s") { +- # em++ flag to link libraries from emscripten-ports; passed on literally. +- copy = true +- out += $$l +- } else: contains(l, "^-L.*") { +- lp = $$replace(l, "^-L", ) +- gcc: lp = $$qtGccSysrootifiedPath($$lp) +- !exists($$lp/.) { +- qtLog("Library path $$val_escape(lp) is invalid.") +- ret = false +- } else { +- paths += $$lp +- } +- } else: contains(l, "^-l.*") { +- lib = $$replace(l, "^-l", ) +- lcan = +- integrity:contains(lib, "^.*\\.a") { +- # INTEGRITY compiler searches for exact filename +- # if -l argument has .a suffix +- lcan += $${lib} +- } else: contains(lib, "^:.*") { +- # Use exact filename when -l:filename syntax is used. +- lib ~= s/^:// +- lcan += $${lib} +- } else: unix { +- # Under UNIX, we look for actual shared libraries, in addition +- # to static ones. +- shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB +- for (ext, shexts) { +- lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext} +- } +- lcan += \ +- $${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB} +- } else { +- # Under Windows, we look only for static libraries, as even for DLLs +- # one actually links against a static import library. +- mingw { +- lcan += \ +- # MinGW supports UNIX-style library naming in addition to +- # the MSVC style. +- lib$${lib}.dll.a lib$${lib}.a \ +- # Fun fact: prefix-less libraries are also supported. +- $${lib}.dll.a $${lib}.a +- } +- lcan += $${lib}.lib +- } +- l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS) +- isEmpty(l) { +- qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.") +- ret = false +- } else { +- out += $$l +- } +- } else { +- out += $$l +- } +- } +- $$1 = $$out ++ for (path, 3): \ ++ pre_lflags += -L$$path ++ $$1 = $$pre_lflags $$2 + export($$1) +- !isEmpty(4) { +- $$4 = $$paths +- export($$4) +- } +- return($$ret) +-} +- +-# source-var +-defineTest(qtConfResolveAllLibs) { +- ret = true +- !qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \ +- ret = false +- for (b, $${1}.builds._KEYS_): \ +- !qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \ +- ret = false +- return($$ret) ++ return(true) + } + + # libs-var, in-paths, libs + defineTest(qtConfResolvePathLibs) { + ret = true +- gcc: 2 = $$qtGccSysrootifiedPaths($$2) +- for (libdir, 2) { ++ gcc: \ ++ local_paths = $$qtGccSysrootifiedPaths($$2) ++ else: \ ++ local_paths = $$2 ++ for (libdir, local_paths) { + !exists($$libdir/.) { + qtLog("Library path $$val_escape(libdir) is invalid.") + ret = false +@@ -667,8 +592,11 @@ + # includes-var, in-paths, test-object-var + defineTest(qtConfResolvePathIncs) { + ret = true +- gcc: 2 = $$qtGccSysrootifiedPaths($$2) +- for (incdir, 2) { ++ gcc: \ ++ local_paths = $$qtGccSysrootifiedPaths($$2) ++ else: \ ++ local_paths = $$2 ++ for (incdir, local_paths) { + !exists($$incdir/.) { + qtLog("Include path $$val_escape(incdir) is invalid.") + ret = false +@@ -727,6 +655,7 @@ + vars += $$eval(config.commandline.rev_assignments.$${iv}) + defined(config.input.$${iv}, var) { + eval($${1}.builds.$${b} = $$eval(config.input.$${iv})) ++ export($${1}.builds.$${b}) + $${1}.builds._KEYS_ *= $${b} + any = true + } else { +@@ -741,11 +670,14 @@ + export($${1}.builds._KEYS_) + # we also reset the generic libs, to avoid surprises. + $${1}.libs = ++ export($${1}.libs) + } + + # direct libs. overwrites inline libs. +- defined(config.input.$${input}.libs, var): \ ++ defined(config.input.$${input}.libs, var) { + eval($${1}.libs = $$eval(config.input.$${input}.libs)) ++ export($${1}.libs) ++ } + + includes = $$eval(config.input.$${input}.incdir) + +@@ -754,6 +686,7 @@ + !isEmpty(prefix) { + includes += $$prefix/include + $${1}.libs = -L$$prefix/lib $$eval($${1}.libs) ++ export($${1}.libs) + } + + libdir = $$eval(config.input.$${input}.libdir) +@@ -762,11 +695,9 @@ + for (ld, libdir): \ + libs += -L$$ld + $${1}.libs = $$libs $$eval($${1}.libs) ++ export($${1}.libs) + } + +- !qtConfResolveAllLibs($$1): \ +- return(false) +- + !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ + return(false) + diff --git a/depends/patches/qt/fix_limits_header.patch b/depends/patches/qt/fix_limits_header.patch new file mode 100644 index 0000000000..e4313770e5 --- /dev/null +++ b/depends/patches/qt/fix_limits_header.patch @@ -0,0 +1,44 @@ +Fix compiling with GCC 11 + +See: https://bugreports.qt.io/browse/QTBUG-90395. + +Upstream commits: + - Qt 5.15 -- unavailable as open source + - Qt 6.0: b2af6332ea37e45ab230a7a5d2d278f86d961b83 + - Qt 6.1: 9c56d4da2ff631a8c1c30475bd792f6c86bda53c + +--- old/qtbase/src/corelib/global/qendian.h ++++ new/qtbase/src/corelib/global/qendian.h +@@ -44,6 +44,8 @@ + #include + #include + ++#include ++ + // include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems + #include + #include + +--- old/qtbase/src/corelib/tools/qbytearraymatcher.h ++++ new/qtbase/src/corelib/tools/qbytearraymatcher.h +@@ -42,6 +42,8 @@ + + #include + ++#include ++ + QT_BEGIN_NAMESPACE + + + +--- old/qtbase/src/tools/moc/generator.cpp ++++ new/qtbase/src/tools/moc/generator.cpp +@@ -40,6 +40,8 @@ + #include + #include + ++#include ++ + #include + #include + diff --git a/depends/patches/qt/fix_no_printer.patch b/depends/patches/qt/fix_no_printer.patch index f868ca2577..1372356138 100644 --- a/depends/patches/qt/fix_no_printer.patch +++ b/depends/patches/qt/fix_no_printer.patch @@ -10,10 +10,10 @@ --- x/qtbase/src/plugins/plugins.pro +++ y/qtbase/src/plugins/plugins.pro -@@ -8,6 +8,3 @@ qtHaveModule(gui) { - qtConfig(imageformatplugin): SUBDIRS *= imageformats +@@ -9,6 +9,3 @@ qtHaveModule(gui) { !android:qtConfig(library): SUBDIRS *= generic } + qtHaveModule(widgets): SUBDIRS += styles - -!winrt:qtHaveModule(printsupport): \ - SUBDIRS += printsupport diff --git a/depends/patches/qt/fix_powerpc_libpng.patch b/depends/patches/qt/fix_powerpc_libpng.patch deleted file mode 100644 index d37b6c7776..0000000000 --- a/depends/patches/qt/fix_powerpc_libpng.patch +++ /dev/null @@ -1,23 +0,0 @@ -commit 6f9feb773a43c5abfa3455da2e324180e789285b -Author: fanquake -Date: Tue Sep 15 21:44:31 2020 +0800 - - Fix PowerPC build of libpng - - See https://bugreports.qt.io/browse/QTBUG-66388. - - Can be dropped when we are building qt 5.12.0 or later. - -diff --git a/qtbase/src/3rdparty/libpng/libpng.pro b/qtbase/src/3rdparty/libpng/libpng.pro -index 577b61d8..a2f56669 100644 ---- a/qtbase/src/3rdparty/libpng/libpng.pro -+++ b/qtbase/src/3rdparty/libpng/libpng.pro -@@ -10,7 +10,7 @@ MODULE_INCLUDEPATH = $$PWD - - load(qt_helper_lib) - --DEFINES += PNG_ARM_NEON_OPT=0 -+DEFINES += PNG_ARM_NEON_OPT=0 PNG_POWERPC_VSX_OPT=0 - SOURCES += \ - png.c \ - pngerror.c \ diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch index 8c722ffb46..a5de2b4b9e 100644 --- a/depends/patches/qt/fix_qt_pkgconfig.patch +++ b/depends/patches/qt/fix_qt_pkgconfig.patch @@ -1,17 +1,17 @@ --- old/qtbase/mkspecs/features/qt_module.prf +++ new/qtbase/mkspecs/features/qt_module.prf -@@ -264,7 +264,7 @@ +@@ -269,7 +269,7 @@ load(qt_installs) load(qt_targets) # this builds on top of qt_common --!internal_module:!lib_bundle:if(unix|mingw) { +-!internal_module:if(unix|mingw) { +if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) { CONFIG += create_pc QMAKE_PKGCONFIG_DESTDIR = pkgconfig host_build: \ -@@ -274,9 +274,9 @@ - QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] - QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME +@@ -284,9 +284,9 @@ load(qt_targets) + QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME + } QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ") - QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION) + QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)$$qtPlatformTargetSuffix() @@ -20,4 +20,4 @@ + QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0))$$qtPlatformTargetSuffix() isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \ QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module - pclib_replace.match = $$lib_replace.match + !isEmpty(lib_replace0.match) { diff --git a/depends/patches/qt/fix_rcc_determinism.patch b/depends/patches/qt/fix_rcc_determinism.patch deleted file mode 100644 index c1b07fe23a..0000000000 --- a/depends/patches/qt/fix_rcc_determinism.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- old/qtbase/src/tools/rcc/rcc.cpp -+++ new/qtbase/src/tools/rcc/rcc.cpp -@@ -207,7 +207,11 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib) - if (lib.formatVersion() >= 2) { - // last modified time stamp - const QDateTime lastModified = m_fileInfo.lastModified(); -- lib.writeNumber8(quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0)); -+ quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0); -+ static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong(); -+ if (sourceDate != 0) -+ lastmod = sourceDate; -+ lib.writeNumber8(lastmod); - if (text || pass1) - lib.writeChar('\n'); - } diff --git a/depends/patches/qt/fix_riscv64_arch.patch b/depends/patches/qt/fix_riscv64_arch.patch deleted file mode 100644 index e7f29f01f9..0000000000 --- a/depends/patches/qt/fix_riscv64_arch.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -index 20bfd36..93729fa 100644 ---- a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -+++ b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -@@ -65,7 +65,8 @@ - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ - defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || \ -- defined(__AARCH64EL__) -+ defined(__AARCH64EL__) || defined(__aarch64__) || \ -+ defined(__riscv) - #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 - #elif defined(_M_IX86) || defined(__i386__) || defined(__i386) - #if defined(_WIN32) diff --git a/depends/patches/qt/freetype_back_compat.patch b/depends/patches/qt/freetype_back_compat.patch deleted file mode 100644 index b0f1c98aa6..0000000000 --- a/depends/patches/qt/freetype_back_compat.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 14bc77db61bf9d56f9b6c8b84aa02573605c19c6 -Author: fanquake -Date: Tue Aug 18 15:15:08 2020 +0800 - - Fix backwards compatibility with older Freetype versions at runtime - - A few years ago, libfreetype introduced FT_Get_Font_Format() as an alias - for FT_Get_X11_Font_Format(), but FT_Get_X11_Font_Format() was kept for abi - backwards-compatibility. - - Qt 5.9 introduced a call to FT_Get_Font_Format(). Replace it with FT_Get_X11_Font_Format() - in order to remain compatibile with older freetype, which is still used by e.g. Ubuntu Trusty. - - See #14348. - -diff --git a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -index 3f543755..8ecc1c8c 100644 ---- a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -+++ b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -@@ -898,7 +898,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, - } - } - #if defined(FT_FONT_FORMATS_H) -- const char *fmt = FT_Get_Font_Format(face); -+ const char *fmt = FT_Get_X11_Font_Format(face); - if (fmt && qstrncmp(fmt, "CFF", 4) == 0) { - FT_Bool no_stem_darkening = true; - FT_Error err = FT_Property_Get(qt_getFreetype(), "cff", "no-stem-darkening", &no_stem_darkening); diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index 4cd96df29f..190ab7a160 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -1,14 +1,13 @@ MAKEFILE_GENERATOR = UNIX -CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname absolute_library_soname +CONFIG += app_bundle incremental lib_version_first absolute_library_soname QMAKE_INCREMENTAL_STYLE = sublib include(../common/macx.conf) include(../common/gcc-base-mac.conf) include(../common/clang.conf) include(../common/clang-mac.conf) QMAKE_MAC_SDK_PATH=$${MAC_SDK_PATH} -QMAKE_XCODE_VERSION=4.3 +QMAKE_XCODE_VERSION = $${XCODE_VERSION} QMAKE_XCODE_DEVELOPER_PATH=/Developer -QMAKE_MACOSX_DEPLOYMENT_TARGET = $${MAC_MIN_VERSION} QMAKE_MAC_SDK=macosx QMAKE_MAC_SDK.macosx.Path = $${MAC_SDK_PATH} QMAKE_MAC_SDK.macosx.platform_name = macosx diff --git a/depends/patches/qt/no-xlib.patch b/depends/patches/qt/no-xlib.patch index fe82c2c73c..f4a6f09ee4 100644 --- a/depends/patches/qt/no-xlib.patch +++ b/depends/patches/qt/no-xlib.patch @@ -22,15 +22,15 @@ index 7c62c2e2b3..c05c6c0a07 100644 #include #include -@@ -384,6 +386,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) - w->setCursor(c, isBitmapCursor); +@@ -391,6 +393,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *window) + xcb_flush(xcb_connection()); } +#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) static int cursorIdForShape(int cshape) { int cursorId = 0; -@@ -437,6 +440,7 @@ static int cursorIdForShape(int cshape) +@@ -444,6 +447,7 @@ static int cursorIdForShape(int cshape) } return cursorId; } @@ -38,7 +38,7 @@ index 7c62c2e2b3..c05c6c0a07 100644 xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape) { -@@ -558,7 +562,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) +@@ -556,7 +560,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) xcb_cursor_t QXcbCursor::createFontCursor(int cshape) { xcb_connection_t *conn = xcb_connection(); @@ -48,22 +48,23 @@ index 7c62c2e2b3..c05c6c0a07 100644 xcb_cursor_t cursor = XCB_NONE; // Try Xcursor first -@@ -589,6 +595,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) +@@ -585,7 +591,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) + // Non-standard X11 cursors are created from bitmaps cursor = createNonStandardCursor(cshape); - +- +#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) // Create a glpyh cursor if everything else failed if (!cursor && cursorId) { cursor = xcb_generate_id(conn); -@@ -596,6 +603,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) +@@ -593,6 +599,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) cursorId, cursorId + 1, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0); } +#endif if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) { - const char *name = cursorNames[cshape]; + const char *name = cursorNames[cshape].front(); -- 2.22.0 diff --git a/depends/patches/qt/no_sdk_version_check.patch b/depends/patches/qt/no_sdk_version_check.patch new file mode 100644 index 0000000000..b16635b572 --- /dev/null +++ b/depends/patches/qt/no_sdk_version_check.patch @@ -0,0 +1,20 @@ +commit f5eb142cd04be2bc4ca610ed3b5b7e8ce3520ee3 +Author: fanquake +Date: Tue Jan 5 16:08:49 2021 +0800 + + Don't invoke macOS SDK version checking + + This tries to use xcrun which is not available when cross-compiling. + +diff --git a/qtbase/mkspecs/features/mac/default_post.prf b/qtbase/mkspecs/features/mac/default_post.prf +index 92a9112bca6..447e186eb26 100644 +--- a/qtbase/mkspecs/features/mac/default_post.prf ++++ b/qtbase/mkspecs/features/mac/default_post.prf +@@ -8,7 +8,6 @@ contains(TEMPLATE, .*app) { + !macx-xcode:if(isEmpty(BUILDS)|build_pass) { + # Detect changes to the platform SDK + QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION QMAKE_XCODE_DEVELOPER_PATH +- QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk) + } + + # Detect incompatible SDK versions diff --git a/depends/patches/qt/qfixed-coretext.patch b/depends/patches/qt/qfixed-coretext.patch deleted file mode 100644 index aa56f1e1de..0000000000 --- a/depends/patches/qt/qfixed-coretext.patch +++ /dev/null @@ -1,34 +0,0 @@ -From dbdd5f0ffbce52c8b789ed09f1aa3f1da6c02e23 Mon Sep 17 00:00:00 2001 -From: Gabriel de Dietrich -Date: Fri, 30 Mar 2018 11:58:16 -0700 -Subject: [PATCH] QCoreTextFontEngine: Fix build with Xcode 9.3 - -Apple LLVM version 9.1.0 (clang-902.0.39.1) - -Error message: - -.../qfontengine_coretext.mm:827:20: error: qualified reference to - 'QFixed' is a constructor name rather than a type in this context - return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont))); - -Change-Id: Iebe26b3b087a16b10664208fc8851cbddb47f043 -Reviewed-by: Konstantin Ritt ---- - src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git old/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm new/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm -index 25ff69d877d..98b753eff96 100644 ---- old/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm -+++ new/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm -@@ -824,7 +824,7 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gl - - QFixed QCoreTextFontEngine::emSquareSize() const - { -- return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont))); -+ return QFixed(int(CTFontGetUnitsPerEm(ctfont))); - } - - QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const --- -2.16.3 \ No newline at end of file diff --git a/depends/patches/qt/qt.pro b/depends/patches/qt/qt.pro new file mode 100644 index 0000000000..8f2e900a84 --- /dev/null +++ b/depends/patches/qt/qt.pro @@ -0,0 +1,16 @@ +# Create the super cache so modules will add themselves to it. +cache(, super) + +!QTDIR_build: cache(CONFIG, add, $$list(QTDIR_build)) + +prl = no_install_prl +CONFIG += $$prl +cache(CONFIG, add stash, prl) + +TEMPLATE = subdirs +SUBDIRS = qtbase qttools qttranslations + +qttools.depends = qtbase +qttranslations.depends = qttools + +load(qt_configure) diff --git a/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch b/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch new file mode 100644 index 0000000000..0358bea6e9 --- /dev/null +++ b/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch @@ -0,0 +1,17 @@ +The moc executable loops through headers on CPLUS_INCLUDE_PATH and stumbles +on the GCC internal _GLIBCXX_VISIBILITY macro. Tell it to ignore it as it is +not supposed to be looking there to begin with. + +Upstream report: https://bugreports.qt.io/browse/QTBUG-83160 + +diff --git a/qtbase/src/tools/moc/main.cpp b/qtbase/src/tools/moc/main.cpp +--- a/qtbase/src/tools/moc/main.cpp ++++ b/qtbase/src/tools/moc/main.cpp +@@ -188,6 +188,7 @@ int runMoc(int argc, char **argv) + dummyVariadicFunctionMacro.arguments += Symbol(0, PP_IDENTIFIER, "__VA_ARGS__"); + pp.macros["__attribute__"] = dummyVariadicFunctionMacro; + pp.macros["__declspec"] = dummyVariadicFunctionMacro; ++ pp.macros["_GLIBCXX_VISIBILITY"] = dummyVariadicFunctionMacro; + + QString filename; + QString output; diff --git a/depends/patches/qt/qttools_src.pro b/depends/patches/qt/qttools_src.pro new file mode 100644 index 0000000000..6ef71a0942 --- /dev/null +++ b/depends/patches/qt/qttools_src.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = linguist + +fb = force_bootstrap +CONFIG += $$fb +cache(CONFIG, add, fb) diff --git a/depends/patches/qt/xkb-default.patch b/depends/patches/qt/xkb-default.patch deleted file mode 100644 index 165abf3e2e..0000000000 --- a/depends/patches/qt/xkb-default.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- old/qtbase/src/gui/configure.pri 2018-06-06 17:28:10.000000000 -0400 -+++ new/qtbase/src/gui/configure.pri 2018-08-17 18:43:01.589384567 -0400 -@@ -43,18 +43,11 @@ - } - - defineTest(qtConfTest_xkbConfigRoot) { -- qtConfTest_getPkgConfigVariable($${1}): return(true) -- -- for (dir, $$list("/usr/share/X11/xkb", "/usr/local/share/X11/xkb")) { -- exists($$dir) { -- $${1}.value = $$dir -- export($${1}.value) -- $${1}.cache += value -- export($${1}.cache) -- return(true) -- } -- } -- return(false) -+ $${1}.value = "/usr/share/X11/xkb" -+ export($${1}.value) -+ $${1}.cache += value -+ export($${1}.cache) -+ return(true) - } - - defineTest(qtConfTest_qpaDefaultPlatform) { diff --git a/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch b/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch deleted file mode 100644 index a6c508fb8a..0000000000 --- a/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 1a159c128c69a42d90819375c06a39994f3fbfc1 Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Tue, 28 Nov 2017 20:33:25 -0500 -Subject: [PATCH] fix build with older mingw64 - ---- - src/windows.hpp | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/windows.hpp b/src/windows.hpp -index 99e889d..e69038e 100644 ---- a/src/windows.hpp -+++ b/src/windows.hpp -@@ -55,6 +55,13 @@ - #include - #include - #include -+ -+#if defined __MINGW64_VERSION_MAJOR && __MINGW64_VERSION_MAJOR < 4 -+// Workaround for mingw-w64 < v4.0 which did not include ws2ipdef.h in iphlpapi.h. -+// Fixed in mingw-w64 by 9bd8fe9148924840d315b4c915dd099955ea89d1. -+#include -+#include -+#endif - #include - - #if !defined __MINGW32__ --- -2.7.4 - diff --git a/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch b/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch deleted file mode 100644 index d220b54f3e..0000000000 --- a/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6e6b47d5ab381c3df3b30bb0b0a6cf210dfb1eba Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Mon, 5 Mar 2018 14:22:05 -0500 -Subject: [PATCH] disable pthread_set_name_np - -pthread_set_name_np adds a Glibc requirement on >= 2.12. ---- - src/thread.cpp | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/thread.cpp b/src/thread.cpp -index 4fc59c3e..c3fdfd46 100644 ---- a/src/thread.cpp -+++ b/src/thread.cpp -@@ -220,7 +220,7 @@ void zmq::thread_t::setThreadName(const char *name_) - */ - if (!name_) - return; -- -+#if 0 - #if defined(ZMQ_HAVE_PTHREAD_SETNAME_1) - int rc = pthread_setname_np(name_); - if(rc) return; -@@ -233,6 +233,8 @@ void zmq::thread_t::setThreadName(const char *name_) - #elif defined(ZMQ_HAVE_PTHREAD_SET_NAME) - pthread_set_name_np(descriptor, name_); - #endif -+#endif -+ return; - } - - #endif --- -2.11.1 - diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000000..38498103bb --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +Doxyfile diff --git a/doc/Doxyfile b/doc/Doxyfile index c23b145f33..422f79f2b6 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1,106 +1,122 @@ -# Doxyfile 1.7.4 - -# !!! Invoke doxygen from project root using: -# doxygen doc/Doxyfile +# Doxyfile 1.8.12 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a single hash (#) is considered a comment and will be ignored. # The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. PROJECT_NAME = "Blackcoin More" -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. -PROJECT_NUMBER = 2.13.2.8 +PROJECT_NUMBER = 2.13.2.9 -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "P2P Digital Currency" -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. PROJECT_LOGO = doc/bitcoin_logo_doxygen.png -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. OUTPUT_DIRECTORY = doc/doxygen -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. CREATE_SUBDIRS = NO -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. +# The default value is: YES. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ @@ -114,531 +130,690 @@ ABBREVIATE_BRIEF = "The $name class" \ an \ the -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief # description. +# The default value is: NO. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. +# The default value is: NO. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. FULL_PATH_NAMES = YES -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. JAVADOC_AUTOBRIEF = YES -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n in the value part of an alias to insert newlines. +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. -ALIASES = +TCL_SUBST = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. +# The default value is: NO. BUILTIN_STL_SUPPORT = NO -# If you use Microsoft's C++/CLI language, you should set this option to YES to +# If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. +# The default value is: NO. CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. IDL_PROPERTY_SUPPORT = YES -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. +# The default value is: NO. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. SUBGROUPING = YES -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. INLINE_GROUPED_CLASSES = NO -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. EXTRACT_PRIVATE = YES -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO -EXTRACT_STATIC = NO +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. EXTRACT_LOCAL_METHODS = NO -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. +# The default value is: system dependent. CASE_SENSE_NAMES = NO -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. SHOW_INCLUDE_FILES = YES -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. FORCE_LOCAL_INCLUDES = NO -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. SORT_BY_SCOPE_NAME = NO -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. -ENABLED_SECTIONS = +ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. +# The default value is: YES. SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. SHOW_FILES = YES -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. SHOW_NAMESPACES = YES -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. -FILE_VERSION_FILTER = +LAYOUT_FILE = -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. -LAYOUT_FILE = +CITE_BIB_FILES = #--------------------------------------------------------------------------- -# configuration options related to warning and progress messages +# Configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. WARN_IF_UNDOCUMENTED = YES -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. WARN_IF_DOC_ERROR = YES -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- -# configuration options related to the input files +# Configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. -INPUT = src +INPUT = src doc/README_doxygen.md -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. INPUT_ENCODING = UTF-8 -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. FILE_PATTERNS = *.c \ *.cc \ @@ -673,875 +848,1301 @@ FILE_PATTERNS = *.c \ *.vhd \ *.vhdl -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. -EXCLUDE = src/leveldb src/json src/test /src/qt/test +EXCLUDE = src/crc32c \ + src/leveldb \ + src/json \ + src/test \ + src/qt/test -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded # from the input. +# The default value is: NO. EXCLUDE_SYMLINKS = NO -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = boost google +EXCLUDE_SYMBOLS = boost \ + google -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). -EXAMPLE_PATH = +EXAMPLE_PATH = -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. EXAMPLE_PATTERNS = * -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). -IMAGE_PATH = +IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. -INPUT_FILTER = +FILTER_PATTERNS = -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. -FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. -FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. -FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = doc/README_doxygen.md #--------------------------------------------------------------------------- -# configuration options related to source browsing +# Configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. SOURCE_BROWSER = YES -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. REFERENCED_BY_RELATION = NO -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. REFERENCES_RELATION = NO -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentation. +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index +# Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. ALPHABETICAL_INDEX = YES -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- -# configuration options related to the HTML output +# Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is adviced to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_BUNDLE_ID = org.bitcoin.Bitcoin-Core -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_ID = org.bitcoin.Bitcoin-Core -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be # written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_FILE = +CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. -HHC_LOCATION = +HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. -QCH_FILE = +QCH_FILE = -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_ATTRS = -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. -QHP_SECT_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. -QHG_LOCATION = +QHG_LOCATION = -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. -USE_INLINE_TREES = NO +ENUM_VALUES_PER_LINE = 4 -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://www.mathjax.org/mathjax -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /