diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..1164abbc --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,136 @@ +# ============================================================================== +# BitSend Core CODEOWNERS +# ============================================================================== + +# Configuration of code ownership and review approvals for the bitsend/bitsend +# repo. + +# Order is important; the last matching pattern takes the most precedence. +# More info on how this file works can be found at: +# https://help.github.com/articles/about-codeowners/ + +# This file is called CODEOWNERS because it is a magic file for GitHub to +# automatically suggest reviewers. In this project's case, the names below +# should be thought of as code reviewers rather than owners. Regular +# contributors are free to add their names to specific directories or files +# provided that they are willing to provide a review when automatically +# assigned. + +# Absence from this list should not be interpreted as a discouragement to +# review a pull request. Peer review is always welcome and is a critical +# component of the progress of the codebase. Information on peer review +# guidelines can be found in the CONTRIBUTING.md doc. + + +# Maintainers +# @laanwj +# @sipa +# @fanquake +# @jonasschnelli +# @marcofalke +# @meshcollider + +# Docs +/doc/*[a-zA-Z-].md @harding +/doc/Doxyfile.in @fanquake +/doc/REST-interface.md @jonasschnelli +/doc/benchmarking.md @ariard +/doc/bitsend-conf.md @hebasto +/doc/build-freebsd.md @fanquake +/doc/build-netbsd.md @fanquake +/doc/build-openbsd.md @laanwj +/doc/build-osx.md @fanquake +/doc/build-unix.md @laanwj +/doc/build-windows.md @sipsorcery +/doc/dependencies.md @fanquake +/doc/developer-notes.md @laanwj +/doc/files.md @hebasto +/doc/gitian-building.md @laanwj +/doc/reduce-memory.md @fanquake +/doc/reduce-traffic.md @jonasschnelli +/doc/release-process.md @laanwj +/doc/translation_strings_policy.md @laanwj + +# Build aux +/build-aux/m4/bitsend_qt.m4 @hebasto + +# MSVC build system +/build_msvc/ @sipsorcery + +# Settings +/src/util/settings.* @ryanofsky + +# Fuzzing +/src/test/fuzz/ @practicalswift +/doc/fuzzing.md @practicalswift + +# Test framework +/test/functional/mempool_updatefromblock.py @hebasto +/test/functional/feature_asmap.py @jonatack +/test/functional/interface_bitsend_cli.py @jonatack +/test/functional/tool_wallet.py @jonatack + +# Translations +/src/util/translation.h @hebasto + +# Dev Tools +/contrib/devtools/security-check.py @fanquake +/contrib/devtools/test-security-check.py @fanquake +/contrib/devtools/symbol-check.py @fanquake + +# Gitian/Guix +/contrib/gitian-build.py @hebasto +/contrib/guix/ @dongcarl + +# Compatibility +/src/compat/glibc_* @fanquake + +# GUI +/src/qt/forms/ @hebasto + +# Wallet +/src/wallet/ @achow101 + +# CLI +/src/bitsend-cli.cpp @jonatack + +# Coinstats +/src/node/coinstats.* @fjahr + +# Index +/src/index/ @fjahr + +# Descriptors +*descriptor* @achow101 @sipa + +# Interfaces +/src/interfaces/ @ryanofsky + +# DB +/src/txdb.* @jamesob +/src/dbwrapper.* @jamesob + +# Scripts/Linter +*.sh @practicalswift +/test/lint/ @practicalswift +/test/lint/lint-shell.sh @hebasto + +# Bech32 +/src/bech32.* @sipa +/src/bench/bech32.* @sipa + +# PSBT +/src/psbt* @achow101 +/src/node/psbt* @achow101 +/doc/psbt.md @achow101 + +# P2P +/src/net_processing.* @sipa +/src/protocol.* @sipa + +# Consensus +/src/coins.* @sipa @jamesob +/src/script/script.* @sipa +/src/script/interpreter.* @sipa +/src/validation.* @sipa +/src/consensus/ @sipa diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md old mode 100755 new mode 100644 index dd00d544..17f7bd14 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,38 +1,74 @@ -Contributing to Bitsend Core +Contributing to BitSend Core ============================ -The Bitsend Core project operates an open contributor model where anyone is +The BitSend Core project operates an open contributor model where anyone is welcome to contribute towards development in the form of peer review, testing and patches. This document explains the practical process and guidelines for contributing. -Firstly in terms of structure, there is no particular concept of "Core +First, in terms of structure, there is no particular concept of "BitSend Core developers" in the sense of privileged people. Open source often naturally -revolves around meritocracy where longer term contributors gain more trust from -the developer community. However, some hierarchy is necessary for practical -purposes. As such there are repository "maintainers" who are responsible for -merging pull requests as well as a "lead maintainer" who is responsible for the -release cycle, overall merging, moderation and appointment of maintainers. +revolves around a meritocracy where contributors earn trust from the developer +community over time. Nevertheless, some hierarchy is necessary for practical +purposes. As such, there are repository "maintainers" who are responsible for +merging pull requests, as well as a "lead maintainer" who is responsible for the +release cycle as well as overall merging, moderation and appointment of +maintainers. +Getting Started +--------------- + +New contributors are very welcome and needed. + +Reviewing and testing is highly valued and the most effective way you can contribute +as a new contributor. It also will teach you much more about the code and +process than opening pull requests. Please refer to the [peer review](#peer-review) +section below. + +Before you start contributing, familiarize yourself with the BitSend Core build +system and tests. Refer to the documentation in the repository on how to build +BitSend Core and how to run the unit tests, functional tests, and fuzz tests. + +There are many open issues of varying difficulty waiting to be fixed. If you're looking for somewhere to start contributing, check out the -[good first issue](https://github.com/bitcoin/bitcoin/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) -list. +[good first issue](https://github.com/bitsend/bitsend/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) +list or changes that are +[up for grabs](https://github.com/bitsend/bitsend/issues?utf8=%E2%9C%93&q=label%3A%22Up+for+grabs%22). +Some of them might no longer be applicable. So if you are interested, but +unsure, you might want to leave a comment on the issue first. + +You may also participate in the weekly +[BitSend Core PR Review Club](https://bitsendcore.reviews/) meeting. + +### Good First Issue Label + +The purpose of the `good first issue` label is to highlight which issues are +suitable for a new contributor without a deep understanding of the codebase. + +However, good first issues can be solved by anyone. If they remain unsolved +for a longer time, a frequent contributor might address them. + +You do not need to request permission to start working on an issue. However, +you are encouraged to leave a comment if you are planning to work on it. This +will help other contributors monitor which issues are actively being addressed +and is also an effective way to request assistance if and when you need it. Communication Channels ---------------------- -Most communication about Bitsend Core development happens on IRC, in the -#bitcoin-core-dev channel on Freenode. The easiest way to participate on IRC is +Most communication about BitSend Core development happens on IRC, in the +`#bitsend-core-dev` channel on Freenode. The easiest way to participate on IRC is with the web client, [webchat.freenode.net](https://webchat.freenode.net/). Chat history logs can be found -on [botbot.me](https://botbot.me/freenode/bitcoin-core-dev/). +on [http://www.erisian.com.au/bitsend-core-dev/](http://www.erisian.com.au/bitsend-core-dev/) +and [http://gnusha.org/bitsend-core-dev/](http://gnusha.org/bitsend-core-dev/). -Discussion about code base improvements happens in GitHub issues and on pull +Discussion about codebase improvements happens in GitHub issues and pull requests. The developer [mailing list](https://lists.linuxfoundation.org/mailman/listinfo/bitsend-dev) -should be used to discuss complicated or controversial changes before working on +should be used to discuss complicated or controversial consensus or P2P protocol changes before working on a patch set. @@ -40,91 +76,127 @@ Contributor Workflow -------------------- The codebase is maintained using the "contributor workflow" where everyone -without exception contributes patch proposals using "pull requests". This +without exception contributes patch proposals using "pull requests" (PRs). This facilitates social contribution, easy testing and peer review. To contribute a patch, the workflow is as follows: - 1. Fork repository + 1. Fork repository ([only for the first time](https://help.github.com/en/articles/fork-a-repo)) 1. Create topic branch 1. Commit patches +For GUI-related issues or pull requests, the https://github.com/bitsend-core/gui repository should be used. +For all other issues and pull requests, the https://github.com/bitsend/bitsend node repository should be used. + +The master branch for all monotree repositories is identical. + +As a rule of thumb, everything that only modifies `src/qt` is a GUI-only pull +request. However: + +* For global refactoring or other transversal changes the node repository + should be used. +* For GUI-related build system changes, the node repository should be used + because the change needs review by the build systems reviewers. +* Changes in `src/interfaces` need to go to the node repository because they + might affect other components like the wallet. + +For large GUI changes that include build system and interface changes, it is +recommended to first open a pull request against the GUI repository. When there +is agreement to proceed with the changes, a pull request with the build system +and interfaces changes can be submitted to the node repository. + The project coding conventions in the [developer notes](doc/developer-notes.md) -must be adhered to. +must be followed. + +### Committing Patches -In general [commits should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) -and diffs should be easy to read. For this reason do not mix any formatting +In general, [commits should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) +and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. +Make sure each individual commit is hygienic: that it builds successfully on its +own without warnings, errors, regressions, or test failures. + Commit messages should be verbose by default consisting of a short subject line (50 chars max), a blank line and detailed explanatory text as separate paragraph(s), unless the title alone is self-explanatory (like "Corrected typo in init.cpp") in which case a single title line is sufficient. Commit messages should be helpful to people reading your code in the future, so explain the reasoning for -your decisions. Further explanation [here](http://chris.beams.io/posts/git-commit/). +your decisions. Further explanation [here](https://chris.beams.io/posts/git-commit/). If a particular commit references another issue, please add the reference. For example: `refs #1234` or `fixes #4321`. Using the `fixes` or `closes` keywords will cause the corresponding issue to be closed when the pull request is merged. +Commit messages should never contain any `@` mentions (usernames prefixed with "@"). + Please refer to the [Git manual](https://git-scm.com/doc) for more information about Git. - Push changes to your fork - Create pull request +### Creating the Pull Request + The title of the pull request should be prefixed by the component or area that the pull request affects. Valid areas as: - - *Consensus* for changes to consensus critical code - - *Docs* for changes to the documentation - - *Qt* for changes to bitsend-qt - - *Mining* for changes to the mining code - - *Net* or *P2P* for changes to the peer-to-peer network code - - *RPC/REST/ZMQ* for changes to the RPC, REST or ZMQ APIs - - *Scripts and tools* for changes to the scripts and tools - - *Tests* for changes to the bitsend unit tests or QA tests - - *Trivial* should **only** be used for PRs that do not change generated - executable code. Notably, refactors (change of function arguments and code - reorganization) and changes in behavior should **not** be marked as trivial. - Examples of trivial PRs are changes to: - - comments - - whitespace - - variable names - - logging and messages - - *Utils and libraries* for changes to the utils and libraries - - *Wallet* for changes to the wallet code + - `consensus` for changes to consensus critical code + - `doc` for changes to the documentation + - `qt` or `gui` for changes to bitsend-qt + - `log` for changes to log messages + - `mining` for changes to the mining code + - `net` or `p2p` for changes to the peer-to-peer network code + - `refactor` for structural changes that do not change behavior + - `rpc`, `rest` or `zmq` for changes to the RPC, REST or ZMQ APIs + - `script` for changes to the scripts and tools + - `test`, `qa` or `ci` for changes to the unit tests, QA tests or CI code + - `util` or `lib` for changes to the utils or libraries + - `wallet` for changes to the wallet code + - `build` for changes to the GNU Autotools or reproducible builds Examples: - Consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG - Net: Automatically create hidden service, listen on Tor - Qt: Add feed bump button - Trivial: Fix typo in init.cpp + consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG + net: Automatically create onion service, listen on Tor + qt: Add feed bump button + log: Fix typo in log message + +The body of the pull request should contain sufficient description of *what* the +patch does, and even more importantly, *why*, with justification and reasoning. +You should include references to any discussions (for example, other issues or +mailing list discussions). + +The description for a new pull request should not contain any `@` mentions. The +PR description will be included in the commit message when the PR is merged and +any users mentioned in the description will be annoyingly notified each time a +fork of BitSend Core copies the merge. Instead, make any username mentions in a +subsequent comment to the PR. -Note that translations should not be submitted as pull requests, please see -[Translation Process](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md) +### Translation changes + +Note that translations should not be submitted as pull requests. Please see +[Translation Process](https://github.com/bitsend/bitsend/blob/master/doc/translation_process.md) for more information on helping with translations. +### Work in Progress Changes and Requests for Comments + If a pull request is not to be considered for merging (yet), please prefix the title with [WIP] or use [Tasks Lists](https://help.github.com/articles/basic-writing-and-formatting-syntax/#task-lists) in the body of the pull request to indicate tasks are pending. -The body of the pull request should contain enough description about what the -patch does together with any justification/reasoning. You should include -references to any discussions (for example other tickets or mailing list -discussions). +### Address Feedback -At this stage one should expect comments and review from other contributors. You +At this stage, one should expect comments and review from other contributors. You can add more commits to your pull request by committing them locally and pushing to your fork until you have satisfied all feedback. -Note: Code review is a burdensome but important part of the development process, and as such, certain types of pull requests are rejected. In general, if the **improvements** do not warrant the **review effort** required, the PR has a high chance of being rejected. It is up to the PR author to convince the reviewers that the changes warrant the review effort, and if reviewers are "Concept NAK'ing" the PR, the author may need to present arguments and/or do research backing their suggested changes. +Note: Code review is a burdensome but important part of the development process, and as such, certain types of pull requests are rejected. In general, if the **improvements** do not warrant the **review effort** required, the PR has a high chance of being rejected. It is up to the PR author to convince the reviewers that the changes warrant the review effort, and if reviewers are "Concept NACK'ing" the PR, the author may need to present arguments and/or do research backing their suggested changes. + +### Squashing Commits -Squashing Commits ---------------------------- -If your pull request is accepted for merging, you may be asked by a maintainer -to squash and or [rebase](https://git-scm.com/docs/git-rebase) your commits +If your pull request contains fixup commits (commits that change the same line of code repeatedly) or too fine-grained +commits, you may be asked to [squash](https://git-scm.com/docs/git-rebase#_interactive_mode) your commits before it will be merged. The basic squashing workflow is shown below. git checkout your_branch_name @@ -135,9 +207,13 @@ before it will be merged. The basic squashing workflow is shown below. # Save and quit. git push -f # (force push to GitHub) -If you have problems with squashing (or other workflows with `git`), you can -alternatively enable "Allow edits from maintainers" in the right GitHub -sidebar and ask for help in the pull request. +Please update the resulting commit message, if needed. It should read as a +coherent message. In most cases, this means not just listing the interim +commits. + +If you have problems with squashing or other git workflows, you can enable +"Allow edits from maintainers" in the right-hand sidebar of the GitHub web +interface and ask for help in the pull request. Please refrain from creating several pull requests for the same change. Use the pull request that is already open (or was created earlier) to amend @@ -147,6 +223,20 @@ the respective change set. The length of time required for peer review is unpredictable and will vary from pull request to pull request. +### Rebasing Changes + +When a pull request conflicts with the target branch, you may be asked to rebase it on top of the current target branch. +The `git rebase` command will take care of rebuilding your commits on top of the new base. + +This project aims to have a clean git history, where code changes are only made in non-merge commits. This simplifies +auditability because merge commits can be assumed to not contain arbitrary code changes. Merge commits should be signed, +and the resulting git tree hash must be deterministic and reproducible. The script in +[/contrib/verify-commits](/contrib/verify-commits) checks that. + +After a rebase, reviewers are encouraged to sign off on the force push. This should be relatively straightforward with +the `git range-diff` tool explained in the [productivity +notes](/doc/productivity.md#diff-the-diffs-with-git-range-diff). To avoid needless review churn, maintainers will +generally merge pull requests that received the most review attention first. Pull Request Philosophy ----------------------- @@ -171,9 +261,9 @@ in the future, they may be removed by the Repository Maintainer. Refactoring is a necessary part of any software project's evolution. The following guidelines cover refactoring pull requests for the project. -There are three categories of refactoring, code only moves, code style fixes, -code refactoring. In general refactoring pull requests should not mix these -three kinds of activity in order to make refactoring pull requests easy to +There are three categories of refactoring: code-only moves, code style fixes, and +code refactoring. In general, refactoring pull requests should not mix these +three kinds of activities in order to make refactoring pull requests easy to review and uncontroversial. In all cases, refactoring PRs must not change the behaviour of code within the pull request (bugs must be preserved as is). @@ -192,11 +282,11 @@ workload on reviewing. "Decision Making" Process ------------------------- -The following applies to code changes to the Bitsend Core project (and related -projects such as libsecp256k1), and is not to be confused with overall Bitsend +The following applies to code changes to the BitSend Core project (and related +projects such as libsecp256k1), and is not to be confused with overall BitSend Network Protocol consensus changes. -Whether a pull request is merged into Bitsend Core rests with the project merge +Whether a pull request is merged into BitSend Core rests with the project merge maintainers and ultimately the project lead. Maintainers will take into consideration if a patch is in line with the general @@ -207,14 +297,15 @@ In general, all pull requests must: - Have a clear use case, fix a demonstrable bug or serve the greater good of the project (for example refactoring for modularisation); - - Be well peer reviewed; - - Have unit tests and functional tests where appropriate; + - Be well peer-reviewed; + - Have unit tests, functional tests, and fuzz tests, where appropriate; - Follow code style guidelines ([C++](doc/developer-notes.md), [functional tests](test/functional/README.md)); - Not break the existing test suite; - Where bugs are fixed, where possible, there should be unit tests demonstrating the bug and also proving the fix. This helps prevent regression. + - Change relevant comments and documentation when behaviour of code changes. -Patches that change Bitsend consensus rules are considerably more involved than +Patches that change BitSend consensus rules are considerably more involved than normal because they affect the entire ecosystem and so must be preceded by extensive mailing list discussions and have a numbered BIP. While each case will be different, one should be prepared to expend more time and effort than for @@ -229,33 +320,45 @@ request. Typically reviewers will review the code for obvious errors, as well as test out the patch set and opine on the technical merits of the patch. Project maintainers take into account the peer review when determining if there is consensus to merge a pull request (remember that discussions may have been -spread out over GitHub, mailing list and IRC discussions). The following -language is used within pull-request comments: - - - ACK means "I have tested the code and I agree it should be merged"; - - NACK means "I disagree this should be merged", and must be accompanied by - sound technical justification (or in certain cases of copyright/patent/licensing - issues, legal justification). NACKs without accompanying reasoning may be - disregarded; - - utACK means "I have not tested the code, but I have reviewed it and it looks - OK, I agree it can be merged"; - - Concept ACK means "I agree in the general principle of this pull request"; - - Nit refers to trivial, often non-blocking issues. +spread out over GitHub, mailing list and IRC discussions). + +#### Conceptual Review + +A review can be a conceptual review, where the reviewer leaves a comment + * `Concept (N)ACK`, meaning "I do (not) agree with the general goal of this pull + request", + * `Approach (N)ACK`, meaning `Concept ACK`, but "I do (not) agree with the + approach of this change". -Reviewers should include the commit hash which they reviewed in their comments. +A `NACK` needs to include a rationale why the change is not worthwhile. +NACKs without accompanying reasoning may be disregarded. + +#### Code Review + +After conceptual agreement on the change, code review can be provided. A review +begins with `ACK BRANCH_COMMIT`, where `BRANCH_COMMIT` is the top of the PR +branch, followed by a description of how the reviewer did the review. The +following language is used within pull request comments: + + - "I have tested the code", involving change-specific manual testing in + addition to running the unit, functional, or fuzz tests, and in case it is + not obvious how the manual testing was done, it should be described; + - "I have not tested the code, but I have reviewed it and it looks + OK, I agree it can be merged"; + - A "nit" refers to a trivial, often non-blocking issue. Project maintainers reserve the right to weigh the opinions of peer reviewers -using common sense judgement and also may weight based on meritocracy: Those -that have demonstrated a deeper commitment and understanding towards the project -(over time) or have clear domain expertise may naturally have more weight, as -one would expect in all walks of life. +using common sense judgement and may also weigh based on merit. Reviewers that +have demonstrated a deeper commitment and understanding of the project over time +or who have clear domain expertise may naturally have more weight, as one would +expect in all walks of life. -Where a patch set affects consensus critical code, the bar will be set much +Where a patch set affects consensus-critical code, the bar will be much higher in terms of discussion and peer review requirements, keeping in mind that mistakes could be very costly to the wider community. This includes refactoring -of consensus critical code. +of consensus-critical code. -Where a patch set proposes to change the Bitsend consensus, it must have been +Where a patch set proposes to change the BitSend consensus, it must have been discussed extensively on the mailing list and IRC, be accompanied by a widely discussed BIP and have a generally widely perceived technical consensus of being a worthwhile change based on the judgement of the maintainers. @@ -270,7 +373,7 @@ about: - It may be because of a feature freeze due to an upcoming release. During this time, only bug fixes are taken into consideration. If your pull request is a new feature, - it will not be prioritized until the release is over. Wait for release. + it will not be prioritized until after the release. Wait for the release. - It may be because the changes you are suggesting do not appeal to people. Rather than nits and critique, which require effort and means they care enough to spend time on your contribution, thundering silence is a good sign of widespread (mild) dislike of a given change @@ -280,27 +383,54 @@ about: [developer notes](doc/developer-notes.md), is dangerous or insecure, is messily written, etc. Identify and address any of the issues you find. Then ask e.g. on IRC if someone could give their opinion on the concept itself. - - It may be because your code is too complex for all but a few people. And those people + - It may be because your code is too complex for all but a few people, and those people may not have realized your pull request even exists. A great way to find people who are qualified and care about the code you are touching is the [Git Blame feature](https://help.github.com/articles/tracing-changes-in-a-file/). Simply - find the person touching the code you are touching before you and see if you can find - them and give them a nudge. Don't be incessant about the nudging though. + look up who last modified the code you are changing and see if you can find + them and give them a nudge. Don't be incessant about the nudging, though. - Finally, if all else fails, ask on IRC or elsewhere for someone to give your pull request - a look. If you think you've been waiting an unreasonably long amount of time (month+) for - no particular reason (few lines changed, etc), this is totally fine. Try to return the favor - when someone else is asking for feedback on their code, and universe balances out. + a look. If you think you've been waiting for an unreasonably long time (say, + more than a month) for no particular reason (a few lines changed, etc.), + this is totally fine. Try to return the favor when someone else is asking + for feedback on their code, and the universe balances out. + - Remember that the best thing you can do while waiting is give review to others! + + +Backporting +----------- + +Security and bug fixes can be backported from `master` to release +branches. +If the backport is non-trivial, it may be appropriate to open an +additional PR to backport the change, but only after the original PR +has been merged. +Otherwise, backports will be done in batches and +the maintainers will use the proper `Needs backport (...)` labels +when needed (the original author does not need to worry about it). + +A backport should contain the following metadata in the commit body: + +``` +Github-Pull: # +Rebased-From: +``` + +Have a look at [an example backport PR]( +https://github.com/bitsend/bitsend/pull/16189). +Also see the [backport.py script]( +https://github.com/bitsend-core/bitsend-maintainer-tools#backport). Release Policy -------------- -The project leader is the release manager for each Bitsend Core release. +The project leader is the release manager for each BitSend Core release. Copyright --------- -By contributing to this repository, you agree to license your work under the -MIT license unless specified otherwise in `contrib/debian/copyright` or at -the top of the file itself. Any work contributed where you are not the original +By contributing to this repository, you agree to license your work under the +MIT license unless specified otherwise in `contrib/debian/copyright` or at +the top of the file itself. Any work contributed where you are not the original author must contain its license header with the original author(s) and source. diff --git a/COPYING b/COPYING old mode 100755 new mode 100644 index d2e9b94b..fa126155 --- a/COPYING +++ b/COPYING @@ -1,9 +1,7 @@ The MIT License (MIT) -Copyright (c) 2009-2018 The Bitcoin Core developers -Copyright (c) 2009-2018 Bitcoin Developers -Copyright (c) 2014-2019 The Dash Core developers -Copyright (c) 2014-2019 The Bitsend Core developers +Copyright (c) 2009-2020 The BitSend Core developers +Copyright (c) 2009-2020 BitSend Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/INSTALL.md b/INSTALL.md old mode 100755 new mode 100644 index 3d200b2e..2d3a8044 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,5 +1,5 @@ -Building Bitsend +Building BitSend ================ See doc/build-*.md for instructions on building the various -elements of the Bitsend Core reference implementation of Bitsend. +elements of the BitSend Core reference implementation of BitSend. diff --git a/Makefile.am b/Makefile.am old mode 100755 new mode 100644 index 9c66a393..f922b229 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,11 @@ -# Copyright (c) 2013-2016 The Bitsend Core developers +# Copyright (c) 2013-2020 The BitSend 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-%: + @echo $* = $($*) + ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src if ENABLE_MAN @@ -19,12 +23,14 @@ endif BITSENDD_BIN=$(top_builddir)/src/$(BITSEND_DAEMON_NAME)$(EXEEXT) BITSEND_QT_BIN=$(top_builddir)/src/qt/$(BITSEND_GUI_NAME)$(EXEEXT) BITSEND_CLI_BIN=$(top_builddir)/src/$(BITSEND_CLI_NAME)$(EXEEXT) -BITSEND_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) +BITSEND_TX_BIN=$(top_builddir)/src/$(BITSEND_TX_NAME)$(EXEEXT) +BITSEND_WALLET_BIN=$(top_builddir)/src/$(BITSEND_WALLET_TOOL_NAME)$(EXEEXT) +BITSEND_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win64-setup$(EXEEXT) empty := space := $(empty) $(empty) -OSX_APP=Bitsend-Qt.app +OSX_APP=BitSend-Qt.app OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) OSX_DMG = $(OSX_VOLNAME).dmg OSX_BACKGROUND_SVG=background.svg @@ -35,14 +41,12 @@ 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/bitsend.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_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) -DIST_CONTRIB = $(top_srcdir)/contrib/bitsend-cli.bash-completion \ - $(top_srcdir)/contrib/bitsend-tx.bash-completion \ - $(top_srcdir)/contrib/bitsendd.bash-completion \ - $(top_srcdir)/contrib/init \ - $(top_srcdir)/contrib/install_db4.sh +OSX_QT_TRANSLATIONS = ar,bg,ca,cs,da,de,es,fa,fi,fr,gd,gl,he,hu,it,ja,ko,lt,lv,pl,pt,ru,sk,sl,sv,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 @@ -61,10 +65,10 @@ OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh -COVERAGE_INFO = baseline.info \ +COVERAGE_INFO = $(COV_TOOL_WRAPPER) baseline.info \ test_bitsend_filtered.info total_coverage.info \ baseline_filtered.info functional_test.info functional_test_filtered.info \ - test_bitsend_coverage.info test_bitsend.info + test_bitsend_coverage.info test_bitsend.info fuzz.info fuzz_filtered.info fuzz_coverage.info dist-hook: -$(GIT) archive --format=tar HEAD -- src/clientversion.cpp | $(AMTAR) -C $(top_distdir) -xf - @@ -74,7 +78,9 @@ $(BITSEND_WIN_INSTALLER): all-recursive STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITSENDD_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITSEND_QT_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITSEND_CLI_BIN) $(top_builddir)/release - @test -f $(MAKENSIS) && $(MAKENSIS) -V2 $(top_builddir)/share/setup.nsi || \ + STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITSEND_TX_BIN) $(top_builddir)/release + STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITSEND_WALLET_BIN) $(top_builddir)/release + @test -f $(MAKENSIS) && echo 'OutFile "$@"' | cat $(top_builddir)/share/setup.nsi - | $(MAKENSIS) -V2 - || \ echo error: could not build $@ @echo built $@ @@ -84,7 +90,7 @@ $(OSX_APP)/Contents/PkgInfo: $(OSX_APP)/Contents/Resources/empty.lproj: $(MKDIR_P) $(@D) - @touch $@ + @touch $@ $(OSX_APP)/Contents/Info.plist: $(OSX_PLIST) $(MKDIR_P) $(@D) @@ -94,7 +100,7 @@ $(OSX_APP)/Contents/Resources/bitsend.icns: $(OSX_INSTALLER_ICONS) $(MKDIR_P) $(@D) $(INSTALL_DATA) $< $@ -$(OSX_APP)/Contents/MacOS/Bitsend-Qt: all-recursive +$(OSX_APP)/Contents/MacOS/BitSend-Qt: all-recursive $(MKDIR_P) $(@D) STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITSEND_QT_BIN) $@ @@ -104,7 +110,7 @@ $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings: OSX_APP_BUILT=$(OSX_APP)/Contents/PkgInfo $(OSX_APP)/Contents/Resources/empty.lproj \ $(OSX_APP)/Contents/Resources/bitsend.icns $(OSX_APP)/Contents/Info.plist \ - $(OSX_APP)/Contents/MacOS/Bitsend-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings + $(OSX_APP)/Contents/MacOS/BitSend-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings osx_volname: echo $(OSX_VOLNAME) >$@ @@ -129,7 +135,7 @@ $(APP_DIST_DIR)/Applications: @rm -f $@ @cd $(@D); $(LN_S) /Applications $(@F) -$(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitsend-Qt +$(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/BitSend-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 @@ -144,7 +150,7 @@ $(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIF $(APP_DIST_DIR)/.DS_Store: $(OSX_DSSTORE_GEN) $(PYTHON) $< "$@" "$(OSX_VOLNAME)" -$(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitsend-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) +$(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/BitSend-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 deploydir: $(APP_DIST_EXTRAS) @@ -167,16 +173,48 @@ $(BITSENDD_BIN): FORCE $(BITSEND_CLI_BIN): FORCE $(MAKE) -C src $(@F) -if USE_LCOV -LCOV_FILTER_PATTERN=-p "/usr/include/" -p "src/leveldb/" -p "src/bench/" -p "src/univalue" -p "src/crypto/ctaes" -p "src/secp256k1" +$(BITSEND_TX_BIN): FORCE + $(MAKE) -C src $(@F) -baseline.info: +$(BITSEND_WALLET_BIN): FORCE + $(MAKE) -C src $(@F) + +if USE_LCOV +LCOV_FILTER_PATTERN = \ + -p "/usr/local/" \ + -p "/usr/include/" \ + -p "/usr/lib/" \ + -p "/usr/lib64/" \ + -p "src/leveldb/" \ + -p "src/crc32c/" \ + -p "src/bench/" \ + -p "src/univalue" \ + -p "src/crypto/ctaes" \ + -p "src/secp256k1" \ + -p "depends" + +DIR_FUZZ_SEED_CORPUS ?= qa-assets/fuzz_seed_corpus + +$(COV_TOOL_WRAPPER): + @echo 'exec $(COV_TOOL) "$$@"' > $(COV_TOOL_WRAPPER) + @chmod +x $(COV_TOOL_WRAPPER) + +baseline.info: $(COV_TOOL_WRAPPER) $(LCOV) -c -i -d $(abs_builddir)/src -o $@ baseline_filtered.info: baseline.info $(abs_builddir)/contrib/filter-lcov.py $(LCOV_FILTER_PATTERN) $< $@ $(LCOV) -a $@ $(LCOV_OPTS) -o $@ +fuzz.info: baseline_filtered.info + @TIMEOUT=15 test/fuzz/test_runner.py $(DIR_FUZZ_SEED_CORPUS) -l DEBUG + $(LCOV) -c $(LCOV_OPTS) -d $(abs_builddir)/src --t fuzz-tests -o $@ + $(LCOV) -z $(LCOV_OPTS) -d $(abs_builddir)/src + +fuzz_filtered.info: fuzz.info + $(abs_builddir)/contrib/filter-lcov.py $(LCOV_FILTER_PATTERN) $< $@ + $(LCOV) -a $@ $(LCOV_OPTS) -o $@ + test_bitsend.info: baseline_filtered.info $(MAKE) -C src/ check $(LCOV) -c $(LCOV_OPTS) -d $(abs_builddir)/src -t test_bitsend -o $@ @@ -187,7 +225,7 @@ test_bitsend_filtered.info: test_bitsend.info $(LCOV) -a $@ $(LCOV_OPTS) -o $@ functional_test.info: test_bitsend_filtered.info - -@TIMEOUT=15 test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) + @TIMEOUT=15 test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) $(LCOV) -c $(LCOV_OPTS) -d $(abs_builddir)/src --t functional-tests -o $@ $(LCOV) -z $(LCOV_OPTS) -d $(abs_builddir)/src @@ -195,12 +233,19 @@ functional_test_filtered.info: functional_test.info $(abs_builddir)/contrib/filter-lcov.py $(LCOV_FILTER_PATTERN) $< $@ $(LCOV) -a $@ $(LCOV_OPTS) -o $@ +fuzz_coverage.info: fuzz_filtered.info + $(LCOV) -a $(LCOV_OPTS) baseline_filtered.info -a fuzz_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt + test_bitsend_coverage.info: baseline_filtered.info test_bitsend_filtered.info $(LCOV) -a $(LCOV_OPTS) baseline_filtered.info -a test_bitsend_filtered.info -o $@ total_coverage.info: test_bitsend_filtered.info functional_test_filtered.info $(LCOV) -a $(LCOV_OPTS) baseline_filtered.info -a test_bitsend_filtered.info -a functional_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt +fuzz.coverage/.dirstamp: fuzz_coverage.info + $(GENHTML) -s $(LCOV_OPTS) $< -o $(@D) + @touch $@ + test_bitsend.coverage/.dirstamp: test_bitsend_coverage.info $(GENHTML) -s $(LCOV_OPTS) $< -o $(@D) @touch $@ @@ -209,13 +254,19 @@ total.coverage/.dirstamp: total_coverage.info $(GENHTML) -s $(LCOV_OPTS) $< -o $(@D) @touch $@ +cov_fuzz: fuzz.coverage/.dirstamp + cov: test_bitsend.coverage/.dirstamp total.coverage/.dirstamp endif dist_noinst_SCRIPTS = autogen.sh -EXTRA_DIST = $(DIST_SHARE) test/functional/test_runner.py test/functional $(DIST_CONTRIB) $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) +EXTRA_DIST = $(DIST_SHARE) $(DIST_CONTRIB) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) + +EXTRA_DIST += \ + test/functional \ + test/fuzz EXTRA_DIST += \ test/util/bitsend-util-test.py \ @@ -266,6 +317,8 @@ EXTRA_DIST += \ test/util/data/txcreatescript3.json \ test/util/data/txcreatescript4.hex \ test/util/data/txcreatescript4.json \ + test/util/data/txcreatescript5.hex \ + test/util/data/txcreatescript6.hex \ test/util/data/txcreatesignv1.hex \ test/util/data/txcreatesignv1.json \ test/util/data/txcreatesignv2.hex \ @@ -293,6 +346,17 @@ clean-docs: rm -rf doc/doxygen clean-local: clean-docs - rm -rf coverage_percent.txt test_bitsend.coverage/ total.coverage/ test/tmp/ cache/ $(OSX_APP) - rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache + rm -rf coverage_percent.txt test_bitsend.coverage/ total.coverage/ fuzz.coverage/ test/tmp/ cache/ $(OSX_APP) + rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache share/rpcauth/__pycache__ + rm -rf osx_volname dist/ dpi36.background.tiff dpi72.background.tiff +test-security-check: +if TARGET_DARWIN + $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO +endif +if TARGET_WINDOWS + $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE +endif +if TARGET_LINUX + $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF +endif diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 0e12e94f..d354a359 --- a/README.md +++ b/README.md @@ -1,37 +1,41 @@ -Bitsend Core integration/staging tree +BitSend Core integration/staging tree ===================================== -# Test 1 +https://bitsendcore.org -https://bitsend.cc - -What is Bitsend? +What is BitSend? ---------------- -Bitsend is an experimental digital currency that enables instant payments to -anyone, anywhere in the world. Bitsend uses peer-to-peer technology to operate +BitSend is an experimental digital currency that enables instant payments to +anyone, anywhere in the world. BitSend uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried -out collectively by the network. Bitsend Core is the name of open source +out collectively by the network. BitSend Core is the name of open source software which enables the use of this currency. -For more information, as well as an immediately useable, binary version of -the Bitsend Core software, see https://github.com/LIMXTEC/BitSend/releases, or read the -[original whitepaper](https://github.com/LIMXTEC/BitSend/releases/download/v0.14.0.5/Z.Whitepaper.E3.Juni.2018.pdf). +For more information, as well as an immediately usable, binary version of +the BitSend Core software, see https://bitsendcore.org/en/download/, or read the +[original whitepaper](https://bitsendcore.org/bitsend.pdf). License ------- -Bitsend Core is released under the terms of the MIT license. See [COPYING](COPYING) for more +BitSend Core is released under the terms of the MIT license. See [COPYING](COPYING) for more information or see https://opensource.org/licenses/MIT. Development Process ------------------- -The `master` branch is regularly built and tested, but is not guaranteed to be -completely stable. [Tags](https://github.com/LIMXTEC/BitSend/tags) are created -regularly to indicate new official, stable release versions of Bitsend Core. +The `master` branch is regularly built (see `doc/build-*.md` for instructions) and tested, but it is not guaranteed to be +completely stable. [Tags](https://github.com/bitsend/bitsend/tags) are created +regularly from release branches to indicate new official, stable release versions of BitSend Core. + +The https://github.com/bitsend-core/gui repository is used exclusively for the +development of the GUI. Its master branch is identical in all monotree +repositories. Release branches and tags do not exist, so please do not fork +that repository unless it is for development reasons. -The contribution workflow is described in [CONTRIBUTING.md](CONTRIBUTING.md). +The contribution workflow is described in [CONTRIBUTING.md](CONTRIBUTING.md) +and useful hints for developers can be found in [doc/developer-notes.md](doc/developer-notes.md). Testing ------- @@ -65,7 +69,7 @@ Translations ------------ Changes to translations as well as new translations can be submitted to -[Bitcoin Core's Transifex page](https://www.transifex.com/projects/p/bitcoin/). +[BitSend Core's Transifex page](https://www.transifex.com/bitsend/bitsend/). Translations are periodically pulled from Transifex and merged into the git repository. See the [translation process](doc/translation_process.md) for details on how this works. @@ -73,4 +77,4 @@ Translations are periodically pulled from Transifex and merged into the git repo **Important**: We do not accept translation changes as GitHub pull requests because the next pull from Transifex would automatically overwrite them again. -Translators should also subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bitcoin-translators). +Translators should also subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bitsend-translators). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..816fbda8 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security Policy + +## Supported Versions + +See our website for versions of BitSend Core that are currently supported with +security updates: https://bitsendcore.org/en/lifecycle/#schedule + +## Reporting a Vulnerability + +To report security issues send an email to security@bitsendcore.org (not for support). + +The following keys may be used to communicate sensitive information to developers: + +| Name | Fingerprint | +|------|-------------| +| Wladimir van der Laan | 71A3 B167 3540 5025 D447 E8F2 7481 0B01 2346 C9A6 | +| Jonas Schnelli | 32EE 5C4C 3FA1 5CCA DB46 ABE5 29D4 BCB6 416F 53EC | +| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 | + +You can import a key by running the following command with that individual’s fingerprint: `gpg --recv-keys ""` Ensure that you put quotes around fingerprints containing spaces. diff --git a/autogen.sh b/autogen.sh index 23c88823..486cf37c 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,16 +1,16 @@ #!/bin/sh -# Copyright (c) 2013-2016 The Bitsend Core developers +# Copyright (c) 2013-2019 The BitSend 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 old mode 100755 new mode 100644 index 650c94fa..2ae33f71 --- 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 @@ -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,110 +52,123 @@ 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 - - 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 - dnl installed to /usr/lib/arm-linux-gnueabihf. Try getting the compiler's - dnl value for an extra chance of finding the correct path. - libsubdirs="lib/`$CXX -dumpmachine 2>/dev/null` $libsubdirs" + 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 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 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 ; 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 +179,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 +191,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 ; 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 +242,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 +250,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 +259,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 +274,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 +283,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 +299,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 deleted file mode 100755 index 6ea77b9b..00000000 --- a/build-aux/m4/ax_boost_chrono.m4 +++ /dev/null @@ -1,118 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_BOOST_CHRONO -# -# DESCRIPTION -# -# Test for Chrono 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_CHRONO_LIB) -# -# And sets: -# -# HAVE_BOOST_CHRONO -# -# LICENSE -# -# Copyright (c) 2012 Xiyue Deng -# -# 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 - -AC_DEFUN([AX_BOOST_CHRONO], -[ - AC_ARG_WITH([boost-chrono], - AS_HELP_STRING([--with-boost-chrono@<:@=special-lib@:>@], - [use the Chrono library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-chrono=boost_chrono-gcc-mt ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_chrono_lib="" - else - want_boost="yes" - ax_boost_user_chrono_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::Chrono library is available, - ax_cv_boost_chrono, - [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[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++]) - ]) - if test "x$ax_cv_boost_chrono" = "xyes"; then - AC_SUBST(BOOST_CPPFLAGS) - - AC_DEFINE(HAVE_BOOST_CHRONO,,[define if the Boost::Chrono library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - LDFLAGS_SAVE=$LDFLAGS - if test "x$ax_boost_user_chrono_lib" = "x"; then - 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, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="no"]) - done - if test "x$link_chrono" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_chrono*.dll* $BOOSTLIBDIR/boost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_chrono.*\)\.dll.*$;\1;' -e 's;^\(boost_chrono.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_chrono_lib boost_chrono-$ax_boost_user_chrono_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="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_chrono" = "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_filesystem.m4 b/build-aux/m4/ax_boost_filesystem.m4 old mode 100755 new mode 100644 index f5c9d564..12f7bc5e --- 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 00000000..5d20e674 --- /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_system.m4 b/build-aux/m4/ax_boost_system.m4 old mode 100755 new mode 100644 index 1c05450c..323e2a67 --- 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 old mode 100755 new mode 100644 index 9f0bd0b2..75e80e6e --- 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 old mode 100755 new mode 100644 index 3d8e93e9..4cca32fc --- a/build-aux/m4/ax_boost_unit_test_framework.m4 +++ b/build-aux/m4/ax_boost_unit_test_framework.m4 @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 21 +#serial 22 AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], [ @@ -124,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 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_check_compile_flag.m4 b/build-aux/m4/ax_check_compile_flag.m4 old mode 100755 new mode 100644 diff --git a/build-aux/m4/ax_check_link_flag.m4 b/build-aux/m4/ax_check_link_flag.m4 old mode 100755 new mode 100644 diff --git a/build-aux/m4/ax_check_preproc_flag.m4 b/build-aux/m4/ax_check_preproc_flag.m4 old mode 100755 new mode 100644 diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 old mode 100755 new mode 100644 index f147cee3..43087b2e --- 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_gcc_func_attribute.m4 b/build-aux/m4/ax_gcc_func_attribute.m4 old mode 100755 new mode 100644 diff --git a/build-aux/m4/ax_pthread.m4 b/build-aux/m4/ax_pthread.m4 old mode 100755 new mode 100644 index 4c4051ea..1598d077 --- 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/bitsend_find_bdb48.m4 b/build-aux/m4/bitsend_find_bdb48.m4 old mode 100755 new mode 100644 index 526737a8..ec91445f --- a/build-aux/m4/bitsend_find_bdb48.m4 +++ b/build-aux/m4/bitsend_find_bdb48.m4 @@ -1,4 +1,4 @@ -dnl Copyright (c) 2013-2015 The Bitsend Core developers +dnl Copyright (c) 2013-2015 The BitSend Core developers dnl Distributed under the MIT software license, see the accompanying dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -61,7 +61,7 @@ AC_DEFUN([BITSEND_FIND_BDB48],[ BDB_CPPFLAGS=${BDB_CFLAGS} fi AC_SUBST(BDB_CPPFLAGS) - + if test "x$BDB_LIBS" = "x"; then # TODO: Ideally this could find the library version and make sure it matches the headers being used for searchlib in db_cxx-4.8 db_cxx db4_cxx; do diff --git a/build-aux/m4/bitsend_qt.m4 b/build-aux/m4/bitsend_qt.m4 old mode 100755 new mode 100644 index bbf58efd..0a9b48cd --- a/build-aux/m4/bitsend_qt.m4 +++ b/build-aux/m4/bitsend_qt.m4 @@ -1,4 +1,4 @@ -dnl Copyright (c) 2013-2016 The Bitsend Core developers +dnl Copyright (c) 2013-2016 The BitSend Core developers dnl Distributed under the MIT software license, see the accompanying dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -72,32 +72,33 @@ AC_DEFUN([BITSEND_QT_INIT],[ AC_ARG_WITH([qtdbus], [AS_HELP_STRING([--with-qtdbus], - [enable DBus support (default is yes if qt is enabled and QtDBus is found)])], + [enable DBus support (default is yes if qt is enabled and QtDBus is found, except on Android)])], [use_dbus=$withval], [use_dbus=auto]) + dnl Android doesn't support D-Bus and certainly doesn't use it for notifications + case $host in + *android*) + if test "x$use_dbus" != xyes; then + use_dbus=no + fi + ;; + esac + 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 _BITSEND_QT_FIND_LIBS_* +dnl Find Qt libraries and includes. +dnl +dnl BITSEND_QT_CONFIGURE([MINIMUM-VERSION]) +dnl +dnl Outputs: See _BITSEND_QT_FIND_LIBS dnl Outputs: Sets variables for all qt-related tools. dnl Outputs: bitsend_enable_qt, bitsend_enable_qt_dbus, bitsend_enable_qt_test AC_DEFUN([BITSEND_QT_CONFIGURE],[ - use_pkgconfig=$1 - - if test "x$use_pkgconfig" = x; then - use_pkgconfig=yes - fi - - if test "x$use_pkgconfig" = xyes; then - BITSEND_QT_CHECK([_BITSEND_QT_FIND_LIBS_WITH_PKGCONFIG]) - else - BITSEND_QT_CHECK([_BITSEND_QT_FIND_LIBS_WITHOUT_PKGCONFIG]) - fi + qt_version=">= $1" + qt_lib_prefix="Qt5" + BITSEND_QT_CHECK([_BITSEND_QT_FIND_LIBS]) dnl This is ugly and complicated. Yuck. Works as follows: dnl For Qt5, we can check a header to find out whether Qt is build @@ -116,26 +117,10 @@ AC_DEFUN([BITSEND_QT_CONFIGURE],[ if test "x$bitsend_cv_static_qt" = xyes; then _BITSEND_QT_FIND_STATIC_PLUGINS AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) - AC_CACHE_CHECK(for Qt < 5.4, bitsend_cv_need_acc_widget,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION >= 0x050400 - choke - #endif - ]])], - [bitsend_cv_need_acc_widget=yes], - [bitsend_cv_need_acc_widget=no]) - ]) - if test "x$bitsend_cv_need_acc_widget" = xyes; then - _BITSEND_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) + if test "x$TARGET_OS" != xandroid; then + _BITSEND_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]) fi - _BITSEND_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 _BITSEND_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]) @@ -146,13 +131,16 @@ AC_DEFUN([BITSEND_QT_CONFIGURE],[ AX_CHECK_LINK_FLAG([[-framework IOKit]],[QT_LIBS="$QT_LIBS -framework IOKit"],[AC_MSG_ERROR(could not iokit framework)]) _BITSEND_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]) + elif test "x$TARGET_OS" = xandroid; then + QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype -lQt5EglSupport $QT_LIBS" + AC_DEFINE(QT_QPA_PLATFORM_ANDROID, 1, [Define this symbol if the qt platform is android]) fi fi CPPFLAGS=$TEMP_CPPFLAGS CXXFLAGS=$TEMP_CXXFLAGS ]) - if test "x$use_pkgconfig$qt_bin_path" = xyes; then + if test "x$qt_bin_path" = x; then qt_bin_path="`$PKG_CONFIG --variable=host_bins Qt5Core 2>/dev/null`" fi @@ -226,7 +214,7 @@ AC_DEFUN([BITSEND_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]) BITSEND_QT_CHECK([ bitsend_enable_qt=yes bitsend_enable_qt_test=yes @@ -246,7 +234,11 @@ AC_DEFUN([BITSEND_QT_CONFIGURE],[ ],[ bitsend_enable_qt=no ]) - AC_MSG_RESULT([$bitsend_enable_qt (Qt5)]) + if test x$bitsend_enable_qt = xyes; then + AC_MSG_RESULT([$bitsend_enable_qt ($qt_lib_prefix)]) + else + AC_MSG_RESULT([$bitsend_enable_qt]) + fi AC_SUBST(QT_PIE_FLAGS) AC_SUBST(QT_INCLUDES) @@ -264,57 +256,15 @@ 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: bitsend_cv_qt5=yes|no -AC_DEFUN([_BITSEND_QT_CHECK_QT5],[ - AC_CACHE_CHECK(for Qt 5, bitsend_cv_qt5,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION < 0x050000 || QT_VERSION_MAJOR < 5 - choke - #endif - ]])], - [bitsend_cv_qt5=yes], - [bitsend_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: bitsend_cv_qt5=yes|no -AC_DEFUN([_BITSEND_QT_CHECK_QT58],[ - AC_CACHE_CHECK(for > Qt 5.7, bitsend_cv_qt58,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION_MINOR < 8 - choke - #endif - ]])], - [bitsend_cv_qt58=yes], - [bitsend_cv_qt58=no]) -])]) - - dnl Internal. Check if the linked version of Qt was built as static libs. dnl Requires: Qt5. dnl Requires: INCLUDES and LIBS must be populated as necessary. dnl Output: bitsend_cv_static_qt=yes|no -dnl Output: Defines QT_STATICPLUGIN if plugins are static. AC_DEFUN([_BITSEND_QT_IS_STATIC],[ AC_CACHE_CHECK(for static Qt, bitsend_cv_static_qt,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - #ifndef QT_VERSION OR QT_VERSION_STR + #ifndef QT_VERSION # include #endif ]], @@ -326,9 +276,6 @@ AC_DEFUN([_BITSEND_QT_IS_STATIC],[ [bitsend_cv_static_qt=yes], [bitsend_cv_static_qt=no]) ]) - if test "x$bitsend_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. @@ -359,172 +306,52 @@ AC_DEFUN([_BITSEND_QT_FIND_STATIC_PLUGINS],[ if test -d "$qt_plugin_path/accessible"; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" fi - if test "x$use_pkgconfig" = xyes; then - : dnl - m4_ifdef([PKG_CHECK_MODULES],[ - if test x$bitsend_cv_qt58 = xno; then - PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) - else - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) - 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([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, bitsend_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 - ]])], - [bitsend_cv_need_platformsupport=yes], - [bitsend_cv_need_platformsupport=no]) - ]) - if test "x$bitsend_cv_need_platformsupport" = xyes; then - if test x$bitsend_cv_qt58 = xno; then - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}PlatformSupport],[main],,BITSEND_QT_FAIL(lib$QT_LIB_PREFIXPlatformSupport not found))) - else - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}FontDatabaseSupport],[main],,BITSEND_QT_FAIL(lib$QT_LIB_PREFIXFontDatabaseSupport not found))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}EventDispatcherSupport],[main],,BITSEND_QT_FAIL(lib$QT_LIB_PREFIXEventDispatcherSupport not found))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}ThemeSupport],[main],,BITSEND_QT_FAIL(lib$QT_LIB_PREFIXThemeSupport not found))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}FbSupport],[main],,BITSEND_QT_FAIL(lib$QT_LIB_PREFIXFbSupport not found))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}DeviceDiscoverySupport],[main],,BITSEND_QT_FAIL(lib$QT_LIB_PREFIXDeviceDiscoverySupport not found))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}AccessibilitySupport],[main],,BITSEND_QT_FAIL(lib$QT_LIB_PREFIXAccessibilitySupport not found))) - QT_LIBS="$QT_LIBS -lversion -ldwmapi -luxtheme" - fi - fi - fi - fi - fi -]) - -dnl Internal. Find Qt libraries using pkg-config. -dnl Inputs: bitsend_qt_want_version (from --with-gui=). The version to check -dnl first. -dnl Inputs: $1: If bitsend_qt_want_version is "auto", check for this version -dnl first. -dnl Outputs: All necessary QT_* variables are set. -dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. -AC_DEFUN([_BITSEND_QT_FIND_LIBS_WITH_PKGCONFIG],[ - m4_ifdef([PKG_CHECK_MODULES],[ - QT_LIB_PREFIX=Qt5 - qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets" - BITSEND_QT_CHECK([ - PKG_CHECK_MODULES([QT5], [$qt5_modules], [QT_INCLUDES="$QT5_CFLAGS"; QT_LIBS="$QT5_LIBS" have_qt=yes],[have_qt=no]) - - if test "x$have_qt" != xyes; then - have_qt=no - BITSEND_QT_FAIL([Qt dependencies not found]) + if test -d "$qt_plugin_path/platforms/android"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" fi - ]) - BITSEND_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]) + PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) + 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"]) + if test "x$TARGET_OS" = xlinux; then + PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xdarwin; then + 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 - ]) - ]) - true; dnl + fi ]) -dnl Internal. Find Qt libraries without using pkg-config. Version is deduced -dnl from the discovered headers. -dnl Inputs: bitsend_qt_want_version (from --with-gui=). The version to use. -dnl If "auto", the version will be discovered by _BITSEND_QT_CHECK_QT5. +dnl Internal. Find Qt libraries using pkg-config. dnl Outputs: All necessary QT_* variables are set. dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. -AC_DEFUN([_BITSEND_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[ - TEMP_CPPFLAGS="$CPPFLAGS" - TEMP_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$PIC_FLAGS $CXXFLAGS" - TEMP_LIBS="$LIBS" +AC_DEFUN([_BITSEND_QT_FIND_LIBS],[ BITSEND_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_CORE], [${qt_lib_prefix}Core $qt_version], [], + [BITSEND_QT_FAIL([${qt_lib_prefix}Core $qt_version not found])]) ]) - - BITSEND_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITSEND_QT_FAIL(QtCore headers missing))]) - BITSEND_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITSEND_QT_FAIL(QtGui headers missing))]) - BITSEND_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITSEND_QT_FAIL(QtNetwork headers missing))]) - BITSEND_QT_CHECK([ - if test "x$bitsend_qt_want_version" = xauto; then - _BITSEND_QT_CHECK_QT5 - _BITSEND_QT_CHECK_QT58 - fi - QT_LIB_PREFIX=Qt5 + PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui $qt_version], [], + [BITSEND_QT_FAIL([${qt_lib_prefix}Gui $qt_version not found])]) ]) - BITSEND_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],, BITSEND_QT_FAIL(libimm32 not found)) - fi + PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets $qt_version], [], + [BITSEND_QT_FAIL([${qt_lib_prefix}Widgets $qt_version not found])]) ]) - - BITSEND_QT_CHECK(AC_CHECK_LIB([z] ,[main],,AC_MSG_WARN([zlib not found. Assuming qt has it built-in]))) - BITSEND_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$bitsend_cv_qt58 = xno; then - BITSEND_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITSEND_QT_CHECK(AC_SEARCH_LIBS([pcre16_exec], [qtpcre pcre16],,AC_MSG_WARN([libpcre16 not found. Assuming qt has it built-in]))) - else - BITSEND_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtlibpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITSEND_QT_CHECK(AC_SEARCH_LIBS([pcre2_match_16], [qtpcre2 libqtpcre2],,AC_MSG_WARN([libqtpcre2 not found. Assuming qt has it built-in]))) - fi - BITSEND_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]))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITSEND_QT_FAIL(lib${QT_LIB_PREFIX}Core not found))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITSEND_QT_FAIL(lib${QT_LIB_PREFIX}Gui not found))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Network],[main],,BITSEND_QT_FAIL(lib${QT_LIB_PREFIX}Network not found))) - BITSEND_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Widgets],[main],,BITSEND_QT_FAIL(lib${QT_LIB_PREFIX}Widgets not found))) - QT_LIBS="$LIBS" - LIBS="$TEMP_LIBS" + BITSEND_QT_CHECK([ + PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network $qt_version], [], + [BITSEND_QT_FAIL([${qt_lib_prefix}Network $qt_version not found])]) + ]) + QT_INCLUDES="$QT_CORE_CFLAGS $QT_GUI_CFLAGS $QT_WIDGETS_CFLAGS $QT_NETWORK_CFLAGS" + QT_LIBS="$QT_CORE_LIBS $QT_GUI_LIBS $QT_WIDGETS_LIBS $QT_NETWORK_LIBS" BITSEND_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" + PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) 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_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/bitsend_subdir_to_include.m4 b/build-aux/m4/bitsend_subdir_to_include.m4 old mode 100755 new mode 100644 index df362186..51c57a64 --- a/build-aux/m4/bitsend_subdir_to_include.m4 +++ b/build-aux/m4/bitsend_subdir_to_include.m4 @@ -1,4 +1,4 @@ -dnl Copyright (c) 2013-2014 The Bitsend Core developers +dnl Copyright (c) 2013-2014 The BitSend Core developers dnl Distributed under the MIT software license, see the accompanying dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/build-aux/m4/l_atomic.m4 b/build-aux/m4/l_atomic.m4 old mode 100755 new mode 100644 diff --git a/build-aux/m4/l_socket.m4 b/build-aux/m4/l_socket.m4 new file mode 100644 index 00000000..38923a98 --- /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/build_msvc/.gitignore b/build_msvc/.gitignore new file mode 100644 index 00000000..81ba7c3c --- /dev/null +++ b/build_msvc/.gitignore @@ -0,0 +1,27 @@ +# Build directories +Debug/* +Release/* +.vs +packages/* +*/Obj +*/Debug +*/Release +*/x64 +*.vcxproj.user + +# .vcxproj files that are auto-generated by the msvc-autogen.py script. +libbitsend_cli/libbitsend_cli.vcxproj +libbitsend_common/libbitsend_common.vcxproj +libbitsend_crypto/libbitsend_crypto.vcxproj +libbitsend_server/libbitsend_server.vcxproj +libbitsend_util/libbitsend_util.vcxproj +libbitsend_wallet_tool/libbitsend_wallet_tool.vcxproj +libbitsend_wallet/libbitsend_wallet.vcxproj +libbitsend_zmq/libbitsend_zmq.vcxproj +bench_bitsend/bench_bitsend.vcxproj +libtest_util/libtest_util.vcxproj + +*/Win32 +libbitsend_qt/QtGeneratedFiles/* +test_bitsend-qt/QtGeneratedFiles/* +vcpkg_installed \ No newline at end of file diff --git a/build_msvc/README.md b/build_msvc/README.md new file mode 100644 index 00000000..c4b5f102 --- /dev/null +++ b/build_msvc/README.md @@ -0,0 +1,79 @@ +Building BitSend Core with Visual Studio +======================================== + +Introduction +--------------------- +Solution and project files to build the BitSend Core applications `msbuild` or Visual Studio can be found in the `build_msvc` directory. The build has been tested with Visual Studio 2017 and 2019. + +Building with Visual Studio is an alternative to the Linux based [cross-compiler build](https://github.com/bitsend/bitsend/blob/master/doc/build-windows.md). + +Quick Start +--------------------- +The minimal steps required to build BitSend Core with the msbuild toolchain are below. More detailed instructions are contained in the following sections. + +``` +cd build_msvc +py -3 msvc-autogen.py +msbuild /m bitsend.sln /p:Platform=x64 /p:Configuration=Release /t:build +``` + +Dependencies +--------------------- +A number of [open source libraries](https://github.com/bitsend/bitsend/blob/master/doc/dependencies.md) are required in order to be able to build BitSend Core. + +Options for installing the dependencies in a Visual Studio compatible manner are: + +- Use Microsoft's [vcpkg](https://docs.microsoft.com/en-us/cpp/vcpkg) to download the source packages and build locally. This is the recommended approach. +- Download the source code, build each dependency, add the required include paths, link libraries and binary tools to the Visual Studio project files. +- Use [nuget](https://www.nuget.org/) packages with the understanding that any binary files have been compiled by an untrusted third party. + +The [external dependencies](https://github.com/bitsend/bitsend/blob/master/doc/dependencies.md) required for building are listed in the `build_msvc/vcpkg.json` file. The `msbuild` project files are configured to automatically install the `vcpkg` dependencies. + +Qt +--------------------- +In order to build the BitSend Core a static build of Qt is required. The runtime library version (e.g. v141, v142) and platform type (x86 or x64) must also match. + +Some prebuilt x64 versions of Qt can be downloaded from [here](https://github.com/sipsorcery/qt_win_binary/releases). Please be aware these downloads are NOT officially sanctioned by BitSend Core and are provided for developer convenience only. They should NOT be used for builds that will be used in a production environment or with real funds. + +To determine which Qt prebuilt version to download open the `.appveyor.yml` file and note the `QT_DOWNLOAD_URL`. When extracting the zip file the destination path must be set to `C:\`. This is due to the way that Qt includes, libraries and tools use internal paths. + +To build BitSend Core without Qt unload or disable the `bitsend-qt`, `libbitsend_qt` and `test_bitsend-qt` projects. + +Building +--------------------- +The instructions below use `vcpkg` to install the dependencies. + +- Install [`vcpkg`](https://github.com/Microsoft/vcpkg). + +- Use Python to generate `*.vcxproj` from Makefile + +``` +PS >py -3 msvc-autogen.py +``` + +- An optional step is to adjust the settings in the `build_msvc` directory and the `common.init.vcxproj` file. This project file contains settings that are common to all projects such as the runtime library version and target Windows SDK version. The Qt directories can also be set. + +- To build from the command line with the Visual Studio 2017 toolchain use: + +``` +msbuild /m bitsend.sln /p:Platform=x64 /p:Configuration=Release /p:PlatformToolset=v141 /t:build +``` + +- To build from the command line with the Visual Studio 2019 toolchain use: + +``` +msbuild /m bitsend.sln /p:Platform=x64 /p:Configuration=Release /t:build +``` + +- Alternatively open the `build_msvc/bitsend.sln` file in Visual Studio. + +AppVeyor +--------------------- +The .appveyor.yml in the root directory is suitable to perform builds on [AppVeyor](https://www.appveyor.com/) Continuous Integration servers. The simplest way to perform an AppVeyor build is to fork BitSend Core and then configure a new AppVeyor Project pointing to the forked repository. + +For safety reasons the BitSend Core .appveyor.yml file has the artifact options disabled. The build will be performed but no executable files will be available. To enable artifacts on a forked repository uncomment the lines shown below: + +``` + #- 7z a bitsend-%APPVEYOR_BUILD_VERSION%.zip %APPVEYOR_BUILD_FOLDER%\build_msvc\%platform%\%configuration%\*.exe + #- path: bitsend-%APPVEYOR_BUILD_VERSION%.zip +``` diff --git a/build_msvc/bench_bitsend/bench_bitsend.vcxproj.in b/build_msvc/bench_bitsend/bench_bitsend.vcxproj.in new file mode 100644 index 00000000..bc5e4219 --- /dev/null +++ b/build_msvc/bench_bitsend/bench_bitsend.vcxproj.in @@ -0,0 +1,62 @@ + + + + + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB} + + + Application + $(SolutionDir)$(Platform)\$(Configuration)\ + + +@SOURCE_FILES@ + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {460fee33-1fe1-483f-b3bf-931ff8e969a5} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {93b86837-b543-48a5-a89b-7c87abb77df2} + + + {792d487f-f14c-49fc-a9de-3fc150f31c3f} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + {bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6} + + + {18430fef-6b61-4c53-b396-718e02850f1b} + + + {1e065f03-3566-47d0-8fa9-daa72b084e7d} + + + + + There was an error executing the raw bench header generation task. + + + + + + + + + + + \ No newline at end of file diff --git a/build_msvc/bitsend-cli/bitsend-cli.vcxproj b/build_msvc/bitsend-cli/bitsend-cli.vcxproj new file mode 100644 index 00000000..ff7c0ad4 --- /dev/null +++ b/build_msvc/bitsend-cli/bitsend-cli.vcxproj @@ -0,0 +1,31 @@ + + + + + {0B2D7431-F876-4A58-87BF-F748338CD3BF} + + + Application + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + {0667528c-d734-4009-adf9-c0d6c4a5a5a6} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + + + + diff --git a/build_msvc/bitsend-tx/bitsend-tx.vcxproj b/build_msvc/bitsend-tx/bitsend-tx.vcxproj new file mode 100644 index 00000000..86da44c0 --- /dev/null +++ b/build_msvc/bitsend-tx/bitsend-tx.vcxproj @@ -0,0 +1,37 @@ + + + + + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF} + + + Application + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + {bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6} + + + + + + diff --git a/build_msvc/bitsend-wallet/bitsend-wallet.vcxproj b/build_msvc/bitsend-wallet/bitsend-wallet.vcxproj new file mode 100644 index 00000000..a642e165 --- /dev/null +++ b/build_msvc/bitsend-wallet/bitsend-wallet.vcxproj @@ -0,0 +1,55 @@ + + + + + {84DE8790-EDE3-4483-81AC-C32F15E861F4} + + + Application + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {0667528c-d734-4009-adf9-c0d6c4a5a5a6} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {460fee33-1fe1-483f-b3bf-931ff8e969a5} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {93b86837-b543-48a5-a89b-7c87abb77df2} + + + {792d487f-f14c-49fc-a9de-3fc150f31c3f} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + {f91ac55e-6f5e-4c58-9ac5-b40db7deef93} + + + {bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6} + + + {18430fef-6b61-4c53-b396-718e02850f1b} + + + + + + diff --git a/build_msvc/bitsend.sln b/build_msvc/bitsend.sln new file mode 100644 index 00000000..03044787 --- /dev/null +++ b/build_msvc/bitsend.sln @@ -0,0 +1,252 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.452 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsendconsensus", "libbitsendconsensus\libbitsendconsensus.vcxproj", "{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testconsensus", "testconsensus\testconsensus.vcxproj", "{E78473E9-B850-456C-9120-276301E04C06}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitsendd", "bitsendd\bitsendd.vcxproj", "{D4513DDF-6013-44DC-ADCC-12EAF6D1F038}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_util", "libbitsend_util\libbitsend_util.vcxproj", "{B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_common", "libbitsend_common\libbitsend_common.vcxproj", "{7C87E378-DF58-482E-AA2F-1BC129BC19CE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_crypto", "libbitsend_crypto\libbitsend_crypto.vcxproj", "{6190199C-6CF4-4DAD-BFBD-93FA72A760C1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_server", "libbitsend_server\libbitsend_server.vcxproj", "{460FEE33-1FE1-483F-B3BF-931FF8E969A5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libunivalue", "libunivalue\libunivalue.vcxproj", "{5724BA7D-A09A-4BA8-800B-C4C1561B3D69}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_wallet", "libbitsend_wallet\libbitsend_wallet.vcxproj", "{93B86837-B543-48A5-A89B-7C87ABB77DF2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_zmq", "libbitsend_zmq\libbitsend_zmq.vcxproj", "{792D487F-F14C-49FC-A9DE-3FC150F31C3F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_bitsend", "test_bitsend\test_bitsend.vcxproj", "{A56B73DB-D46D-4882-8374-1FE3FFA08F07}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_cli", "libbitsend_cli\libbitsend_cli.vcxproj", "{0667528C-D734-4009-ADF9-C0D6C4A5A5A6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitsend-cli", "bitsend-cli\bitsend-cli.vcxproj", "{0B2D7431-F876-4A58-87BF-F748338CD3BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_bitsend", "bench_bitsend\bench_bitsend.vcxproj", "{1125654E-E1B2-4431-8B5C-62EA9A2FEECB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitsend-tx", "bitsend-tx\bitsend-tx.vcxproj", "{D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitsend-wallet", "bitsend-wallet\bitsend-wallet.vcxproj", "{84DE8790-EDE3-4483-81AC-C32F15E861F4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_wallet_tool", "libbitsend_wallet_tool\libbitsend_wallet_tool.vcxproj", "{F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsecp256k1", "libsecp256k1\libsecp256k1.vcxproj", "{BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libleveldb", "libleveldb\libleveldb.vcxproj", "{18430FEF-6B61-4C53-B396-718E02850F1B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitsend_qt", "libbitsend_qt\libbitsend_qt.vcxproj", "{2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitsend-qt", "bitsend-qt\bitsend-qt.vcxproj", "{7E99172D-7FF2-4CB6-B736-AC9B76ED412A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtest_util", "libtest_util\libtest_util.vcxproj", "{868474FD-35F6-4400-8EED-30A33E7521D4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_bitsend-qt", "test_bitsend-qt\test_bitsend-qt.vcxproj", "{51201D5E-D939-4854-AE9D-008F03FF518E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x64.ActiveCfg = Debug|x64 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x64.Build.0 = Debug|x64 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x86.ActiveCfg = Debug|Win32 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Debug|x86.Build.0 = Debug|Win32 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x64.ActiveCfg = Release|x64 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x64.Build.0 = Release|x64 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x86.ActiveCfg = Release|Win32 + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE}.Release|x86.Build.0 = Release|Win32 + {E78473E9-B850-456C-9120-276301E04C06}.Debug|x64.ActiveCfg = Debug|x64 + {E78473E9-B850-456C-9120-276301E04C06}.Debug|x64.Build.0 = Debug|x64 + {E78473E9-B850-456C-9120-276301E04C06}.Debug|x86.ActiveCfg = Debug|Win32 + {E78473E9-B850-456C-9120-276301E04C06}.Debug|x86.Build.0 = Debug|Win32 + {E78473E9-B850-456C-9120-276301E04C06}.Release|x64.ActiveCfg = Release|x64 + {E78473E9-B850-456C-9120-276301E04C06}.Release|x64.Build.0 = Release|x64 + {E78473E9-B850-456C-9120-276301E04C06}.Release|x86.ActiveCfg = Release|Win32 + {E78473E9-B850-456C-9120-276301E04C06}.Release|x86.Build.0 = Release|Win32 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x64.ActiveCfg = Debug|x64 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x64.Build.0 = Debug|x64 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x86.ActiveCfg = Debug|Win32 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Debug|x86.Build.0 = Debug|Win32 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x64.ActiveCfg = Release|x64 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x64.Build.0 = Release|x64 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x86.ActiveCfg = Release|Win32 + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038}.Release|x86.Build.0 = Release|Win32 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Debug|x64.ActiveCfg = Debug|x64 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Debug|x64.Build.0 = Debug|x64 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Debug|x86.ActiveCfg = Debug|Win32 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Debug|x86.Build.0 = Debug|Win32 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Release|x64.ActiveCfg = Release|x64 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Release|x64.Build.0 = Release|x64 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Release|x86.ActiveCfg = Release|Win32 + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}.Release|x86.Build.0 = Release|Win32 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Debug|x64.ActiveCfg = Debug|x64 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Debug|x64.Build.0 = Debug|x64 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Debug|x86.ActiveCfg = Debug|Win32 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Debug|x86.Build.0 = Debug|Win32 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Release|x64.ActiveCfg = Release|x64 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Release|x64.Build.0 = Release|x64 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Release|x86.ActiveCfg = Release|Win32 + {7C87E378-DF58-482E-AA2F-1BC129BC19CE}.Release|x86.Build.0 = Release|Win32 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Debug|x64.ActiveCfg = Debug|x64 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Debug|x64.Build.0 = Debug|x64 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Debug|x86.ActiveCfg = Debug|Win32 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Debug|x86.Build.0 = Debug|Win32 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Release|x64.ActiveCfg = Release|x64 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Release|x64.Build.0 = Release|x64 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Release|x86.ActiveCfg = Release|Win32 + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1}.Release|x86.Build.0 = Release|Win32 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Debug|x64.ActiveCfg = Debug|x64 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Debug|x64.Build.0 = Debug|x64 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Debug|x86.ActiveCfg = Debug|Win32 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Debug|x86.Build.0 = Debug|Win32 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Release|x64.ActiveCfg = Release|x64 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Release|x64.Build.0 = Release|x64 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Release|x86.ActiveCfg = Release|Win32 + {460FEE33-1FE1-483F-B3BF-931FF8E969A5}.Release|x86.Build.0 = Release|Win32 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Debug|x64.ActiveCfg = Debug|x64 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Debug|x64.Build.0 = Debug|x64 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Debug|x86.ActiveCfg = Debug|Win32 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Debug|x86.Build.0 = Debug|Win32 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Release|x64.ActiveCfg = Release|x64 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Release|x64.Build.0 = Release|x64 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Release|x86.ActiveCfg = Release|Win32 + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69}.Release|x86.Build.0 = Release|Win32 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Debug|x64.ActiveCfg = Debug|x64 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Debug|x64.Build.0 = Debug|x64 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Debug|x86.ActiveCfg = Debug|Win32 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Debug|x86.Build.0 = Debug|Win32 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Release|x64.ActiveCfg = Release|x64 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Release|x64.Build.0 = Release|x64 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Release|x86.ActiveCfg = Release|Win32 + {93B86837-B543-48A5-A89B-7C87ABB77DF2}.Release|x86.Build.0 = Release|Win32 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Debug|x64.ActiveCfg = Debug|x64 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Debug|x64.Build.0 = Debug|x64 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Debug|x86.ActiveCfg = Debug|Win32 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Debug|x86.Build.0 = Debug|Win32 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Release|x64.ActiveCfg = Release|x64 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Release|x64.Build.0 = Release|x64 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Release|x86.ActiveCfg = Release|Win32 + {792D487F-F14C-49FC-A9DE-3FC150F31C3F}.Release|x86.Build.0 = Release|Win32 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Debug|x64.ActiveCfg = Debug|x64 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Debug|x64.Build.0 = Debug|x64 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Debug|x86.ActiveCfg = Debug|Win32 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Debug|x86.Build.0 = Debug|Win32 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Release|x64.ActiveCfg = Release|x64 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Release|x64.Build.0 = Release|x64 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Release|x86.ActiveCfg = Release|Win32 + {A56B73DB-D46D-4882-8374-1FE3FFA08F07}.Release|x86.Build.0 = Release|Win32 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Debug|x64.ActiveCfg = Debug|x64 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Debug|x64.Build.0 = Debug|x64 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Debug|x86.ActiveCfg = Debug|Win32 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Debug|x86.Build.0 = Debug|Win32 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Release|x64.ActiveCfg = Release|x64 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Release|x64.Build.0 = Release|x64 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Release|x86.ActiveCfg = Release|Win32 + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6}.Release|x86.Build.0 = Release|Win32 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Debug|x64.ActiveCfg = Debug|x64 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Debug|x64.Build.0 = Debug|x64 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Debug|x86.ActiveCfg = Debug|Win32 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Debug|x86.Build.0 = Debug|Win32 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Release|x64.ActiveCfg = Release|x64 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Release|x64.Build.0 = Release|x64 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Release|x86.ActiveCfg = Release|Win32 + {0B2D7431-F876-4A58-87BF-F748338CD3BF}.Release|x86.Build.0 = Release|Win32 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Debug|x64.ActiveCfg = Debug|x64 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Debug|x64.Build.0 = Debug|x64 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Debug|x86.ActiveCfg = Debug|Win32 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Debug|x86.Build.0 = Debug|Win32 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Release|x64.ActiveCfg = Release|x64 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Release|x64.Build.0 = Release|x64 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Release|x86.ActiveCfg = Release|Win32 + {1125654E-E1B2-4431-8B5C-62EA9A2FEECB}.Release|x86.Build.0 = Release|Win32 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Debug|x64.ActiveCfg = Debug|x64 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Debug|x64.Build.0 = Debug|x64 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Debug|x86.ActiveCfg = Debug|Win32 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Debug|x86.Build.0 = Debug|Win32 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x64.ActiveCfg = Release|x64 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x64.Build.0 = Release|x64 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x86.ActiveCfg = Release|Win32 + {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x86.Build.0 = Release|Win32 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Debug|x64.ActiveCfg = Debug|x64 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Debug|x64.Build.0 = Debug|x64 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Debug|x86.ActiveCfg = Debug|Win32 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Debug|x86.Build.0 = Debug|Win32 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Release|x64.ActiveCfg = Release|x64 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Release|x64.Build.0 = Release|x64 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Release|x86.ActiveCfg = Release|Win32 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Release|x86.Build.0 = Release|Win32 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Debug|x64.ActiveCfg = Debug|x64 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Debug|x64.Build.0 = Debug|x64 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Debug|x86.ActiveCfg = Debug|Win32 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Debug|x86.Build.0 = Debug|Win32 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Release|x64.ActiveCfg = Release|x64 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Release|x64.Build.0 = Release|x64 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Release|x86.ActiveCfg = Release|Win32 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Release|x86.Build.0 = Release|Win32 + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}.Debug|x64.ActiveCfg = Debug|x64 + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}.Debug|x64.Build.0 = Debug|x64 + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}.Debug|x86.ActiveCfg = Debug|Win32 + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}.Debug|x86.Build.0 = Debug|Win32 + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}.Release|x64.ActiveCfg = Release|x64 + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}.Release|x64.Build.0 = Release|x64 + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}.Release|x86.ActiveCfg = Release|Win32 + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}.Release|x86.Build.0 = Release|Win32 + {18430FEF-6B61-4C53-B396-718E02850F1B}.Debug|x64.ActiveCfg = Debug|x64 + {18430FEF-6B61-4C53-B396-718E02850F1B}.Debug|x64.Build.0 = Debug|x64 + {18430FEF-6B61-4C53-B396-718E02850F1B}.Debug|x86.ActiveCfg = Debug|Win32 + {18430FEF-6B61-4C53-B396-718E02850F1B}.Debug|x86.Build.0 = Debug|Win32 + {18430FEF-6B61-4C53-B396-718E02850F1B}.Release|x64.ActiveCfg = Release|x64 + {18430FEF-6B61-4C53-B396-718E02850F1B}.Release|x64.Build.0 = Release|x64 + {18430FEF-6B61-4C53-B396-718E02850F1B}.Release|x86.ActiveCfg = Release|Win32 + {18430FEF-6B61-4C53-B396-718E02850F1B}.Release|x86.Build.0 = Release|Win32 + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}.Debug|x64.ActiveCfg = Debug|x64 + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}.Debug|x64.Build.0 = Debug|x64 + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}.Debug|x86.ActiveCfg = Debug|Win32 + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}.Debug|x86.Build.0 = Debug|Win32 + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}.Release|x64.ActiveCfg = Release|x64 + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}.Release|x64.Build.0 = Release|x64 + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}.Release|x86.ActiveCfg = Release|Win32 + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF}.Release|x86.Build.0 = Release|Win32 + {7E99172D-7FF2-4CB6-B736-AC9B76ED412A}.Debug|x64.ActiveCfg = Debug|x64 + {7E99172D-7FF2-4CB6-B736-AC9B76ED412A}.Debug|x64.Build.0 = Debug|x64 + {7E99172D-7FF2-4CB6-B736-AC9B76ED412A}.Debug|x86.ActiveCfg = Debug|Win32 + {7E99172D-7FF2-4CB6-B736-AC9B76ED412A}.Debug|x86.Build.0 = Debug|Win32 + {7E99172D-7FF2-4CB6-B736-AC9B76ED412A}.Release|x64.ActiveCfg = Release|x64 + {7E99172D-7FF2-4CB6-B736-AC9B76ED412A}.Release|x64.Build.0 = Release|x64 + {7E99172D-7FF2-4CB6-B736-AC9B76ED412A}.Release|x86.ActiveCfg = Release|Win32 + {7E99172D-7FF2-4CB6-B736-AC9B76ED412A}.Release|x86.Build.0 = Release|Win32 + {868474FD-35F6-4400-8EED-30A33E7521D4}.Debug|x64.ActiveCfg = Debug|x64 + {868474FD-35F6-4400-8EED-30A33E7521D4}.Debug|x64.Build.0 = Debug|x64 + {868474FD-35F6-4400-8EED-30A33E7521D4}.Debug|x86.ActiveCfg = Debug|Win32 + {868474FD-35F6-4400-8EED-30A33E7521D4}.Debug|x86.Build.0 = Debug|Win32 + {868474FD-35F6-4400-8EED-30A33E7521D4}.Release|x64.ActiveCfg = Release|x64 + {868474FD-35F6-4400-8EED-30A33E7521D4}.Release|x64.Build.0 = Release|x64 + {868474FD-35F6-4400-8EED-30A33E7521D4}.Release|x86.ActiveCfg = Release|Win32 + {868474FD-35F6-4400-8EED-30A33E7521D4}.Release|x86.Build.0 = Release|Win32 + {51201D5E-D939-4854-AE9D-008F03FF518E}.Debug|x64.ActiveCfg = Debug|x64 + {51201D5E-D939-4854-AE9D-008F03FF518E}.Debug|x64.Build.0 = Debug|x64 + {51201D5E-D939-4854-AE9D-008F03FF518E}.Debug|x86.ActiveCfg = Debug|Win32 + {51201D5E-D939-4854-AE9D-008F03FF518E}.Debug|x86.Build.0 = Debug|Win32 + {51201D5E-D939-4854-AE9D-008F03FF518E}.Release|x64.ActiveCfg = Release|x64 + {51201D5E-D939-4854-AE9D-008F03FF518E}.Release|x64.Build.0 = Release|x64 + {51201D5E-D939-4854-AE9D-008F03FF518E}.Release|x86.ActiveCfg = Release|Win32 + {51201D5E-D939-4854-AE9D-008F03FF518E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8AA72EDA-2CD4-4564-B1E4-688B760EEEE9} + SolutionGuid = {8607C0F4-F33D-41B8-8D51-18E366A0F8DF} + SolutionGuid = {58AAB032-7274-49BD-845E-5EF4DBB69B70} + EndGlobalSection +EndGlobal diff --git a/build_msvc/bitsend_config.h b/build_msvc/bitsend_config.h new file mode 100644 index 00000000..662a3b44 --- /dev/null +++ b/build_msvc/bitsend_config.h @@ -0,0 +1,338 @@ +// Copyright (c) 2018-2020 The BitSend Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITSEND_BITSEND_CONFIG_H +#define BITSEND_BITSEND_CONFIG_H + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Version Build */ +#define CLIENT_VERSION_BUILD 0 + +/* Version is release */ +#define CLIENT_VERSION_IS_RELEASE true + +/* Major version */ +#define CLIENT_VERSION_MAJOR 0 + +/* Minor version */ +#define CLIENT_VERSION_MINOR 21 + +/* Build revision */ +#define CLIENT_VERSION_REVISION 1 + +/* Copyright holder(s) before %s replacement */ +#define COPYRIGHT_HOLDERS "The %s developers" + +/* Copyright holder(s) */ +#define COPYRIGHT_HOLDERS_FINAL "The BitSend Core developers" + +/* Replacement for %s in copyright holders string */ +#define COPYRIGHT_HOLDERS_SUBSTITUTION "BitSend Core" + +/* Copyright year */ +#define COPYRIGHT_YEAR 2019 + +/* Define to 1 to enable wallet functions */ +#define ENABLE_WALLET 1 + +/* Define to 1 to enable ZMQ functions */ +#define ENABLE_ZMQ 1 + +/* define if the Boost library is available */ +#define HAVE_BOOST /**/ + +/* define if the Boost::Filesystem library is available */ +#define HAVE_BOOST_FILESYSTEM /**/ + +/* define if the Boost::Process library is available */ +#define HAVE_BOOST_PROCESS /**/ + +/* define if the Boost::System library is available */ +#define HAVE_BOOST_SYSTEM /**/ + +/* define if the Boost::Thread library is available */ +#define HAVE_BOOST_THREAD /**/ + +/* define if the Boost::Unit_Test_Framework library is available */ +#define HAVE_BOOST_UNIT_TEST_FRAMEWORK /**/ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BYTESWAP_H */ + +/* Define this symbol if the consensus lib has been built */ +#define HAVE_CONSENSUS_LIB 1 + +/* define if the compiler supports basic C++11 syntax */ +#define HAVE_CXX11 1 + +/* Define to 1 if you have the declaration of `be16toh', and to 0 if you + don't. */ +#define HAVE_DECL_BE16TOH 0 + +/* Define to 1 if you have the declaration of `be32toh', and to 0 if you + don't. */ +#define HAVE_DECL_BE32TOH 0 + +/* Define to 1 if you have the declaration of `be64toh', and to 0 if you + don't. */ +#define HAVE_DECL_BE64TOH 0 + +/* Define to 1 if you have the declaration of `bswap_16', and to 0 if you + don't. */ +#define HAVE_DECL_BSWAP_16 0 + +/* Define to 1 if you have the declaration of `bswap_32', and to 0 if you + don't. */ +#define HAVE_DECL_BSWAP_32 0 + +/* Define to 1 if you have the declaration of `bswap_64', and to 0 if you + don't. */ +#define HAVE_DECL_BSWAP_64 0 + +/* Define to 1 if you have the declaration of `daemon', and to 0 if you don't. + */ +#define HAVE_DECL_DAEMON 0 + +/* Define to 1 if you have the declaration of `htobe16', and to 0 if you + don't. */ +#define HAVE_DECL_HTOBE16 0 + +/* Define to 1 if you have the declaration of `htobe32', and to 0 if you + don't. */ +#define HAVE_DECL_HTOBE32 0 + +/* Define to 1 if you have the declaration of `htobe64', and to 0 if you + don't. */ +#define HAVE_DECL_HTOBE64 0 + +/* Define to 1 if you have the declaration of `htole16', and to 0 if you + don't. */ +#define HAVE_DECL_HTOLE16 0 + +/* Define to 1 if you have the declaration of `htole32', and to 0 if you + don't. */ +#define HAVE_DECL_HTOLE32 0 + +/* Define to 1 if you have the declaration of `htole64', and to 0 if you + don't. */ +#define HAVE_DECL_HTOLE64 0 + +/* Define to 1 if you have the declaration of `le16toh', and to 0 if you + don't. */ +#define HAVE_DECL_LE16TOH 0 + +/* Define to 1 if you have the declaration of `le32toh', and to 0 if you + don't. */ +#define HAVE_DECL_LE32TOH 0 + +/* Define to 1 if you have the declaration of `le64toh', and to 0 if you + don't. */ +#define HAVE_DECL_LE64TOH 0 + +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#define HAVE_DECL_STRERROR_R 0 + +/* Define to 1 if you have the declaration of `strnlen', and to 0 if you + don't. */ +#define HAVE_DECL_STRNLEN 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ENDIAN_H */ + +/* Define to 1 if the system has the `dllexport' function attribute */ +#define HAVE_FUNC_ATTRIBUTE_DLLEXPORT 1 + +/* Define to 1 if the system has the `dllimport' function attribute */ +#define HAVE_FUNC_ATTRIBUTE_DLLIMPORT 1 + +/* Define to 1 if the system has the `visibility' function attribute */ +#define HAVE_FUNC_ATTRIBUTE_VISIBILITY 1 + +/* Define this symbol if the BSD getentropy system call is available */ +/* #undef HAVE_GETENTROPY */ + +/* Define this symbol if the BSD getentropy system call is available with + sys/random.h */ +/* #undef HAVE_GETENTROPY_RAND */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define this symbol if you have malloc_info */ +/* #undef HAVE_MALLOC_INFO */ + +/* Define this symbol if you have mallopt with M_ARENA_MAX */ +/* #undef HAVE_MALLOPT_ARENA_MAX */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MINIUPNPC_MINIUPNPC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MINIUPNPC_MINIWGET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MINIUPNPC_UPNPCOMMANDS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MINIUPNPC_UPNPERRORS_H 1 + +/* Define this symbol if you have MSG_DONTWAIT */ +/* #undef HAVE_MSG_DONTWAIT */ + +/* Define this symbol if you have MSG_NOSIGNAL */ +/* #undef HAVE_MSG_NOSIGNAL */ + +/* Define if you have POSIX threads libraries and header files. */ +//#define HAVE_PTHREAD 1 + +/* Have PTHREAD_PRIO_INHERIT. */ +//#define HAVE_PTHREAD_PRIO_INHERIT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strerror_r' function. */ +/* #undef HAVE_STRERROR_R */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define this symbol if the BSD sysctl(KERN_ARND) is available */ +/* #undef HAVE_SYSCTL_ARND */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_ENDIAN_H */ + +/* Define this symbol if the Linux getrandom system call is available */ +/* #undef HAVE_SYS_GETRANDOM */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PRCTL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SELECT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +//#define HAVE_UNISTD_H 1 + +/* Define if the visibility attribute is supported. */ +#define HAVE_VISIBILITY_ATTRIBUTE 1 + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://github.com/bitsend/bitsend/issues" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "BitSend Core" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "BitSend Core 0.21.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "bitsend" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "https://bitsendcore.org/" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.21.1" + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* Define this symbol if the qt platform is cocoa */ +/* #undef QT_QPA_PLATFORM_COCOA */ + +/* Define this symbol if the minimal qt platform exists */ +#define QT_QPA_PLATFORM_MINIMAL 1 + +/* Define this symbol if the qt platform is windows */ +#define QT_QPA_PLATFORM_WINDOWS 1 + +/* Define this symbol if the qt platform is xcb */ +/* #undef QT_QPA_PLATFORM_XCB */ + +/* Define this symbol if qt plugins are static */ +#define QT_STATICPLUGIN 1 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if strerror_r returns char *. */ +/* #undef STRERROR_R_CHAR_P */ + +/* Define this symbol to build in assembly routines */ +//#define USE_ASM 1 + +/* Define if dbus support should be compiled in */ +/* #undef USE_DBUS */ + +/* Define if QR support should be compiled in */ +//#define USE_QRCODE 1 + +/* UPnP support not compiled if undefined, otherwise value (0 or 1) determines + default state */ +//#define USE_UPNP 0 + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#define _FILE_OFFSET_BITS 64 + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Windows Universal Platform constraints */ +#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) +/* Either a desktop application without API restrictions, or and older system + before these macros were defined. */ + +/* ::wsystem is available */ +#define HAVE_SYSTEM 1 + +#endif // !WINAPI_FAMILY || WINAPI_FAMILY_DESKTOP_APP + +#endif //BITSEND_BITSEND_CONFIG_H diff --git a/build_msvc/bitsendd/bitsendd.vcxproj b/build_msvc/bitsendd/bitsendd.vcxproj new file mode 100644 index 00000000..f0a02226 --- /dev/null +++ b/build_msvc/bitsendd/bitsendd.vcxproj @@ -0,0 +1,75 @@ + + + + + {D4513DDF-6013-44DC-ADCC-12EAF6D1F038} + + + Application + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {460fee33-1fe1-483f-b3bf-931ff8e969a5} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {93b86837-b543-48a5-a89b-7c87abb77df2} + + + {792d487f-f14c-49fc-a9de-3fc150f31c3f} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + {bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6} + + + {18430fef-6b61-4c53-b396-718e02850f1b} + + + + + + + ..\..\test\config.ini.in + ..\..\test\config.ini + + + + + + + + + + + + + + + diff --git a/build_msvc/common.init.vcxproj b/build_msvc/common.init.vcxproj new file mode 100644 index 00000000..9c589bcc --- /dev/null +++ b/build_msvc/common.init.vcxproj @@ -0,0 +1,114 @@ + + + + + + 16.0 + true + + + + true + true + true + true + true + $(Configuration) + x86-windows-static + x64-windows-static + + + + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) + + $(WindowsTargetPlatformVersion_10).0 + $(WindowsTargetPlatformVersion_10) + + + + + Release + x64 + + + Debug + x64 + + + Release + Win32 + + + Debug + Win32 + + + + + false + false + v142 + Unicode + No + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + true + true + v142 + Unicode + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + + Disabled + false + true + true + true + MultiThreaded + None + + + false + false + /LTCG:OFF + + + + + + Disabled + false + _DEBUG;%(PreprocessorDefinitions) + true + MultiThreadedDebug + /bigobj %(AdditionalOptions) + + + + + + Level3 + NotUsing + /utf-8 /std:c++17 %(AdditionalOptions) + 4018;4221;4244;4267;4334;4715;4805;4834 + true + _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;ZMQ_STATIC;NOMINMAX;WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;_WIN32_WINNT=0x0601;_WIN32_IE=0x0501;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) + ..\..\src;..\..\src\univalue\include;..\..\src\secp256k1\include;..\..\src\leveldb\include;..\..\src\leveldb\helpers\memenv;%(AdditionalIncludeDirectories) + + + Console + Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + /ignore:4221 + + + + diff --git a/build_msvc/common.qt.init.vcxproj b/build_msvc/common.qt.init.vcxproj new file mode 100644 index 00000000..42150a23 --- /dev/null +++ b/build_msvc/common.qt.init.vcxproj @@ -0,0 +1,16 @@ + + + + + C:\Qt5.9.8_x64_static_vs2019 + $(QtBaseDir)\plugins + $(QtBaseDir)\lib + $(QtBaseDir)\include + $(QtIncludeDir);$(QtIncludeDir)\QtNetwork;$(QtIncludeDir)\QtCore;$(QtIncludeDir)\QtWidgets;$(QtIncludeDir)\QtGui; + .\QtGeneratedFiles\qt + $(QtBaseDir)\bin + $(QtPluginsLibraryDir)\platforms\qminimal.lib;$(QtPluginsLibraryDir)\platforms\qwindows.lib;$(QtLibraryDir)\qtfreetype.lib;$(QtLibraryDir)\qtharfbuzz.lib;$(QtLibraryDir)\qtlibpng.lib;$(QtLibraryDir)\qtpcre2.lib;$(QtLibraryDir)\Qt5AccessibilitySupport.lib;$(QtLibraryDir)\Qt5Core.lib;$(QtLibraryDir)\Qt5Concurrent.lib;$(QtLibraryDir)\Qt5EventDispatcherSupport.lib;$(QtLibraryDir)\Qt5FontDatabaseSupport.lib;$(QtLibraryDir)\Qt5Gui.lib;$(QtLibraryDir)\Qt5Network.lib;$(QtLibraryDir)\Qt5PlatformCompositorSupport.lib;$(QtLibraryDir)\Qt5ThemeSupport.lib;$(QtLibraryDir)\Qt5Widgets.lib;$(QtLibraryDir)\Qt5WinExtras.lib;$(QtLibraryDir)\qtmain.lib;userenv.lib;netapi32.lib;imm32.lib;Dwmapi.lib;version.lib;winmm.lib;UxTheme.lib + $(QtPluginsLibraryDir)\platforms\qwindowsd.lib;$(QtPluginsLibraryDir)\platforms\qminimald.lib;$(QtLibraryDir)\*d.lib;crypt32.lib;userenv.lib;netapi32.lib;imm32.lib;Dwmapi.lib;version.lib;winmm.lib;UxTheme.lib + + + diff --git a/build_msvc/common.vcxproj b/build_msvc/common.vcxproj new file mode 100644 index 00000000..270c75e8 --- /dev/null +++ b/build_msvc/common.vcxproj @@ -0,0 +1,12 @@ + + +$(BuildDependsOn);CopyBuildArtifacts + + + + + + + + + diff --git a/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj.in b/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj.in new file mode 100644 index 00000000..620df72a --- /dev/null +++ b/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj.in @@ -0,0 +1,16 @@ + + + + + {0667528C-D734-4009-ADF9-C0D6C4A5A5A6} + + + StaticLibrary + + +@SOURCE_FILES@ + + + + + diff --git a/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj.in b/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj.in new file mode 100644 index 00000000..b47d62b2 --- /dev/null +++ b/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj.in @@ -0,0 +1,16 @@ + + + + + {7C87E378-DF58-482E-AA2F-1BC129BC19CE} + + + StaticLibrary + + +@SOURCE_FILES@ + + + + + diff --git a/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj.in b/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj.in new file mode 100644 index 00000000..32cb75bf --- /dev/null +++ b/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj.in @@ -0,0 +1,16 @@ + + + + + {6190199C-6CF4-4DAD-BFBD-93FA72A760C1} + + + StaticLibrary + + +@SOURCE_FILES@ + + + + + diff --git a/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj b/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj new file mode 100644 index 00000000..171b346c --- /dev/null +++ b/build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj @@ -0,0 +1,233 @@ + + + + + + {2B4ABFF8-D1FD-4845-88C9-1F3C0A6512BF} + StaticLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _AMD64_;%(PreprocessorDefinitions) + $(QtIncludes);$(GeneratedFilesOutDir)\..;%(AdditionalIncludeDirectories) + + + + + + _AMD64_;%(PreprocessorDefinitions) + $(QtIncludes);$(GeneratedFilesOutDir)\..;%(AdditionalIncludeDirectories) + + + + + + _X86_;%(PreprocessorDefinitions) + $(QtIncludes);$(GeneratedFilesOutDir)\..;%(AdditionalIncludeDirectories) + + + + + + _X86_;%(PreprocessorDefinitions) + $(QtIncludes);$(GeneratedFilesOutDir)\..;%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + There was an error executing the libbitsend_qt moc code include generation task. + + + + + + + + + + There was an error executing the libbitsend_qt moc header generation task. + + + + + + + + + + There was an error executing the libbitsend_qt forms header generation task. + + + + + + + + + There was an error executing the libbitsend_qt translation file generation task. + + + + + + + + There was an error executing the libbitsend_qt resource code generation task. + + + + + + + + + + + + + + + moccode; + mocheader; + forms; + translation; + resource; + $(BuildDependsOn); + + + + + qtclean; + $(CleanDependsOn); + + + + diff --git a/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in b/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in new file mode 100644 index 00000000..58e90dba --- /dev/null +++ b/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in @@ -0,0 +1,19 @@ + + + + + {460FEE33-1FE1-483F-B3BF-931FF8E969A5} + + + StaticLibrary + + +@SOURCE_FILES@ + + $(IntDir)wallet_init.obj + + + + + + \ No newline at end of file diff --git a/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj.in b/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj.in new file mode 100644 index 00000000..6ec40461 --- /dev/null +++ b/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj.in @@ -0,0 +1,17 @@ + + + + + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754} + + + StaticLibrary + + + +@SOURCE_FILES@ + + + + + diff --git a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in new file mode 100644 index 00000000..9c8279c7 --- /dev/null +++ b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in @@ -0,0 +1,16 @@ + + + + + {93B86837-B543-48A5-A89B-7C87ABB77DF2} + + + StaticLibrary + + +@SOURCE_FILES@ + + + + + diff --git a/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in b/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in new file mode 100644 index 00000000..1a6b7b6b --- /dev/null +++ b/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in @@ -0,0 +1,16 @@ + + + + + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93} + + + StaticLibrary + + +@SOURCE_FILES@ + + + + + diff --git a/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj.in b/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj.in new file mode 100644 index 00000000..e86eea81 --- /dev/null +++ b/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj.in @@ -0,0 +1,16 @@ + + + + + {792D487F-F14C-49FC-A9DE-3FC150F31C3F} + + + StaticLibrary + + +@SOURCE_FILES@ + + + + + diff --git a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj new file mode 100644 index 00000000..c684ff83 --- /dev/null +++ b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj @@ -0,0 +1,37 @@ + + + + + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE} + + + StaticLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build_msvc/libleveldb/libleveldb.vcxproj b/build_msvc/libleveldb/libleveldb.vcxproj new file mode 100644 index 00000000..1610ae7d --- /dev/null +++ b/build_msvc/libleveldb/libleveldb.vcxproj @@ -0,0 +1,61 @@ + + + + + {18430FEF-6B61-4C53-B396-718E02850F1B} + + + StaticLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HAVE_CRC32C=0;HAVE_SNAPPY=0;__STDC_LIMIT_MACROS;LEVELDB_IS_BIG_ENDIAN=0;_UNICODE;UNICODE;_CRT_NONSTDC_NO_DEPRECATE;LEVELDB_PLATFORM_WINDOWS;LEVELDB_ATOMIC_PRESENT;%(PreprocessorDefinitions) + 4244;4267;4312;4722; + ..\..\src\leveldb;..\..\src\leveldb\include;%(AdditionalIncludeDirectories) + + + + + + diff --git a/build_msvc/libsecp256k1/libsecp256k1.vcxproj b/build_msvc/libsecp256k1/libsecp256k1.vcxproj new file mode 100644 index 00000000..c42918d6 --- /dev/null +++ b/build_msvc/libsecp256k1/libsecp256k1.vcxproj @@ -0,0 +1,22 @@ + + + + + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6} + + + StaticLibrary + + + + + + + ENABLE_MODULE_ECDH;ENABLE_MODULE_RECOVERY;ENABLE_MODULE_EXTRAKEYS;ENABLE_MODULE_SCHNORRSIG;%(PreprocessorDefinitions) + ..\..\src\secp256k1;%(AdditionalIncludeDirectories) + + + + + + \ No newline at end of file diff --git a/build_msvc/libsecp256k1_config.h b/build_msvc/libsecp256k1_config.h new file mode 100644 index 00000000..7250dc59 --- /dev/null +++ b/build_msvc/libsecp256k1_config.h @@ -0,0 +1,32 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef BITSEND_LIBSECP256K1_CONFIG_H +#define BITSEND_LIBSECP256K1_CONFIG_H + +#undef USE_ASM_X86_64 +#undef USE_ENDOMORPHISM +#undef USE_FIELD_10X26 +#undef USE_FIELD_5X52 +#undef USE_FIELD_INV_BUILTIN +#undef USE_FIELD_INV_NUM +#undef USE_NUM_GMP +#undef USE_NUM_NONE +#undef USE_SCALAR_4X64 +#undef USE_SCALAR_8X32 +#undef USE_SCALAR_INV_BUILTIN +#undef USE_SCALAR_INV_NUM + +#define USE_NUM_NONE 1 +#define USE_FIELD_INV_BUILTIN 1 +#define USE_SCALAR_INV_BUILTIN 1 +#define USE_FIELD_10X26 1 +#define USE_SCALAR_8X32 1 + +#define ECMULT_GEN_PREC_BITS 4 +#define ECMULT_WINDOW_SIZE 15 + +#endif /* BITSEND_LIBSECP256K1_CONFIG_H */ diff --git a/build_msvc/libtest_util/libtest_util.vcxproj.in b/build_msvc/libtest_util/libtest_util.vcxproj.in new file mode 100644 index 00000000..b5e84401 --- /dev/null +++ b/build_msvc/libtest_util/libtest_util.vcxproj.in @@ -0,0 +1,16 @@ + + + + + {868474FD-35F6-4400-8EED-30A33E7521D4} + + + StaticLibrary + + +@SOURCE_FILES@ + + + + + diff --git a/build_msvc/libunivalue/libunivalue.vcxproj b/build_msvc/libunivalue/libunivalue.vcxproj new file mode 100644 index 00000000..0f13a572 --- /dev/null +++ b/build_msvc/libunivalue/libunivalue.vcxproj @@ -0,0 +1,19 @@ + + + + + {5724BA7D-A09A-4BA8-800B-C4C1561B3D69} + + + StaticLibrary + + + + + + + + + + + diff --git a/build_msvc/msbuild/tasks/hexdump.targets b/build_msvc/msbuild/tasks/hexdump.targets new file mode 100644 index 00000000..12868a98 --- /dev/null +++ b/build_msvc/msbuild/tasks/hexdump.targets @@ -0,0 +1,53 @@ + + + + + + + + + + + + + outFileInfo.LastWriteTime) + { + using (Stream inStm = File.OpenRead(RawFilePath)) + { + using (StreamWriter sw = new StreamWriter(HeaderFilePath)) + { + sw.WriteLine(SourceHeader); + int count = 0; + int rawChar = inStm.ReadByte(); + while(rawChar != -1) + { + sw.Write("0x{0:x2}, ", rawChar); + count++; + if(count % 8 == 0) + { + sw.WriteLine(); + } + rawChar = inStm.ReadByte(); + } + sw.WriteLine(SourceFooter); + } + } + } +} +]]> + + + + \ No newline at end of file diff --git a/build_msvc/msbuild/tasks/replaceinfile.targets b/build_msvc/msbuild/tasks/replaceinfile.targets new file mode 100644 index 00000000..2ccb8b30 --- /dev/null +++ b/build_msvc/msbuild/tasks/replaceinfile.targets @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build_msvc/msvc-autogen.py b/build_msvc/msvc-autogen.py new file mode 100644 index 00000000..8c075117 --- /dev/null +++ b/build_msvc/msvc-autogen.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016-2019 The BitSend Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import os +import re +import argparse +from shutil import copyfile + +SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src')) +DEFAULT_PLATFORM_TOOLSET = R'v141' + +libs = [ + 'libbitsend_cli', + 'libbitsend_common', + 'libbitsend_crypto', + 'libbitsend_server', + 'libbitsend_util', + 'libbitsend_wallet_tool', + 'libbitsend_wallet', + 'libbitsend_zmq', + 'bench_bitsend', + 'libtest_util', +] + +ignore_list = [ +] + +lib_sources = {} + + +def parse_makefile(makefile): + with open(makefile, 'r', encoding='utf-8') as file: + current_lib = '' + for line in file.read().splitlines(): + if current_lib: + source = line.split()[0] + if source.endswith('.cpp') and not source.startswith('$') and source not in ignore_list: + source_filename = source.replace('/', '\\') + object_filename = source.replace('/', '_')[:-4] + ".obj" + lib_sources[current_lib].append((source_filename, object_filename)) + if not line.endswith('\\'): + current_lib = '' + continue + for lib in libs: + _lib = lib.replace('-', '_') + if re.search(_lib + '.*_SOURCES \\= \\\\', line): + current_lib = lib + lib_sources[current_lib] = [] + break + +def set_common_properties(toolset): + with open(os.path.join(SOURCE_DIR, '../build_msvc/common.init.vcxproj'), 'r', encoding='utf-8') as rfile: + s = rfile.read() + s = re.sub('.*?', ''+toolset+'', s) + with open(os.path.join(SOURCE_DIR, '../build_msvc/common.init.vcxproj'), 'w', encoding='utf-8',newline='\n') as wfile: + wfile.write(s) + +def main(): + parser = argparse.ArgumentParser(description='BitSend-core msbuild configuration initialiser.') + parser.add_argument('-toolset', nargs='?',help='Optionally sets the msbuild platform toolset, e.g. v142 for Visual Studio 2019.' + ' default is %s.'%DEFAULT_PLATFORM_TOOLSET) + args = parser.parse_args() + if args.toolset: + set_common_properties(args.toolset) + + for makefile_name in os.listdir(SOURCE_DIR): + if 'Makefile' in makefile_name: + parse_makefile(os.path.join(SOURCE_DIR, makefile_name)) + for key, value in lib_sources.items(): + vcxproj_filename = os.path.abspath(os.path.join(os.path.dirname(__file__), key, key + '.vcxproj')) + content = '' + for source_filename, object_filename in value: + content += ' \n' + content += ' $(IntDir)' + object_filename + '\n' + content += ' \n' + with open(vcxproj_filename + '.in', 'r', encoding='utf-8') as vcxproj_in_file: + with open(vcxproj_filename, 'w', encoding='utf-8') as vcxproj_file: + vcxproj_file.write(vcxproj_in_file.read().replace( + '@SOURCE_FILES@\n', content)) + copyfile(os.path.join(SOURCE_DIR,'../build_msvc/bitsend_config.h'), os.path.join(SOURCE_DIR, 'config/bitsend-config.h')) + copyfile(os.path.join(SOURCE_DIR,'../build_msvc/libsecp256k1_config.h'), os.path.join(SOURCE_DIR, 'secp256k1/src/libsecp256k1-config.h')) + +if __name__ == '__main__': + main() diff --git a/build_msvc/test_bitsend-qt/test_bitsend-qt.vcxproj b/build_msvc/test_bitsend-qt/test_bitsend-qt.vcxproj new file mode 100644 index 00000000..6dff4ee4 --- /dev/null +++ b/build_msvc/test_bitsend-qt/test_bitsend-qt.vcxproj @@ -0,0 +1,122 @@ + + + + + + {51201D5E-D939-4854-AE9D-008F03FF518E} + Application + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + + + + + + + + + + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {0667528c-d734-4009-adf9-c0d6c4a5a5a6} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {2b4abff8-d1fd-4845-88c9-1f3c0a6512bf} + + + {460fee33-1fe1-483f-b3bf-931ff8e969a5} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {93b86837-b543-48a5-a89b-7c87abb77df2} + + + {792d487f-f14c-49fc-a9de-3fc150f31c3f} + + + {18430fef-6b61-4c53-b396-718e02850f1b} + + + {bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + + + + + + + ..\libbitsend_qt\$(GeneratedFilesOutDir)\..\;$(QtIncludeDir)\QtTest;$(QtIncludes);%(AdditionalIncludeDirectories) + + + $(QtLibraryDir)\Qt5Test.lib;$(QtReleaseLibraries);%(AdditionalDependencies) + /ignore:4206 /LTCG:OFF + + + + + + ..\libbitsend_qt\$(GeneratedFilesOutDir)\..\;$(QtIncludeDir)\QtTest;$(QtIncludes);%(AdditionalIncludeDirectories) + + + $(QtDebugLibraries);%(AdditionalDependencies) + /ignore:4206 + + + + + + + + + + + + + There was an error executing the test_bitsend-qt moc code generation task. + + + + + + + + + + + + + moccode; + $(BuildDependsOn); + + + + + QtTestCleanGeneratedFiles; + $(CleanDependsOn); + + + diff --git a/build_msvc/test_bitsend/test_bitsend.vcxproj b/build_msvc/test_bitsend/test_bitsend.vcxproj new file mode 100644 index 00000000..b02f0559 --- /dev/null +++ b/build_msvc/test_bitsend/test_bitsend.vcxproj @@ -0,0 +1,73 @@ + + + + + {A56B73DB-D46D-4882-8374-1FE3FFA08F07} + + + Application + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + + + + + + + {2b384fa8-9ee1-4544-93cb-0d733c25e8ce} + + + {0667528c-d734-4009-adf9-c0d6c4a5a5a6} + + + {7c87e378-df58-482e-aa2f-1bc129bc19ce} + + + {6190199c-6cf4-4dad-bfbd-93fa72a760c1} + + + {460fee33-1fe1-483f-b3bf-931ff8e969a5} + + + {b53a5535-ee9d-4c6f-9a26-f79ee3bc3754} + + + {93b86837-b543-48a5-a89b-7c87abb77df2} + + + {792d487f-f14c-49fc-a9de-3fc150f31c3f} + + + {1e065f03-3566-47d0-8fa9-daa72b084e7d} + + + {5724ba7d-a09a-4ba8-800b-c4c1561b3d69} + + + {bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6} + + + {18430fef-6b61-4c53-b396-718e02850f1b} + + + + + There was an error executing the JSON test header generation task. + + + + + + + + + + + + + diff --git a/build_msvc/testconsensus/testconsensus.cpp b/build_msvc/testconsensus/testconsensus.cpp new file mode 100644 index 00000000..8ddbd4f0 --- /dev/null +++ b/build_msvc/testconsensus/testconsensus.cpp @@ -0,0 +1,54 @@ +// Copyright (c) 2018-2019 The BitSend Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +// bitsend includes. +#include <..\src\script\bitsendconsensus.h> +#include <..\src\primitives\transaction.h> +#include <..\src\script\script.h> +#include <..\src\streams.h> +#include <..\src\version.h> + +CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, int nValue = 0) +{ + CMutableTransaction txSpend; + txSpend.nVersion = 1; + txSpend.nLockTime = 0; + txSpend.vin.resize(1); + txSpend.vout.resize(1); + txSpend.vin[0].scriptWitness = scriptWitness; + txSpend.vin[0].prevout.hash = uint256(); + txSpend.vin[0].prevout.n = 0; + txSpend.vin[0].scriptSig = scriptSig; + txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; + txSpend.vout[0].scriptPubKey = CScript(); + txSpend.vout[0].nValue = nValue; + + return txSpend; +} + +int main() +{ + std::cout << "bitsendconsensus version: " << bitsendconsensus_version() << std::endl; + + CScript pubKeyScript; + pubKeyScript << OP_1 << OP_0 << OP_1; + + int amount = 0; // 600000000; + + CScript scriptSig; + CScriptWitness scriptWitness; + CTransaction vanillaSpendTx = BuildSpendingTransaction(scriptSig, scriptWitness, amount); + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << vanillaSpendTx; + + bitsendconsensus_error err; + auto op0Result = bitsendconsensus_verify_script_with_amount(pubKeyScript.data(), pubKeyScript.size(), amount, (const unsigned char*)&stream[0], stream.size(), 0, bitsendconsensus_SCRIPT_FLAGS_VERIFY_ALL, &err); + std::cout << "Op0 result: " << op0Result << ", error code " << err << std::endl; + + getchar(); + + return 0; +} diff --git a/build_msvc/testconsensus/testconsensus.vcxproj b/build_msvc/testconsensus/testconsensus.vcxproj new file mode 100644 index 00000000..cde0f99d --- /dev/null +++ b/build_msvc/testconsensus/testconsensus.vcxproj @@ -0,0 +1,28 @@ + + + + + {E78473E9-B850-456C-9120-276301E04C06} + + + Application + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + {2B384FA8-9EE1-4544-93CB-0D733C25E8CE} + + + {B53A5535-EE9D-4C6F-9A26-F79EE3BC3754} + + + {BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6} + + + + + + diff --git a/build_msvc/vcpkg.json b/build_msvc/vcpkg.json new file mode 100644 index 00000000..efa39684 --- /dev/null +++ b/build_msvc/vcpkg.json @@ -0,0 +1,20 @@ +{ + "name": "bitsend-core", + "version-string": "1", + "dependencies": [ + "berkeleydb", + "boost-filesystem", + "boost-multi-index", + "boost-process", + "boost-signals2", + "boost-test", + "boost-thread", + "sqlite3", + "double-conversion", + { + "name": "libevent", + "features": ["thread"] + }, + "zeromq" + ] +} diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 00000000..3c5f04c3 --- /dev/null +++ b/ci/README.md @@ -0,0 +1,65 @@ +## CI Scripts + +This directory contains scripts for each build step in each build stage. + +### Running a Stage Locally + +Be aware that the tests will be built and run in-place, so please run at your own risk. +If the repository is not a fresh git clone, you might have to clean files from previous builds or test runs first. + +The ci needs to perform various sysadmin tasks such as installing packages or writing to the user's home directory. +While most of the actions are done inside a docker container, this is not possible for all. Thus, cache directories, +such as the depends cache, previous release binaries, or ccache, are mounted as read-write into the docker container. While it should be fine to run +the ci system locally on you development box, the ci scripts can generally be assumed to have received less review and +testing compared to other parts of the codebase. If you want to keep the work tree clean, you might want to run the ci +system in a virtual machine with a Linux operating system of your choice. + +To allow for a wide range of tested environments, but also ensure reproducibility to some extent, the test stage +requires `docker` to be installed. To install all requirements on Ubuntu, run + +``` +sudo apt install docker.io bash +``` + +To run the default test stage, + +``` +./ci/test_run_all.sh +``` + +To run the test stage with a specific configuration, + +``` +FILE_ENV="./ci/test/00_setup_env_arm.sh" ./ci/test_run_all.sh +``` + +### Configurations + +The test files (`FILE_ENV`) are constructed to test a wide range of +configurations, rather than a single pass/fail. This helps to catch build +failures and logic errors that present on platforms other than the ones the +author has tested. + +Some builders use the dependency-generator in `./depends`, rather than using +the system package manager to install build dependencies. This guarantees that +the tester is using the same versions as the release builds, which also use +`./depends`. + +If no `FILE_ENV` has been specified or values are left out, `00_setup_env.sh` +is used as the default configuration with fallback values. + +It is also possible to force a specific configuration without modifying the +file. For example, + +``` +MAKEJOBS="-j1" FILE_ENV="./ci/test/00_setup_env_arm.sh" ./ci/test_run_all.sh +``` + +The files starting with `0n` (`n` greater than 0) are the scripts that are run +in order. + +### Cache + +In order to avoid rebuilding all dependencies for each build, the binaries are +cached and re-used when possible. Changes in the dependency-generator will +trigger cache-invalidation and rebuilds as necessary. diff --git a/ci/lint/04_install.sh b/ci/lint/04_install.sh new file mode 100755 index 00000000..c34b527d --- /dev/null +++ b/ci/lint/04_install.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2019 The BitSend 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 + +travis_retry sudo apt update && sudo apt install -y clang-format-9 +sudo update-alternatives --install /usr/bin/clang-format clang-format $(which clang-format-9 ) 100 +sudo update-alternatives --install /usr/bin/clang-format-diff clang-format-diff $(which clang-format-diff-9) 100 + +travis_retry pip3 install codespell==1.17.1 +travis_retry pip3 install flake8==3.8.3 +travis_retry pip3 install yq +travis_retry pip3 install mypy==0.781 + +SHELLCHECK_VERSION=v0.7.1 +curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar --xz -xf - --directory /tmp/ +export PATH="/tmp/shellcheck-${SHELLCHECK_VERSION}:${PATH}" diff --git a/ci/lint/05_before_script.sh b/ci/lint/05_before_script.sh new file mode 100755 index 00000000..cf6787fa --- /dev/null +++ b/ci/lint/05_before_script.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2019 The BitSend 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 + +git fetch --unshallow diff --git a/ci/lint/06_script.sh b/ci/lint/06_script.sh new file mode 100755 index 00000000..e57e7857 --- /dev/null +++ b/ci/lint/06_script.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2019 The BitSend 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 [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then + # TRAVIS_BRANCH will be present in a Travis environment. For builds triggered + # by a pull request this is the name of the branch targeted by the pull request. + # https://docs.travis-ci.com/user/environment-variables/ + COMMIT_RANGE="$TRAVIS_BRANCH..HEAD" + test/lint/commit-script-check.sh $COMMIT_RANGE +fi + +test/lint/git-subtree-check.sh src/crypto/ctaes +test/lint/git-subtree-check.sh src/secp256k1 +test/lint/git-subtree-check.sh src/univalue +test/lint/git-subtree-check.sh src/leveldb +test/lint/git-subtree-check.sh src/crc32c +test/lint/check-doc.py +test/lint/check-rpc-mappings.py . +test/lint/lint-all.sh + +if [ "$TRAVIS_REPO_SLUG" = "bitsend/bitsend" ] && [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then + git log --merges --before="2 days ago" -1 --format='%H' > ./contrib/verify-commits/trusted-sha512-root-commit + travis_retry gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys $( $max_sleep ? $max_sleep : t)}"` + fi +} + +__log_out() { + echo "$1" 1>&2 +} + +# Parameters: max_tries min_sleep max_sleep constant_sleep fail_script EXECUTION_COMMAND +retry() +{ + local max_tries="$1"; shift + local min_sleep="$1"; shift + local max_sleep="$1"; shift + local constant_sleep="$1"; shift + local fail_script="$1"; shift + if [ -n "$VERBOSE" ]; then + __log_out "Retry Parameters: max_tries=$max_tries min_sleep=$min_sleep max_sleep=$max_sleep constant_sleep=$constant_sleep" + if [ -n "$fail_script" ]; then __log_out "Fail script: $fail_script"; fi + __log_out "" + __log_out "Execution Command: $*" + __log_out "" + fi + + local attempts=0 + local return_code=1 + + + while [[ $return_code -ne 0 && $attempts -le $max_tries ]]; do + if [ $attempts -gt 0 ]; then + __sleep_amount + __log_out "Before retry #$attempts: sleeping $sleep_time seconds" + sleep $sleep_time + fi + + P="$1" + for param in "${@:2}"; do P="$P '$param'"; done + #TODO: replace single quotes in each arg with '"'"' ? + export RETRY_ATTEMPT=$attempts + bash -c "$P" + return_code=$? + #__log_out "Process returned $return_code on attempt $attempts" + if [ $return_code -eq 127 ]; then + # command not found + exit $return_code + elif [ $return_code -ne 0 ]; then + attempts=$[$attempts +1] + fi + done + + if [ $attempts -gt $max_tries ]; then + if [ -n "$fail_script" ]; then + __log_out "Retries exhausted, running fail script" + eval $fail_script + else + __log_out "Retries exhausted" + fi + fi + + exit $return_code +} + +# If we're being sourced, don't worry about such things +if [ "$BASH_SOURCE" == "$0" ]; then + # Prints the help text + help() + { + local retry=$(basename $0) + cat < /dev/null + if [[ $? -ne 4 ]]; then + echo "I’m sorry, 'getopt --test' failed in this environment. Please load GNU getopt." + exit 1 + fi + + OPTIONS=vt:s:m:x:f: + LONGOPTIONS=verbose,tries:,sleep:,min:,max:,fail: + + PARSED=$($GETOPT_BIN --options="$OPTIONS" --longoptions="$LONGOPTIONS" --name "$0" -- "$@") + if [[ $? -ne 0 ]]; then + # e.g. $? == 1 + # then getopt has complained about wrong arguments to stdout + exit 2 + fi + # read getopt’s output this way to handle the quoting right: + eval set -- "$PARSED" + + max_tries=10 + min_sleep=0.3 + max_sleep=60.0 + constant_sleep= + fail_script= + + # now enjoy the options in order and nicely split until we see -- + while true; do + case "$1" in + -v|--verbose) + VERBOSE=true + shift + ;; + -t|--tries) + max_tries="$2" + shift 2 + ;; + -s|--sleep) + constant_sleep="$2" + shift 2 + ;; + -m|--min) + min_sleep="$2" + shift 2 + ;; + -x|--max) + max_sleep="$2" + shift 2 + ;; + -f|--fail) + fail_script="$2" + shift 2 + ;; + --) + shift + break + ;; + *) + echo "Programming error" + exit 3 + ;; + esac + done + + retry "$max_tries" "$min_sleep" "$max_sleep" "$constant_sleep" "$fail_script" "$@" + +fi diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh new file mode 100755 index 00000000..0a267228 --- /dev/null +++ b/ci/test/00_setup_env.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +# The root dir. +# The ci system copies this folder. +# This is where the depends build is done. +BASE_ROOT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../../ >/dev/null 2>&1 && pwd ) +export BASE_ROOT_DIR + +echo "Setting specific values in env" +if [ -n "${FILE_ENV}" ]; then + set -o errexit; + # shellcheck disable=SC1090 + source "${FILE_ENV}" +fi + +echo "Fallback to default values in env (if not yet set)" +# The number of parallel jobs to pass down to make and test_runner.py +export MAKEJOBS=${MAKEJOBS:--j4} +# A folder for the ci system to put temporary files (ccache, datadirs for tests, ...) +# This folder only exists on the ci host. +export BASE_SCRATCH_DIR=${BASE_SCRATCH_DIR:-$BASE_ROOT_DIR/ci/scratch} +# What host to compile for. See also ./depends/README.md +# Tests that need cross-compilation export the appropriate HOST. +# Tests that run natively guess the host +export HOST=${HOST:-$("$BASE_ROOT_DIR/depends/config.guess")} +# Whether to prefer BusyBox over GNU utilities +export USE_BUSY_BOX=${USE_BUSY_BOX:-false} + +export RUN_UNIT_TESTS=${RUN_UNIT_TESTS:-true} +export RUN_FUNCTIONAL_TESTS=${RUN_FUNCTIONAL_TESTS:-true} +export RUN_SECURITY_TESTS=${RUN_SECURITY_TESTS:-false} +# By how much to scale the test_runner timeouts (option --timeout-factor). +# This is needed because some ci machines have slow CPU or disk, so sanitizers +# might be slow or a reindex might be waiting on disk IO. +export TEST_RUNNER_TIMEOUT_FACTOR=${TEST_RUNNER_TIMEOUT_FACTOR:-40} +export TEST_RUNNER_ENV=${TEST_RUNNER_ENV:-} +export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false} +export EXPECTED_TESTS_DURATION_IN_SECONDS=${EXPECTED_TESTS_DURATION_IN_SECONDS:-1000} + +export CONTAINER_NAME=${CONTAINER_NAME:-ci_unnamed} +export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:18.04} +# Randomize test order. +# See https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/random.html +export BOOST_TEST_RANDOM=${BOOST_TEST_RANDOM:-1} +# See man 7 debconf +export DEBIAN_FRONTEND=noninteractive +export CCACHE_SIZE=${CCACHE_SIZE:-100M} +export CCACHE_TEMPDIR=${CCACHE_TEMPDIR:-/tmp/.ccache-temp} +export CCACHE_COMPRESS=${CCACHE_COMPRESS:-1} +# The cache dir. +# This folder exists on the ci host and ci guest. Changes are propagated back and forth. +export CCACHE_DIR=${CCACHE_DIR:-$BASE_SCRATCH_DIR/.ccache} +# The depends dir. +# This folder exists on the ci host and ci guest. Changes are propagated back and forth. +export DEPENDS_DIR=${DEPENDS_DIR:-$BASE_ROOT_DIR/depends} +# Folder where the build result is put (bin and lib). +export BASE_OUTDIR=${BASE_OUTDIR:-$BASE_SCRATCH_DIR/out/$HOST} +# Folder where the build is done (dist and out-of-tree build). +export BASE_BUILD_DIR=${BASE_BUILD_DIR:-$BASE_SCRATCH_DIR/build} +export PREVIOUS_RELEASES_DIR=${PREVIOUS_RELEASES_DIR:-$BASE_ROOT_DIR/releases/$HOST} +export SDK_URL=${SDK_URL:-https://bitsendcore.org/depends-sources/sdks} +export DOCKER_PACKAGES=${DOCKER_PACKAGES:-build-essential libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates ccache python3 rsync git procps} +export GOAL=${GOAL:-install} +export DIR_QA_ASSETS=${DIR_QA_ASSETS:-${BASE_SCRATCH_DIR}/qa-assets} +export PATH=${BASE_ROOT_DIR}/ci/retry:$PATH +export CI_RETRY_EXE=${CI_RETRY_EXE:-"retry --"} diff --git a/ci/test/00_setup_env_arm.sh b/ci/test/00_setup_env_arm.sh new file mode 100644 index 00000000..f9e6d50d --- /dev/null +++ b/ci/test/00_setup_env_arm.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export HOST=arm-linux-gnueabihf +# The host arch is unknown, so we run the tests through qemu. +# If the host is arm and wants to run the tests natively, it can set QEMU_USER_CMD to the empty string. +if [ -z ${QEMU_USER_CMD+x} ]; then export QEMU_USER_CMD="${QEMU_USER_CMD:-"qemu-arm -L /usr/arm-linux-gnueabihf/"}"; fi +export DPKG_ADD_ARCH="armhf" +export PACKAGES="python3-zmq g++-arm-linux-gnueabihf busybox libc6:armhf libstdc++6:armhf libfontconfig1:armhf libxcb1:armhf" +if [ -n "$QEMU_USER_CMD" ]; then + # Likely cross-compiling, so install the needed gcc and qemu-user + export PACKAGES="$PACKAGES qemu-user" +fi +export CONTAINER_NAME=ci_arm_linux +# Use debian to avoid 404 apt errors when cross compiling +export DOCKER_NAME_TAG="debian:buster" +export USE_BUSY_BOX=true +export RUN_UNIT_TESTS=true +export RUN_FUNCTIONAL_TESTS=false +export GOAL="install" +# -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1" +# This could be removed once the ABI change warning does not show up by default +export BITSEND_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CXXFLAGS=-Wno-psabi --enable-werror --with-boost-process" diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh new file mode 100644 index 00000000..7a0125da --- /dev/null +++ b/ci/test/00_setup_env_i686_centos.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2020 The BitSend 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.UTF-8 + +export HOST=i686-pc-linux-gnu +export CONTAINER_NAME=ci_i686_centos_7 +export DOCKER_NAME_TAG=centos:7 +export DOCKER_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache libtool make git python3 python36-zmq which patch lbzip2 dash" +export GOAL="install" +export BITSEND_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports --with-boost-process" +export CONFIG_SHELL="/bin/dash" diff --git a/ci/test/00_setup_env_mac.sh b/ci/test/00_setup_env_mac.sh new file mode 100644 index 00000000..36572d2f --- /dev/null +++ b/ci/test/00_setup_env_mac.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export CONTAINER_NAME=ci_macos_cross +export DOCKER_NAME_TAG=ubuntu:18.04 # Check that bionic can cross-compile to macos (bionic is used in the gitian build as well) +export HOST=x86_64-apple-darwin16 +export PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev python3-setuptools" +export XCODE_VERSION=11.3.1 +export XCODE_BUILD_ID=11C505 +export RUN_UNIT_TESTS=false +export RUN_FUNCTIONAL_TESTS=false +export GOAL="deploy" +export BITSEND_CONFIG="--with-gui --enable-reduce-exports --enable-werror --with-boost-process" diff --git a/ci/test/00_setup_env_mac_host.sh b/ci/test/00_setup_env_mac_host.sh new file mode 100644 index 00000000..6a813961 --- /dev/null +++ b/ci/test/00_setup_env_mac_host.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export HOST=x86_64-apple-darwin16 +export PIP_PACKAGES="zmq" +export GOAL="install" +export BITSEND_CONFIG="--with-gui --enable-reduce-exports --enable-werror --with-boost-process" +export CI_OS_NAME="macos" +export NO_DEPENDS=1 +export OSX_SDK="" +export CCACHE_SIZE=300M + +export RUN_SECURITY_TESTS="true" diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh new file mode 100644 index 00000000..739f1832 --- /dev/null +++ b/ci/test/00_setup_env_native_asan.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export CONTAINER_NAME=ci_native_asan +export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev libsqlite3-dev" +export DOCKER_NAME_TAG=ubuntu:20.04 +export NO_DEPENDS=1 +export GOAL="install" +export BITSEND_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' --with-sanitizers=address,integer,undefined CC=clang CXX=clang++ --with-boost-process" diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh new file mode 100644 index 00000000..76e9eeec --- /dev/null +++ b/ci/test/00_setup_env_native_fuzz.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export DOCKER_NAME_TAG="ubuntu:20.04" +export CONTAINER_NAME=ci_native_fuzz +export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev" +export NO_DEPENDS=1 +export RUN_UNIT_TESTS=false +export RUN_FUNCTIONAL_TESTS=false +export RUN_FUZZ_TESTS=true +export GOAL="install" +export BITSEND_CONFIG="--enable-fuzz --with-sanitizers=fuzzer,address,undefined CC=clang CXX=clang++ --with-boost-process" +export CCACHE_SIZE=200M diff --git a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh new file mode 100644 index 00000000..f74702f8 --- /dev/null +++ b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export DOCKER_NAME_TAG="ubuntu:20.04" +export CONTAINER_NAME=ci_native_fuzz_valgrind +export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev valgrind" +export NO_DEPENDS=1 +export RUN_UNIT_TESTS=false +export RUN_FUNCTIONAL_TESTS=false +export RUN_FUZZ_TESTS=true +export FUZZ_TESTS_CONFIG="--valgrind" +export GOAL="install" +export BITSEND_CONFIG="--enable-fuzz --with-sanitizers=fuzzer CC=clang CXX=clang++" +export CCACHE_SIZE=200M diff --git a/ci/test/00_setup_env_native_msan.sh b/ci/test/00_setup_env_native_msan.sh new file mode 100644 index 00000000..97488cd2 --- /dev/null +++ b/ci/test/00_setup_env_native_msan.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2020 The BitSend 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.UTF-8 + +export DOCKER_NAME_TAG="ubuntu:20.04" +LIBCXX_DIR="${BASE_ROOT_DIR}/ci/scratch/msan/build/" +export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls" +LIBCXX_FLAGS="-nostdinc++ -stdlib=libc++ -L${LIBCXX_DIR}lib -lc++abi -I${LIBCXX_DIR}include -I${LIBCXX_DIR}include/c++/v1 -lpthread -Wl,-rpath,${LIBCXX_DIR}lib -Wno-unused-command-line-argument" +export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" +export BDB_PREFIX="${BASE_ROOT_DIR}/db4" + +export CONTAINER_NAME="ci_native_msan" +export PACKAGES="clang-9 llvm-9 cmake" +export DEP_OPTS="NO_BDB=1 NO_QT=1 CC='clang' CXX='clang++' CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}' boost_cxxflags='-std=c++11 -fvisibility=hidden -fPIC ${MSAN_AND_LIBCXX_FLAGS}' zeromq_cxxflags='-std=c++11 ${MSAN_AND_LIBCXX_FLAGS}'" +export GOAL="install" +export BITSEND_CONFIG="--enable-wallet --with-sanitizers=memory --with-asm=no --prefix=${BASE_ROOT_DIR}/depends/x86_64-pc-linux-gnu/ CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}' BDB_LIBS='-L${BDB_PREFIX}/lib -ldb_cxx-4.8' BDB_CFLAGS='-I${BDB_PREFIX}/include'" +export USE_MEMORY_SANITIZER="true" +export RUN_FUNCTIONAL_TESTS="false" +export CCACHE_SIZE=250M diff --git a/ci/test/00_setup_env_native_multiprocess.sh b/ci/test/00_setup_env_native_multiprocess.sh new file mode 100644 index 00000000..85cae543 --- /dev/null +++ b/ci/test/00_setup_env_native_multiprocess.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2020 The BitSend 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.UTF-8 + +export CONTAINER_NAME=ci_native_multiprocess +export DOCKER_NAME_TAG=ubuntu:20.04 +export PACKAGES="cmake python3" +export DEP_OPTS="MULTIPROCESS=1" +export GOAL="install" +export BITSEND_CONFIG="--with-boost-process" +export TEST_RUNNER_ENV="BITSENDD=bitsend-node" diff --git a/ci/test/00_setup_env_native_nowallet.sh b/ci/test/00_setup_env_native_nowallet.sh new file mode 100644 index 00000000..c90e9aa6 --- /dev/null +++ b/ci/test/00_setup_env_native_nowallet.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export CONTAINER_NAME=ci_native_nowallet +export DOCKER_NAME_TAG=ubuntu:16.04 # Use xenial to have one config run the tests in python3.5, see doc/dependencies.md +export PACKAGES="python3-zmq clang-3.8 llvm-3.8" # Use clang-3.8 to test C++11 compatibility, see doc/dependencies.md +export DEP_OPTS="NO_WALLET=1" +export GOAL="install" +export BITSEND_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CC=clang-3.8 CXX=clang++-3.8 --with-boost-process" diff --git a/ci/test/00_setup_env_native_qt5.sh b/ci/test/00_setup_env_native_qt5.sh new file mode 100644 index 00000000..7795ff49 --- /dev/null +++ b/ci/test/00_setup_env_native_qt5.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export CONTAINER_NAME=ci_native_qt5 +export DOCKER_NAME_TAG=ubuntu:18.04 # Check that bionic can compile our c++17 and run our functional tests in python3 +export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev" +export DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1" +export TEST_RUNNER_EXTRA="--previous-releases --coverage --extended --exclude feature_dbcrash" # Run extended tests so that coverage does not fail, but exclude the very slow dbcrash +export RUN_SECURITY_TESTS="true" +export RUN_UNIT_TESTS_SEQUENTIAL="true" +export RUN_UNIT_TESTS="false" +export GOAL="install" +export PREVIOUS_RELEASES_TO_DOWNLOAD="v0.15.2 v0.16.3 v0.17.2 v0.18.1 v0.19.1" +export BITSEND_CONFIG="--enable-zmq --with-libs=no --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-c++17 --enable-debug CFLAGS=\"-g0 -O2 -funsigned-char\" CXXFLAGS=\"-g0 -O2 -funsigned-char\" --with-boost-process" diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh new file mode 100644 index 00000000..9defa1d7 --- /dev/null +++ b/ci/test/00_setup_env_native_tsan.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export CONTAINER_NAME=ci_native_tsan +export DOCKER_NAME_TAG=ubuntu:20.04 +export PACKAGES="clang llvm libc++abi-dev libc++-dev python3-zmq" +export DEP_OPTS="CC=clang CXX='clang++ -stdlib=libc++'" +export TEST_RUNNER_EXTRA="--exclude feature_block" # Low memory on Travis machines, exclude feature_block. +export GOAL="install" +export BITSEND_CONFIG="--enable-zmq --with-gui=no CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' CXXFLAGS='-g' --with-sanitizers=thread CC=clang CXX='clang++ -stdlib=libc++' --with-boost-process" diff --git a/ci/test/00_setup_env_native_valgrind.sh b/ci/test/00_setup_env_native_valgrind.sh new file mode 100644 index 00000000..7ee18ae1 --- /dev/null +++ b/ci/test/00_setup_env_native_valgrind.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export CONTAINER_NAME=ci_native_valgrind +export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libsqlite3-dev" +export USE_VALGRIND=1 +export NO_DEPENDS=1 +export TEST_RUNNER_EXTRA="--exclude rpc_bind" # Excluded for now, see https://github.com/bitsend/bitsend/issues/17765#issuecomment-602068547 +export GOAL="install" +export BITSEND_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=no CC=clang CXX=clang++" # TODO enable GUI diff --git a/ci/test/00_setup_env_s390x.sh b/ci/test/00_setup_env_s390x.sh new file mode 100644 index 00000000..82ddb1c5 --- /dev/null +++ b/ci/test/00_setup_env_s390x.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export HOST=s390x-linux-gnu +# The host arch is unknown, so we run the tests through qemu. +# If the host is s390x and wants to run the tests natively, it can set QEMU_USER_CMD to the empty string. +if [ -z ${QEMU_USER_CMD+x} ]; then export QEMU_USER_CMD="${QEMU_USER_CMD:-"qemu-s390x"}"; fi +export PACKAGES="python3-zmq" +if [ -n "$QEMU_USER_CMD" ]; then + # Likely cross-compiling, so install the needed gcc and qemu-user + export DPKG_ADD_ARCH="s390x" + export PACKAGES="$PACKAGES g++-s390x-linux-gnu qemu-user libc6:s390x libstdc++6:s390x libfontconfig1:s390x libxcb1:s390x" +fi +# Use debian to avoid 404 apt errors +export CONTAINER_NAME=ci_s390x +export DOCKER_NAME_TAG="debian:buster" +export RUN_UNIT_TESTS=true +export TEST_RUNNER_ENV="LC_ALL=C" +export RUN_FUNCTIONAL_TESTS=true +export GOAL="install" +export BITSEND_CONFIG="--enable-reduce-exports --with-incompatible-bdb --with-boost-process" diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh new file mode 100644 index 00000000..568519da --- /dev/null +++ b/ci/test/00_setup_env_win64.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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.UTF-8 + +export CONTAINER_NAME=ci_win64 +export DOCKER_NAME_TAG=ubuntu:18.04 # Check that bionic can cross-compile to win64 (bionic is used in the gitian build as well) +export HOST=x86_64-w64-mingw32 +export PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64 file" +export RUN_FUNCTIONAL_TESTS=false +export RUN_SECURITY_TESTS="true" +export GOAL="deploy" +export BITSEND_CONFIG="--enable-reduce-exports --disable-gui-tests --without-boost-process" diff --git a/ci/test/03_before_install.sh b/ci/test/03_before_install.sh new file mode 100755 index 00000000..922ae90a --- /dev/null +++ b/ci/test/03_before_install.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2019 The BitSend 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.UTF-8 + +BEGIN_FOLD () { + echo "" + CURRENT_FOLD_NAME=$1 + echo "travis_fold:start:${CURRENT_FOLD_NAME}" +} + +END_FOLD () { + RET=$? + echo "travis_fold:end:${CURRENT_FOLD_NAME}" + if [ $RET != 0 ]; then + echo "${CURRENT_FOLD_NAME} failed with status code ${RET}" + fi +} + diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh new file mode 100755 index 00000000..9f86d08d --- /dev/null +++ b/ci/test/04_install.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2020 The BitSend 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.UTF-8 + +if [[ $DOCKER_NAME_TAG == centos* ]]; then + export LC_ALL=en_US.utf8 +fi +if [[ $QEMU_USER_CMD == qemu-s390* ]]; then + export LC_ALL=C +fi + +if [ "$CI_OS_NAME" == "macos" ]; then + IN_GETOPT_BIN="/usr/local/opt/gnu-getopt/bin/getopt" ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES +fi + +# Create folders that are mounted into the docker +mkdir -p "${CCACHE_DIR}" +mkdir -p "${PREVIOUS_RELEASES_DIR}" + +export ASAN_OPTIONS="detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" +export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan" +export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1:log_path=${BASE_SCRATCH_DIR}/sanitizer-output/tsan" +export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" +env | grep -E '^(BITSEND_CONFIG|BASE_|QEMU_|CCACHE_|LC_ALL|BOOST_TEST_RANDOM|DEBIAN_FRONTEND|CONFIG_SHELL|(ASAN|LSAN|TSAN|UBSAN)_OPTIONS|PREVIOUS_RELEASES_DIR)' | tee /tmp/env +if [[ $BITSEND_CONFIG = *--with-sanitizers=*address* ]]; then # If ran with (ASan + LSan), Docker needs access to ptrace (https://github.com/google/sanitizers/issues/764) + DOCKER_ADMIN="--cap-add SYS_PTRACE" +fi + +export P_CI_DIR="$PWD" + +if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then + echo "Creating $DOCKER_NAME_TAG container to run in" + ${CI_RETRY_EXE} docker pull "$DOCKER_NAME_TAG" + + DOCKER_ID=$(docker run $DOCKER_ADMIN -idt \ + --mount type=bind,src=$BASE_ROOT_DIR,dst=/ro_base,readonly \ + --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR \ + --mount type=bind,src=$DEPENDS_DIR,dst=$DEPENDS_DIR \ + --mount type=bind,src=$PREVIOUS_RELEASES_DIR,dst=$PREVIOUS_RELEASES_DIR \ + -w $BASE_ROOT_DIR \ + --env-file /tmp/env \ + --name $CONTAINER_NAME \ + $DOCKER_NAME_TAG) + export DOCKER_CI_CMD_PREFIX="docker exec $DOCKER_ID" +else + echo "Running on host system without docker wrapper" +fi + +DOCKER_EXEC () { + $DOCKER_CI_CMD_PREFIX bash -c "export PATH=$BASE_SCRATCH_DIR/bins/:\$PATH && cd $P_CI_DIR && $*" +} +export -f DOCKER_EXEC + +if [ -n "$DPKG_ADD_ARCH" ]; then + DOCKER_EXEC dpkg --add-architecture "$DPKG_ADD_ARCH" +fi + +if [[ $DOCKER_NAME_TAG == centos* ]]; then + ${CI_RETRY_EXE} DOCKER_EXEC yum -y install epel-release + ${CI_RETRY_EXE} DOCKER_EXEC yum -y install $DOCKER_PACKAGES $PACKAGES +elif [ "$CI_USE_APT_INSTALL" != "no" ]; then + ${CI_RETRY_EXE} DOCKER_EXEC apt-get update + ${CI_RETRY_EXE} DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -y $PACKAGES $DOCKER_PACKAGES +fi + +if [ "$CI_OS_NAME" == "macos" ]; then + top -l 1 -s 0 | awk ' /PhysMem/ {print}' + echo "Number of CPUs: $(sysctl -n hw.logicalcpu)" +else + DOCKER_EXEC free -m -h + DOCKER_EXEC echo "Number of CPUs \(nproc\):" \$\(nproc\) + DOCKER_EXEC echo $(lscpu | grep Endian) +fi +DOCKER_EXEC echo "Free disk space:" +DOCKER_EXEC df -h + +if [ ! -d ${DIR_QA_ASSETS} ]; then + DOCKER_EXEC git clone --depth=1 https://github.com/bitsend-core/qa-assets ${DIR_QA_ASSETS} +fi +export DIR_FUZZ_IN=${DIR_QA_ASSETS}/fuzz_seed_corpus/ +export DIR_UNIT_TEST_DATA=${DIR_QA_ASSETS}/unit_test_data/ + +DOCKER_EXEC mkdir -p "${BASE_SCRATCH_DIR}/sanitizer-output/" + +if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then + DOCKER_EXEC "update-alternatives --install /usr/bin/clang++ clang++ \$(which clang++-9) 100" + DOCKER_EXEC "update-alternatives --install /usr/bin/clang clang \$(which clang-9) 100" + DOCKER_EXEC "mkdir -p ${BASE_SCRATCH_DIR}/msan/build/" + DOCKER_EXEC "git clone --depth=1 https://github.com/llvm/llvm-project -b llvmorg-10.0.0 ${BASE_SCRATCH_DIR}/msan/llvm-project" + DOCKER_EXEC "cd ${BASE_SCRATCH_DIR}/msan/build/ && cmake -DLLVM_ENABLE_PROJECTS='libcxx;libcxxabi' -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_SANITIZER=Memory -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_TARGETS_TO_BUILD=X86 ../llvm-project/llvm/" + DOCKER_EXEC "cd ${BASE_SCRATCH_DIR}/msan/build/ && make $MAKEJOBS cxx" +fi + +if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then + echo "Create $BASE_ROOT_DIR" + DOCKER_EXEC rsync -a /ro_base/ $BASE_ROOT_DIR +fi + +if [ "$USE_BUSY_BOX" = "true" ]; then + echo "Setup to use BusyBox utils" + DOCKER_EXEC mkdir -p $BASE_SCRATCH_DIR/bins/ + # tar excluded for now because it requires passing in the exact archive type in ./depends (fixed in later BusyBox version) + # find excluded for now because it does not recognize the -delete option in ./depends (fixed in later BusyBox version) + # ar excluded for now because it does not recognize the -q option in ./depends (unknown if fixed) + # shellcheck disable=SC1010 + DOCKER_EXEC for util in \$\(busybox --list \| grep -v "^ar$" \| grep -v "^tar$" \| grep -v "^find$"\)\; do ln -s \$\(command -v busybox\) $BASE_SCRATCH_DIR/bins/\$util\; done + # Print BusyBox version + DOCKER_EXEC patch --help +fi diff --git a/ci/test/05_before_script.sh b/ci/test/05_before_script.sh new file mode 100755 index 00000000..b36f2092 --- /dev/null +++ b/ci/test/05_before_script.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2020 The BitSend 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.UTF-8 + +# Make sure default datadir does not exist and is never read by creating a dummy file +if [ "$CI_OS_NAME" == "macos" ]; then + echo > $HOME/Library/Application\ Support/BitSend +else + DOCKER_EXEC echo \> \$HOME/.bitsend +fi + +DOCKER_EXEC mkdir -p ${DEPENDS_DIR}/SDKs ${DEPENDS_DIR}/sdk-sources + +OSX_SDK_BASENAME="Xcode-${XCODE_VERSION}-${XCODE_BUILD_ID}-extracted-SDK-with-libcxx-headers.tar.gz" +OSX_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${OSX_SDK_BASENAME}" + +if [ -n "$XCODE_VERSION" ] && [ ! -f "$OSX_SDK_PATH" ]; then + curl --location --fail "${SDK_URL}/${OSX_SDK_BASENAME}" -o "$OSX_SDK_PATH" +fi + +if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then + # Use BDB compiled using install_db4.sh script to work around linking issue when using BDB + # from depends. See https://github.com/bitsend/bitsend/pull/18288#discussion_r433189350 for + # details. + DOCKER_EXEC "contrib/install_db4.sh \$(pwd) --enable-umrw CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" +fi + +if [ -n "$XCODE_VERSION" ] && [ -f "$OSX_SDK_PATH" ]; then + DOCKER_EXEC tar -C "${DEPENDS_DIR}/SDKs" -xf "$OSX_SDK_PATH" +fi +if [[ $HOST = *-mingw32 ]]; then + DOCKER_EXEC update-alternatives --set $HOST-g++ \$\(which $HOST-g++-posix\) +fi +if [ -z "$NO_DEPENDS" ]; then + if [[ $DOCKER_NAME_TAG == centos* ]]; then + # CentOS has problems building the depends if the config shell is not explicitly set + # (i.e. for libevent a Makefile with an empty SHELL variable is generated, leading to + # an error as the first command is executed) + SHELL_OPTS="CONFIG_SHELL=/bin/bash" + else + SHELL_OPTS="CONFIG_SHELL=" + fi + DOCKER_EXEC $SHELL_OPTS make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS +fi +if [ -n "$PREVIOUS_RELEASES_TO_DOWNLOAD" ]; then + BEGIN_FOLD previous-versions + DOCKER_EXEC test/get_previous_releases.py -b -t "$PREVIOUS_RELEASES_DIR" "${PREVIOUS_RELEASES_TO_DOWNLOAD}" + END_FOLD +fi diff --git a/ci/test/06_script_a.sh b/ci/test/06_script_a.sh new file mode 100755 index 00000000..0143e4d3 --- /dev/null +++ b/ci/test/06_script_a.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2020 The BitSend 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.UTF-8 + +BITSEND_CONFIG_ALL="--disable-dependency-tracking --prefix=$DEPENDS_DIR/$HOST --bindir=$BASE_OUTDIR/bin --libdir=$BASE_OUTDIR/lib" +DOCKER_EXEC "ccache --zero-stats --max-size=$CCACHE_SIZE" + +BEGIN_FOLD autogen +if [ -n "$CONFIG_SHELL" ]; then + DOCKER_EXEC "$CONFIG_SHELL" -c "./autogen.sh" +else + DOCKER_EXEC ./autogen.sh +fi +END_FOLD + +DOCKER_EXEC mkdir -p "${BASE_BUILD_DIR}" +export P_CI_DIR="${BASE_BUILD_DIR}" + +BEGIN_FOLD configure +DOCKER_EXEC "${BASE_ROOT_DIR}/configure" --cache-file=config.cache $BITSEND_CONFIG_ALL $BITSEND_CONFIG || ( (DOCKER_EXEC cat config.log) && false) +END_FOLD + +BEGIN_FOLD distdir +DOCKER_EXEC make distdir VERSION=$HOST +END_FOLD + +export P_CI_DIR="${BASE_BUILD_DIR}/bitsend-$HOST" + +BEGIN_FOLD configure +DOCKER_EXEC ./configure --cache-file=../config.cache $BITSEND_CONFIG_ALL $BITSEND_CONFIG || ( (DOCKER_EXEC cat config.log) && false) +END_FOLD + +set -o errtrace +trap 'DOCKER_EXEC "cat ${BASE_SCRATCH_DIR}/sanitizer-output/* 2> /dev/null"' ERR + +if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then + # MemorySanitizer (MSAN) does not support tracking memory initialization done by + # using the Linux getrandom syscall. Avoid using getrandom by undefining + # HAVE_SYS_GETRANDOM. See https://github.com/google/sanitizers/issues/852 for + # details. + DOCKER_EXEC 'grep -v HAVE_SYS_GETRANDOM src/config/bitsend-config.h > src/config/bitsend-config.h.tmp && mv src/config/bitsend-config.h.tmp src/config/bitsend-config.h' +fi + +BEGIN_FOLD build +DOCKER_EXEC make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && DOCKER_EXEC make $GOAL V=1 ; false ) +END_FOLD + +BEGIN_FOLD cache_stats +DOCKER_EXEC "ccache --version | head -n 1 && ccache --show-stats" +DOCKER_EXEC du -sh "${DEPENDS_DIR}"/*/ +DOCKER_EXEC du -sh "${PREVIOUS_RELEASES_DIR}" +END_FOLD diff --git a/ci/test/06_script_b.sh b/ci/test/06_script_b.sh new file mode 100755 index 00000000..1fb4af2a --- /dev/null +++ b/ci/test/06_script_b.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2020 The BitSend 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.UTF-8 + +if [[ $HOST = *-mingw32 ]]; then + BEGIN_FOLD wrap-wine + # Generate all binaries, so that they can be wrapped + DOCKER_EXEC make $MAKEJOBS -C src/secp256k1 VERBOSE=1 + DOCKER_EXEC make $MAKEJOBS -C src/univalue VERBOSE=1 + DOCKER_EXEC "${BASE_ROOT_DIR}/ci/test/wrap-wine.sh" + END_FOLD +fi + +if [ -n "$QEMU_USER_CMD" ]; then + BEGIN_FOLD wrap-qemu + # Generate all binaries, so that they can be wrapped + DOCKER_EXEC make $MAKEJOBS -C src/secp256k1 VERBOSE=1 + DOCKER_EXEC make $MAKEJOBS -C src/univalue VERBOSE=1 + DOCKER_EXEC "${BASE_ROOT_DIR}/ci/test/wrap-qemu.sh" + END_FOLD +fi + +if [ -n "$USE_VALGRIND" ]; then + BEGIN_FOLD wrap-valgrind + DOCKER_EXEC "${BASE_ROOT_DIR}/ci/test/wrap-valgrind.sh" + END_FOLD +fi + +if [ "$RUN_UNIT_TESTS" = "true" ]; then + BEGIN_FOLD unit-tests + DOCKER_EXEC ${TEST_RUNNER_ENV} DIR_UNIT_TEST_DATA=${DIR_UNIT_TEST_DATA} LD_LIBRARY_PATH=$DEPENDS_DIR/$HOST/lib make $MAKEJOBS check VERBOSE=1 + END_FOLD +fi + +if [ "$RUN_UNIT_TESTS_SEQUENTIAL" = "true" ]; then + BEGIN_FOLD unit-tests-seq + DOCKER_EXEC ${TEST_RUNNER_ENV} DIR_UNIT_TEST_DATA=${DIR_UNIT_TEST_DATA} LD_LIBRARY_PATH=$DEPENDS_DIR/$HOST/lib "${BASE_BUILD_DIR}/bitsend-*/src/test/test_bitsend*" --catch_system_errors=no -l test_suite + END_FOLD +fi + +if [ "$RUN_FUNCTIONAL_TESTS" = "true" ]; then + BEGIN_FOLD functional-tests + DOCKER_EXEC LD_LIBRARY_PATH=$DEPENDS_DIR/$HOST/lib ${TEST_RUNNER_ENV} test/functional/test_runner.py --ci $MAKEJOBS --tmpdirprefix "${BASE_SCRATCH_DIR}/test_runner/" --ansi --combinedlogslen=4000 --timeout-factor=${TEST_RUNNER_TIMEOUT_FACTOR} ${TEST_RUNNER_EXTRA} --quiet --failfast + END_FOLD +fi + +if [ "$RUN_SECURITY_TESTS" = "true" ]; then + BEGIN_FOLD security-tests + DOCKER_EXEC make test-security-check + END_FOLD +fi + +if [ "$RUN_FUZZ_TESTS" = "true" ]; then + BEGIN_FOLD fuzz-tests + DOCKER_EXEC LD_LIBRARY_PATH=$DEPENDS_DIR/$HOST/lib test/fuzz/test_runner.py ${FUZZ_TESTS_CONFIG} $MAKEJOBS -l DEBUG ${DIR_FUZZ_IN} + END_FOLD +fi diff --git a/ci/test/wrap-qemu.sh b/ci/test/wrap-qemu.sh new file mode 100755 index 00000000..3437dc61 --- /dev/null +++ b/ci/test/wrap-qemu.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2019 The BitSend 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.UTF-8 + +for b_name in {"${BASE_OUTDIR}/bin"/*,src/secp256k1/*tests,src/univalue/{no_nul,test_json,unitester,object}}; do + # shellcheck disable=SC2044 + for b in $(find "${BASE_ROOT_DIR}" -executable -type f -name $(basename $b_name)); do + echo "Wrap $b ..." + mv "$b" "${b}_orig" + echo '#!/usr/bin/env bash' > "$b" + echo "$QEMU_USER_CMD \"${b}_orig\" \"\$@\"" >> "$b" + chmod +x "$b" + done +done diff --git a/ci/test/wrap-valgrind.sh b/ci/test/wrap-valgrind.sh new file mode 100755 index 00000000..fb101f8a --- /dev/null +++ b/ci/test/wrap-valgrind.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2019 The BitSend 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.UTF-8 + +for b_name in "${BASE_OUTDIR}/bin"/*; do + # shellcheck disable=SC2044 + for b in $(find "${BASE_ROOT_DIR}" -executable -type f -name $(basename $b_name)); do + echo "Wrap $b ..." + mv "$b" "${b}_orig" + echo '#!/usr/bin/env bash' > "$b" + echo "valgrind --gen-suppressions=all --quiet --error-exitcode=1 --suppressions=${BASE_ROOT_DIR}/contrib/valgrind.supp \"${b}_orig\" \"\$@\"" >> "$b" + chmod +x "$b" + done +done diff --git a/ci/test/wrap-wine.sh b/ci/test/wrap-wine.sh new file mode 100755 index 00000000..cc161018 --- /dev/null +++ b/ci/test/wrap-wine.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2020 The BitSend 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.UTF-8 + +for b_name in {"${BASE_OUTDIR}/bin"/*,src/secp256k1/*tests,src/univalue/{no_nul,test_json,unitester,object}}.exe; do + # shellcheck disable=SC2044 + for b in $(find "${BASE_ROOT_DIR}" -executable -type f -name "$(basename $b_name)"); do + if (file "$b" | grep "Windows"); then + echo "Wrap $b ..." + mv "$b" "${b}_orig" + echo '#!/usr/bin/env bash' > "$b" + echo "wine64 \"${b}_orig\" \"\$@\"" >> "$b" + chmod +x "$b" + fi + done +done diff --git a/ci/test_run_all.sh b/ci/test_run_all.sh new file mode 100755 index 00000000..840fd191 --- /dev/null +++ b/ci/test_run_all.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019 The BitSend 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.UTF-8 + +set -o errexit; source ./ci/test/00_setup_env.sh +set -o errexit; source ./ci/test/03_before_install.sh +set -o errexit; source ./ci/test/04_install.sh +set -o errexit; source ./ci/test/05_before_script.sh +set -o errexit; source ./ci/test/06_script_a.sh +set -o errexit; source ./ci/test/06_script_b.sh diff --git a/configure.ac b/configure.ac old mode 100755 new mode 100644 index b8646a7c..171ba9cc --- a/configure.ac +++ b/configure.ac @@ -1,23 +1,30 @@ -dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) -AC_PREREQ([2.60]) +AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 17) -define(_CLIENT_VERSION_REVISION, 9) -define(_CLIENT_VERSION_BUILD, 2) +define(_CLIENT_VERSION_MINOR, 21) +define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_BUILD, 0) +define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2021) +define(_COPYRIGHT_YEAR, 2020) define(_COPYRIGHT_HOLDERS,[The %s developers]) -define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitsend Core]]) -AC_INIT([Bitsend Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/LIMXTEC/BitSend/issues],[bitsend],[https://bitsend.cc/]) +define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[BitSend Core]]) +AC_INIT([BitSend Core],m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_REVISION, m4_if(_CLIENT_VERSION_BUILD, [0], [], _CLIENT_VERSION_BUILD))m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC),[https://github.com/bitsend/bitsend/issues],[bitsend],[https://bitsendcore.org/]) AC_CONFIG_SRCDIR([src/validation.cpp]) AC_CONFIG_HEADERS([src/config/bitsend-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 + BITSEND_DAEMON_NAME=bitsendd BITSEND_GUI_NAME=bitsend-qt BITSEND_CLI_NAME=bitsend-cli BITSEND_TX_NAME=bitsend-tx +BITSEND_WALLET_TOOL_NAME=bitsend-wallet dnl Unless the user specified ARFLAGS, force it to be cr AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to if not set]) @@ -35,14 +42,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 @@ -60,8 +67,20 @@ case $host in lt_cv_deplibs_check_method="pass_all" ;; 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 @@ -74,6 +93,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]) @@ -82,9 +105,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.7 python3.6 python3.5 python3.4 python3 python]) +dnl Python 3.5 is specified in .python-version and should be used if available, see doc/dependencies.md +AC_PATH_PROGS([PYTHON], [python3.5 python3.6 python3.7 python3.8 python3 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) @@ -94,20 +118,22 @@ AC_PATH_TOOL(READELF, readelf) AC_PATH_TOOL(CPPFILT, c++filt) AC_PATH_TOOL(OBJCOPY, objcopy) AC_PATH_PROG(DOXYGEN, doxygen) -if test -z "$DOXYGEN"; then - AC_MSG_WARN([Doxygen not found]) -fi 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]) +AC_ARG_WITH([sqlite], + [AS_HELP_STRING([--with-sqlite=yes|no|auto], + [enable sqlite wallet support (default: auto, i.e., enabled if wallet is enabled and sqlite is found)])], + [use_sqlite=$withval], + [use_sqlite=auto]) + AC_ARG_WITH([miniupnpc], [AS_HELP_STRING([--with-miniupnpc], [enable UPNP (default is yes if libminiupnpc is found)])], @@ -121,9 +147,9 @@ AC_ARG_ENABLE([upnp-default], [use_upnp_default=no]) AC_ARG_ENABLE(tests, - AS_HELP_STRING([--disable-tests],[do not compile tests (default is to no)]), + AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]), [use_tests=$enableval], - [use_tests=no]) + [use_tests=yes]) AC_ARG_ENABLE(gui-tests, AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]), @@ -140,6 +166,12 @@ AC_ARG_ENABLE([extended-functional-tests], [use_extended_functional_tests=$enableval], [use_extended_functional_tests=no]) +AC_ARG_ENABLE([fuzz], + AS_HELP_STRING([--enable-fuzz], + [enable building of fuzz targets (default no). enabling this will disable all other targets]), + [enable_fuzz=$enableval], + [enable_fuzz=no]) + AC_ARG_WITH([qrencode], [AS_HELP_STRING([--with-qrencode], [enable QR code support (default is yes if qt is enabled and libqrencode is found)])], @@ -164,6 +196,16 @@ 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 BitSend 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)])], @@ -182,9 +224,15 @@ 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([--enable-asm], - [Enable assembly routines (default is yes)])], + [AS_HELP_STRING([--disable-asm], + [disable assembly routines (enabled by default)])], [use_asm=$enableval], [use_asm=yes]) @@ -204,7 +252,23 @@ AC_ARG_ENABLE([zmq], [use_zmq=$enableval], [use_zmq=yes]) -AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) +AC_ARG_WITH([libmultiprocess], + [AS_HELP_STRING([--with-libmultiprocess=yes|no|auto], + [Build with libmultiprocess library. (default: auto, i.e. detect with pkg-config)])], + [with_libmultiprocess=$withval], + [with_libmultiprocess=auto]) + +AC_ARG_WITH([mpgen], + [AS_HELP_STRING([--with-mpgen=yes|no|auto|PREFIX], + [Build with libmultiprocess codegen tool. Useful to specify different libmultiprocess host system library and build system codegen tool prefixes when cross-compiling (default is host system libmultiprocess prefix)])], + [with_mpgen=$withval], + [with_mpgen=auto]) + +AC_ARG_ENABLE([multiprocess], + [AS_HELP_STRING([--enable-multiprocess], + [build multiprocess bitsend-node, bitsend-wallet, and bitsend-gui executables in addition to monolithic bitsendd and bitsend-qt executables. Requires libmultiprocess library. Experimental (default is no)])], + [enable_multiprocess=$enableval], + [enable_multiprocess=no]) AC_ARG_ENABLE(man, [AS_HELP_STRING([--disable-man], @@ -212,27 +276,34 @@ AC_ARG_ENABLE(man, 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]) -# Enable different -fsanitize options +dnl Enable different -fsanitize options AC_ARG_WITH([sanitizers], [AS_HELP_STRING([--with-sanitizers], [comma separated list of extra sanitizers to build with (default is none enabled)])], [use_sanitizers=$withval]) -# Enable gprof profiling +dnl Enable gprof profiling AC_ARG_ENABLE([gprof], [AS_HELP_STRING([--enable-gprof], [use gprof profiling compiler flags (default is no)])], [enable_gprof=$enableval], [enable_gprof=no]) -# Turn warnings into errors +dnl Pass compiler & linker flags that make builds deterministic +AC_ARG_ENABLE([determinism], + [AS_HELP_STRING([--enable-determinism], + [Enable compilation flags that make builds deterministic (default is no)])], + [enable_determinism=$enableval], + [enable_determinism=no]) + +dnl Turn warnings into errors AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], [Treat certain compiler warnings as errors (default is no)])], @@ -240,21 +311,40 @@ 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 - # Clear default -g -O2 flags + dnl Clear default -g -O2 flags if test "x$CXXFLAGS_overridden" = xno; then CXXFLAGS="" fi - # Prefer -Og, fall back to -O0 if that is unavailable. - AX_CHECK_COMPILE_FLAG( - [-Og], - [[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -Og"]], - [AX_CHECK_COMPILE_FLAG([-O0],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -O0"]],,[[$CXXFLAG_WERROR]])], - [[$CXXFLAG_WERROR]]) - # Prefer -g3, fall back to -g if that is unavailable. + 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"]], @@ -267,23 +357,30 @@ if test "x$enable_debug" = xyes; then fi if test x$use_sanitizers != x; then - # First check if the compiler accepts flags. If an incompatible pair like - # -fsanitize=address,thread is used here, this check will fail. This will also - # fail if a bad argument is passed, e.g. -fsanitize=undfeined + dnl First check if the compiler accepts flags. If an incompatible pair like + dnl -fsanitize=address,thread is used here, this check will fail. This will also + dnl fail if a bad argument is passed, e.g. -fsanitize=undfeined AX_CHECK_COMPILE_FLAG( [[-fsanitize=$use_sanitizers]], [[SANITIZER_CXXFLAGS=-fsanitize=$use_sanitizers]], [AC_MSG_ERROR([compiler did not accept requested flags])]) - # Some compilers (e.g. GCC) require additional libraries like libasan, - # libtsan, libubsan, etc. Make sure linking still works with the sanitize - # flag. This is a separate check so we can give a better error message when - # the sanitize flags are supported by the compiler but the actual sanitizer - # libs are missing. + dnl Some compilers (e.g. GCC) require additional libraries like libasan, + dnl libtsan, libubsan, etc. Make sure linking still works with the sanitize + dnl flag. This is a separate check so we can give a better error message when + dnl the sanitize flags are supported by the compiler but the actual sanitizer + dnl libs are missing. AX_CHECK_LINK_FLAG( [[-fsanitize=$use_sanitizers]], [[SANITIZER_LDFLAGS=-fsanitize=$use_sanitizers]], - [AC_MSG_ERROR([linker did not accept requested flags, you are missing required libraries])]) + [AC_MSG_ERROR([linker did not accept requested flags, you are missing required libraries])], + [], + [AC_LANG_PROGRAM([[ + #include + #include + extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; } + __attribute__((weak)) // allow for libFuzzer linking + ]],[[]])]) fi ERROR_CXXFLAGS= @@ -291,32 +388,74 @@ 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=thread-safety-analysis],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=thread-safety-analysis"],,[[$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]]) + dnl -Wsuggest-override is broken with GCC before 9.2 + dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78010 + AX_CHECK_COMPILE_FLAG([-Werror=suggest-override],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=suggest-override"],,[[$CXXFLAG_WERROR]], + [AC_LANG_SOURCE([[struct A { virtual void f(); }; struct B : A { void f() final; };]])]) + AX_CHECK_COMPILE_FLAG([-Werror=unreachable-code-loop-increment],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=unreachable-code-loop-increment"],,[[$CXXFLAG_WERROR]]) fi if test "x$CXXFLAGS_overridden" = "xno"; then 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([-Wformat],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wformat"],,[[$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([-Wformat-security],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wthread-safety-analysis],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wthread-safety-analysis"],,[[$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]]) - - ## 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([-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([-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([-Wsuggest-override],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wsuggest-override"],,[[$CXXFLAG_WERROR]], + [AC_LANG_SOURCE([[struct A { virtual void f(); }; struct B : A { void f() final; };]])]) + AX_CHECK_COMPILE_FLAG([-Wunreachable-code-loop-increment],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wunreachable-code-loop-increment"],,[[$CXXFLAG_WERROR]]) + + 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]]) AX_CHECK_COMPILE_FLAG([-Wdeprecated-register],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-register"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-implicit-fallthrough"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wdeprecated-copy],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-copy"],,[[$CXXFLAG_WERROR]]) fi -# Check for optional instruction set support. Enabling these does _not_ imply that all code will -# be compiled with them, rather that specific objects/libs may use them after checking for runtime -# compatibility. +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]]) @@ -324,7 +463,7 @@ AX_CHECK_COMPILE_FLAG([-msse4 -msha],[[SHANI_CXXFLAGS="-msse4 -msha"]],,[[$CXXFL TEMP_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $SSE42_CXXFLAGS" -AC_MSG_CHECKING(for assembler crc32 support) +AC_MSG_CHECKING(for SSE4.2 intrinsics) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #if defined(_MSC_VER) @@ -339,7 +478,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ l = _mm_crc32_u64(l, 0); return l; ]])], - [ AC_MSG_RESULT(yes); enable_hwcrc32=yes], + [ AC_MSG_RESULT(yes); enable_sse42=yes], [ AC_MSG_RESULT(no)] ) CXXFLAGS="$TEMP_CXXFLAGS" @@ -391,14 +530,52 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ) 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 bitsend-cli bitsend-tx (default=yes)])], + [build bitsend-cli bitsend-tx bitsend-wallet (default=yes)])], [build_bitsend_utils=$withval], [build_bitsend_utils=yes]) +AC_ARG_ENABLE([util-cli], + [AS_HELP_STRING([--enable-util-cli], + [build bitsend-cli])], + [build_bitsend_cli=$enableval], + [build_bitsend_cli=$build_bitsend_utils]) + +AC_ARG_ENABLE([util-tx], + [AS_HELP_STRING([--enable-util-tx], + [build bitsend-tx])], + [build_bitsend_tx=$enableval], + [build_bitsend_tx=$build_bitsend_utils]) + +AC_ARG_ENABLE([util-wallet], + [AS_HELP_STRING([--enable-util-wallet], + [build bitsend-wallet])], + [build_bitsend_wallet=$enableval], + [build_bitsend_wallet=$build_bitsend_utils]) + AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], [build libraries (default=yes)])], @@ -411,36 +588,26 @@ AC_ARG_WITH([daemon], [build_bitsendd=$withval], [build_bitsendd=yes]) -use_pkgconfig=yes case $host in *mingw*) - - #pkgconfig does more harm than good with MinGW - use_pkgconfig=no - TARGET_OS=windows - AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(libmingwthrd missing)) - AC_CHECK_LIB([kernel32], [main],, 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([winspool], [main],, AC_MSG_ERROR(libwinspool missing)) - AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(libwinmm missing)) - AC_CHECK_LIB([shell32], [main],, AC_MSG_ERROR(libshell32 missing)) - AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(libcomctl32 missing)) - AC_CHECK_LIB([ole32], [main],, 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([rpcrt4], [main],, AC_MSG_ERROR(librpcrt4 missing)) - AC_CHECK_LIB([advapi32], [main],, AC_MSG_ERROR(libadvapi32 missing)) - AC_CHECK_LIB([ws2_32], [main],, AC_MSG_ERROR(libws2_32 missing)) - AC_CHECK_LIB([mswsock], [main],, AC_MSG_ERROR(libmswsock missing)) - AC_CHECK_LIB([shlwapi], [main],, AC_MSG_ERROR(libshlwapi missing)) - AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(libiphlpapi missing)) - AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(libcrypt32 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) @@ -453,17 +620,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 @@ -473,23 +630,13 @@ 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) - if test x$PORT = xport; then - dnl add default macports paths - CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" - LIBS="$LIBS -L/opt/local/lib" - if test -d /opt/local/include/db48; then - CPPFLAGS="$CPPFLAGS -I/opt/local/include/db48" - LIBS="$LIBS -L/opt/local/lib/db48" - fi - fi - AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_CHECK_PROG([BREW],brew, brew) if test x$BREW = xbrew; then @@ -499,20 +646,19 @@ case $host in dnl It's safe to add these paths even if the functionality is disabled by dnl the user (--without-wallet or --without-gui for example). - openssl_prefix=`$BREW --prefix openssl 2>/dev/null` - bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null` - qt5_prefix=`$BREW --prefix qt5 2>/dev/null` - if test x$openssl_prefix != x; then - PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" - export PKG_CONFIG_PATH + if test "x$use_bdb" != xno && $BREW list --versions berkeley-db4 >/dev/null && test "x$BDB_CFLAGS" = "x" && test "x$BDB_LIBS" = "x"; then + bdb_prefix=$($BREW --prefix berkeley-db4 2>/dev/null) + dnl This must precede the call to BITSEND_FIND_BDB48 below. + BDB_CFLAGS="-I$bdb_prefix/include" + BDB_LIBS="-L$bdb_prefix/lib -ldb_cxx-4.8" fi - if test x$bdb_prefix != x; then - CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include" - LIBS="$LIBS -L$bdb_prefix/lib" + + if test "x$use_sqlite" != xno && $BREW list --versions sqlite3 >/dev/null; then + export PKG_CONFIG_PATH="$($BREW --prefix sqlite3 2>/dev/null)/lib/pkgconfig:$PKG_CONFIG_PATH" fi - if test x$qt5_prefix != x; then - PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" - export PKG_CONFIG_PATH + + if $BREW list --versions qt5 >/dev/null; then + export PKG_CONFIG_PATH="$($BREW --prefix qt5 2>/dev/null)/lib/pkgconfig:$PKG_CONFIG_PATH" fi fi else @@ -521,6 +667,7 @@ 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) @@ -537,54 +684,19 @@ case $host in esac fi - AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"]) - CPPFLAGS="$CPPFLAGS -DMAC_OSX" + 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" ;; *android*) dnl make sure android stays above linux for hosts like *linux-android* - LEVELDB_TARGET_FLAGS="-DOS_ANDROID" + TARGET_OS=android ;; *linux*) TARGET_OS=linux - LEVELDB_TARGET_FLAGS="-DOS_LINUX" - ;; - *kfreebsd*) - LEVELDB_TARGET_FLAGS="-DOS_KFREEBSD" - ;; - *freebsd*) - LEVELDB_TARGET_FLAGS="-DOS_FREEBSD" - ;; - *openbsd*) - LEVELDB_TARGET_FLAGS="-DOS_OPENBSD" - ;; - *netbsd*) - LEVELDB_TARGET_FLAGS="-DOS_NETBSD" - ;; - *dragonfly*) - LEVELDB_TARGET_FLAGS="-DOS_DRAGONFLYBSD" - ;; - *solaris*) - LEVELDB_TARGET_FLAGS="-DOS_SOLARIS" - ;; - *hpux*) - LEVELDB_TARGET_FLAGS="-DOS_HPUX" - ;; - *) - AC_MSG_ERROR(Cannot build leveldb for $host. Please file a bug report.) ;; 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_extended_functional_tests != xno; then AC_SUBST(EXTENDED_FUNCTIONAL_TESTS, --extended) fi @@ -593,21 +705,41 @@ if test x$use_lcov = xyes; then if test x$LCOV = x; then AC_MSG_ERROR("lcov testing requested but lcov not found") fi - if test x$GCOV = x; then - AC_MSG_ERROR("lcov testing requested but gcov not found") - fi if test x$PYTHON = x; then AC_MSG_ERROR("lcov testing requested but python not found") fi if test x$GENHTML = x; then AC_MSG_ERROR("lcov testing requested but genhtml not found") fi - LCOV="$LCOV --gcov-tool=$GCOV" + + 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")]) AX_CHECK_COMPILE_FLAG([--coverage],[CXXFLAGS="$CXXFLAGS --coverage"], [AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")]) - AC_DEFINE(USE_COVERAGE, 1, [Define this symbol if coverage is enabled]) CXXFLAGS="$CXXFLAGS -Og" fi @@ -621,11 +753,11 @@ AC_C_BIGENDIAN dnl Check for pthread compile/link requirements AX_PTHREAD -# The following macro will add the necessary defines to bitsend-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 bitsend-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 && @@ -640,31 +772,11 @@ if test x$ac_cv_sys_large_files != x && CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=$ac_cv_sys_large_files" fi -AX_CHECK_LINK_FLAG([[-Wl,--large-address-aware]], [LDFLAGS="$LDFLAGS -Wl,--large-address-aware"]) - AX_GCC_FUNC_ATTRIBUTE([visibility]) AX_GCC_FUNC_ATTRIBUTE([dllexport]) AX_GCC_FUNC_ATTRIBUTE([dllimport]) if test x$use_glibc_compat != xno; then - - #glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link - #in anyway for back-compat. - AC_CHECK_LIB([rt],[clock_gettime],, AC_MSG_ERROR(librt missing)) - - #__fdelt_chk's params and return type have changed from long unsigned int to long int. - # See which one is present here. - AC_MSG_CHECKING(__fdelt_chk type) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef _FORTIFY_SOURCE - #undef _FORTIFY_SOURCE - #endif - #define _FORTIFY_SOURCE 2 - #include - extern "C" long unsigned int __fdelt_warn(long unsigned int);]],[[]])], - [ fdelt_type="long unsigned int"], - [ 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"]) else @@ -689,27 +801,45 @@ if test "x$enable_gprof" = xyes; then 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" + AX_CHECK_COMPILE_FLAG([-fcf-protection=full],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fcf-protection=full"]) + + dnl stack-clash-protection does not work properly when building for Windows. + dnl We use the test case from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 + dnl to determine if it can be enabled. + AX_CHECK_COMPILE_FLAG([-fstack-clash-protection],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-clash-protection"],[],["-O0"], + [AC_LANG_SOURCE([[class D {public: unsigned char buf[32768];}; int main() {D d; return 0;}]])]) + + 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" ]) - HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2" - ]) + fi - 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"]) + 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 @@ -719,16 +849,30 @@ if test x$use_hardening != xno; then 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 + +if test x$enable_determinism = xyes; then + if test x$TARGET_OS = xwindows; then + AX_CHECK_LINK_FLAG([[-Wl,--no-insert-timestamp]], [LDFLAGS="$LDFLAGS -Wl,--no-insert-timestamp"],, [[$LDFLAG_WERROR]]) + fi 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]) -# Check for daemon(3), unrelated to --with-daemon (although used by it) +dnl Check for daemon(3), unrelated to --with-daemon (although used by it) AC_CHECK_DECLS([daemon]) AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,, @@ -743,7 +887,21 @@ AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,, #include #endif]) -AC_CHECK_DECLS([__builtin_clz, __builtin_clzl, __builtin_clzll]) +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 __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) @@ -761,6 +919,22 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ 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 visibility attribute]) AC_LINK_IFELSE([AC_LANG_SOURCE([ int foo_def( void ) __attribute__((visibility("default"))); @@ -778,29 +952,65 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([ ] ) -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; - } - ])], - [ - AC_DEFINE(HAVE_THREAD_LOCAL,1,[Define if thread_local 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) ] + ) ] ) -LDFLAGS="$TEMP_LDFLAGS" -# Check for different ways of gathering OS randomness +dnl Check for different ways of gathering OS randomness AC_MSG_CHECKING(for Linux getrandom syscall) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include @@ -825,10 +1035,24 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include [ 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 ]], - [[ static const int name[2] = {CTL_KERN, KERN_ARND}; + [[ #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)] @@ -842,12 +1066,100 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include [ AC_MSG_RESULT(no)] ) -# Check for reduced exports +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 ] +) + +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_MSG_RESULT(no); HAVE_STRONG_GETAUXVAL=0 ] +) + +AC_MSG_CHECKING(for weak getauxval support in the compiler) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + unsigned long getauxval(unsigned long type) __attribute__((weak)); + #define AT_HWCAP 16 + ]], [[ + getauxval(AT_HWCAP); + ]])], + [ AC_MSG_RESULT(yes); HAVE_WEAK_GETAUXVAL=1 ], + [ AC_MSG_RESULT(no); HAVE_WEAK_GETAUXVAL=0 ] +) + +dnl Check for reduced exports 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.])]) fi +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= @@ -856,9 +1168,89 @@ 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')]) + +dnl enable-fuzz should disable all other targets +if test "x$enable_fuzz" = "xyes"; then + AC_MSG_WARN(enable-fuzz will disable all other targets) + build_bitsend_utils=no + build_bitsend_cli=no + build_bitsend_tx=no + build_bitsend_wallet=no + build_bitsendd=no + build_bitsend_libs=no + bitsend_enable_qt=no + bitsend_enable_qt_test=no + bitsend_enable_qt_dbus=no + enable_wallet=no + use_bench=no + use_upnp=no + use_zmq=no + + AC_MSG_CHECKING([whether main function is needed]) + AX_CHECK_LINK_FLAG( + [[-fsanitize=$use_sanitizers]], + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([yes]) + CPPFLAGS="$CPPFLAGS -DPROVIDE_MAIN_FUNCTION"], + [], + [AC_LANG_PROGRAM([[ + #include + #include + extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; } + /* unterminated comment to remove the main function ... + ]],[[]])]) +else + BITSEND_QT_INIT + + dnl sets $bitsend_enable_qt, $bitsend_enable_qt_test, $bitsend_enable_qt_dbus + BITSEND_QT_CONFIGURE([5.5.1]) + + dnl Keep a copy of the original $QT_INCLUDES and use it when invoking qt's moc + QT_INCLUDES_UNSUPPRESSED=$QT_INCLUDES + if test x$suppress_external_warnings != xno ; then + QT_INCLUDES=SUPPRESS_WARNINGS($QT_INCLUDES) + QT_DBUS_INCLUDES=SUPPRESS_WARNINGS($QT_DBUS_INCLUDES) + QT_TEST_INCLUDES=SUPPRESS_WARNINGS($QT_TEST_INCLUDES) + fi +fi + if test x$enable_wallet != xno; then dnl Check for libdb_cxx only if wallet enabled BITSEND_FIND_BDB48 + if test x$suppress_external_warnings != xno ; then + BDB_CPPFLAGS=SUPPRESS_WARNINGS($BDB_CPPFLAGS) + fi + + dnl Check for sqlite3 + if test "x$use_sqlite" != "xno"; then + PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.7.17], [have_sqlite=yes], [have_sqlite=no]) + fi + AC_MSG_CHECKING([whether to build wallet with support for sqlite]) + if test "x$use_sqlite" = "xno"; then + use_sqlite=no + elif test "x$have_sqlite" = "xno"; then + if test "x$use_sqlite" = "xyes"; then + AC_MSG_ERROR([sqlite support requested but cannot be built. Use --without-sqlite]) + fi + use_sqlite=no + else + if test x$use_sqlite != xno; then + AC_DEFINE([USE_SQLITE],[1],[Define if sqlite support should be compiled in]) + use_sqlite=yes + fi + fi + AC_MSG_RESULT([$use_sqlite]) fi dnl Check for libminiupnpc (optional) @@ -868,14 +1260,29 @@ if test x$use_upnp != xno; then [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 -BITSEND_QT_INIT - -dnl sets $bitsend_enable_qt, $bitsend_enable_qt_test, $bitsend_enable_qt_dbus -BITSEND_QT_CONFIGURE([$use_pkgconfig]) - -if test x$build_bitsend_utils$build_bitsendd$bitsend_enable_qt$use_tests$use_bench = xnonononono; then +if test x$build_bitsend_wallet$build_bitsend_cli$build_bitsend_tx$build_bitsendd$bitsend_enable_qt$use_tests$use_bench = xnonononononono; then use_boost=no else use_boost=yes @@ -884,9 +1291,9 @@ fi if test x$use_boost = xyes; then dnl Minimum required Boost version -define(MINIMUM_REQUIRED_BOOST, 1.47.0) +define(MINIMUM_REQUIRED_BOOST, 1.58.0) -dnl Check for boost libs +dnl Check for Boost libs AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) if test x$want_boost = xno; then AC_MSG_ERROR([[only libbitsendconsensus can be built without boost]]) @@ -894,37 +1301,25 @@ fi AX_BOOST_SYSTEM AX_BOOST_FILESYSTEM AX_BOOST_THREAD -AX_BOOST_CHRONO + +dnl Opt-in to boost-process +AS_IF([ test x$with_boost_process != x ], [ AX_BOOST_PROCESS ], [ ax_cv_boost_process=no ] ) + +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" -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" -fi +BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_THREAD_LIB" fi 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_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"],, [[$LDFLAG_WERROR]]) fi if test x$use_tests = xyes; then @@ -933,7 +1328,6 @@ 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 @@ -959,237 +1353,127 @@ if test x$use_tests = xyes; then fi fi -if test x$use_boost = xyes; then +dnl libevent check -BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" - - -dnl If boost (prior to 1.57) was built without c++11, it emulated scoped enums -dnl using c++98 constructs. Unfortunately, this implementation detail leaked into -dnl the abi. This was fixed in 1.57. - -dnl When building against that installed version using c++11, the headers pick up -dnl on the native c++11 scoped enum support and enable it, however it will fail to -dnl link. This can be worked around by disabling c++11 scoped enums if linking will -dnl fail. -dnl BOOST_NO_SCOPED_ENUMS was changed to BOOST_NO_CXX11_SCOPED_ENUMS in 1.51. - -TEMP_LIBS="$LIBS" -LIBS="$BOOST_LIBS $LIBS" -TEMP_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" -AC_MSG_CHECKING([for mismatched boost c++11 scoped enums]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - #if !defined(BOOST_NO_SCOPED_ENUMS) && !defined(BOOST_NO_CXX11_SCOPED_ENUMS) && BOOST_VERSION < 105700 - #define BOOST_NO_SCOPED_ENUMS - #define BOOST_NO_CXX11_SCOPED_ENUMS - #define CHECK - #endif - #include - ]],[[ - #if defined(CHECK) - boost::filesystem::copy_file("foo", "bar"); - #else - choke; - #endif - ]])], - [AC_MSG_RESULT(mismatched); BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS"], [AC_MSG_RESULT(ok)]) -LIBS="$TEMP_LIBS" -CPPFLAGS="$TEMP_CPPFLAGS" - -dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however -dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if -dnl a working version is available, else fall back to sleep. sleep was removed -dnl after 1.56. -dnl If neither is available, abort. -TEMP_LIBS="$LIBS" -LIBS="$BOOST_LIBS $LIBS" -TEMP_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - ]],[[ - #if BOOST_VERSION >= 105000 && (!defined(BOOST_HAS_NANOSLEEP) || BOOST_VERSION >= 105200) - boost::this_thread::sleep_for(boost::chrono::milliseconds(0)); - #else - choke me - #endif - ]])], - [boost_sleep=yes; - AC_DEFINE(HAVE_WORKING_BOOST_SLEEP_FOR, 1, [Define this symbol if boost sleep_for works])], - [boost_sleep=no]) -LIBS="$TEMP_LIBS" -CPPFLAGS="$TEMP_CPPFLAGS" - -if test x$boost_sleep != xyes; then -TEMP_LIBS="$LIBS" -LIBS="$BOOST_LIBS $LIBS" -TEMP_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - #include - ]],[[ - #if BOOST_VERSION <= 105600 - boost::this_thread::sleep(boost::posix_time::milliseconds(0)); - #else - choke me - #endif - ]])], - [boost_sleep=yes; AC_DEFINE(HAVE_WORKING_BOOST_SLEEP, 1, [Define this symbol if boost sleep works])], - [boost_sleep=no]) -LIBS="$TEMP_LIBS" -CPPFLAGS="$TEMP_CPPFLAGS" +if test x$build_bitsend_cli$build_bitsendd$bitsend_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$boost_sleep != xyes; then - AC_MSG_ERROR(No working boost sleep implementation found.) -fi +dnl QR Code encoding library check +if test "x$use_qr" != xno; then + BITSEND_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) 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.)]) - BITSEND_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITSEND_QT_FAIL(libprotobuf not found)])]) - if test x$use_qr != xno; then - BITSEND_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) - fi - if test x$build_bitsend_utils$build_bitsendd$bitsend_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 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 + 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_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)) - - if test x$build_bitsend_utils$build_bitsendd$bitsend_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 - - 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]) - 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 - - BITSEND_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITSEND_QT_FAIL(libprotobuf not found))) - if test x$use_qr != xno; then - BITSEND_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) - BITSEND_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) - fi + AC_DEFINE_UNQUOTED([ENABLE_ZMQ], [0], [Define to 1 to enable ZMQ functions]) fi -save_CXXFLAGS="${CXXFLAGS}" -CXXFLAGS="${CXXFLAGS} ${CRYPTO_CFLAGS} ${SSL_CFLAGS}" -AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT -#include -]) -CXXFLAGS="${save_CXXFLAGS}" +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 univalue check need_bundled_univalue=yes - -if test x$build_bitsend_utils$build_bitsendd$bitsend_enable_qt$use_tests$use_bench = xnonononono; then +if test x$build_bitsend_wallet$build_bitsend_cli$build_bitsend_tx$build_bitsendd$bitsend_enable_qt$use_tests$use_bench = xnonononononono; 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 >= 1.0.4],[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' +AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) +AC_SUBST(UNIVALUE_CFLAGS) +AC_SUBST(UNIVALUE_LIBS) + +dnl libmultiprocess library check + +libmultiprocess_found=no +if test "x$with_libmultiprocess" = xyes || test "x$with_libmultiprocess" = xauto; then + m4_ifdef([PKG_CHECK_MODULES], [PKG_CHECK_MODULES([LIBMULTIPROCESS], [libmultiprocess], [ + libmultiprocess_found=yes; + libmultiprocess_prefix=`$PKG_CONFIG --variable=prefix libmultiprocess`; + ], [true])]) +elif test "x$with_libmultiprocess" != xno; then + AC_MSG_ERROR([--with-libmultiprocess=$with_libmultiprocess value is not yes, auto, or no]) fi +AC_SUBST(LIBMULTIPROCESS_CFLAGS) +AC_SUBST(LIBMULTIPROCESS_LIBS) + +dnl Enable multiprocess check +if test "x$enable_multiprocess" = xyes; then + if test "x$libmultiprocess_found" != xyes; then + AC_MSG_ERROR([--enable-multiprocess=yes option specified but libmultiprocess library was not found. May need to install libmultiprocess library, or specify install path with PKG_CONFIG_PATH environment variable. Running 'pkg-config --debug libmultiprocess' may be helpful for debugging.]) + fi + build_multiprocess=yes +elif test "x$enable_multiprocess" = xauto; then + build_multiprocess=$libmultiprocess_found +else + build_multiprocess=no fi -AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) -AC_SUBST(UNIVALUE_CFLAGS) -AC_SUBST(UNIVALUE_LIBS) +AM_CONDITIONAL([BUILD_MULTIPROCESS],[test "x$build_multiprocess" = xyes]) +AM_CONDITIONAL([BUILD_BITSEND_NODE], [test "x$build_multiprocess" = xyes]) +AM_CONDITIONAL([BUILD_BITSEND_GUI], [test "x$build_multiprocess" = xyes]) -BITSEND_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) +dnl codegen tools check + +if test x$build_multiprocess != xno; then + if test "x$with_mpgen" = xyes || test "x$with_mpgen" = xauto; then + MPGEN_PREFIX="$libmultiprocess_prefix" + elif test "x$with_mpgen" != xno; then + MPGEN_PREFIX="$with_mpgen"; + fi + AC_SUBST(MPGEN_PREFIX) +fi AC_MSG_CHECKING([whether to build bitsendd]) AM_CONDITIONAL([BUILD_BITSENDD], [test x$build_bitsendd = xyes]) AC_MSG_RESULT($build_bitsendd) -AC_MSG_CHECKING([whether to build utils (bitsend-cli bitsend-tx)]) -AM_CONDITIONAL([BUILD_BITSEND_UTILS], [test x$build_bitsend_utils = xyes]) -AC_MSG_RESULT($build_bitsend_utils) +AC_MSG_CHECKING([whether to build bitsend-cli]) +AM_CONDITIONAL([BUILD_BITSEND_CLI], [test x$build_bitsend_cli = xyes]) +AC_MSG_RESULT($build_bitsend_cli) + +AC_MSG_CHECKING([whether to build bitsend-tx]) +AM_CONDITIONAL([BUILD_BITSEND_TX], [test x$build_bitsend_tx = xyes]) +AC_MSG_RESULT($build_bitsend_tx) + +AC_MSG_CHECKING([whether to build bitsend-wallet]) +AM_CONDITIONAL([BUILD_BITSEND_WALLET], [test x$build_bitsend_wallet = xyes]) +AC_MSG_RESULT($build_bitsend_wallet) AC_MSG_CHECKING([whether to build libraries]) AM_CONDITIONAL([BUILD_BITSEND_LIBS], [test x$build_bitsend_libs = xyes]) @@ -1216,9 +1500,6 @@ if test "x$use_ccache" != "xno"; then fi AC_MSG_RESULT($use_ccache) fi -if test "x$use_ccache" = "xyes"; then - AX_CHECK_PREPROC_FLAG([-Qunused-arguments],[CPPFLAGS="-Qunused-arguments $CPPFLAGS"]) -fi dnl enable wallet AC_MSG_CHECKING([if wallet should be enabled]) @@ -1234,9 +1515,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) @@ -1271,18 +1553,16 @@ if test x$bitsend_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") @@ -1315,27 +1595,33 @@ else AC_MSG_RESULT([no]) fi -if test x$build_bitsend_utils$build_bitsend_libs$build_bitsendd$bitsend_enable_qt$use_bench$use_tests = xnononononono; then +if test x$build_bitsend_wallet$build_bitsend_cli$build_bitsend_tx$build_bitsend_libs$build_bitsendd$bitsend_enable_qt$use_bench$use_tests = xnononononononono; then AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests]) 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([USE_SQLITE], [test "x$use_sqlite" = "xyes"]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) +AM_CONDITIONAL([ENABLE_FUZZ],[test x$enable_fuzz = xyes]) AM_CONDITIONAL([ENABLE_QT],[test x$bitsend_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_LCOV],[test x$use_lcov = xyes]) +AM_CONDITIONAL([USE_LIBEVENT],[test x$use_libevent = xyes]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) -AM_CONDITIONAL([ENABLE_HWCRC32],[test x$enable_hwcrc32 = 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]) @@ -1360,6 +1646,7 @@ AC_SUBST(BITSEND_DAEMON_NAME) AC_SUBST(BITSEND_GUI_NAME) AC_SUBST(BITSEND_CLI_NAME) AC_SUBST(BITSEND_TX_NAME) +AC_SUBST(BITSEND_WALLET_TOOL_NAME) AC_SUBST(RELDFLAGS) AC_SUBST(DEBUG_CPPFLAGS) @@ -1381,26 +1668,36 @@ 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_SQLITE) AC_SUBST(USE_UPNP) AC_SUBST(USE_QRCODE) AC_SUBST(BOOST_LIBS) +AC_SUBST(SQLITE_LIBS) AC_SUBST(TESTDEFS) -AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) -AC_SUBST(CRYPTO_LIBS) -AC_SUBST(SSL_LIBS) AC_SUBST(EVENT_LIBS) 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 test/config.ini]) 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([contrib/devtools/security-check.py:contrib/devtools/security-check.py]) +AC_CONFIG_LINKS([contrib/devtools/test-security-check.py:contrib/devtools/test-security-check.py]) AC_CONFIG_LINKS([contrib/filter-lcov.py:contrib/filter-lcov.py]) AC_CONFIG_LINKS([test/functional/test_runner.py:test/functional/test_runner.py]) +AC_CONFIG_LINKS([test/fuzz/test_runner.py:test/fuzz/test_runner.py]) AC_CONFIG_LINKS([test/util/bitsend-util-test.py:test/util/bitsend-util-test.py]) AC_CONFIG_LINKS([test/util/rpcauth-test.py:test/util/rpcauth-test.py]) @@ -1431,22 +1728,11 @@ 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 --disable-jni" +ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --with-bignum=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental" AC_CONFIG_SUBDIRS([src/secp256k1]) AC_OUTPUT -dnl Taken from https://wiki.debian.org/RpathIssue -case $host in - *-*-linux-gnu) - AC_MSG_RESULT([Fixing libtool for -rpath problems.]) - sed < libtool > libtool-2 \ - 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_IS_A_FOOL__ "/' - mv libtool-2 libtool - chmod 755 libtool - ;; -esac - dnl Replace the BUILDDIR path with the correct Windows path if compiling on Native Windows case ${OS} in *Windows*) @@ -1457,13 +1743,21 @@ esac echo echo "Options used to compile and link:" +echo " boost process = $ax_cv_boost_process" +echo " multiprocess = $build_multiprocess" echo " with wallet = $enable_wallet" +if test "x$enable_wallet" != "xno"; then + echo " with sqlite = $use_sqlite" +fi echo " with gui / qt = $bitsend_enable_qt" if test x$bitsend_enable_qt != xno; then echo " with qr = $use_qr" fi echo " with zmq = $use_zmq" echo " with test = $use_tests" +if test x$use_tests != xno; then + echo " with fuzz = $enable_fuzz" +fi echo " with bench = $use_bench" echo " with upnp = $use_upnp" echo " use asm = $use_asm" @@ -1473,13 +1767,13 @@ echo " gprof enabled = $enable_gprof" echo " werror = $enable_werror" echo echo " target os = $TARGET_OS" -echo " build os = $BUILD_OS" +echo " build os = $build_os" echo echo " CC = $CC" -echo " CFLAGS = $CFLAGS" +echo " CFLAGS = $PTHREAD_CFLAGS $CFLAGS" echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" echo " CXX = $CXX" echo " CXXFLAGS = $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" -echo " LDFLAGS = $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " LDFLAGS = $PTHREAD_LIBS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" echo " ARFLAGS = $ARFLAGS" echo diff --git a/contrib/README.md b/contrib/README.md old mode 100755 new mode 100644 index 61ae4cff..5306651c --- a/contrib/README.md +++ b/contrib/README.md @@ -3,17 +3,17 @@ Repository Tools ### [Developer tools](/contrib/devtools) ### Specific tools for developers working on this repository. -Contains the script `github-merge.py` for merging GitHub pull requests securely and signing them using GPG. +Additional tools, including the `github-merge.py` script, are available in the [maintainer-tools](https://github.com/bitsend-core/bitsend-maintainer-tools) repository. ### [Verify-Commits](/contrib/verify-commits) ### -Tool to verify that every merge commit was signed by a developer using the above `github-merge.py` script. +Tool to verify that every merge commit was signed by a developer using the `github-merge.py` script. ### [Linearize](/contrib/linearize) ### Construct a linear, no-fork, best version of the blockchain. ### [Qos](/contrib/qos) ### -A Linux bash script that will set up traffic control (tc) to limit the outgoing bandwidth for connections to the Bitsend network. This means one can have an always-on bitsendd instance running, and another local bitsendd/bitsend-qt instance which connects to this node and receives blocks from it. +A Linux bash script that will set up traffic control (tc) to limit the outgoing bandwidth for connections to the BitSend network. This means one can have an always-on bitsendd instance running, and another local bitsendd/bitsend-qt instance which connects to this node and receives blocks from it. ### [Seeds](/contrib/seeds) ### Utility to generate the pnSeed[] array that is compiled into the client. @@ -24,25 +24,25 @@ Build Tools and Keys ### Packaging ### The [Debian](/contrib/debian) subfolder contains the copyright file. -All other packaging related files can be found in the [bitcoin-core/packaging](https://github.com/bitcoin-core/packaging) repository. +All other packaging related files can be found in the [bitsend-core/packaging](https://github.com/bitsend-core/packaging) repository. ### [Gitian-descriptors](/contrib/gitian-descriptors) ### -Files used during the gitian build process. For more information about gitian, see the [the Bitcoin Core documentation repository](https://github.com/bitcoin-core/docs). +Files used during the gitian build process. For more information about gitian, see the [the BitSend Core documentation repository](https://github.com/bitsend-core/docs). ### [Gitian-keys](/contrib/gitian-keys) -PGP keys used for signing Bitsend Core [Gitian release](/doc/release-process.md) results. +PGP keys used for signing BitSend Core [Gitian release](/doc/release-process.md) results. ### [MacDeploy](/contrib/macdeploy) ### -Scripts and notes for Mac builds. +Scripts and notes for Mac builds. ### [Gitian-build](/contrib/gitian-build.py) ### Script for running full Gitian builds. -Test and Verify Tools +Test and Verify Tools --------------------- ### [TestGen](/contrib/testgen) ### -Utilities to generate test vectors for the data-driven Bitsend tests. +Utilities to generate test vectors for the data-driven BitSend tests. ### [Verify Binaries](/contrib/verifybinaries) ### -This script attempts to download and verify the signature file SHA256SUMS.asc from bitcoin.org. +This script attempts to download and verify the signature file SHA256SUMS.asc from bitsend.org. diff --git a/contrib/bitsend-cli.bash-completion b/contrib/bitsend-cli.bash-completion old mode 100755 new mode 100644 index 681177c0..f4c5304a --- a/contrib/bitsend-cli.bash-completion +++ b/contrib/bitsend-cli.bash-completion @@ -1,5 +1,5 @@ # bash programmable completion for bitsend-cli(1) -# Copyright (c) 2012-2016 The Bitsend Core developers +# Copyright (c) 2012-2019 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,13 +17,6 @@ _bitsend_rpc() { $bitsend_cli "${rpcargs[@]}" "$@" } -# Add wallet accounts to COMPREPLY -_bitsend_accounts() { - local accounts - accounts=$(_bitsend_rpc listaccounts | awk -F '"' '{ print $2 }') - COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) -} - _bitsend_cli() { local cur prev words=() cword local bitsend_cli @@ -50,7 +43,7 @@ _bitsend_cli() { COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) return 0 ;; - signrawtransaction) + signrawtransactionwithkey|signrawtransactionwithwallet) COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) return 0 ;; @@ -60,10 +53,9 @@ _bitsend_cli() { if ((cword > 3)); then case ${words[cword-3]} in addmultisigaddress) - _bitsend_accounts return 0 ;; - getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) + getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaddress|listsinceblock) COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) return 0 ;; @@ -80,14 +72,10 @@ _bitsend_cli() { COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) return 0 ;; - fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) + fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listreceivedbyaddress|sendrawtransaction) COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) return 0 ;; - move|setaccount) - _bitsend_accounts - return 0 - ;; esac fi @@ -96,12 +84,11 @@ _bitsend_cli() { _filedir return 0 ;; - getaddednodeinfo|getrawmempool|lockunspent|setgenerate) + getaddednodeinfo|getrawmempool|lockunspent) COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) return 0 ;; - getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) - _bitsend_accounts + getbalance|getnewaddress|listtransactions|sendmany) return 0 ;; esac diff --git a/contrib/bitsend-qt.pro b/contrib/bitsend-qt.pro old mode 100755 new mode 100644 index 7f33201c..0d95acf0 --- a/contrib/bitsend-qt.pro +++ b/contrib/bitsend-qt.pro @@ -16,6 +16,7 @@ FORMS += \ ../src/qt/forms/sendcoinsentry.ui \ ../src/qt/forms/signverifymessagedialog.ui \ ../src/qt/forms/transactiondescdialog.ui \ + ../src/qt/forms/createwalletdialog.ui RESOURCES += \ ../src/qt/bitsend.qrc diff --git a/contrib/bitsend-tx.bash-completion b/contrib/bitsend-tx.bash-completion old mode 100755 new mode 100644 index 15cba3c5..55fe3764 --- a/contrib/bitsend-tx.bash-completion +++ b/contrib/bitsend-tx.bash-completion @@ -1,5 +1,5 @@ # bash programmable completion for bitsend-tx(1) -# Copyright (c) 2016 The Bitsend Core developers +# Copyright (c) 2016 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/bitsendd.bash-completion b/contrib/bitsendd.bash-completion old mode 100755 new mode 100644 index f2e4de9f..04995dd0 --- a/contrib/bitsendd.bash-completion +++ b/contrib/bitsendd.bash-completion @@ -1,5 +1,5 @@ # bash programmable completion for bitsendd(1) and bitsend-qt(1) -# Copyright (c) 2012-2016 The Bitsend Core developers +# Copyright (c) 2012-2019 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,7 +15,7 @@ _bitsendd() { _get_comp_words_by_ref -n = cur prev words cword case "$cur" in - -conf=*|-pid=*|-loadblock=*|-rootcertificates=*|-rpccookiefile=*|-wallet=*) + -conf=*|-pid=*|-loadblock=*|-rpccookiefile=*|-wallet=*) cur="${cur#*=}" _filedir return 0 diff --git a/contrib/debian/copyright b/contrib/debian/copyright old mode 100755 new mode 100644 index 3065df13..293b2ca6 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -1,13 +1,13 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: Bitsend +Upstream-Name: BitSend Upstream-Contact: Satoshi Nakamoto irc://#bitsend@freenode.net -Source: https://github.com/bitcoin/bitcoin +Source: https://github.com/bitsend/bitsend Files: * -Copyright: 2009-2018, Bitsend Core Developers +Copyright: 2009-2020, BitSend Core Developers License: Expat -Comment: The Bitsend Core Developers encompasses the current developers listed on bitsend.cc, +Comment: The BitSend Core Developers encompasses the current developers listed on bitsend.org, as well as the numerous contributors to the project. Files: debian/* @@ -26,21 +26,14 @@ 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 @@ -60,7 +53,7 @@ Files: src/qt/res/icons/connect*.png 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 @@ -72,31 +65,27 @@ 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/tx_in*.png - src/qt/res/icons/verify.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/bitsend.* +Files: src/qt/res/icons/bitsend.* share/pixmaps/bitsend* src/qt/res/src/bitsend.svg Copyright: Bitboy, Jonas Schnelli License: public-domain -Comment: Site: https://bitcointalk.org/?topic=1756.0 +Comment: Site: https://bitsendtalk.org/?topic=1756.0 Files: src/qt/res/icons/proxy.png src/qt/res/src/proxy.svg Copyright: Cristian Mircea Messel -Licese: public-domain +License: public-domain License: Expat diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md old mode 100755 new mode 100644 index bbd9f602..384bc964 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -7,6 +7,8 @@ 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. + For instance, to format the last commit with 0 lines of context, the script should be called from the git root folder as follows. @@ -17,7 +19,7 @@ git diff -U0 HEAD~1.. | ./contrib/devtools/clang-format-diff.py -p1 -i -v copyright\_header.py ==================== -Provides utilities for managing copyright headers of `The Bitsend Core +Provides utilities for managing copyright headers of `The BitSend Core developers` in repository source files. It has three subcommands: ``` @@ -36,31 +38,31 @@ Specifying `verbose` will list the full filenames of files of each category. copyright\_header.py update \ [verbose] --------------------------------------------------------- -Updates all the copyright headers of `The Bitsend Core developers` which were +Updates all the copyright headers of `The BitSend Core developers` which were changed in a year more recent than is listed. For example: ``` -// Copyright (c) - The Bitsend Core developers +// Copyright (c) - The BitSend Core developers ``` will be updated to: ``` -// Copyright (c) - The Bitsend Core developers +// Copyright (c) - The BitSend 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 Bitsend Core developers +// Copyright (c) The BitSend Core developers ``` will be updated to: ``` -// Copyright (c) - The Bitsend Core developers +// Copyright (c) - The BitSend Core developers ``` where the update is appropriate. copyright\_header.py insert \ ------------------------------------ -Inserts a copyright header for `The Bitsend Core developers` at the top of the +Inserts a copyright header for `The BitSend 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. @@ -70,7 +72,7 @@ The copyright dates will be set to be `-` where `` 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 Bitsend Core developers`, the +If the file already has a copyright for `The BitSend Core developers`, the script will exit. gen-manpages.sh @@ -87,91 +89,35 @@ example: BUILDDIR=$PWD/build contrib/devtools/gen-manpages.sh ``` -github-merge.py -=============== - -A small script to automate merging pull-requests securely and sign them with GPG. - -For example: - - ./github-merge.py 3077 - -(in any git repository) will help you merge pull request #3077 for the -bitsend/bitsend repository. - -What it does: -* Fetch master and the pull request. -* Locally construct a merge commit. -* Show the diff that merge results in. -* Ask you to verify the resulting source tree (so you can do a make -check or whatever). -* Ask you whether to GPG sign the merge commit. -* Ask you whether to push the result upstream. - -This means that there are no potential race conditions (where a -pullreq gets updated while you're reviewing it, but before you click -merge), and when using GPG signatures, that even a compromised GitHub -couldn't mess with the sources. - -Setup ---------- -Configuring the github-merge tool for the bitsend repository is done in the following way: - - git config githubmerge.repository bitsend/bitsend - 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) - -Create and verify timestamps of merge commits ---------------------------------------------- -To create or verify timestamps on the merge commits, install the OpenTimestamps -client via `pip3 install opentimestamps-client`. Then, dowload the gpg wrapper -`ots-git-gpg-wrapper.sh` and set it as git's `gpg.program`. See -[the ots git integration documentation](https://github.com/opentimestamps/opentimestamps-client/blob/master/doc/git-integration.md#usage) -for further details. - -optimize-pngs.py -================ - -A script to optimize png files in the bitsend -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_bitsend: symbol memcpy from unsupported version GLIBC_2.14 .../64/test_bitsend: symbol __fdelt_chk from unsupported version GLIBC_2.15 .../64/test_bitsend: symbol std::out_of_range::~out_of_range() from unsupported version GLIBCXX_3.4.15 .../64/test_bitsend: symbol _ZNSt8__detail15_List_nod from unsupported version GLIBCXX_3.4.15 -update-translations.py -====================== - -Run this script from the root of the repository to update all translations from transifex. -It will do the following automatically: - -- fetch all translations -- post-process them into valid and committable format -- add missing translations to the build system (TODO) - -See doc/translation-process.md for more information. - circular-dependencies.py ======================== diff --git a/contrib/devtools/circular-dependencies.py b/contrib/devtools/circular-dependencies.py index abfa5ed5..4676b17c 100755 --- a/contrib/devtools/circular-dependencies.py +++ b/contrib/devtools/circular-dependencies.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# Copyright (c) 2018-2019 The BitSend 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 @@ -8,9 +11,18 @@ '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"): diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py index 77e845a9..98eee67f 100755 --- a/contrib/devtools/clang-format-diff.py +++ b/contrib/devtools/clang-format-diff.py @@ -106,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: @@ -119,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 diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py index 3e3e60a9..9e44dac4 100755 --- a/contrib/devtools/copyright_header.py +++ b/contrib/devtools/copyright_header.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016-2018 The Bitsend Core developers +# Copyright (c) 2016-2020 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,35 +15,36 @@ ################################################################################ EXCLUDE = [ - # libsecp256k1: - 'src/secp256k1/include/secp256k1.h', - 'src/secp256k1/include/secp256k1_ecdh.h', - 'src/secp256k1/include/secp256k1_recovery.h', - 'src/secp256k1/include/secp256k1_schnorr.h', - 'src/secp256k1/src/java/org_bitsend_NativeSecp256k1.c', - 'src/secp256k1/src/java/org_bitsend_NativeSecp256k1.h', - 'src/secp256k1/src/java/org_bitsend_Secp256k1Context.c', - 'src/secp256k1/src/java/org_bitsend_Secp256k1Context.h', - # univalue: - 'src/univalue/test/object.cpp', - 'src/univalue/lib/univalue_escapes.h', # auto generated: 'src/qt/bitsendstrings.cpp', 'src/chainparamsseeds.h', # other external copyrights: + 'src/reverse_iterator.h', + 'src/test/fuzz/FuzzedDataProvider.h', 'src/tinyformat.h', - 'src/leveldb/util/env_win.cc', - 'src/crypto/ctaes/bench.c', + '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])) -INCLUDE = ['*.h', '*.cpp', '*.cc', '*.c', '*.py'] +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)) @@ -51,15 +52,22 @@ def applies_to_file(filename): # obtain list of files in repo according to INCLUDE and EXCLUDE ################################################################################ -GIT_LS_CMD = 'git ls-files' +GIT_LS_CMD = 'git ls-files --full-name'.split(' ') +GIT_TOPLEVEL_CMD = 'git rev-parse --show-toplevel'.split(' ') -def call_git_ls(): - out = subprocess.check_output(GIT_LS_CMD.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 get_filenames_to_examine(): - filenames = call_git_ls() - return sorted([filename for filename in filenames if +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)]) ################################################################################ @@ -67,7 +75,7 @@ def get_filenames_to_examine(): ################################################################################ -COPYRIGHT_WITH_C = 'Copyright \(c\)' +COPYRIGHT_WITH_C = r'Copyright \(c\)' COPYRIGHT_WITHOUT_C = 'Copyright' ANY_COPYRIGHT_STYLE = '(%s|%s)' % (COPYRIGHT_WITH_C, COPYRIGHT_WITHOUT_C) @@ -81,32 +89,21 @@ def get_filenames_to_examine(): ANY_COPYRIGHT_COMPILED = re.compile(ANY_COPYRIGHT_STYLE_OR_YEAR_STYLE) def compile_copyright_regex(copyright_style, year_style, name): - return re.compile('%s %s %s' % (copyright_style, year_style, name)) + return re.compile(r'%s %s,? %s( +\*)?\n' % (copyright_style, year_style, name)) EXPECTED_HOLDER_NAMES = [ - "Satoshi Nakamoto\n", - "The Bitsend Core developers\n", - "The Bitsend Core developers \n", - "Bitsend Core Developers\n", - "the Bitsend Core developers\n", - "The Bitsend developers\n", - "The LevelDB Authors\. All rights reserved\.\n", - "BitPay Inc\.\n", - "BitPay, Inc\.\n", - "University of Illinois at Urbana-Champaign\.\n", - "MarcoFalke\n", - "Pieter Wuille\n", - "Pieter Wuille +\*\n", - "Pieter Wuille, Gregory Maxwell +\*\n", - "Pieter Wuille, Andrew Poelstra +\*\n", - "Andrew Poelstra +\*\n", - "Wladimir J. van der Laan\n", - "Jeff Garzik\n", - "Diederik Huys, Pieter Wuille +\*\n", - "Thomas Daede, Cory Fields +\*\n", - "Jan-Klaas Kollhof\n", - "Sam Rushing\n", - "ArtForz -- public domain half-a-node\n", + r"Satoshi Nakamoto", + r"The BitSend 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 = {} @@ -146,7 +143,7 @@ def file_has_without_c_style_copyright_for_holder(contents, holder_name): ################################################################################ def read_file(filename): - return open(os.path.abspath(filename), 'r', encoding="utf8").read() + return open(filename, 'r', encoding="utf8").read() def gather_file_info(filename): info = {} @@ -260,12 +257,9 @@ def print_report(file_infos, verbose): print(SEPARATOR) def exec_report(base_directory, verbose): - original_cwd = os.getcwd() - os.chdir(base_directory) - filenames = get_filenames_to_examine() + filenames = get_filenames_to_examine(base_directory) file_infos = [gather_file_info(f) for f in filenames] print_report(file_infos, verbose) - os.chdir(original_cwd) ################################################################################ # report cmd @@ -325,13 +319,13 @@ def get_most_recent_git_change_year(filename): ################################################################################ def read_file_lines(filename): - f = open(os.path.abspath(filename), 'r', encoding="utf8") + f = open(filename, 'r', encoding="utf8") file_lines = f.readlines() f.close() return file_lines def write_file_lines(filename, file_lines): - f = open(os.path.abspath(filename), 'w', encoding="utf8") + f = open(filename, 'w', encoding="utf8") f.write(''.join(file_lines)) f.close() @@ -339,10 +333,10 @@ def write_file_lines(filename, file_lines): # update header years execution ################################################################################ -COPYRIGHT = 'Copyright \(c\)' +COPYRIGHT = r'Copyright \(c\)' YEAR = "20[0-9][0-9]" YEAR_RANGE = '(%s)(-%s)?' % (YEAR, YEAR) -HOLDER = 'The Bitsend Core developers' +HOLDER = 'The BitSend Core developers' UPDATEABLE_LINE_COMPILED = re.compile(' '.join([COPYRIGHT, YEAR_RANGE, HOLDER])) def get_updatable_copyright_line(file_lines): @@ -399,35 +393,32 @@ def update_updatable_copyright(filename): "Copyright updated! -> %s" % last_git_change_year) def exec_update_header_year(base_directory): - original_cwd = os.getcwd() - os.chdir(base_directory) - for filename in get_filenames_to_examine(): + for filename in get_filenames_to_examine(base_directory): update_updatable_copyright(filename) - os.chdir(original_cwd) ################################################################################ # update cmd ################################################################################ UPDATE_USAGE = """ -Updates all the copyright headers of "The Bitsend Core developers" which were +Updates all the copyright headers of "The BitSend Core developers" which were changed in a year more recent than is listed. For example: -// Copyright (c) - The Bitsend Core developers +// Copyright (c) - The BitSend Core developers will be updated to: -// Copyright (c) - The Bitsend Core developers +// Copyright (c) - The BitSend 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 Bitsend Core developers +// Copyright (c) The BitSend Core developers will be updated to: -// Copyright (c) - The Bitsend Core developers +// Copyright (c) - The BitSend Core developers where the update is appropriate. @@ -460,7 +451,7 @@ def get_header_lines(header, start_year, end_year): return [line + '\n' for line in lines] CPP_HEADER = ''' -// Copyright (c) %s The Bitsend Core developers +// Copyright (c) %s The BitSend Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' @@ -468,14 +459,14 @@ def get_header_lines(header, start_year, end_year): def get_cpp_header_lines_to_insert(start_year, end_year): return reversed(get_header_lines(CPP_HEADER, start_year, end_year)) -PYTHON_HEADER = ''' -# Copyright (c) %s The Bitsend Core developers +SCRIPT_HEADER = ''' +# Copyright (c) %s The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' -def get_python_header_lines_to_insert(start_year, end_year): - return reversed(get_header_lines(PYTHON_HEADER, start_year, end_year)) +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 @@ -491,7 +482,7 @@ def get_git_change_year_range(filename): def file_already_has_core_copyright(file_lines): index, _ = get_updatable_copyright_line(file_lines) - return index != None + return index is not None ################################################################################ # insert header execution @@ -504,17 +495,18 @@ def file_has_hashbang(file_lines): return False return file_lines[0][:2] == '#!' -def insert_python_header(filename, file_lines, start_year, end_year): +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_python_header_lines_to_insert(start_year, end_year) + 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) @@ -523,11 +515,11 @@ def insert_cpp_header(filename, file_lines, start_year, end_year): 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 Bitsend Core developers' + sys.exit('*** %s already has a copyright by The BitSend Core developers' % (filename)) start_year, end_year = get_git_change_year_range(filename) - if style == 'python': - insert_python_header(filename, file_lines, start_year, end_year) + 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) @@ -536,7 +528,7 @@ def exec_insert_header(filename, style): ################################################################################ INSERT_USAGE = """ -Inserts a copyright header for "The Bitsend Core developers" at the top of the +Inserts a copyright header for "The BitSend 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. @@ -550,7 +542,7 @@ def exec_insert_header(filename, style): "" -If the file already has a copyright for "The Bitsend Core developers", the +If the file already has a copyright for "The BitSend Core developers", the script will exit. Usage: @@ -568,11 +560,13 @@ def insert_cmd(argv): 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']: + 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) @@ -582,7 +576,7 @@ def insert_cmd(argv): ################################################################################ USAGE = """ -copyright_header.py - utilities for managing copyright headers of 'The Bitsend +copyright_header.py - utilities for managing copyright headers of 'The BitSend Core developers' in repository source files. Usage: diff --git a/contrib/devtools/gen-manpages.sh b/contrib/devtools/gen-manpages.sh index 7c3b4957..e2d4326d 100755 --- a/contrib/devtools/gen-manpages.sh +++ b/contrib/devtools/gen-manpages.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# Copyright (c) 2016-2019 The BitSend 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)} @@ -10,12 +13,13 @@ MANDIR=${MANDIR:-$TOPDIR/doc/man} BITSENDD=${BITSENDD:-$BINDIR/bitsendd} BITSENDCLI=${BITSENDCLI:-$BINDIR/bitsend-cli} BITSENDTX=${BITSENDTX:-$BINDIR/bitsend-tx} +WALLET_TOOL=${WALLET_TOOL:-$BINDIR/bitsend-wallet} BITSENDQT=${BITSENDQT:-$BINDIR/qt/bitsend-qt} [ ! -x $BITSENDD ] && echo "$BITSENDD not found or not executable." && exit 1 # The autodetected version git tag can screw up manpage output a little bit -BTCVER=($($BITSENDCLI --version | head -n1 | awk -F'[ -]' '{ print $6, $7 }')) +read -r -a BTCVER <<< "$($BITSENDCLI --version | head -n1 | awk -F'[ -]' '{ print $6, $7 }')" # Create a footer file with copyright content. # This gets autodetected fine for bitsendd if --version-string is not set, @@ -23,7 +27,7 @@ BTCVER=($($BITSENDCLI --version | head -n1 | awk -F'[ -]' '{ print $6, $7 }')) echo "[COPYRIGHT]" > footer.h2m $BITSENDD --version | sed -n '1!p' >> footer.h2m -for cmd in $BITSENDD $BITSENDCLI $BITSENDTX $BITSENDQT; do +for cmd in $BITSENDD $BITSENDCLI $BITSENDTX $WALLET_TOOL $BITSENDQT; 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 diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py deleted file mode 100755 index 0bf9384f..00000000 --- a/contrib/devtools/github-merge.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2016-2017 Bitsend Core Developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# This script will locally construct a merge commit for a pull request on a -# github repository, inspect it, sign it and optionally push it. - -# The following temporary branches are created/overwritten and deleted: -# * pull/$PULL/base (the current master we're merging onto) -# * pull/$PULL/head (the current state of the remote pull request) -# * pull/$PULL/merge (github's merge) -# * pull/$PULL/local-merge (our merge) - -# In case of a clean merge that is accepted by the user, the local branch with -# name $BRANCH is overwritten with the merged result, and optionally pushed. -from __future__ import division,print_function,unicode_literals -import os -from sys import stdin,stdout,stderr -import argparse -import hashlib -import subprocess -import sys -import json -import codecs -try: - from urllib.request import Request,urlopen -except: - from urllib2 import Request,urlopen - -# External tools (can be overridden using environment) -GIT = os.getenv('GIT','git') -BASH = os.getenv('BASH','bash') - -# OS specific configuration for terminal attributes -ATTR_RESET = '' -ATTR_PR = '' -COMMIT_FORMAT = '%h %s (%an)%d' -if os.name == 'posix': # if posix, assume we can use basic terminal escapes - ATTR_RESET = '\033[0m' - ATTR_PR = '\033[1;36m' - COMMIT_FORMAT = '%C(bold blue)%h%Creset %s %C(cyan)(%an)%Creset%C(green)%d%Creset' - -def git_config_get(option, default=None): - ''' - Get named configuration option from git repository. - ''' - try: - return subprocess.check_output([GIT,'config','--get',option]).rstrip().decode('utf-8') - except subprocess.CalledProcessError: - return default - -def retrieve_pr_info(repo,pull): - ''' - Retrieve pull request information from github. - Return None if no title can be found, or an error happens. - ''' - try: - req = Request("https://api.github.com/repos/"+repo+"/pulls/"+pull) - result = urlopen(req) - reader = codecs.getreader('utf-8') - obj = json.load(reader(result)) - return obj - except Exception as e: - print('Warning: unable to retrieve pull information from github: %s' % e) - return None - -def ask_prompt(text): - print(text,end=" ",file=stderr) - stderr.flush() - reply = stdin.readline().rstrip() - print("",file=stderr) - return reply - -def get_symlink_files(): - files = sorted(subprocess.check_output([GIT, 'ls-tree', '--full-tree', '-r', 'HEAD']).splitlines()) - ret = [] - for f in files: - if (int(f.decode('utf-8').split(" ")[0], 8) & 0o170000) == 0o120000: - ret.append(f.decode('utf-8').split("\t")[1]) - return ret - -def tree_sha512sum(commit='HEAD'): - # 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 print_merge_details(pull, title, branch, base_branch, head_branch): - print('%s#%s%s %s %sinto %s%s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title,ATTR_RESET+ATTR_PR,branch,ATTR_RESET)) - subprocess.check_call([GIT,'log','--graph','--topo-order','--pretty=format:'+COMMIT_FORMAT,base_branch+'..'+head_branch]) - -def parse_arguments(): - epilog = ''' - In addition, you can set the following git configuration variables: - githubmerge.repository (mandatory), - user.signingkey (mandatory), - githubmerge.host (default: git@github.com), - githubmerge.branch (no default), - githubmerge.testcmd (default: none). - ''' - parser = argparse.ArgumentParser(description='Utility to merge, sign and push github pull requests', - epilog=epilog) - parser.add_argument('pull', metavar='PULL', type=int, nargs=1, - help='Pull request ID to merge') - parser.add_argument('branch', metavar='BRANCH', type=str, nargs='?', - default=None, help='Branch to merge against (default: githubmerge.branch setting, or base branch for pull, or \'master\')') - return parser.parse_args() - -def main(): - # Extract settings from git repo - repo = git_config_get('githubmerge.repository') - host = git_config_get('githubmerge.host','git@github.com') - opt_branch = git_config_get('githubmerge.branch',None) - testcmd = git_config_get('githubmerge.testcmd') - signingkey = git_config_get('user.signingkey') - if repo is None: - print("ERROR: No repository configured. Use this command to set:", file=stderr) - print("git config githubmerge.repository /", file=stderr) - sys.exit(1) - if signingkey is None: - print("ERROR: No GPG signing key set. Set one using:",file=stderr) - print("git config --global user.signingkey ",file=stderr) - sys.exit(1) - - host_repo = host+":"+repo # shortcut for push/pull target - - # Extract settings from command line - args = parse_arguments() - pull = str(args.pull[0]) - - # Receive pull information from github - info = retrieve_pr_info(repo,pull) - if info is None: - sys.exit(1) - title = info['title'].strip() - body = info['body'].strip() - # precedence order for destination branch argument: - # - command line argument - # - githubmerge.branch setting - # - base branch for pull (as retrieved from github) - # - 'master' - branch = args.branch or opt_branch or info['base']['ref'] or 'master' - - # Initialize source branches - head_branch = 'pull/'+pull+'/head' - base_branch = 'pull/'+pull+'/base' - merge_branch = 'pull/'+pull+'/merge' - local_merge_branch = 'pull/'+pull+'/local-merge' - - devnull = open(os.devnull, 'w', encoding="utf8") - try: - subprocess.check_call([GIT,'checkout','-q',branch]) - except subprocess.CalledProcessError: - print("ERROR: Cannot check out branch %s." % (branch), file=stderr) - sys.exit(3) - try: - subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/pull/'+pull+'/*:refs/heads/pull/'+pull+'/*', - '+refs/heads/'+branch+':refs/heads/'+base_branch]) - except subprocess.CalledProcessError: - print("ERROR: Cannot find pull request #%s or branch %s on %s." % (pull,branch,host_repo), file=stderr) - sys.exit(3) - try: - subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+head_branch], stdout=devnull, stderr=stdout) - except subprocess.CalledProcessError: - print("ERROR: Cannot find head of pull request #%s on %s." % (pull,host_repo), file=stderr) - sys.exit(3) - try: - subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+merge_branch], stdout=devnull, stderr=stdout) - except subprocess.CalledProcessError: - print("ERROR: Cannot find merge of pull request #%s on %s." % (pull,host_repo), file=stderr) - sys.exit(3) - subprocess.check_call([GIT,'checkout','-q',base_branch]) - subprocess.call([GIT,'branch','-q','-D',local_merge_branch], stderr=devnull) - subprocess.check_call([GIT,'checkout','-q','-b',local_merge_branch]) - - try: - # Go up to the repository's root. - toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip() - os.chdir(toplevel) - # Create unsigned merge commit. - if title: - firstline = 'Merge #%s: %s' % (pull,title) - else: - firstline = 'Merge #%s' % (pull,) - message = firstline + '\n\n' - message += subprocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%h %s (%an)',base_branch+'..'+head_branch]).decode('utf-8') - message += '\n\nPull request description:\n\n ' + body.replace('\n', '\n ') + '\n' - try: - subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','-m',message.encode('utf-8'),head_branch]) - except subprocess.CalledProcessError: - print("ERROR: Cannot be merged cleanly.",file=stderr) - subprocess.check_call([GIT,'merge','--abort']) - sys.exit(4) - logmsg = subprocess.check_output([GIT,'log','--pretty=format:%s','-n','1']).decode('utf-8') - if logmsg.rstrip() != firstline.rstrip(): - print("ERROR: Creating merge failed (already merged?).",file=stderr) - sys.exit(4) - - symlink_files = get_symlink_files() - for f in symlink_files: - print("ERROR: File %s was a symlink" % f) - if len(symlink_files) > 0: - sys.exit(4) - - # Put tree SHA512 into the message - try: - first_sha512 = tree_sha512sum() - message += '\n\nTree-SHA512: ' + first_sha512 - except subprocess.CalledProcessError: - print("ERROR: Unable to compute tree hash") - sys.exit(4) - try: - subprocess.check_call([GIT,'commit','--amend','-m',message.encode('utf-8')]) - except subprocess.CalledProcessError: - print("ERROR: Cannot update message.", file=stderr) - sys.exit(4) - - print_merge_details(pull, title, branch, base_branch, head_branch) - print() - - # Run test command if configured. - if testcmd: - if subprocess.call(testcmd,shell=True): - print("ERROR: Running %s failed." % testcmd,file=stderr) - sys.exit(5) - - # Show the created merge. - diff = subprocess.check_output([GIT,'diff',merge_branch+'..'+local_merge_branch]) - subprocess.check_call([GIT,'diff',base_branch+'..'+local_merge_branch]) - if diff: - print("WARNING: merge differs from github!",file=stderr) - reply = ask_prompt("Type 'ignore' to continue.") - if reply.lower() == 'ignore': - print("Difference with github ignored.",file=stderr) - else: - sys.exit(6) - else: - # Verify the result manually. - print("Dropping you on a shell so you can try building/testing the merged source.",file=stderr) - print("Run 'git diff HEAD~' to show the changes being merged.",file=stderr) - print("Type 'exit' when done.",file=stderr) - if os.path.isfile('/etc/debian_version'): # Show pull number on Debian default prompt - os.putenv('debian_chroot',pull) - subprocess.call([BASH,'-i']) - - second_sha512 = tree_sha512sum() - if first_sha512 != second_sha512: - print("ERROR: Tree hash changed unexpectedly",file=stderr) - sys.exit(8) - - # Sign the merge commit. - print_merge_details(pull, title, branch, base_branch, head_branch) - while True: - reply = ask_prompt("Type 's' to sign off on the above merge, or 'x' to reject and exit.").lower() - if reply == 's': - try: - subprocess.check_call([GIT,'commit','-q','--gpg-sign','--amend','--no-edit']) - break - except subprocess.CalledProcessError: - print("Error while signing, asking again.",file=stderr) - elif reply == 'x': - print("Not signing off on merge, exiting.",file=stderr) - sys.exit(1) - - # Put the result in branch. - subprocess.check_call([GIT,'checkout','-q',branch]) - subprocess.check_call([GIT,'reset','-q','--hard',local_merge_branch]) - finally: - # Clean up temporary branches. - subprocess.call([GIT,'checkout','-q',branch]) - subprocess.call([GIT,'branch','-q','-D',head_branch],stderr=devnull) - subprocess.call([GIT,'branch','-q','-D',base_branch],stderr=devnull) - subprocess.call([GIT,'branch','-q','-D',merge_branch],stderr=devnull) - subprocess.call([GIT,'branch','-q','-D',local_merge_branch],stderr=devnull) - - # Push the result. - while True: - reply = ask_prompt("Type 'push' to push the result to %s, branch %s, or 'x' to exit without pushing." % (host_repo,branch)).lower() - if reply == 'push': - subprocess.check_call([GIT,'push',host_repo,'refs/heads/'+branch]) - break - elif reply == 'x': - sys.exit(1) - -if __name__ == '__main__': - main() - diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py deleted file mode 100755 index 6c5b6de3..00000000 --- a/contrib/devtools/optimize-pngs.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2014-2018 The Bitsend Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' -Run this script every time you change one of the png files. Using pngcrush, it will optimize the png files, remove various color profiles, remove ancillary chunks (alla) and text chunks (text). -#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text -''' -import os -import sys -import subprocess -import hashlib -from PIL import Image # pip3 install Pillow - -def file_hash(filename): - '''Return hash of raw file contents''' - with open(filename, 'rb') as f: - return hashlib.sha256(f.read()).hexdigest() - -def content_hash(filename): - '''Return hash of RGBA contents of image''' - i = Image.open(filename) - i = i.convert('RGBA') - data = i.tobytes() - return hashlib.sha256(data).hexdigest() - -pngcrush = 'pngcrush' -git = 'git' -folders = ["src/qt/res/movies", "src/qt/res/icons", "share/pixmaps"] -basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel'], universal_newlines=True).rstrip('\n') -totalSaveBytes = 0 -noHashChange = True - -outputArray = [] -for folder in folders: - absFolder=os.path.join(basePath, folder) - for file in os.listdir(absFolder): - extension = os.path.splitext(file)[1] - if extension.lower() == '.png': - print("optimizing {}...".format(file), end =' ') - file_path = os.path.join(absFolder, file) - fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)} - fileMetaMap['contentHashPre'] = content_hash(file_path) - - try: - subprocess.call([pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path], - stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - except: - print("pngcrush is not installed, aborting...") - sys.exit(0) - - #verify - if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT, universal_newlines=True): - print("PNG file "+file+" is corrupted after crushing, check out pngcursh version") - sys.exit(1) - - fileMetaMap['sha256New'] = file_hash(file_path) - fileMetaMap['contentHashPost'] = content_hash(file_path) - - if fileMetaMap['contentHashPre'] != fileMetaMap['contentHashPost']: - print("Image contents of PNG file {} before and after crushing don't match".format(file)) - sys.exit(1) - - fileMetaMap['psize'] = os.path.getsize(file_path) - outputArray.append(fileMetaMap) - print("done") - -print("summary:\n+++++++++++++++++") -for fileDict in outputArray: - oldHash = fileDict['sha256Old'] - newHash = fileDict['sha256New'] - totalSaveBytes += fileDict['osize'] - fileDict['psize'] - noHashChange = noHashChange and (oldHash == newHash) - print(fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n") - -print("completed. Checksum stable: "+str(noHashChange)+". Total reduction: "+str(totalSaveBytes)+" bytes") diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index c75c4a6a..84740cd7 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -1,188 +1,336 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2018 The Bitsend Core developers +# Copyright (c) 2015-2020 The BitSend 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). +Needs `readelf` (for ELF), `objdump` (for PE) and `otool` (for MACHO). ''' 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 = {} # checks which are non-fatal for now but only generate a warning +OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool') + +def run_command(command) -> str: + p = subprocess.run(command, stdout=subprocess.PIPE, check=True, universal_newlines=True) + return p.stdout -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, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') + stdout = run_command([READELF_CMD, '-h', '-W', executable]) ok = False for line in stdout.splitlines(): - line = line.split() - if len(line)>=2 and line[0] == 'Type:' and line[1] == 'DYN': + tokens = line.split() + if len(line)>=2 and tokens[0] == 'Type:' and tokens[1] == '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, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') + stdout = run_command([READELF_CMD, '-l', '-W', executable]) + in_headers = False - count = 0 headers = [] for line in stdout.splitlines(): if line.startswith('Program Headers:'): in_headers = True + count = 0 if line == '': in_headers = False if in_headers: if count == 1: # header line - ofs_typ = line.find('Type') - ofs_offset = line.find('Offset') - ofs_flags = line.find('Flg') - ofs_align = line.find('Align') - if ofs_typ == -1 or ofs_offset == -1 or ofs_flags == -1 or ofs_align == -1: + header = [x.strip() for x in line.split()] + ofs_typ = header.index('Type') + ofs_flags = header.index('Flg') + # assert readelf output is what we expect + if ofs_typ == -1 or ofs_flags == -1: + raise ValueError('Cannot parse elfread -lW output') + elif count > 1: + splitline = [x.strip() for x in line.split()] + typ = splitline[ofs_typ] + if not typ.startswith('[R'): # skip [Requesting ...] + splitline = [x.strip() for x in line.split()] + flags = splitline[ofs_flags] + # check for 'R', ' E' + if splitline[ofs_flags + 1] == 'E': + flags += ' E' + headers.append((typ, flags, [])) + count += 1 + + if line.startswith(' Section to Segment mapping:'): + in_mapping = True + count = 0 + if line == '': + in_mapping = False + if in_mapping: + if count == 1: # header line + ofs_segment = line.find('Segment') + ofs_sections = line.find('Sections...') + if ofs_segment == -1 or ofs_sections == -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)) + segment = int(line[ofs_segment:ofs_sections].strip()) + sections = line[ofs_sections:].strip().split() + headers[segment][2].extend(sections) 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) ''' have_wx = False have_gnu_stack = False - for (typ, flags) in get_ELF_program_headers(executable): + for (typ, flags, _) in get_ELF_program_headers(executable): if typ == 'GNU_STACK': have_gnu_stack = True if 'W' in flags and 'E' in flags: # 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 ''' have_gnu_relro = False - for (typ, flags) in get_ELF_program_headers(executable): + 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. + # 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 + # See also https://marc.info/?l=binutils&m=1498883354122353 if typ == '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, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') + stdout = run_command([READELF_CMD, '-d', '-W', executable]) + for line in stdout.splitlines(): tokens = line.split() if len(tokens)>1 and tokens[1] == '(BIND_NOW)' or (len(tokens)>2 and tokens[1] == '(FLAGS)' and 'BIND_NOW' in tokens[2:]): 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, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') + stdout = run_command([READELF_CMD, '--dyn-syms', '-W', executable]) + ok = False for line in stdout.splitlines(): if '__stack_chk_fail' in line: ok = True return ok -def get_PE_dll_characteristics(executable): +def check_ELF_separate_code(executable): ''' - Get PE DllCharacteristics bits. - Returns a tuple (arch,bits) where arch is 'i386:x86-64' or 'i386' - and bits is the DllCharacteristics value. + 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. ''' - p = subprocess.Popen([OBJDUMP_CMD, '-x', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') - arch = '' + EXPECTED_FLAGS = { + # Read + execute + '.init': 'R E', + '.plt': 'R E', + '.plt.got': 'R E', + '.plt.sec': 'R E', + '.text': 'R E', + '.fini': 'R E', + # Read-only data + '.interp': 'R', + '.note.gnu.property': 'R', + '.note.gnu.build-id': 'R', + '.note.ABI-tag': 'R', + '.gnu.hash': 'R', + '.dynsym': 'R', + '.dynstr': 'R', + '.gnu.version': 'R', + '.gnu.version_r': 'R', + '.rela.dyn': 'R', + '.rela.plt': 'R', + '.rodata': 'R', + '.eh_frame_hdr': 'R', + '.eh_frame': 'R', + '.qtmetadata': 'R', + '.gcc_except_table': 'R', + '.stapsdt.base': 'R', + # Writable data + '.init_array': 'RW', + '.fini_array': 'RW', + '.dynamic': 'RW', + '.got': 'RW', + '.data': 'RW', + '.bss': 'RW', + } + # 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 (typ, flags, sections) in get_ELF_program_headers(executable): + if typ == 'LOAD': + for section in sections: + assert(section not in flags_per_section) + flags_per_section[section] = 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 get_PE_dll_characteristics(executable) -> int: + '''Get PE DllCharacteristics bits''' + stdout = run_command([OBJDUMP_CMD, '-x', executable]) + bits = 0 for line in stdout.splitlines(): 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) + return 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_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 + bits = get_PE_dll_characteristics(executable) + return (bits & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE) == IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE -# 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): + bits = get_PE_dll_characteristics(executable) + return (bits & IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA) == IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA + +def check_PE_RELOC_SECTION(executable) -> bool: + '''Check for a reloc section. This is required for functional ASLR.''' + stdout = run_command([OBJDUMP_CMD, '-h', executable]) + + for line in stdout.splitlines(): + if '.reloc' in line: + return True + return False + +def check_PE_NX(executable) -> bool: '''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)''' - (arch,bits) = get_PE_dll_characteristics(executable) + bits = get_PE_dll_characteristics(executable) return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT +def get_MACHO_executable_flags(executable) -> List[str]: + stdout = run_command([OTOOL_CMD, '-vh', executable]) + + flags = [] + for line in stdout.splitlines(): + tokens = line.split() + # filter first two header lines + if 'magic' in tokens or 'Mach' in tokens: + continue + # filter ncmds and sizeofcmds values + flags += [t for t in tokens if not t.isdigit()] + return flags + +def check_MACHO_PIE(executable) -> bool: + ''' + Check for position independent executable (PIE), allowing for address space randomization. + ''' + flags = get_MACHO_executable_flags(executable) + if 'PIE' in flags: + return True + return False + +def check_MACHO_NOUNDEFS(executable) -> bool: + ''' + Check for no undefined references. + ''' + flags = get_MACHO_executable_flags(executable) + if 'NOUNDEFS' in flags: + return True + return False + +def check_MACHO_NX(executable) -> bool: + ''' + Check for no stack execution + ''' + flags = get_MACHO_executable_flags(executable) + if 'ALLOW_STACK_EXECUTION' in flags: + return False + return True + +def check_MACHO_LAZY_BINDINGS(executable) -> bool: + ''' + Check for no lazy bindings. + We don't use or check for MH_BINDATLOAD. See #18295. + ''' + stdout = run_command([OTOOL_CMD, '-l', executable]) + + for line in stdout.splitlines(): + tokens = line.split() + if 'lazy_bind_off' in tokens or 'lazy_bind_size' in tokens: + if tokens[1] != '0': + return False + return True + +def check_MACHO_Canary(executable) -> bool: + ''' + Check for use of stack canary + ''' + stdout = run_command([OTOOL_CMD, '-Iv', executable]) + + ok = False + for line in stdout.splitlines(): + if '___stack_chk_fail' in line: + ok = True + return ok + 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': [ ('DYNAMIC_BASE', check_PE_DYNAMIC_BASE), ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), - ('NX', check_PE_NX) + ('NX', check_PE_NX), + ('RELOC_SECTION', check_PE_RELOC_SECTION) +], +'MACHO': [ + ('PIE', check_MACHO_PIE), + ('NOUNDEFS', check_MACHO_NOUNDEFS), + ('NX', check_MACHO_NX), + ('LAZY_BINDINGS', check_MACHO_LAZY_BINDINGS), + ('Canary', check_MACHO_Canary) ] } -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__': @@ -196,18 +344,12 @@ def identify_executable(executable): continue failed = [] - warning = [] 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))) retval = 1 - if warning: - print('%s: warning %s' % (filename, ' '.join(warning))) except IOError: print('%s: cannot open' % filename) retval = 1 diff --git a/contrib/devtools/split-debug.sh.in b/contrib/devtools/split-debug.sh.in old mode 100755 new mode 100644 index deda49cc..92b72b14 --- 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 89912c42..9df68a95 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -3,72 +3,123 @@ # 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 the executables produced by gitian 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 ../gitian-builder/build -type f -executable | xargs python3 contrib/devtools/symbol-check.py ''' import subprocess import re import sys import os +from typing import List, Optional, Tuple -# Debian 6.0.9 (Squeeze) has: +# Debian 8 (Jessie) EOL: 2020. https://wiki.debian.org/DebianReleases#Production_Releases # -# - 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) +# - 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) # -# Ubuntu 10.04.4 (Lucid Lynx) has: +# Ubuntu 16.04 (Xenial) EOL: 2024. https://wiki.ubuntu.com/Releases # -# - 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) +# - 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) +# +# 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': (2,17), +'LIBATOMIC': (1,0) } # 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 = { -'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr' +'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__', '__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr', +'environ', '_environ', '__environ', } READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') +OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump') +OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool') + # Allowed NEEDED libraries -ALLOWED_LIBRARIES = { +ELF_ALLOWED_LIBRARIES = { # bitsendd and bitsend-qt 'libgcc_s.so.1', # GCC base support 'libc.so.6', # C library 'libpthread.so.0', # threading -'libanl.so.1', # DNS resolve '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 +'ld-linux-riscv64-lp64d.so.1', # 64-bit RISC-V dynamic linker # bitsend-qt only -'libX11-xcb.so.1', # part of X11 -'libX11.so.6', # part of X11 'libxcb.so.1', # part of X11 'libfontconfig.so.1', # font support 'libfreetype.so.6', # font parsing 'libdl.so.2' # programming interface to dynamic linker } +ARCH_MIN_GLIBC_VER = { +'80386': (2,1), +'X86-64': (2,2,5), +'ARM': (2,4), +'AArch64':(2,17), +'RISC-V': (2,27) +} + +MACHO_ALLOWED_LIBRARIES = { +# bitsendd and bitsend-qt +'libc++.1.dylib', # C++ Standard Library +'libSystem.B.dylib', # libc, libm, libpthread, libinfo +# bitsend-qt only +'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. +'Foundation', # base layer functionality for apps/frameworks +'ImageIO', # read and write image file formats. +'IOKit', # user-space access to hardware devices and drivers. +'libobjc.A.dylib', # Objective-C runtime library +} + +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 +# bitsend-qt only +'dwmapi.dll', # desktop window manager +'GDI32.dll', # graphics device interface +'IMM32.dll', # input method editor +'ole32.dll', # component object model +'OLEAUT32.dll', # OLE Automation API +'SHLWAPI.dll', # light weight shell API +'UxTheme.dll', +'VERSION.dll', # version checking +'WINMM.dll', # WinMM audio API +} class CPPFilt(object): ''' @@ -89,28 +140,30 @@ def close(self): self.proc.stdout.close() self.proc.wait() -def read_symbols(executable, imports=True): +def read_symbols(executable, imports=True) -> List[Tuple[str, str, str]]: ''' - Parse an ELF executable and return a list of (symbol,version) tuples + Parse an ELF executable and return a list of (symbol,version, arch) tuples for dynamic, imported symbols. ''' - p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) + p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', '-h', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) (stdout, stderr) = p.communicate() if p.returncode: - raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip())) + raise IOError('Could not read symbols for {}: {}'.format(executable, stderr.strip())) syms = [] for line in stdout.splitlines(): line = line.split() + if 'Machine:' in line: + arch = line[-1] if len(line)>7 and re.match('[0-9]+:$', line[0]): (sym, _, version) = line[7].partition('@') is_import = line[6] == 'UND' if version.startswith('@'): version = version[1:] if is_import == imports: - syms.append((sym, version)) + syms.append((sym, version, arch)) return syms -def check_version(max_versions, version): +def check_version(max_versions, version, arch) -> bool: if '_' in version: (lib, _, ver) = version.rpartition('_') else: @@ -119,9 +172,9 @@ def check_version(max_versions, version): ver = tuple([int(x) for x in ver.split('.')]) if not lib in max_versions: return False - return ver <= max_versions[lib] + return ver <= max_versions[lib] or lib == 'GLIBC' and ver <= ARCH_MIN_GLIBC_VER[arch] -def read_libraries(filename): +def elf_read_libraries(filename) -> List[str]: p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) (stdout, stderr) = p.communicate() if p.returncode: @@ -130,34 +183,124 @@ def read_libraries(filename): for line in stdout.splitlines(): tokens = line.split() if len(tokens)>2 and tokens[1] == '(NEEDED)': - match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) + match = re.match(r'^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) if match: libraries.append(match.group(1)) else: raise ValueError('Unparseable (NEEDED) specification') return libraries -if __name__ == '__main__': +def check_imported_symbols(filename) -> bool: + cppfilt = CPPFilt() + ok = True + for sym, version, arch in read_symbols(filename, True): + if version and not check_version(MAX_VERSIONS, version, arch): + print('{}: symbol {} from unsupported version {}'.format(filename, cppfilt(sym), version)) + ok = False + return ok + +def check_exported_symbols(filename) -> bool: cppfilt = CPPFilt() + ok = True + for sym,version,arch in read_symbols(filename, False): + if arch == 'RISC-V' 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 = True + for library_name in elf_read_libraries(filename): + if library_name not in ELF_ALLOWED_LIBRARIES: + print('{}: NEEDED library {} is not allowed'.format(filename, library_name)) + ok = False + return ok + +def macho_read_libraries(filename) -> List[str]: + p = subprocess.Popen([OTOOL_CMD, '-L', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + libraries = [] + for line in stdout.splitlines(): + tokens = line.split() + if len(tokens) == 1: # skip executable name + continue + libraries.append(tokens[0].split('/')[-1]) + return libraries + +def check_MACHO_libraries(filename) -> bool: + ok = True + for dylib in macho_read_libraries(filename): + if dylib not in MACHO_ALLOWED_LIBRARIES: + print('{} is not in ALLOWED_LIBRARIES!'.format(dylib)) + ok = False + return ok + +def pe_read_libraries(filename) -> List[str]: + p = subprocess.Popen([OBJDUMP_CMD, '-x', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + libraries = [] + for line in stdout.splitlines(): + if 'DLL Name:' in line: + tokens = line.split(': ') + libraries.append(tokens[1]) + return libraries + +def check_PE_libraries(filename) -> bool: + ok = True + for dylib in pe_read_libraries(filename): + if dylib not in PE_ALLOWED_LIBRARIES: + print('{} is not in ALLOWED_LIBRARIES!'.format(dylib)) + ok = False + return ok + +CHECKS = { +'ELF': [ + ('IMPORTED_SYMBOLS', check_imported_symbols), + ('EXPORTED_SYMBOLS', check_exported_symbols), + ('LIBRARY_DEPENDENCIES', check_ELF_libraries) +], +'MACHO': [ + ('DYNAMIC_LIBRARIES', check_MACHO_libraries) +], +'PE' : [ + ('DYNAMIC_LIBRARIES', check_PE_libraries) +] +} + +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 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), version)) + try: + etype = identify_executable(filename) + if etype is None: + print('{}: unknown format'.format(filename)) 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))) - 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)) - retval = 1 + failed = [] + for (name, func) in CHECKS[etype]: + if not func(filename): + failed.append(name) + if failed: + print('{}: failed {}'.format(filename, ' '.join(failed))) + retval = 1 + except IOError: + print('{}: cannot open'.format(filename)) + retval = 1 sys.exit(retval) - - diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index bde30ba7..cca4219e 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2018 The Bitsend Core developers +# Copyright (c) 2015-2020 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' @@ -20,10 +20,9 @@ def write_testcode(filename): ''') 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, universal_newlines=True) - (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): @@ -32,39 +31,54 @@ def test_ELF(self): cc = 'gcc' write_testcode(source) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE']), + 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','-no-pie','-fno-PIE']), + 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','-no-pie','-fno-PIE']), + 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, '')) - def test_32bit_PE(self): + def test_PE(self): source = 'test1.c' executable = 'test1.exe' - cc = 'i686-w64-mingw32-gcc' + cc = 'x86_64-w64-mingw32-gcc' write_testcode(source) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--no-dynamicbase']), - (1, executable+': failed DYNAMIC_BASE NX')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--no-dynamicbase']), - (1, executable+': failed DYNAMIC_BASE')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase']), - (0, '')) - def test_64bit_PE(self): + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']), + (1, executable+': failed DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']), + (1, executable+': failed DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']), + (1, executable+': failed HIGH_ENTROPY_VA RELOC_SECTION')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--high-entropy-va','-no-pie','-fno-PIE']), + (1, executable+': failed RELOC_SECTION')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE']), + (0, '')) + + def test_MACHO(self): source = 'test1.c' - executable = 'test1.exe' - cc = 'x86_64-w64-mingw32-gcc' + executable = 'test1' + cc = 'clang' write_testcode(source) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va']), (1, executable+': failed DYNAMIC_BASE HIGH_ENTROPY_VA NX')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va']), (1, executable+': failed DYNAMIC_BASE HIGH_ENTROPY_VA')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--no-high-entropy-va']), (1, executable+': failed HIGH_ENTROPY_VA')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--high-entropy-va']), (0, '')) + 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')) + 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')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fstack-protector-all']), + (1, executable+': failed PIE NOUNDEFS LAZY_BINDINGS')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all']), + (1, executable+': failed PIE LAZY_BINDINGS')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all']), + (1, executable+': failed PIE')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-Wl,-bind_at_load','-fstack-protector-all']), + (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 00000000..b89231f7 --- /dev/null +++ b/contrib/devtools/test_deterministic_coverage.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019-2020 The BitSend 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_BITSEND_BINARY="src/test/test_bitsend" + +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_BITSEND_BINARY} ]]; then + echo "Error: Executable ${TEST_BITSEND_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_BITSEND_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/update-translations.py b/contrib/devtools/update-translations.py deleted file mode 100755 index d0ec697e..00000000 --- a/contrib/devtools/update-translations.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/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. -''' -Run this script from the root of the repository to update all translations from -transifex. -It will do the following automatically: - -- fetch all translations using the tx tool -- post-process them into valid and committable format - - remove invalid control characters - - remove location tags (makes diffs less noisy) - -TODO: -- auto-add new translations to the build system according to the translation process -''' -import subprocess -import re -import sys -import os -import io -import xml.etree.ElementTree as ET - -# Name of transifex tool -TX = 'tx' -# Name of source language file -SOURCE_LANG = 'bitsend_en.ts' -# Directory with locale files -LOCALE_DIR = 'src/qt/locale' -# Minimum number of messages for translation to be considered at all -MIN_NUM_MESSAGES = 10 -# Regexp to check for Bitsend addresses -ADDRESS_REGEXP = re.compile('([13]|bc1)[a-zA-Z0-9]{30,}') - -def check_at_repository_root(): - if not os.path.exists('.git'): - print('No .git directory found') - print('Execute this script at the root of the repository', file=sys.stderr) - sys.exit(1) - -def fetch_all_translations(): - if subprocess.call([TX, 'pull', '-f', '-a']): - print('Error while fetching translations', file=sys.stderr) - sys.exit(1) - -def find_format_specifiers(s): - '''Find all format specifiers in a string.''' - pos = 0 - specifiers = [] - while True: - percent = s.find('%', pos) - if percent < 0: - break - specifiers.append(s[percent+1]) - pos = percent+2 - return specifiers - -def split_format_specifiers(specifiers): - '''Split format specifiers between numeric (Qt) and others (strprintf)''' - numeric = [] - other = [] - for s in specifiers: - if s in {'1','2','3','4','5','6','7','8','9'}: - numeric.append(s) - else: - other.append(s) - - # If both numeric format specifiers and "others" are used, assume we're dealing - # with a Qt-formatted message. In the case of Qt formatting (see https://doc.qt.io/qt-5/qstring.html#arg) - # only numeric formats are replaced at all. This means "(percentage: %1%)" is valid, without needing - # any kind of escaping that would be necessary for strprintf. Without this, this function - # would wrongly detect '%)' as a printf format specifier. - if numeric: - other = [] - - # numeric (Qt) can be present in any order, others (strprintf) must be in specified order - return set(numeric),other - -def sanitize_string(s): - '''Sanitize string for printing''' - return s.replace('\n',' ') - -def check_format_specifiers(source, translation, errors, numerus): - source_f = split_format_specifiers(find_format_specifiers(source)) - # assert that no source messages contain both Qt and strprintf format specifiers - # if this fails, go change the source as this is hacky and confusing! - assert(not(source_f[0] and source_f[1])) - try: - translation_f = split_format_specifiers(find_format_specifiers(translation)) - except IndexError: - errors.append("Parse error in translation for '%s': '%s'" % (sanitize_string(source), sanitize_string(translation))) - return False - else: - if source_f != translation_f: - if numerus and source_f == (set(), ['n']) and translation_f == (set(), []) and translation.find('%') == -1: - # Allow numerus translations to omit %n specifier (usually when it only has one possible value) - return True - errors.append("Mismatch between '%s' and '%s'" % (sanitize_string(source), sanitize_string(translation))) - return False - return True - -def all_ts_files(suffix=''): - for filename in os.listdir(LOCALE_DIR): - # process only language files, and do not process source language - if not filename.endswith('.ts'+suffix) or filename == SOURCE_LANG+suffix: - continue - if suffix: # remove provided suffix - filename = filename[0:-len(suffix)] - filepath = os.path.join(LOCALE_DIR, filename) - yield(filename, filepath) - -FIX_RE = re.compile(b'[\x00-\x09\x0b\x0c\x0e-\x1f]') -def remove_invalid_characters(s): - '''Remove invalid characters from translation string''' - return FIX_RE.sub(b'', s) - -# Override cdata escape function to make our output match Qt's (optional, just for cleaner diffs for -# comparison, disable by default) -_orig_escape_cdata = None -def escape_cdata(text): - text = _orig_escape_cdata(text) - text = text.replace("'", ''') - text = text.replace('"', '"') - return text - -def contains_bitsend_addr(text, errors): - if text != None and ADDRESS_REGEXP.search(text) != None: - errors.append('Translation "%s" contains a bitsend address. This will be removed.' % (text)) - return True - return False - -def postprocess_translations(reduce_diff_hacks=False): - print('Checking and postprocessing...') - - if reduce_diff_hacks: - global _orig_escape_cdata - _orig_escape_cdata = ET._escape_cdata - ET._escape_cdata = escape_cdata - - for (filename,filepath) in all_ts_files(): - os.rename(filepath, filepath+'.orig') - - have_errors = False - for (filename,filepath) in all_ts_files('.orig'): - # pre-fixups to cope with transifex output - parser = ET.XMLParser(encoding='utf-8') # need to override encoding because 'utf8' is not understood only 'utf-8' - with open(filepath + '.orig', 'rb') as f: - data = f.read() - # remove control characters; this must be done over the entire file otherwise the XML parser will fail - data = remove_invalid_characters(data) - tree = ET.parse(io.BytesIO(data), parser=parser) - - # iterate over all messages in file - root = tree.getroot() - for context in root.findall('context'): - for message in context.findall('message'): - numerus = message.get('numerus') == 'yes' - source = message.find('source').text - translation_node = message.find('translation') - # pick all numerusforms - if numerus: - translations = [i.text for i in translation_node.findall('numerusform')] - else: - translations = [translation_node.text] - - for translation in translations: - if translation is None: - continue - errors = [] - valid = check_format_specifiers(source, translation, errors, numerus) and not contains_bitsend_addr(translation, errors) - - for error in errors: - print('%s: %s' % (filename, error)) - - if not valid: # set type to unfinished and clear string if invalid - translation_node.clear() - translation_node.set('type', 'unfinished') - have_errors = True - - # Remove location tags - for location in message.findall('location'): - message.remove(location) - - # Remove entire message if it is an unfinished translation - if translation_node.get('type') == 'unfinished': - context.remove(message) - - # check if document is (virtually) empty, and remove it if so - num_messages = 0 - for context in root.findall('context'): - for message in context.findall('message'): - num_messages += 1 - if num_messages < MIN_NUM_MESSAGES: - print('Removing %s, as it contains only %i messages' % (filepath, num_messages)) - continue - - # write fixed-up tree - # if diff reduction requested, replace some XML to 'sanitize' to qt formatting - if reduce_diff_hacks: - out = io.BytesIO() - tree.write(out, encoding='utf-8') - out = out.getvalue() - out = out.replace(b' />', b'/>') - with open(filepath, 'wb') as f: - f.write(out) - else: - tree.write(filepath, encoding='utf-8') - return have_errors - -if __name__ == '__main__': - check_at_repository_root() - fetch_all_translations() - postprocess_translations() - diff --git a/contrib/devtools/utxo_snapshot.sh b/contrib/devtools/utxo_snapshot.sh new file mode 100755 index 00000000..c751d8f0 --- /dev/null +++ b/contrib/devtools/utxo_snapshot.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019 The BitSend 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/bitsend-cli -datadir=\$(pwd)/testdata" + echo ' ./contrib/devtools/utxo_snapshot.sh 570000 - ./src/bitsend-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. +BITSEND_CLI_CALL="${*} -rpcclienttimeout=9999999" + +# Block we'll invalidate/reconsider to rewind/fast-forward the chain. +PIVOT_BLOCKHASH=$($BITSEND_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") +${BITSEND_CLI_CALL} invalidateblock "${PIVOT_BLOCKHASH}" + +if [[ "${OUTPUT_PATH}" = "-" ]]; then + (>&2 echo "Generating txoutset info...") + ${BITSEND_CLI_CALL} gettxoutsetinfo | grep hash_serialized_2 | sed 's/^.*: "\(.\+\)\+",/\1/g' +else + (>&2 echo "Generating UTXO snapshot...") + ${BITSEND_CLI_CALL} dumptxoutset "${OUTPUT_PATH}" +fi + +(>&2 echo "Restoring chain to original height; this may take a while") +${BITSEND_CLI_CALL} reconsiderblock "${PIVOT_BLOCKHASH}" diff --git a/contrib/filter-lcov.py b/contrib/filter-lcov.py index df1db76e..46b17fcb 100755 --- a/contrib/filter-lcov.py +++ b/contrib/filter-lcov.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# Copyright (c) 2017-2019 The BitSend Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. import argparse diff --git a/contrib/gitian-build.py b/contrib/gitian-build.py index cd11686b..f1b24c12 100755 --- a/contrib/gitian-build.py +++ b/contrib/gitian-build.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# Copyright (c) 2018-2019 The BitSend 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 @@ -7,29 +10,29 @@ def setup(): global args, workdir - programs = ['ruby', 'git', 'apt-cacher-ng', 'make', 'wget'] + programs = ['ruby', 'git', 'make', 'wget', 'curl'] if args.kvm: - programs += ['python-vm-builder', 'qemu-kvm', 'qemu-utils'] - elif args.docker: + 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) - exit(1) + print('Cannot find any way to install Docker.', file=sys.stderr) + sys.exit(1) else: - programs += ['lxc', 'debootstrap'] + 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']) + subprocess.check_call(['git', 'clone', 'https://github.com/bitsend-core/gitian.sigs.git']) if not os.path.isdir('bitsend-detached-sigs'): - subprocess.check_call(['git', 'clone', 'https://github.com/bitcoin-core/bitsend-detached-sigs.git']) + subprocess.check_call(['git', 'clone', 'https://github.com/bitsend-core/bitsend-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('bitsend'): - subprocess.check_call(['git', 'clone', 'https://github.com/LIMXTEC/BitSend.git']) + subprocess.check_call(['git', 'clone', 'https://github.com/bitsend/bitsend.git']) os.chdir('gitian-builder') make_image_prog = ['bin/make-base-vm', '--suite', 'bionic', '--arch', 'amd64'] if args.docker: @@ -41,7 +44,7 @@ def setup(): 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') - exit(0) + sys.exit(0) def build(): global args, workdir @@ -51,8 +54,8 @@ def build(): os.chdir('gitian-builder') os.makedirs('inputs', exist_ok=True) - subprocess.check_call(['wget', '-N', '-P', 'inputs', 'http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz']) - subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch']) + 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', '../bitsend/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common']) if args.linux: @@ -65,15 +68,15 @@ def build(): print('\nCompiling ' + args.version + ' Windows') subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'bitsend='+args.commit, '--url', 'bitsend='+args.url, '../bitsend/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/', '../bitsend/contrib/gitian-descriptors/gitian-win.yml']) - subprocess.check_call('mv build/out/bitsend-*-win-unsigned.tar.gz inputs/bitsend-win-unsigned.tar.gz', shell=True) - subprocess.check_call('mv build/out/bitsend-*.zip build/out/bitsend-*.exe ../bitsend-binaries/'+args.version, shell=True) + subprocess.check_call('mv build/out/bitsend-*-win-unsigned.tar.gz inputs/', shell=True) + subprocess.check_call('mv build/out/bitsend-*.zip build/out/bitsend-*.exe build/out/src/bitsend-*.tar.gz ../bitsend-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', 'bitsend='+args.commit, '--url', 'bitsend='+args.url, '../bitsend/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/', '../bitsend/contrib/gitian-descriptors/gitian-osx.yml']) - subprocess.check_call('mv build/out/bitsend-*-osx-unsigned.tar.gz inputs/bitsend-osx-unsigned.tar.gz', shell=True) - subprocess.check_call('mv build/out/bitsend-*.tar.gz build/out/bitsend-*.dmg ../bitsend-binaries/'+args.version, shell=True) + subprocess.check_call('mv build/out/bitsend-*-osx-unsigned.tar.gz inputs/', shell=True) + subprocess.check_call('mv build/out/bitsend-*.tar.gz build/out/bitsend-*.dmg build/out/src/bitsend-*.tar.gz ../bitsend-binaries/'+args.version, shell=True) os.chdir(workdir) @@ -92,14 +95,15 @@ def sign(): if args.windows: print('\nSigning ' + args.version + ' Windows') - subprocess.check_call(['bin/gbuild', '-i', '--commit', 'signature='+args.commit, '../bitsend/contrib/gitian-descriptors/gitian-win-signer.yml']) + subprocess.check_call('cp inputs/bitsend-' + args.version + '-win-unsigned.tar.gz inputs/bitsend-win-unsigned.tar.gz', shell=True) + subprocess.check_call(['bin/gbuild', '--skip-image', '--upgrade', '--commit', 'signature='+args.commit, '../bitsend/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/', '../bitsend/contrib/gitian-descriptors/gitian-win-signer.yml']) subprocess.check_call('mv build/out/bitsend-*win64-setup.exe ../bitsend-binaries/'+args.version, shell=True) - subprocess.check_call('mv build/out/bitsend-*win32-setup.exe ../bitsend-binaries/'+args.version, shell=True) if args.macos: print('\nSigning ' + args.version + ' MacOS') - subprocess.check_call(['bin/gbuild', '-i', '--commit', 'signature='+args.commit, '../bitsend/contrib/gitian-descriptors/gitian-osx-signer.yml']) + subprocess.check_call('cp inputs/bitsend-' + args.version + '-osx-unsigned.tar.gz inputs/bitsend-osx-unsigned.tar.gz', shell=True) + subprocess.check_call(['bin/gbuild', '--skip-image', '--upgrade', '--commit', 'signature='+args.commit, '../bitsend/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/', '../bitsend/contrib/gitian-descriptors/gitian-osx-signer.yml']) subprocess.check_call('mv build/out/bitsend-osx-signed.dmg ../bitsend-binaries/'+args.version+'/bitsend-'+args.version+'-osx.dmg', shell=True) @@ -115,27 +119,44 @@ def sign(): def verify(): global args, workdir + rc = 0 os.chdir('gitian-builder') print('\nVerifying v'+args.version+' Linux\n') - subprocess.check_call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-linux', '../bitsend/contrib/gitian-descriptors/gitian-linux.yml']) + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-linux', '../bitsend/contrib/gitian-descriptors/gitian-linux.yml']): + print('Verifying v'+args.version+' Linux FAILED\n') + rc = 1 + print('\nVerifying v'+args.version+' Windows\n') - subprocess.check_call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win-unsigned', '../bitsend/contrib/gitian-descriptors/gitian-win.yml']) + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win-unsigned', '../bitsend/contrib/gitian-descriptors/gitian-win.yml']): + print('Verifying v'+args.version+' Windows FAILED\n') + rc = 1 + print('\nVerifying v'+args.version+' MacOS\n') - subprocess.check_call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx-unsigned', '../bitsend/contrib/gitian-descriptors/gitian-osx.yml']) + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx-unsigned', '../bitsend/contrib/gitian-descriptors/gitian-osx.yml']): + print('Verifying v'+args.version+' MacOS FAILED\n') + rc = 1 + print('\nVerifying v'+args.version+' Signed Windows\n') - subprocess.check_call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win-signed', '../bitsend/contrib/gitian-descriptors/gitian-win-signer.yml']) + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win-signed', '../bitsend/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') - subprocess.check_call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx-signed', '../bitsend/contrib/gitian-descriptors/gitian-osx-signer.yml']) + if subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx-signed', '../bitsend/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(usage='%(prog)s [options] signer version') + 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('-u', '--url', dest='url', default='https://github.com/LIMXTEC/BitSend', help='Specify the URL of the repository. Default is %(default)s') + 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/bitsend/bitsend', 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') @@ -145,68 +166,86 @@ def main(): 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. Uses LXC. If you want to use KVM, use the --kvm option. Only works on Debian-based systems (Ubuntu, Debian)') + 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', help='GPG signer to sign each build assert file') - parser.add_argument('version', help='Version number, commit, or branch to build. If building a commit or branch, the -c option must be specified') + 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.linux = 'l' in args.os - args.windows = 'w' in args.os - args.macos = 'm' in args.os - args.is_bionic = b'bionic' in subprocess.check_output(['lsb_release', '-cs']) - if args.buildsign: - args.build=True - args.sign=True - if args.kvm and args.docker: raise Exception('Error: cannot have both kvm and docker') - args.sign_prog = 'true' if args.detach_sign else 'gpg --detach-sign' - - # Set enviroment variable USE_LXC or USE_DOCKER, let gitian-builder know that we use lxc or 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 not 'GITIAN_HOST_IP' in os.environ.keys(): + if 'GITIAN_HOST_IP' not in os.environ.keys(): os.environ['GITIAN_HOST_IP'] = '10.0.3.1' - if not 'LXC_GUEST_IP' in os.environ.keys(): + 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/MacOSX10.11.sdk.tar.gz'): + 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]) - # Signer and version shouldn't be empty - if args.signer == '': - print(script_name+': Missing signer.') + if not args.signer: + print(script_name+': Missing signer') print('Try '+script_name+' --help for more information') - exit(1) - if args.version == '': - print(script_name+': Missing version.') + sys.exit(1) + if not args.version: + print(script_name+': Missing version') print('Try '+script_name+' --help for more information') - exit(1) + 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 - print(args.commit) - - if args.setup: - setup() os.chdir('bitsend') + if args.pull: + subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) + os.chdir('../gitian-builder/inputs/bitsend') + 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() @@ -214,7 +253,10 @@ def main(): sign() if args.verify: - 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-descriptors/assign_DISTNAME b/contrib/gitian-descriptors/assign_DISTNAME new file mode 100755 index 00000000..e65b6a56 --- /dev/null +++ b/contrib/gitian-descriptors/assign_DISTNAME @@ -0,0 +1,12 @@ +# Copyright (c) 2020 The BitSend 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)"; then + VERSION="${RECENT_TAG#v}" +else + VERSION="$(git rev-parse --short=12 HEAD)" +fi +DISTNAME="bitsend-${VERSION}" diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml old mode 100755 new mode 100644 index 3e66b351..facadb20 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,53 +1,55 @@ --- -name: "bitsend-linux-0.17" +name: "bitsend-core-linux-0.21" enable_cache: true +distro: "ubuntu" suites: - "bionic" architectures: - "amd64" packages: -- "curl" -- "g++-aarch64-linux-gnu" -- "g++-7-aarch64-linux-gnu" -- "gcc-7-aarch64-linux-gnu" -- "binutils-aarch64-linux-gnu" -- "g++-arm-linux-gnueabihf" -- "g++-7-arm-linux-gnueabihf" -- "gcc-7-arm-linux-gnueabihf" -- "binutils-arm-linux-gnueabihf" -- "g++-7-multilib" -- "gcc-7-multilib" -- "binutils-gold" -- "git" -- "pkg-config" +# Common dependencies. - "autoconf" -- "libtool" - "automake" -- "faketime" +- "binutils" - "bsdmainutils" - "ca-certificates" -- "python" +- "curl" +- "faketime" +- "git" +- "libtool" +- "patch" +- "pkg-config" +- "python3" +# 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" +# - riscv64-linux-gnu +- "binutils-riscv64-linux-gnu" +- "g++-8-riscv64-linux-gnu" remotes: -- "url": "https://github.com/LIMXTEC/BitSend.git" +- "url": "https://github.com/bitsend/bitsend.git" "dir": "bitsend" 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" + HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu" CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" - FAKETIME_HOST_PROGS="" + 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,11 +57,12 @@ 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 '#!/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} chmod +x ${WRAP_DIR}/${prog} @@ -69,12 +72,15 @@ script: | function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do - echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} - echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} - echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} - echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} - chmod +x ${WRAP_DIR}/${i}-${prog} + 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} + echo "\$REAL \"\$@\"" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + fi done done } @@ -85,45 +91,11 @@ script: | 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} - #!/usr/bin/env 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 bitsend - 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 done # Faketime for binaries @@ -132,62 +104,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 bitsend-*.tar.gz` - DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` - # Correct tar file order - mkdir -p temp - pushd temp - tar xf ../$SOURCEDIST - find bitsend-* | 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" - # Workaround for tarball not building with the bare tag version (prep) - make -C src obj/build.h + # 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}" = "riscv64-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 - - # Workaround for tarball not building with the bare tag version - echo '#!/bin/true' >share/genbuild.sh - mkdir src/obj - cp ../src/obj/build.h src/obj/ + 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}" LDFLAGS="${HOST_LDFLAGS}" 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 old mode 100755 new mode 100644 index 41af8127..b8de90da --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -1,5 +1,6 @@ --- name: "bitsend-dmg-signer" +distro: "ubuntu" suites: - "bionic" architectures: @@ -7,21 +8,23 @@ architectures: packages: - "faketime" remotes: -- "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git" +- "url": "https://github.com/bitsend-core/bitsend-detached-sigs.git" "dir": "signature" files: - "bitsend-osx-unsigned.tar.gz" script: | + set -e -o pipefail + WRAP_DIR=$HOME/wrapped mkdir -p ${WRAP_DIR} - export PATH=`pwd`:$PATH + export PATH="$PWD":$PATH FAKETIME_PROGS="dmg genisoimage" # Create global faketime wrappers for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml old mode 100755 new mode 100644 index 03c000c6..7588a7d0 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,6 +1,7 @@ --- -name: "bitsend-osx-0.17" +name: "bitsend-core-osx-0.21" enable_cache: true +distro: "ubuntu" suites: - "bionic" architectures: @@ -23,28 +24,28 @@ packages: - "libcap-dev" - "libz-dev" - "libbz2-dev" -- "python" -- "python-dev" -- "python-setuptools" +- "python3" +- "python3-dev" +- "python3-setuptools" - "fonts-tuffy" remotes: -- "url": "https://github.com/LIMXTEC/BitSend.git" +- "url": "https://github.com/bitsend/bitsend.git" "dir": "bitsend" files: -- "MacOSX10.11.sdk.tar.gz" +- "Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz" script: | + set -e -o pipefail + WRAP_DIR=$HOME/wrapped - HOSTS="x86_64-apple-darwin14" + HOSTS="x86_64-apple-darwin16" CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 - export GZIP="-9n" - export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" - export BUILD_DIR=`pwd` + export BUILD_DIR="$PWD" mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} @@ -54,11 +55,12 @@ 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 '#!/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} chmod +x ${WRAP_DIR}/${prog} @@ -70,7 +72,7 @@ script: | for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export 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} chmod +x ${WRAP_DIR}/${i}-${prog} @@ -85,10 +87,10 @@ script: | export PATH=${WRAP_DIR}:${PATH} cd bitsend - 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-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz # Build dependencies for each host for i in $HOSTS; do @@ -101,40 +103,31 @@ 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 bitsend-*.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 bitsend-* | 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" - # Workaround for tarball not building with the bare tag version (prep) - make -C src obj/build.h + # 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 - - # Workaround for tarball not building with the bare tag version - echo '#!/bin/true' >share/genbuild.sh - mkdir src/obj - cp ../src/obj/build.h src/obj/ + 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 @@ -149,7 +142,7 @@ script: | cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff mv dist unsigned-app-${i} pushd unsigned-app-${i} - find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz + 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 @@ -159,9 +152,8 @@ script: | 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 old mode 100755 new mode 100644 index 38e3ba04..48906efb --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -1,39 +1,42 @@ --- name: "bitsend-win-signer" +distro: "ubuntu" suites: - "bionic" architectures: - "amd64" packages: -# Once osslsigncode supports openssl 1.1, we can change this back to libssl-dev -- "libssl1.0-dev" +- "libssl-dev" - "autoconf" +- "automake" +- "libtool" +- "pkg-config" remotes: -- "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git" +- "url": "https://github.com/bitsend-core/bitsend-detached-sigs.git" "dir": "signature" files: -- "osslsigncode-1.7.1.tar.gz" -- "osslsigncode-Backports-to-1.7.1.patch" +- "osslsigncode-2.0.tar.gz" - "bitsend-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 bitsend-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 old mode 100755 new mode 100644 index dbecfd80..72766e1a --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,6 +1,7 @@ --- -name: "bitsend-win-0.17" +name: "bitsend-core-win-0.21" enable_cache: true +distro: "ubuntu" suites: - "bionic" architectures: @@ -20,27 +21,26 @@ packages: - "nsis" - "zip" - "ca-certificates" -- "python" -- "rename" +- "python3" remotes: -- "url": "https://github.com/LIMXTEC/BitSend.git" +- "url": "https://github.com/bitsend/bitsend.git" "dir": "bitsend" files: [] script: | + set -e -o pipefail + WRAP_DIR=$HOME/wrapped - HOSTS="i686-w64-mingw32 x86_64-w64-mingw32" + HOSTS="x86_64-w64-mingw32" CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests" 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} @@ -48,11 +48,12 @@ 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 '#!/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} chmod +x ${WRAP_DIR}/${prog} @@ -64,7 +65,7 @@ script: | for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export 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} chmod +x ${WRAP_DIR}/${i}-${prog} @@ -72,25 +73,15 @@ script: | 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 '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}/${prog} - REAL=$(${i}-gcc -print-prog-name=${prog}) - echo "export MALLOC_PERTURB_=255" >> ${WRAP_DIR}/${i}/${prog} - echo "${REAL} \$@" >> $WRAP_DIR/${i}/${prog} - chmod +x ${WRAP_DIR}/${i}/${prog} - done for prog in gcc g++; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog}-posix | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export 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 "\$REAL \"\$@\"" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done @@ -100,11 +91,11 @@ script: | 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 bitsend - BASEPREFIX=`pwd`/depends + BASEPREFIX="${PWD}/depends" # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" @@ -114,68 +105,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 bitsend-*.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 bitsend-* | 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 + GIT_ARCHIVE="${OUTDIR}/src/${DISTNAME}.tar.gz" - # Workaround for tarball not building with the bare tag version (prep) - make -C src obj/build.h + # 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 - - # Workaround for tarball not building with the bare tag version - echo '#!/bin/true' >share/genbuild.sh - mkdir src/obj - cp ../src/obj/build.h src/obj/ + 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 BITSEND_WIN_INSTALLER="${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" make install DESTDIR=${INSTALLPATH} - rename 's/-setup\.exe$/-setup-unsigned.exe/' *-setup.exe - cp -f bitsend-*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 + cp -rf contrib/windeploy $BUILD_DIR cd $BUILD_DIR/windeploy mkdir unsigned - cp $OUTDIR/bitsend-*setup-unsigned.exe unsigned/ - find . | 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 ${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/README.md b/contrib/gitian-keys/README.md old mode 100755 new mode 100644 index 94f7e99f..ca6f1d3b --- a/contrib/gitian-keys/README.md +++ b/contrib/gitian-keys/README.md @@ -24,4 +24,4 @@ while read fingerprint keyholder_name; do gpg --keyserver hkp://subset.pool.sks- ``` Add your key to the list if you provided Gitian signatures for two major or -minor releases of Bitsend Core. +minor releases of BitSend Core. diff --git a/contrib/gitian-keys/keys.txt b/contrib/gitian-keys/keys.txt old mode 100755 new mode 100644 index 593fba1d..0a2c1302 --- a/contrib/gitian-keys/keys.txt +++ b/contrib/gitian-keys/keys.txt @@ -1,3 +1,4 @@ +9D3CC86A72F8494342EA5FD10A41BDC3F4FAFF1C Aaron Clauson (sipsorcery) 617C90010B3BD370B0AC7D424BB42E31C79111B8 Akira Takizawa E944AE667CF960B1004BC32FCA662BE18B877A60 Andreas Schildbach 152812300785C96444D3334D17565732E08E5E41 Andrew Chow @@ -6,10 +7,13 @@ C519EBCF3B926298946783EFF6430754120EC2F4 Christian Decker (cdecker) F20F56EF6A067F70E8A5C99FFF95FAA971697405 centaur C060A6635913D98A3587D7DB1C2491FFEB0EF770 Cory Fields BF6273FAEF7CC0BA1F562E50989F6B3048A116B5 Dev Random +6D3170C1DC2C6FD0AEEBCA6743811D1A26623924 Douglas Roark 9A1689B60D1B3CCE9262307A2F40A9BF167FBA47 Erik Mossberg (erkmos) D35176BE9264832E4ACA8986BF0792FBE95DC863 fivepiece 01CDF4627A3B88AAE4A571C87588242FBE38D3A8 Gavin Andresen +D1DBF2C4B96F2DEBF4C16654410108112E7EA81F Hennadii Stepanov (hebasto) D3CC177286005BB8FF673294C5242A1AB3936517 jl2012 +82921A4B88FD454B7EB8CE3C796C4109063D4EAF Jon Atack 32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC Jonas Schnelli 4B4E840451149DD7FB0D633477DFAB5C3108B9A8 Jorge Timon C42AFF7C61B3E44A1454CD3557AF762DB3353322 Karl-Johan Alm (kallewoof) @@ -24,7 +28,9 @@ D62A803E27E7F43486035ADBBCD04D8E9CCCAC2A Paul Rabahy 37EC7D7B0A217CDB4B4E007E7FAB114267E4FA04 Peter Todd D762373D24904A3E42F33B08B9A408E71DAAC974 Pieter Wuille (Location: Leuven, Belgium) 133EAC179436F14A5CF1B794860FEB804E669320 Pieter Wuille +A8FC55F3B04BA3146F3492E79303B33A305224CB Sebastian Kung (TheCharlatan) ED9BDF7AD6A55E232E84524257FF9BDBCC301009 Sjors Provoost +9EDAFF80E080659604F4A76B2EBB056FD847F8A7 Stephan Oeste (Emzy) AEC1884398647C47413C1C3FB1179EB7347DC10D Warren Togami 79D00BAC68B56D422F945A8F8E3A8F3247DBCBBF Willy Ko 71A3B16735405025D447E8F274810B012346C9A6 Wladimir J. van der Laan diff --git a/contrib/guix/README.md b/contrib/guix/README.md new file mode 100644 index 00000000..7a581f3b --- /dev/null +++ b/contrib/guix/README.md @@ -0,0 +1,230 @@ +# Bootstrappable BitSend Core Builds + +This directory contains the files necessary to perform bootstrappable BitSend +Core builds. + +[Bootstrappability][b17e] furthers our binary security guarantees by allowing us +to _audit and reproduce_ our toolchain instead of blindly _trusting_ binary +downloads. + +We achieve bootstrappability by using Guix as a functional package manager. + +## Requirements + +Conservatively, a x86_64 machine with: + +- 4GB of free disk space on the partition that /gnu/store will reside in +- 24GB of free disk space on the partition that the BitSend Core git repository + resides in + +> Note: these requirements are slightly less onerous than those of Gitian builds + +## Setup + +### Installing Guix + +If you're just testing this out, you can use the +[Dockerfile][fanquake/guix-docker] for convenience. It automatically speeds up +your builds by [using substitutes](#speeding-up-builds-with-substitute-servers). +If you don't want this behaviour, refer to the [next +section](#choosing-your-security-model). + +Otherwise, follow the [Guix installation guide][guix/bin-install]. + +> Note: For those who like to keep their filesystems clean, Guix is designed to +> be very standalone and _will not_ conflict with your system's package +> manager/existing setup. It _only_ touches `/var/guix`, `/gnu`, and +> `~/.config/guix`. + +### Choosing your security model + +Guix allows us to achieve better binary security by using our CPU time to build +everything from scratch. However, it doesn't sacrifice user choice in pursuit of +this: users can decide whether or not to bootstrap and to use substitutes. + +After installation, you may want to consider [adding substitute +servers](#speeding-up-builds-with-substitute-servers) to speed up your build if +that fits your security model (say, if you're just testing that this works). +This is skippable if you're using the [Dockerfile][fanquake/guix-docker]. + +If you prefer not to use any substitutes, make sure to set +`ADDITIONAL_GUIX_ENVIRONMENT_FLAGS` like the following snippet. The first build +will take a while, but the resulting packages will be cached for future builds. + +```sh +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--no-substitutes' +``` + +Likewise, to perform a bootstrapped build (takes even longer): + +```sh +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--bootstrap --no-substitutes' +``` + +### Using a version of Guix with `guix time-machine` capabilities + +> Note: This entire section can be skipped if you are already using a version of +> Guix that has [the `guix time-machine` command][guix/time-machine]. + +Once Guix is installed, if it doesn't have the `guix time-machine` command, pull +the latest `guix`. + +```sh +guix pull --max-jobs=4 # change number of jobs accordingly +``` + +Make sure that you are using your current profile. (You are prompted to do this +at the end of the `guix pull`) + +```bash +export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH" +``` + +## Usage + +### As a Development Environment + +For a BitSend Core depends development environment, simply invoke + +```sh +guix environment --manifest=contrib/guix/manifest.scm +``` + +And you'll land back in your shell with all the build dependencies required for +a `depends` build injected into your environment. + +### As a Tool for Deterministic Builds + +From the top of a clean BitSend Core repository: + +```sh +./contrib/guix/guix-build.sh +``` + +After the build finishes successfully (check the status code please), compare +hashes: + +```sh +find output/ -type f -print0 | sort -z | xargs -r0 sha256sum +``` + +#### Recognized environment variables + +* _**HOSTS**_ + + Override the space-separated list of platform triples for which to perform a + bootstrappable build. _(defaults to "x86\_64-linux-gnu + arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu")_ + + > Windows and OS X platform triplet support are WIP. + +* _**SOURCES_PATH**_ + + Set the depends tree download cache for sources. This is passed through to the + depends tree. Setting this to the same directory across multiple builds of the + depends tree can eliminate unnecessary redownloading of package sources. + +* _**MAX_JOBS**_ + + Override the maximum number of jobs to run simultaneously, you might want to + do so on a memory-limited machine. This may be passed to `make` as in `make + --jobs="$MAX_JOBS"` or `xargs` as in `xargs -P"$MAX_JOBS"`. _(defaults to the + value of `nproc` outside the container)_ + +* _**SOURCE_DATE_EPOCH**_ + + Override the reference UNIX timestamp used for bit-for-bit reproducibility, + the variable name conforms to [standard][r12e/source-date-epoch]. _(defaults + to the output of `$(git log --format=%at -1)`)_ + +* _**V**_ + + If non-empty, will pass `V=1` to all `make` invocations, making `make` output + verbose. + + Note that any given value is ignored. The variable is only checked for + emptiness. More concretely, this means that `V=` (setting `V` to the empty + string) is interpreted the same way as not setting `V` at all, and that `V=0` + has the same effect as `V=1`. + +* _**ADDITIONAL_GUIX_ENVIRONMENT_FLAGS**_ + + Additional flags to be passed to `guix environment`. For a fully-bootstrapped + build, set this to `--bootstrap --no-substitutes` (refer to the [security + model section](#choosing-your-security-model) for more details). Note that a + fully-bootstrapped build will take quite a long time on the first run. + +## Tips and Tricks + +### Speeding up builds with substitute servers + +_This whole section is automatically done in the convenience +[Dockerfiles][fanquake/guix-docker]_ + +For those who are used to life in the fast _(and trustful)_ lane, you can use +[substitute servers][guix/substitutes] to enable binary downloads of packages. + +> For those who only want to use substitutes from the official Guix build farm +> and have authorized the build farm's signing key during Guix's installation, +> you don't need to do anything. + +#### Authorize the signing keys + +For the official Guix build farm at https://ci.guix.gnu.org, run as root: + +``` +guix archive --authorize < ~root/.config/guix/current/share/guix/ci.guix.gnu.org.pub +``` + +For dongcarl's substitute server at https://guix.carldong.io, run as root: + +```sh +wget -qO- 'https://guix.carldong.io/signing-key.pub' | guix archive --authorize +``` + +#### Use the substitute servers + +The official Guix build farm at https://ci.guix.gnu.org is automatically used +unless the `--no-substitutes` flag is supplied. + +This can be overridden for all `guix` invocations by passing the +`--substitute-urls` option to your invocation of `guix-daemon`. This can also be +overridden on a call-by-call basis by passing the same `--substitute-urls` +option to client tools such at `guix environment`. + +To use dongcarl's substitute server for BitSend Core builds after having +[authorized his signing key](#authorize-the-signing-keys): + +``` +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--substitute-urls="https://guix.carldong.io https://ci.guix.gnu.org"' +``` + +## FAQ + +### How can I trust the binary installation? + +As mentioned at the bottom of [this manual page][guix/bin-install]: + +> The binary installation tarballs can be (re)produced and verified simply by +> running the following command in the Guix source tree: +> +> make guix-binary.x86_64-linux.tar.xz + +### When will Guix be packaged in debian? + +Vagrant Cascadian has been making good progress on this +[here][debian/guix-package]. We have all the pieces needed to put up an APT +repository and will likely put one up soon. + +[b17e]: http://bootstrappable.org/ +[r12e/source-date-epoch]: https://reproducible-builds.org/docs/source-date-epoch/ + +[guix/install.sh]: https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh +[guix/bin-install]: https://www.gnu.org/software/guix/manual/en/html_node/Binary-Installation.html +[guix/env-setup]: https://www.gnu.org/software/guix/manual/en/html_node/Build-Environment-Setup.html +[guix/substitutes]: https://www.gnu.org/software/guix/manual/en/html_node/Substitutes.html +[guix/substitute-server-auth]: https://www.gnu.org/software/guix/manual/en/html_node/Substitute-Server-Authorization.html +[guix/time-machine]: https://guix.gnu.org/manual/en/html_node/Invoking-guix-time_002dmachine.html + +[debian/guix-package]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=850644 +[fanquake/guix-docker]: https://github.com/fanquake/core-review/tree/master/guix diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh new file mode 100755 index 00000000..4d1bcaca --- /dev/null +++ b/contrib/guix/guix-build.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +export LC_ALL=C +set -e -o pipefail + +# Determine the maximum number of jobs to run simultaneously (overridable by +# environment) +MAX_JOBS="${MAX_JOBS:-$(nproc)}" + +# Download the depends sources now as we won't have internet access in the build +# container +make -C "${PWD}/depends" -j"$MAX_JOBS" download ${V:+V=1} ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} + +# Determine the reference time used for determinism (overridable by environment) +SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}" + +# Execute "$@" in a pinned, possibly older version of Guix, for reproducibility +# across time. +time-machine() { + guix time-machine --url=https://github.com/dongcarl/guix.git \ + --commit=b066c25026f21fb57677aa34692a5034338e7ee3 \ + -- "$@" +} + +# Function to be called when building for host ${1} and the user interrupts the +# build +int_trap() { +cat << EOF +** INT received while building ${1}, you may want to clean up the relevant + output, deploy, and distsrc-* directories before rebuilding + +Hint: To blow everything away, you may want to use: + + $ git clean -xdff --exclude='/depends/SDKs/*' + +Specifically, this will remove all files without an entry in the index, +excluding the SDK directory. Practically speaking, this means that all ignored +and untracked files and directories will be wiped, allowing you to start anew. +EOF +} + +# Deterministically build BitSend Core for HOSTs (overridable by environment) +# shellcheck disable=SC2153 +for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu x86_64-w64-mingw32}; do + + # Display proper warning when the user interrupts the build + trap 'int_trap ${host}' INT + + ( + # Required for 'contrib/guix/manifest.scm' to output the right manifest + # for the particular $HOST we're building for + export HOST="$host" + + # Run the build script 'contrib/guix/libexec/build.sh' in the build + # container specified by 'contrib/guix/manifest.scm'. + # + # Explanation of `guix environment` flags: + # + # --container run command within an isolated container + # + # Running in an isolated container minimizes build-time differences + # between machines and improves reproducibility + # + # --pure unset existing environment variables + # + # Same rationale as --container + # + # --no-cwd do not share current working directory with an + # isolated container + # + # When --container is specified, the default behavior is to share + # the current working directory with the isolated container at the + # same exact path (e.g. mapping '/home/satoshi/bitsend/' to + # '/home/satoshi/bitsend/'). This means that the $PWD inside the + # container becomes a source of irreproducibility. --no-cwd disables + # this behaviour. + # + # --share=SPEC for containers, share writable host file system + # according to SPEC + # + # --share="$PWD"=/bitsend + # + # maps our current working directory to /bitsend + # inside the isolated container, which we later cd + # into. + # + # While we don't want to map our current working directory to the + # same exact path (as this introduces irreproducibility), we do want + # it to be at a _fixed_ path _somewhere_ inside the isolated + # container so that we have something to build. '/bitsend' was + # chosen arbitrarily. + # + # ${SOURCES_PATH:+--share="$SOURCES_PATH"} + # + # make the downloaded depends sources path available + # inside the isolated container + # + # The isolated container has no network access as it's in a + # different network namespace from the main machine, so we have to + # make the downloaded depends sources available to it. The sources + # should have been downloaded prior to this invocation. + # + # shellcheck disable=SC2086 + time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \ + --container \ + --pure \ + --no-cwd \ + --share="$PWD"=/bitsend \ + --expose="$(git rev-parse --git-common-dir)" \ + ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ + ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ + -- env HOST="$host" \ + MAX_JOBS="$MAX_JOBS" \ + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ + ${V:+V=1} \ + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ + bash -c "cd /bitsend && bash contrib/guix/libexec/build.sh" + ) + +done diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh new file mode 100644 index 00000000..c3e39eeb --- /dev/null +++ b/contrib/guix/libexec/build.sh @@ -0,0 +1,321 @@ +#!/usr/bin/env bash +export LC_ALL=C +set -e -o pipefail +export TZ=UTC + +if [ -n "$V" ]; then + # Print both unexpanded (-v) and expanded (-x) forms of commands as they are + # read from this file. + set -vx + # Set VERBOSE for CMake-based builds + export VERBOSE="$V" +fi + +# Check that environment variables assumed to be set by the environment are set +echo "Building for platform triple ${HOST:?not set} with reference timestamp ${SOURCE_DATE_EPOCH:?not set}..." +echo "At most ${MAX_JOBS:?not set} jobs will run at once..." + +##################### +# Environment Setup # +##################### + +# The depends folder also serves as a base-prefix for depends packages for +# $HOSTs after successfully building. +BASEPREFIX="${PWD}/depends" + +# Setup an output directory for our build +OUTDIR="${OUTDIR:-${PWD}/output}" +[ -e "$OUTDIR" ] || mkdir -p "$OUTDIR" + +# Setup the directory where our BitSend Core build for HOST will occur +DISTSRC="${DISTSRC:-${PWD}/distsrc-${HOST}}" +if [ -e "$DISTSRC" ]; then + echo "DISTSRC directory '${DISTSRC}' exists, probably because of previous builds... Aborting..." + exit 1 +else + mkdir -p "$DISTSRC" +fi + +# Given a package name and an output name, return the path of that output in our +# current guix environment +store_path() { + grep --extended-regexp "/[^-]{32}-${1}-[^-]+${2:+-${2}}" "${GUIX_ENVIRONMENT}/manifest" \ + | head --lines=1 \ + | sed --expression='s|^[[:space:]]*"||' \ + --expression='s|"[[:space:]]*$||' +} + +# Set environment variables to point Guix's cross-toolchain to the right +# includes/libs for $HOST +case "$HOST" in + *mingw*) + # Determine output paths to use in CROSS_* environment variables + CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + NATIVE_GCC="$(store_path gcc-glibc-2.27-toolchain)" + export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC}/lib64" + export CPATH="${NATIVE_GCC}/include" + + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" + ;; + *linux*) + CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" + CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" + CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + # NOTE: CROSS_C_INCLUDE_PATH is missing ${CROSS_GCC_LIB}/include-fixed, because + # the limits.h in it is missing a '#include_next ' + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" + ;; + *) + exit 1 ;; +esac + +# Sanity check CROSS_*_PATH directories +IFS=':' read -ra PATHS <<< "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +for p in "${PATHS[@]}"; do + if [ ! -d "$p" ]; then + echo "'$p' doesn't exist or isn't a directory... Aborting..." + exit 1 + fi +done + +# Disable Guix ld auto-rpath behavior +export GUIX_LD_WRAPPER_DISABLE_RPATH=yes + +# Make /usr/bin if it doesn't exist +[ -e /usr/bin ] || mkdir -p /usr/bin + +# Symlink file and env to a conventional path +[ -e /usr/bin/file ] || ln -s --no-dereference "$(command -v file)" /usr/bin/file +[ -e /usr/bin/env ] || ln -s --no-dereference "$(command -v env)" /usr/bin/env + +# Determine the correct value for -Wl,--dynamic-linker for the current $HOST +case "$HOST" in + *linux*) + glibc_dynamic_linker=$( + case "$HOST" in + i686-linux-gnu) echo /lib/ld-linux.so.2 ;; + x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; + arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; + aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; + riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; + *) exit 1 ;; + esac + ) + ;; +esac + +# Environment variables for determinism +export QT_RCC_TEST=1 +export QT_RCC_SOURCE_DATE_OVERRIDE=1 +export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" +export TZ="UTC" + +#################### +# Depends Building # +#################### + +# Build the depends tree, overriding variables that assume multilib gcc +make -C depends --jobs="$MAX_JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + i686_linux_CC=i686-linux-gnu-gcc \ + i686_linux_CXX=i686-linux-gnu-g++ \ + i686_linux_AR=i686-linux-gnu-ar \ + i686_linux_RANLIB=i686-linux-gnu-ranlib \ + i686_linux_NM=i686-linux-gnu-nm \ + i686_linux_STRIP=i686-linux-gnu-strip \ + x86_64_linux_CC=x86_64-linux-gnu-gcc \ + x86_64_linux_CXX=x86_64-linux-gnu-g++ \ + x86_64_linux_AR=x86_64-linux-gnu-ar \ + x86_64_linux_RANLIB=x86_64-linux-gnu-ranlib \ + x86_64_linux_NM=x86_64-linux-gnu-nm \ + x86_64_linux_STRIP=x86_64-linux-gnu-strip \ + qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitsend-linux-g++' + + +########################### +# Source Tarball Building # +########################### + +# 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 if not already there +if [ ! -e "$GIT_ARCHIVE" ]; then + mkdir -p "$(dirname "$GIT_ARCHIVE")" + git archive --prefix="${DISTNAME}/" --output="$GIT_ARCHIVE" HEAD +fi + +########################### +# Binary Tarball Building # +########################### + +# CONFIGFLAGS +CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests" +case "$HOST" in + *linux*) CONFIGFLAGS+=" --enable-glibc-back-compat" ;; +esac + +# CFLAGS +HOST_CFLAGS="-O2 -g" +case "$HOST" in + *linux*) HOST_CFLAGS+=" -ffile-prefix-map=${PWD}=." ;; + *mingw*) HOST_CFLAGS+=" -fno-ident" ;; +esac + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +case "$HOST" in + *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -static-libstdc++ -Wl,-O2" ;; + *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; +esac + +# Make $HOST-specific native binaries from depends available in $PATH +export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + ./autogen.sh + + # Configure this DISTSRC for $HOST + # shellcheck disable=SC2086 + env CONFIG_SITE="${BASEPREFIX}/${HOST}/share/config.site" \ + ./configure --prefix=/ \ + --disable-ccache \ + --disable-maintainer-mode \ + --disable-dependency-tracking \ + ${CONFIGFLAGS} \ + CFLAGS="${HOST_CFLAGS}" \ + CXXFLAGS="${HOST_CXXFLAGS}" \ + ${HOST_LDFLAGS:+LDFLAGS="${HOST_LDFLAGS}"} + + sed -i.old 's/-lstdc++ //g' config.status libtool src/univalue/config.status src/univalue/libtool + + # Build BitSend Core + make --jobs="$MAX_JOBS" ${V:+V=1} + + # Perform basic ELF security checks on a series of executables. + make -C src --jobs=1 check-security ${V:+V=1} + + case "$HOST" in + *linux*|*mingw*) + # Check that executables only contain allowed gcc, glibc and libstdc++ + # version symbols for Linux distro back-compatibility. + make -C src --jobs=1 check-symbols ${V:+V=1} + ;; + esac + + # Make the os-specific installers + case "$HOST" in + *mingw*) + make deploy ${V:+V=1} BITSEND_WIN_INSTALLER="${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" + ;; + esac + + # Setup the directory where our BitSend Core build for HOST will be + # installed. This directory will also later serve as the input for our + # binary tarballs. + INSTALLPATH="${PWD}/installed/${DISTNAME}" + mkdir -p "${INSTALLPATH}" + # Install built BitSend Core to $INSTALLPATH + make install DESTDIR="${INSTALLPATH}" ${V:+V=1} + + ( + cd installed + + case "$HOST" in + *mingw*) + mv --target-directory="$DISTNAME"/lib/ "$DISTNAME"/bin/*.dll + ;; + esac + + # Prune libtool and object archives + find . -name "lib*.la" -delete + find . -name "lib*.a" -delete + + # Prune pkg-config files + rm -r "${DISTNAME}/lib/pkgconfig" + + # Split binaries and libraries from their debug symbols + { + find "${DISTNAME}/bin" -type f -executable -print0 + find "${DISTNAME}/lib" -type f -print0 + } | xargs -0 -n1 -P"$MAX_JOBS" -I{} "${DISTSRC}/contrib/devtools/split-debug.sh" {} {} {}.dbg + + case "$HOST" in + *mingw*) + cp "${DISTSRC}/doc/README_windows.txt" "${DISTNAME}/readme.txt" + ;; + *linux*) + cp "${DISTSRC}/README.md" "${DISTNAME}/" + ;; + esac + + # Finally, deterministically produce {non-,}debug binary tarballs ready + # for release + case "$HOST" in + *mingw*) + find "${DISTNAME}" -not -name "*.dbg" -print0 \ + | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" + find "${DISTNAME}" -not -name "*.dbg" \ + | sort \ + | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" && exit 1 ) + find "${DISTNAME}" -name "*.dbg" -print0 \ + | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" + find "${DISTNAME}" -name "*.dbg" \ + | sort \ + | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-debug.zip" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-debug.zip" && exit 1 ) + ;; + *linux*) + find "${DISTNAME}" -not -name "*.dbg" -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" && exit 1 ) + find "${DISTNAME}" -name "*.dbg" -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" && exit 1 ) + ;; + esac + ) +) + +case "$HOST" in + *mingw*) + cp -rf --target-directory=. contrib/windeploy + ( + cd ./windeploy + mkdir unsigned + cp --target-directory=unsigned/ "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" + find . -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" && exit 1 ) + ) + ;; +esac diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm new file mode 100644 index 00000000..1c8dd4b4 --- /dev/null +++ b/contrib/guix/manifest.scm @@ -0,0 +1,198 @@ +(use-modules (gnu) + (gnu packages) + (gnu packages autotools) + (gnu packages base) + (gnu packages bash) + (gnu packages check) + (gnu packages commencement) + (gnu packages compression) + (gnu packages cross-base) + (gnu packages file) + (gnu packages gawk) + (gnu packages gcc) + (gnu packages installers) + (gnu packages linux) + (gnu packages mingw) + (gnu packages perl) + (gnu packages pkg-config) + (gnu packages python) + (gnu packages shells) + (gnu packages version-control) + (guix build-system gnu) + (guix build-system trivial) + (guix gexp) + (guix packages) + (guix profiles) + (guix utils)) + +(define (make-ssp-fixed-gcc xgcc) + "Given a XGCC package, return a modified package that uses the SSP function +from glibc instead of from libssp.so. Our `symbol-check' script will complain if +we link against libssp.so, and thus will ensure that this works properly. + +Taken from: +http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html" + (package + (inherit xgcc) + (arguments + (substitute-keyword-arguments (package-arguments xgcc) + ((#:make-flags flags) + `(cons "gcc_cv_libc_provides_ssp=yes" ,flags)))))) + +(define (make-gcc-rpath-link xgcc) + "Given a XGCC package, return a modified package that replace each instance of +-rpath in the default system spec that's inserted by Guix with -rpath-link" + (package + (inherit xgcc) + (arguments + (substitute-keyword-arguments (package-arguments xgcc) + ((#:phases phases) + `(modify-phases ,phases + (add-after 'pre-configure 'replace-rpath-with-rpath-link + (lambda _ + (substitute* (cons "gcc/config/rs6000/sysv4.h" + (find-files "gcc/config" + "^gnu-user.*\\.h$")) + (("-rpath=") "-rpath-link=")) + #t)))))))) + +(define (make-cross-toolchain target + base-gcc-for-libc + base-kernel-headers + base-libc + base-gcc) + "Create a cross-compilation toolchain package for TARGET" + (let* ((xbinutils (cross-binutils target)) + ;; 1. Build a cross-compiling gcc without targeting any libc, derived + ;; from BASE-GCC-FOR-LIBC + (xgcc-sans-libc (cross-gcc target + #:xgcc base-gcc-for-libc + #:xbinutils xbinutils)) + ;; 2. Build cross-compiled kernel headers with XGCC-SANS-LIBC, derived + ;; from BASE-KERNEL-HEADERS + (xkernel (cross-kernel-headers target + base-kernel-headers + xgcc-sans-libc + xbinutils)) + ;; 3. Build a cross-compiled libc with XGCC-SANS-LIBC and XKERNEL, + ;; derived from BASE-LIBC + (xlibc (cross-libc target + base-libc + xgcc-sans-libc + xbinutils + xkernel)) + ;; 4. Build a cross-compiling gcc targeting XLIBC, derived from + ;; BASE-GCC + (xgcc (cross-gcc target + #:xgcc base-gcc + #:xbinutils xbinutils + #:libc xlibc))) + ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and + ;; XGCC + (package + (name (string-append target "-toolchain")) + (version (package-version xgcc)) + (source #f) + (build-system trivial-build-system) + (arguments '(#:builder (begin (mkdir %output) #t))) + (propagated-inputs + `(("binutils" ,xbinutils) + ("libc" ,xlibc) + ("libc:static" ,xlibc "static") + ("gcc" ,xgcc))) + (synopsis (string-append "Complete GCC tool chain for " target)) + (description (string-append "This package provides a complete GCC tool +chain for " target " development.")) + (home-page (package-home-page xgcc)) + (license (package-license xgcc))))) + +(define* (make-bitsend-cross-toolchain target + #:key + (base-gcc-for-libc gcc-5) + (base-kernel-headers linux-libre-headers-4.19) + (base-libc glibc-2.27) + (base-gcc (make-gcc-rpath-link gcc-9))) + "Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values +desirable for building BitSend Core release binaries." + (make-cross-toolchain target + base-gcc-for-libc + base-kernel-headers + base-libc + base-gcc)) + +(define (make-gcc-with-pthreads gcc) + (package-with-extra-configure-variable gcc "--enable-threads" "posix")) + +(define (make-mingw-pthreads-cross-toolchain target) + "Create a cross-compilation toolchain package for TARGET" + (let* ((xbinutils (cross-binutils target)) + (pthreads-xlibc mingw-w64-x86_64-winpthreads) + (pthreads-xgcc (make-gcc-with-pthreads + (cross-gcc target + #:xgcc (make-ssp-fixed-gcc gcc-9) + #:xbinutils xbinutils + #:libc pthreads-xlibc)))) + ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and + ;; XGCC + (package + (name (string-append target "-posix-toolchain")) + (version (package-version pthreads-xgcc)) + (source #f) + (build-system trivial-build-system) + (arguments '(#:builder (begin (mkdir %output) #t))) + (propagated-inputs + `(("binutils" ,xbinutils) + ("libc" ,pthreads-xlibc) + ("gcc" ,pthreads-xgcc))) + (synopsis (string-append "Complete GCC tool chain for " target)) + (description (string-append "This package provides a complete GCC tool +chain for " target " development.")) + (home-page (package-home-page pthreads-xgcc)) + (license (package-license pthreads-xgcc))))) + + +(packages->manifest + (append + (list ;; The Basics + bash-minimal + which + coreutils + util-linux + ;; File(system) inspection + file + grep + diffutils + findutils + ;; File transformation + patch + gawk + sed + ;; Compression and archiving + tar + bzip2 + gzip + xz + zlib + ;; Build tools + gnu-make + libtool + autoconf + automake + pkg-config + ;; Scripting + perl + python-3.7 + ;; Git + git + ;; Native gcc 9 toolchain targeting glibc 2.27 + (make-gcc-toolchain gcc-9 glibc-2.27)) + (let ((target (getenv "HOST"))) + (cond ((string-suffix? "-mingw32" target) + ;; Windows + (list zip (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32") nsis-x86_64)) + ((string-contains target "riscv64-linux-") + (list (make-bitsend-cross-toolchain "riscv64-linux-gnu" + #:base-gcc-for-libc gcc-7))) + ((string-contains target "-linux-") + (list (make-bitsend-cross-toolchain target))) + (else '()))))) diff --git a/contrib/init/README.md b/contrib/init/README.md old mode 100755 new mode 100644 index 36f0a2b9..3cfdff9a --- a/contrib/init/README.md +++ b/contrib/init/README.md @@ -5,7 +5,7 @@ Upstart: bitsendd.conf OpenRC: bitsendd.openrc bitsendd.openrcconf CentOS: bitsendd.init -macOS: org.bitsend.bitsendd.plist +macOS: org.bitsend.bitsendd.plist ``` have been made available to assist packagers in creating node packages here. diff --git a/contrib/init/bitsendd.conf b/contrib/init/bitsendd.conf old mode 100755 new mode 100644 index a6aed8e7..25c6342e --- a/contrib/init/bitsendd.conf +++ b/contrib/init/bitsendd.conf @@ -1,4 +1,4 @@ -description "Bitsend Core Daemon" +description "BitSend Core Daemon" start on runlevel [2345] stop on starting rc RUNLEVEL=[016] @@ -16,7 +16,7 @@ expect fork respawn respawn limit 5 120 -kill timeout 60 +kill timeout 600 pre-start script # this will catch non-existent config files @@ -38,7 +38,7 @@ pre-start script echo "It is recommended that you also set alertnotify so you are " echo "notified of problems:" echo - echo "ie: alertnotify=echo %%s | mail -s \"Bitsend Alert\"" \ + echo "ie: alertnotify=echo %%s | mail -s \"BitSend Alert\"" \ "admin@foo.com" echo exit 1 diff --git a/contrib/init/bitsendd.init b/contrib/init/bitsendd.init old mode 100755 new mode 100644 index ea8b2198..a7516b47 --- a/contrib/init/bitsendd.init +++ b/contrib/init/bitsendd.init @@ -39,7 +39,7 @@ start() { stop() { echo -n $"Stopping $prog: " - killproc $prog + killproc $prog -t600 RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f $lockfile diff --git a/contrib/init/bitsendd.openrc b/contrib/init/bitsendd.openrc old mode 100755 new mode 100644 index fbaa8ab5..f0c9ac17 --- a/contrib/init/bitsendd.openrc +++ b/contrib/init/bitsendd.openrc @@ -18,8 +18,8 @@ BITSENDD_BIN=${BITSENDD_BIN:-/usr/bin/bitsendd} BITSENDD_NICE=${BITSENDD_NICE:-${NICELEVEL:-0}} BITSENDD_OPTS="${BITSENDD_OPTS:-${BITSEND_OPTS}}" -name="Bitsend Core Daemon" -description="Bitsend cryptocurrency P2P network daemon" +name="BitSend Core Daemon" +description="BitSend cryptocurrency P2P network daemon" command="/usr/bin/bitsendd" command_args="-pid=\"${BITSENDD_PIDFILE}\" \ @@ -84,7 +84,7 @@ checkconfig() eerror "It is recommended that you also set alertnotify so you are " eerror "notified of problems:" eerror "" - eerror "ie: alertnotify=echo %%s | mail -s \"Bitsend Alert\"" \ + eerror "ie: alertnotify=echo %%s | mail -s \"BitSend Alert\"" \ "admin@foo.com" eerror "" return 1 diff --git a/contrib/init/bitsendd.openrcconf b/contrib/init/bitsendd.openrcconf old mode 100755 new mode 100644 index 368178a4..2ebb6768 --- a/contrib/init/bitsendd.openrcconf +++ b/contrib/init/bitsendd.openrcconf @@ -30,4 +30,4 @@ # Note that this will be mapped as argument to start-stop-daemon's # '--retry' option, which means you can specify a retry schedule # here. For more information see man 8 start-stop-daemon. -BITSENDD_SIGTERM_TIMEOUT=60 +BITSENDD_SIGTERM_TIMEOUT=600 diff --git a/contrib/init/bitsendd.service b/contrib/init/bitsendd.service old mode 100755 new mode 100644 index bfee7c3d..86c0d900 --- a/contrib/init/bitsendd.service +++ b/contrib/init/bitsendd.service @@ -5,20 +5,50 @@ # See "man systemd.service" for details. # Note that almost all daemon options could be specified in -# /etc/bitsend/bitsend.conf +# /etc/bitsend/bitsend.conf, but keep in mind those explicitly +# specified as arguments in ExecStart= will override those in the +# config file. [Unit] -Description=Bitsend daemon +Description=BitSend daemon After=network.target [Service] -ExecStart=/usr/bin/bitsendd -daemon -conf=/etc/bitsend/bitsend.conf -pid=/run/bitsendd/bitsendd.pid -# Creates /run/bitsendd owned by bitsend -RuntimeDirectory=bitsendd -User=bitsend +ExecStart=/usr/bin/bitsendd -daemon \ + -pid=/run/bitsendd/bitsendd.pid \ + -conf=/etc/bitsend/bitsend.conf \ + -datadir=/var/lib/bitsendd + +# Make sure the config directory is readable by the service user +PermissionsStartOnly=true +ExecStartPre=/bin/chgrp bitsend /etc/bitsend + +# Process management +#################### + Type=forking PIDFile=/run/bitsendd/bitsendd.pid Restart=on-failure +TimeoutStopSec=600 + +# Directory creation and permissions +#################################### + +# Run as bitsend:bitsend +User=bitsend +Group=bitsend + +# /run/bitsendd +RuntimeDirectory=bitsendd +RuntimeDirectoryMode=0710 + +# /etc/bitsend +ConfigurationDirectory=bitsend +ConfigurationDirectoryMode=0710 + +# /var/lib/bitsendd +StateDirectory=bitsendd +StateDirectoryMode=0710 # Hardening measures #################### @@ -29,6 +59,9 @@ PrivateTmp=true # Mount /usr, /boot/ and /etc read-only for the process. ProtectSystem=full +# Deny access to /home, /root and /run/user +ProtectHome=true + # Disallow the process and all of its children to gain # new privileges through execve(). NoNewPrivileges=true diff --git a/contrib/init/org.bitsend.bitsendd.plist b/contrib/init/org.bitsend.bitsendd.plist deleted file mode 100755 index 691730bf..00000000 --- a/contrib/init/org.bitsend.bitsendd.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Label - org.bitsend.bitsendd - ProgramArguments - - /usr/local/bin/bitsendd - - RunAtLoad - - - diff --git a/contrib/install_db4.sh b/contrib/install_db4.sh index a864d555..3f35e174 100755 --- a/contrib/install_db4.sh +++ b/contrib/install_db4.sh @@ -1,4 +1,7 @@ #!/bin/sh +# Copyright (c) 2017-2019 The BitSend 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). @@ -6,7 +9,7 @@ export LC_ALL=C set -e if [ -z "${1}" ]; then - echo "Usage: ./install_db4.sh [ ...]" + 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 bitsend repository." @@ -14,7 +17,7 @@ if [ -z "${1}" ]; then fi expand_path() { - echo "$(cd "${1}" && pwd -P)" + cd "${1}" && pwd -P } BDB_PREFIX="$(expand_path ${1})/db4"; shift; @@ -23,7 +26,7 @@ BDB_HASH='12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef' BDB_URL="https://download.oracle.com/berkeley-db/${BDB_VERSION}.tar.gz" check_exists() { - which "$1" >/dev/null 2>&1 + command -v "$1" >/dev/null } sha256_check() { @@ -51,7 +54,7 @@ http_get() { if [ -f "${2}" ]; then echo "File ${2} already exists; not downloading again" elif check_exists curl; then - curl --insecure "${1}" -o "${2}" + curl --insecure --retry 5 "${1}" -o "${2}" else wget --no-check-certificate "${1}" -O "${2}" fi @@ -70,6 +73,20 @@ CLANG_CXX11_PATCH_HASH='7a9a47b03fd5fb93a16ef42235fa9512db9b0829cfc3bdf90edd3ec1 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/bitsend/bitsend/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" \ @@ -81,7 +98,9 @@ make install echo echo "db4 build complete." echo +# shellcheck disable=SC2016 echo 'When compiling bitsendd, 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 old mode 100755 new mode 100644 index 2c2979ee..0dc5cc2d --- a/contrib/linearize/README.md +++ b/contrib/linearize/README.md @@ -1,6 +1,5 @@ # Linearize -Construct a linear, no-fork, best version of the Bitsend blockchain. The scripts -run using Python 3 but are compatible with Python 2. +Construct a linear, no-fork, best version of the BitSend blockchain. ## Step 1: Download hash list diff --git a/contrib/linearize/example-linearize.cfg b/contrib/linearize/example-linearize.cfg old mode 100755 new mode 100644 index b934a537..1c53dcc2 --- a/contrib/linearize/example-linearize.cfg +++ b/contrib/linearize/example-linearize.cfg @@ -13,6 +13,9 @@ port=8332 #regtest default #port=18443 +#signet default +#port=38332 + # bootstrap.dat hashlist settings (linearize-hashes) max_height=313000 @@ -28,6 +31,16 @@ input=/home/example/.bitsend/blocks #genesis=000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 #input=/home/example/.bitsend/testnet3/blocks +# regtest +#netmagic=fabfb5da +#genesis=0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206 +#input=/home/example/.bitsend/regtest/blocks + +# signet +#netmagic=0a03cf40 +#genesis=00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6 +#input=/home/example/.bitsend/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 diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index 78dc0d3d..0e3f7791 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -2,12 +2,11 @@ # # linearize-data.py: Construct a linear, no-fork version of the chain. # -# Copyright (c) 2013-2018 The Bitsend Core developers +# Copyright (c) 2013-2020 The BitSend 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 struct import re import os @@ -16,8 +15,9 @@ import hashlib import datetime import time +import glob from collections import namedtuple -from binascii import hexlify, unhexlify +from binascii import unhexlify settings = {} @@ -62,7 +62,7 @@ def calc_hash_str(blk_hdr): hash = calc_hdr_hash(blk_hdr) hash = bufreverse(hash) hash = wordreverse(hash) - hash_str = hexlify(hash).decode('utf-8') + hash_str = hash.hex() return hash_str def get_blk_dt(blk_hdr): @@ -93,6 +93,30 @@ def mkblockmap(blkindex): blkmap[hash] = height return blkmap +# This gets the first block file ID that exists from the input block +# file directory. +def getFirstBlockFileId(block_dir_path): + # First, this sets up a pattern to search for block files, for + # example 'blkNNNNN.dat'. + blkFilePattern = os.path.join(block_dir_path, "blk[0-9][0-9][0-9][0-9][0-9].dat") + + # This search is done with glob + blkFnList = glob.glob(blkFilePattern) + + if len(blkFnList) == 0: + print("blocks not pruned - starting at 0") + return 0 + # We then get the lexicographic minimum, which should be the first + # block file name. + firstBlkFilePath = min(blkFnList) + firstBlkFn = os.path.basename(firstBlkFilePath) + + # now, the string should be ['b','l','k','N','N','N','N','N','.','d','a','t'] + # So get the ID by choosing: 3 4 5 6 7 + # The ID is not necessarily 0 if this is a pruned node. + blkId = int(firstBlkFn[3:8]) + return blkId + # Block header and extent on disk BlockExtent = namedtuple('BlockExtent', ['fn', 'offset', 'inhdr', 'blkhdr', 'size']) @@ -102,7 +126,9 @@ def __init__(self, settings, blkindex, blkmap): self.blkindex = blkindex self.blkmap = blkmap - self.inFn = 0 + # Get first occurring block file id - for pruned nodes this + # will not necessarily be 0 + self.inFn = getFirstBlockFileId(self.settings['input']) self.inF = None self.outFn = 0 self.outsz = 0 @@ -214,8 +240,11 @@ def run(self): inMagic = inhdr[:4] if (inMagic != self.settings['netmagic']): - print("Invalid magic: " + hexlify(inMagic).decode('utf-8')) - return + # 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(" diff --git a/contrib/macdeploy/custom_dsstore.py b/contrib/macdeploy/custom_dsstore.py index 9690fada..69ef279e 100755 --- a/contrib/macdeploy/custom_dsstore.py +++ b/contrib/macdeploy/custom_dsstore.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2013-2017 The Bitsend Core developers +# Copyright (c) 2013-2018 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import biplist @@ -13,7 +13,7 @@ ds = DSStore.open(output_file, 'w+') ds['.']['bwsp'] = { 'ShowStatusBar': False, - 'WindowBounds': b'{{300, 280}, {500, 343}}', + 'WindowBounds': '{{300, 280}, {500, 343}}', 'ContainerShowSidebar': False, 'SidebarWidth': 0, 'ShowTabView': False, @@ -53,7 +53,7 @@ ds['.']['vSrn'] = ('long', 1) ds['Applications']['Iloc'] = (370, 156) -ds['Bitsend-Qt.app']['Iloc'] = (128, 156) +ds['BitSend-Qt.app']['Iloc'] = (128, 156) ds.flush() ds.close() diff --git a/contrib/macdeploy/detached-sig-apply.sh b/contrib/macdeploy/detached-sig-apply.sh index c442033f..8d1a6476 100755 --- a/contrib/macdeploy/detached-sig-apply.sh +++ b/contrib/macdeploy/detached-sig-apply.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2015 The Bitsend Core developers +# Copyright (c) 2014-2019 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -36,13 +36,13 @@ if [ -z "${CODESIGN_ALLOCATE}" ]; then fi find ${TEMPDIR} -name "*.sign" | while read i; do - SIZE=`stat -c %s "${i}"` - TARGET_FILE="`echo "${i}" | sed 's/\.sign$//'`" + 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'` + 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 diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh index b6889aea..10385cde 100755 --- a/contrib/macdeploy/detached-sig-create.sh +++ b/contrib/macdeploy/detached-sig-create.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2015 The Bitsend Core developers +# Copyright (c) 2014-2019 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,14 +7,14 @@ export LC_ALL=C set -e ROOTDIR=dist -BUNDLE="${ROOTDIR}/Bitsend-Qt.app" +BUNDLE="${ROOTDIR}/BitSend-Qt.app" CODESIGN=codesign TEMPDIR=sign.temp TEMPLIST=${TEMPDIR}/signatures.txt OUT=signature-osx.tar.gz OUTROOT=osx -if [ ! -n "$1" ]; then +if [ -z "$1" ]; then echo "usage: $0 " echo "example: $0 -s MyIdentity" exit 1 @@ -26,20 +26,20 @@ 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'` + 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}"`" + 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}/||"`" + TARGETFILE="${BUNDLE}/$(echo "${i}" | sed "s|.*${BUNDLE}/||")" RESOURCE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}" - DIRNAME="`dirname "${RESOURCE}"`" + DIRNAME="$(dirname "${RESOURCE}")" mkdir -p "${DIRNAME}" echo "Adding resource for: \"${TARGETFILE}\"" cp "${i}" "${RESOURCE}" diff --git a/contrib/macdeploy/extract-osx-sdk.sh b/contrib/macdeploy/extract-osx-sdk.sh index d8047535..59e1fb72 100755 --- a/contrib/macdeploy/extract-osx-sdk.sh +++ b/contrib/macdeploy/extract-osx-sdk.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2016 The Bitsend Core developers +# Copyright (c) 2016-2020 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/macdeploy/fancy.plist b/contrib/macdeploy/fancy.plist deleted file mode 100755 index 10d148d6..00000000 --- a/contrib/macdeploy/fancy.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - window_bounds - - 300 - 300 - 800 - 620 - - background_picture - background.tiff - icon_size - 96 - applications_symlink - - items_position - - Applications - - 370 - 156 - - Bitsend-Qt.app - - 128 - 156 - - - - diff --git a/contrib/macdeploy/gen-sdk b/contrib/macdeploy/gen-sdk new file mode 100755 index 00000000..457d8f5e --- /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 0c78001a..80564c0b 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -19,6 +19,7 @@ import subprocess, sys, re, os, shutil, stat, os.path, time from string import Template from argparse import ArgumentParser +from typing import List, Optional # This is ported from the original macdeployqt with modifications @@ -48,18 +49,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, + return """ Framework name: {} + Framework directory: {} + Framework path: {} + Binary name: {} + Binary directory: {} + Binary path: {} + Version: {} + Install name: {} + Deployed install name: {} + Source file Path: {} + Deployed Directory (relative to bundle): {} +""".format(self.frameworkName, self.frameworkDirectory, self.frameworkPath, self.binaryName, @@ -85,7 +86,7 @@ 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 @@ -146,15 +147,14 @@ class FrameworkInfo(object): 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 = "Bitsend-Qt" + appName = "BitSend-Qt" self.binaryPath = os.path.join(path, "Contents", "MacOS", appName) if not os.path.exists(self.binaryPath): raise RuntimeError("Could not find bundle binary for " + path) @@ -167,17 +167,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) @@ -186,9 +180,9 @@ 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: + nameDot = "{}.".format(name) + libNameDot = "lib{}.".format(name) for framework in self.deployedFrameworks: if framework.endswith(".framework"): if framework.startswith(nameDot): @@ -198,7 +192,7 @@ class DeploymentInfo(object): return True return False -def getFrameworks(binaryPath, verbose): +def getFrameworks(binaryPath: str, verbose: int) -> List[FrameworkInfo]: if verbose >= 3: print("Inspecting with otool: " + binaryPath) otoolbin=os.getenv("OTOOL", "otool") @@ -208,7 +202,7 @@ def getFrameworks(binaryPath, verbose): if verbose >= 1: sys.stderr.write(o_stderr) sys.stderr.flush() - raise RuntimeError("otool failed with return code %d" % otool.returncode) + raise RuntimeError("otool failed with return code {}".format(otool.returncode)) otoolLines = o_stdout.split("\n") otoolLines.pop(0) # First line is the inspected binary @@ -227,11 +221,11 @@ def getFrameworks(binaryPath, verbose): 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)) -def changeInstallName(oldName, newName, binaryPath, verbose): +def changeInstallName(oldName: str, newName: str, binaryPath: str, verbose: int): if verbose >= 3: print("Using install_name_tool:") print(" in", binaryPath) @@ -239,21 +233,21 @@ def changeInstallName(oldName, newName, binaryPath, verbose): print(" to", newName) runInstallNameTool("change", oldName, newName, binaryPath) -def changeIdentification(id, binaryPath, verbose): +def changeIdentification(id: str, binaryPath: str, verbose: int): if verbose >= 3: 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: print("Using strip:") print(" stripped", binaryPath) subprocess.check_call([stripbin, "-x", binaryPath]) -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 @@ -315,7 +309,7 @@ def copyFramework(framework, path, verbose): 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() @@ -361,15 +355,15 @@ 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)) + print("Warning: Could not find any external frameworks to deploy in {}.".format(applicationBundle.path)) return DeploymentInfo() else: return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) -def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): +def deployPlugins(appBundleInfo: ApplicationBundleInfo, deploymentInfo: DeploymentInfo, strip: bool, verbose: int): # Lookup available plugins, exclude unneeded plugins = [] if deploymentInfo.pluginPath is None: @@ -379,10 +373,12 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): if pluginDirectory == "designer": # Skip designer plugins 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 == "printsupport": + # Skip printsupport plugins + continue + elif pluginDirectory == "imageformats": + # Skip imageformats plugins + continue elif pluginDirectory == "sqldrivers": # Deploy the sql plugins only if QtSql is in use if not deploymentInfo.usesFramework("QtSql"): @@ -415,6 +411,42 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): # Deploy the mediaservice plugins only if QtMultimediaWidgets is in use if not deploymentInfo.usesFramework("QtMultimediaWidgets"): continue + elif pluginDirectory == "canbus": + # Deploy the canbus plugins only if QtSerialBus is in use + if not deploymentInfo.usesFramework("QtSerialBus"): + continue + elif pluginDirectory == "webview": + # Deploy the webview plugins only if QtWebView is in use + if not deploymentInfo.usesFramework("QtWebView"): + continue + elif pluginDirectory == "gamepads": + # Deploy the webview plugins only if QtGamepad is in use + if not deploymentInfo.usesFramework("QtGamepad"): + continue + elif pluginDirectory == "geoservices": + # Deploy the webview plugins only if QtLocation is in use + if not deploymentInfo.usesFramework("QtLocation"): + continue + elif pluginDirectory == "texttospeech": + # Deploy the texttospeech plugins only if QtTextToSpeech is in use + if not deploymentInfo.usesFramework("QtTextToSpeech"): + continue + elif pluginDirectory == "virtualkeyboard": + # Deploy the virtualkeyboard plugins only if QtVirtualKeyboard is in use + if not deploymentInfo.usesFramework("QtVirtualKeyboard"): + continue + elif pluginDirectory == "sceneparsers": + # Deploy the virtualkeyboard plugins only if Qt3DCore is in use + if not deploymentInfo.usesFramework("Qt3DCore"): + continue + elif pluginDirectory == "renderplugins": + # Deploy the renderplugins plugins only if Qt3DCore is in use + if not deploymentInfo.usesFramework("Qt3DCore"): + continue + elif pluginDirectory == "geometryloaders": + # Deploy the geometryloaders plugins only if Qt3DCore is in use + if not deploymentInfo.usesFramework("Qt3DCore"): + continue for pluginName in filenames: pluginPath = os.path.join(pluginDirectory, pluginName) @@ -437,6 +469,10 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): # Deploy the accessible qtquick plugin only if QtQuick is in use if not deploymentInfo.usesFramework("QtQuick"): continue + elif pluginPath == "platforminputcontexts/libqtvirtualkeyboardplugin.dylib": + # Deploy the virtualkeyboardplugin plugin only if QtVirtualKeyboard is in use + if not deploymentInfo.usesFramework("QtVirtualKeyboard"): + continue plugins.append((pluginDirectory, pluginName)) @@ -505,7 +541,7 @@ app_bundle = config.app_bundle[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("Error: Could not find app bundle \"{}\"\n".format(app_bundle)) sys.exit(1) app_bundle_name = os.path.splitext(os.path.basename(app_bundle))[0] @@ -517,7 +553,7 @@ if config.translations_dir and 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.stderr.write("Error: Could not find translation dir \"{}\"\n".format(translations_dir)) sys.exit(1) # ------------------------------------------------ @@ -526,7 +562,7 @@ for p in config.add_resources: 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.stderr.write("Error: Could not find additional resource file \"{}\"\n".format(p)) sys.exit(1) # ------------------------------------------------ @@ -543,17 +579,18 @@ if len(config.fancy) == 1: p = config.fancy[0] if verbose >= 3: - print("Fancy: Loading \"%s\"..." % p) + print("Fancy: Loading \"{}\"...".format(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.stderr.write("Error: Could not find fancy disk image plist at \"{}\"\n".format(p)) sys.exit(1) try: - fancy = plistlib.readPlist(p) + 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.stderr.write("Error: Could not parse fancy disk image plist at \"{}\"\n".format(p)) sys.exit(1) try: @@ -567,18 +604,18 @@ if len(config.fancy) == 1: 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.stderr.write("Error: Bad format of fancy disk image plist at \"{}\"\n".format(p)) sys.exit(1) if "background_picture" in fancy: bp = fancy["background_picture"] if verbose >= 3: - print("Fancy: Resolving background picture \"%s\"..." % bp) + print("Fancy: Resolving background picture \"{}\"...".format(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.stderr.write("Error: Could not find background picture at \"{}\" or \"{}\"\n".format(fancy["background_picture"], bp)) sys.exit(1) else: fancy["background_picture"] = bp @@ -602,7 +639,7 @@ else: # ------------------------------------------------ -target = os.path.join("dist", "Bitsend-Qt.app") +target = os.path.join("dist", "BitSend-Qt.app") if verbose >= 2: print("+ Copying source bundle +") @@ -629,7 +666,7 @@ try: config.plugins = False except RuntimeError as e: if verbose >= 1: - sys.stderr.write("Error: %s\n" % str(e)) + sys.stderr.write("Error: {}\n".format(str(e))) sys.exit(1) # ------------------------------------------------ @@ -642,7 +679,7 @@ if config.plugins: deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose) except RuntimeError as e: if verbose >= 1: - sys.stderr.write("Error: %s\n" % str(e)) + sys.stderr.write("Error: {}\n".format(str(e))) sys.exit(1) # ------------------------------------------------ @@ -658,14 +695,14 @@ else: 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(",")] + add_qt_tr = ["qt_{}.qm".format(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) + print("Checking for \"{}\"...".format(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.stderr.write("Error: Could not find Qt translation file \"{}\"\n".format(lng_file)) sys.exit(1) # ------------------------------------------------ @@ -706,14 +743,14 @@ 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("Code-signing app bundle {}".format(target)) + subprocess.check_call("codesign --force {} {}".format(os.environ['CODESIGNARGS'], target), shell=True) # ------------------------------------------------ if config.dmg is not None: - def runHDIUtil(verb, image_basename, **kwargs): + def runHDIUtil(verb: str, image_basename: str, **kwargs) -> int: hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"] if "capture_stdout" in kwargs: del kwargs["capture_stdout"] @@ -727,7 +764,7 @@ if config.dmg is not None: for key, value in kwargs.items(): hdiutil_args.append("-" + key) - if not value is True: + if value is not True: hdiutil_args.append(str(value)) return run(hdiutil_args, universal_newlines=True) @@ -771,8 +808,8 @@ if config.dmg is not None: 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) + + m = re.search(r"/Volumes/(.+$)", output) disk_root = m.group(0) disk_name = m.group(1) diff --git a/contrib/qos/README.md b/contrib/qos/README.md old mode 100755 new mode 100644 index d3e6ba2d..f57b6df6 --- a/contrib/qos/README.md +++ b/contrib/qos/README.md @@ -1,5 +1,5 @@ ### QoS (Quality of service) ### -This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitsend network. It limits outbound TCP traffic with a source or destination port of 8333, but not if the destination IP is within a LAN. +This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the BitSend network. It limits outbound TCP traffic with a source or destination port of 8333, but not if the destination IP is within a LAN. This means one can have an always-on bitsendd instance running, and another local bitsendd/bitsend-qt instance which connects to this node and receives blocks from it. diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh old mode 100755 new mode 100644 index 1cf4c84e..314a028d --- a/contrib/qos/tc.sh +++ b/contrib/qos/tc.sh @@ -1,4 +1,6 @@ -# Copyright (c) 2017 The Bitsend Core developers +#!/usr/bin/env bash +# +# Copyright (c) 2017-2019 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,7 +9,7 @@ export LC_ALL=C IF="eth0" #limit of the network interface in question LINKCEIL="1gbit" -#limit outbound Bitsend protocol traffic to this rate +#limit outbound BitSend protocol traffic to this rate LIMIT="160kbit" #defines the IPv4 address space for which you wish to disable rate limiting LOCALNET_V4="192.168.0.0/16" @@ -31,7 +33,7 @@ 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 [ ! -z "${LOCALNET_V6}" ] ; then +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 @@ -54,7 +56,7 @@ fi iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET_V4} -j MARK --set-mark 0x2 iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET_V4} -j MARK --set-mark 0x2 -if [ ! -z "${LOCALNET_V6}" ] ; then +if [ -n "${LOCALNET_V6}" ] ; then ip6tables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET_V6} -j MARK --set-mark 0x4 ip6tables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET_V6} -j MARK --set-mark 0x4 fi diff --git a/contrib/seeds/.gitignore b/contrib/seeds/.gitignore new file mode 100644 index 00000000..e4a39d60 --- /dev/null +++ b/contrib/seeds/.gitignore @@ -0,0 +1 @@ +seeds_main.txt diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md old mode 100755 new mode 100644 diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index 6c0a473d..0864865c 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -74,7 +74,7 @@ def name_to_ipv6(addr): raise ValueError('Could not parse address %s' % addr) def parse_spec(s, defaultport): - match = re.match('\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s) + match = re.match(r'\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s) if match: # ipv6 host = match.group(1) port = match.group(2) @@ -136,4 +136,3 @@ def main(): if __name__ == '__main__': main() - diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index ba4d50db..1ea0ea05 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2013-2018 The Bitsend Core developers +# Copyright (c) 2013-2020 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -19,18 +19,24 @@ # These are hosts that have been observed to be behaving strangely (e.g. # aggressively connecting to every node). -SUSPICIOUS_HOSTS = { - "130.211.129.106", "178.63.107.226", - "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6", - "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211", - "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214", - "54.94.195.96", "54.94.200.247" -} +with open("suspicious_hosts.txt", mode="r", encoding="utf-8") as f: + SUSPICIOUS_HOSTS = {s.strip() for s in f if s.strip()} + PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$") PATTERN_IPV6 = re.compile(r"^\[([0-9a-z:]+)\]:(\d+)$") PATTERN_ONION = re.compile(r"^([abcdefghijklmnopqrstuvwxyz234567]{16}\.onion):(\d+)$") -PATTERN_AGENT = re.compile(r"^(/Satoshi:0.14.(0|1|2|99)/|/Satoshi:0.15.(0|1|2|99)|/Satoshi:0.16.(0|1|2|99)/)$") +PATTERN_AGENT = re.compile( + r"^/Satoshi:(" + r"0.14.(0|1|2|3|99)|" + r"0.15.(0|1|2|99)|" + r"0.16.(0|1|2|3|99)|" + r"0.17.(0|0.1|1|2|99)|" + r"0.18.(0|1|99)|" + r"0.19.(0|1|99)|" + r"0.20.(0|1|99)|" + r"0.21.99" + r")") def parseline(line): sline = line.split() @@ -99,6 +105,13 @@ def parseline(line): 'sortkey': sortkey, } +def dedup(ips): + '''deduplicate by address,port''' + d = {} + for ip in ips: + d[ip['ip'],ip['port']] = ip + return list(d.values()) + def filtermultiport(ips): '''Filter out hosts with more nodes per IP''' hist = collections.defaultdict(list) @@ -106,62 +119,105 @@ def filtermultiport(ips): hist[ip['sortkey']].append(ip) return [value[0] for (key,value) in list(hist.items()) if len(value)==1] +def lookup_asn(net, ip): + ''' + Look up the asn for an IP (4 or 6) address by querying cymru.com, or None + if it could not be found. + ''' + try: + if net == 'ipv4': + ipaddr = ip + prefix = '.origin' + else: # http://www.team-cymru.com/IP-ASN-mapping.html + res = str() # 2001:4860:b002:23::68 + for nb in ip.split(':')[:4]: # pick the first 4 nibbles + for c in nb.zfill(4): # right padded with '0' + res += c + '.' # 2001 4860 b002 0023 + ipaddr = res.rstrip('.') # 2.0.0.1.4.8.6.0.b.0.0.2.0.0.2.3 + prefix = '.origin6' + + asn = int([x.to_text() for x in dns.resolver.query('.'.join( + reversed(ipaddr.split('.'))) + prefix + '.asn.cymru.com', + 'TXT').response.answer][0].split('\"')[1].split(' ')[0]) + return asn + except Exception: + sys.stderr.write('ERR: Could not resolve ASN for "' + ip + '"\n') + return None + # Based on Greg Maxwell's seed_filter.py -def filterbyasn(ips, max_per_asn, max_total): +def filterbyasn(ips, max_per_asn, max_per_net): # Sift out ips by type - ips_ipv4 = [ip for ip in ips if ip['net'] == 'ipv4'] - ips_ipv6 = [ip for ip in ips if ip['net'] == 'ipv6'] + ips_ipv46 = [ip for ip in ips if ip['net'] in ['ipv4', 'ipv6']] ips_onion = [ip for ip in ips if ip['net'] == 'onion'] - # Filter IPv4 by ASN + # Filter IPv46 by ASN, and limit to max_per_net per network result = [] - asn_count = {} - for ip in ips_ipv4: - if len(result) == max_total: - break - try: - asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0]) - if asn not in asn_count: - asn_count[asn] = 0 - if asn_count[asn] == max_per_asn: - continue - asn_count[asn] += 1 - result.append(ip) - except: - sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n') - - # TODO: filter IPv6 by ASN - - # Add back non-IPv4 - result.extend(ips_ipv6) - result.extend(ips_onion) + net_count = collections.defaultdict(int) + asn_count = collections.defaultdict(int) + for ip in ips_ipv46: + if net_count[ip['net']] == max_per_net: + continue + asn = lookup_asn(ip['net'], ip['ip']) + if asn is None or asn_count[asn] == max_per_asn: + continue + asn_count[asn] += 1 + net_count[ip['net']] += 1 + result.append(ip) + + # Add back Onions (up to max_per_net) + result.extend(ips_onion[0:max_per_net]) return result +def ip_stats(ips): + hist = collections.defaultdict(int) + for ip in ips: + if ip is not None: + hist[ip['net']] += 1 + + return '%6d %6d %6d' % (hist['ipv4'], hist['ipv6'], hist['onion']) + def main(): lines = sys.stdin.readlines() ips = [parseline(line) for line in lines] - # Skip entries with valid address. + print('\x1b[7m IPv4 IPv6 Onion Pass \x1b[0m', file=sys.stderr) + print('%s Initial' % (ip_stats(ips)), file=sys.stderr) + # Skip entries with invalid address. ips = [ip for ip in ips if ip is not None] + print('%s Skip entries with invalid address' % (ip_stats(ips)), file=sys.stderr) + # Skip duplicates (in case multiple seeds files were concatenated) + ips = dedup(ips) + print('%s After removing duplicates' % (ip_stats(ips)), file=sys.stderr) # Skip entries from suspicious hosts. ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS] + print('%s Skip entries from suspicious hosts' % (ip_stats(ips)), file=sys.stderr) # Enforce minimal number of blocks. ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS] + print('%s Enforce minimal number of blocks' % (ip_stats(ips)), file=sys.stderr) # Require service bit 1. ips = [ip for ip in ips if (ip['service'] & 1) == 1] - # Require at least 50% 30-day uptime. - ips = [ip for ip in ips if ip['uptime'] > 50] + print('%s Require service bit 1' % (ip_stats(ips)), file=sys.stderr) + # Require at least 50% 30-day uptime for clearnet, 10% for onion. + req_uptime = { + 'ipv4': 50, + 'ipv6': 50, + 'onion': 10, + } + ips = [ip for ip in ips if ip['uptime'] > req_uptime[ip['net']]] + print('%s Require minimum uptime' % (ip_stats(ips)), file=sys.stderr) # Require a known and recent user agent. ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])] + print('%s Require a known and recent user agent' % (ip_stats(ips)), file=sys.stderr) # Sort by availability (and use last success as tie breaker) ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True) # Filter out hosts with multiple bitsend ports, these are likely abusive ips = filtermultiport(ips) + print('%s Filter out hosts with multiple bitsend ports' % (ip_stats(ips)), file=sys.stderr) # Look up ASNs and limit results, both per ASN and globally. ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS) + print('%s Look up ASNs and limit results per ASN and per net' % (ip_stats(ips)), file=sys.stderr) # Sort the results by IP address (for deterministic output). ips.sort(key=lambda x: (x['net'], x['sortkey'])) - for ip in ips: if ip['net'] == 'ipv6': print('[%s]:%i' % (ip['ip'], ip['port'])) diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt old mode 100755 new mode 100644 index c0b5b299..5fcfc9f3 --- a/contrib/seeds/nodes_main.txt +++ b/contrib/seeds/nodes_main.txt @@ -1,1268 +1,1164 @@ -2.132.100.47:8333 -5.1.97.4:8333 -5.39.174.116:8333 -5.45.79.14:8333 -5.53.16.133:8333 -5.101.139.166:8333 -5.178.78.139:8333 -5.189.176.17:8333 -5.228.64.71:8333 -8.18.38.122:8333 -13.115.96.63:8333 -14.2.124.84:8333 -14.3.170.1:8333 -23.94.28.250:8333 -23.111.172.106:8333 -23.125.224.84:8333 -23.152.0.108:8333 -23.175.0.222:8333 -23.229.16.234:8333 -23.233.6.70:8333 -24.142.34.253:8333 -24.171.203.87:8333 -24.188.200.170:8333 -24.216.65.41:8333 -24.227.69.146:8333 -27.33.11.193:8333 -31.24.11.139:8333 -31.28.10.13:8333 -31.165.17.164:8333 -31.179.204.142:8333 -31.186.96.186:8333 -31.210.172.21:8333 -31.211.102.129:62734 -34.217.122.178:8333 -35.230.64.29:8333 -35.231.225.42:8333 -36.3.172.13:8333 -36.251.163.42:8333 -37.136.97.246:8333 -37.153.1.150:8333 -37.153.1.157:8333 +2.39.173.126:8333 +3.14.168.201:48333 +4.36.112.44:8333 +5.8.18.31:8333 +5.14.200.167:8333 +5.56.20.2:8333 +5.102.146.99:8333 +5.103.137.146:9333 +5.128.87.126:8333 +5.133.65.82:8333 +5.187.55.242:8333 +5.188.62.24:8333 +5.188.62.33:8333 +5.199.133.193:8333 +8.38.89.152:8333 +13.231.20.249:8333 +18.27.79.17:8333 +20.184.15.116:8433 +23.28.205.97:8333 +23.106.252.230:8333 +23.175.0.202:8333 +23.175.0.212:8333 +23.241.250.252:8333 +23.245.24.154:8333 +24.86.184.66:8333 +24.116.246.9:8333 +24.141.34.166:8333 +24.155.196.246:8333 +24.157.130.222:8333 +24.188.176.255:8333 +24.237.70.53:8333 +27.124.4.67:8333 +31.17.70.80:8333 +31.21.8.32:8333 +31.45.118.10:8333 +31.132.17.56:8333 +31.134.121.223:8333 +32.214.183.114:8333 +35.137.236.32:8333 +35.185.145.105:8333 +35.209.51.212:8333 +35.245.175.76:8333 +37.116.95.41:8333 +37.143.9.107:8333 +37.143.116.43:8333 +37.191.244.149:8333 +37.211.78.253:8333 +37.221.209.222:24333 37.228.92.110:8333 -37.252.14.22:8333 -38.27.101.224:8333 -38.102.134.85:8333 -38.104.225.30:8333 -43.229.76.38:8333 -45.40.132.57:8333 -45.45.34.122:8333 -45.48.177.222:8333 -46.19.34.236:8333 -46.28.66.196:8333 +43.225.62.107:8333 +43.225.157.152:8333 +45.36.184.6:8333 +45.48.168.16:8333 +45.85.85.8:8333 +45.85.85.9:8333 +45.129.180.214:8333 +45.149.78.128:8333 +45.151.125.218:8333 +45.154.255.46:8333 +45.155.157.239:8333 +46.28.132.34:8333 46.28.204.21:8333 -46.28.205.161:8333 -46.30.42.144:8333 -46.138.139.195:8333 -46.165.245.221:8333 -46.166.129.155:8333 -46.166.160.52:8333 -46.166.160.56:8333 -46.188.44.82:8333 -46.188.126.74:8333 -46.229.165.145:8333 -46.229.168.201:8333 +46.32.50.98:8333 +46.59.13.35:8333 +46.128.40.173:8333 +46.128.140.193:8333 +46.146.248.89:8333 +46.166.162.45:20001 +46.188.15.6:8333 +46.229.165.142:8333 46.229.238.187:8333 -47.54.204.246:8333 -47.74.128.138:8333 -47.94.224.99:8333 -47.97.96.198:8333 -47.187.36.48:8333 -47.218.16.81:8333 -47.223.66.222:8333 -47.254.128.15:8333 -50.31.170.53:8333 -50.35.67.146:8333 -50.76.96.230:8333 -50.82.177.142:8333 -51.15.3.46:8333 -51.175.141.243:8333 -52.144.47.153:8333 -52.232.38.122:8333 -54.38.192.164:8333 -54.85.65.6:8333 -54.91.227.188:8333 -58.180.36.14:8333 -59.106.208.68:8333 -60.70.73.26:8333 -61.160.234.57:8333 -62.43.198.56:8333 -62.45.0.15:8333 -62.107.200.30:8333 -62.133.194.2:8333 -62.138.3.224:8333 -62.146.70.216:8333 -64.78.163.10:8333 -64.120.110.2:8333 -64.131.160.31:8333 -66.18.172.16:8333 -66.85.74.242:8333 -66.110.132.10:8333 -66.114.33.90:8333 -66.180.64.95:8333 -66.222.164.188:8333 -67.11.139.67:8333 -67.43.191.118:8333 -67.61.137.157:8333 -67.193.184.12:8333 +46.249.83.82:8333 +46.254.217.169:8333 +47.74.191.34:8333 +47.115.53.163:8333 +47.187.26.135:8333 +47.222.103.234:8333 +47.253.5.99:8333 +49.232.82.76:8333 +49.247.215.43:8333 +50.2.13.166:8333 +50.34.39.72:8333 +50.45.232.189:8333 +50.68.104.92:8333 +51.68.36.57:8333 +51.154.60.34:8333 +52.169.238.66:8333 +54.197.30.223:8333 +54.227.66.57:8333 +58.158.0.86:8333 +58.171.135.242:8333 +58.229.208.158:8333 +60.244.109.19:8333 +62.38.75.208:8333 +62.74.143.11:8333 +62.80.227.49:8333 +62.152.58.16:9421 +62.210.167.199:8333 +62.234.188.160:8333 +62.251.54.163:8333 +63.227.116.162:8333 +65.19.155.82:8333 +65.95.49.102:8333 +66.18.172.21:8333 +66.240.237.155:8333 67.210.228.203:8333 -67.215.12.43:8333 -67.253.72.119:8333 -68.201.228.6:8333 -68.202.128.19:8333 -69.30.218.226:8333 -69.61.35.175:8333 -69.61.171.22:8333 -69.125.194.25:8333 -70.35.98.12:8333 -70.103.171.66:8333 -70.172.252.29:8333 -71.34.96.135:8333 -71.68.48.149:8333 -71.93.161.162:8333 -71.162.192.5:8333 -72.11.174.71:8333 -72.50.240.124:8333 -72.70.32.215:8333 -72.211.196.232:8333 -72.234.112.22:8333 -72.253.237.0:8333 -73.241.192.40:8333 -74.15.230.112:8333 -74.83.79.52:8333 -74.126.14.27:8333 -75.76.137.164:8333 -76.64.166.230:8333 -76.191.79.98:8333 -77.37.170.106:8333 -77.70.107.83:8333 -77.95.226.194:8333 -77.111.172.134:8333 -77.163.136.136:8333 -77.203.13.57:8333 -77.239.37.12:8333 -77.240.168.19:8333 -77.244.219.164:8333 -78.31.67.156:8333 -78.34.2.126:8333 -78.108.187.246:8333 -78.109.163.153:8333 -79.28.205.145:8333 -79.66.70.89:8333 -79.132.230.144:8333 -80.209.224.79:8333 -80.211.252.104:8333 +69.30.215.42:8333 +69.59.18.206:8333 +69.64.33.71:8333 +69.119.193.9:8333 +69.209.23.72:8333 +70.123.125.237:8333 +70.185.56.136:8333 +71.38.90.235:8333 +72.12.73.70:8333 +72.53.134.182:8333 +72.225.7.80:8333 +72.234.182.39:8333 +72.250.184.57:8333 +73.83.103.79:8333 +74.118.137.119:8333 +74.133.100.74:8333 +74.215.219.214:8333 +74.220.255.190:8333 +75.158.39.231:8333 +77.53.53.196:8333 +77.70.16.245:8333 +77.105.87.97:8333 +77.120.113.69:8433 +77.120.122.22:8433 +77.166.83.167:8333 +77.247.178.130:8333 +78.27.139.13:8333 +78.63.28.146:8333 +78.83.103.4:8333 +78.141.123.99:8333 +79.77.33.131:8333 +79.77.133.30:8333 +79.101.1.25:8333 +79.117.192.229:8333 +79.133.228.55:8333 +79.146.21.163:8333 +80.89.203.172:8001 +80.93.213.246:8333 +80.192.98.110:8334 80.229.28.60:8333 +80.232.247.210:8333 +80.242.39.76:8333 +80.253.94.252:8333 +81.0.198.25:8333 81.7.13.84:8333 -81.7.16.182:8333 -81.18.224.62:8333 -81.171.27.138:8333 -81.187.80.221:8333 -81.217.112.225:8333 -81.245.141.6:8333 -82.43.171.91:8333 -82.102.10.251:8333 -82.118.234.178:8333 -82.144.197.93:8333 -82.161.109.190:8333 -82.193.102.228:8333 -82.193.109.199:8333 +81.117.225.245:8333 +81.135.137.225:8333 +81.171.22.143:8333 +81.191.233.134:8333 +81.232.78.75:8333 +81.242.91.23:8333 +82.29.58.109:8333 +82.136.99.22:8333 +82.149.97.25:17567 +82.165.19.48:8333 +82.194.153.233:8333 +82.197.215.125:8333 82.199.102.10:8333 -82.212.130.94:8333 -82.213.208.16:8333 -82.217.67.17:8333 -82.221.108.27:8333 -82.221.133.174:8333 -83.55.130.30:8333 -83.77.39.46:8333 +82.200.205.30:8333 +82.202.68.231:8333 +82.221.128.31:8333 +82.228.6.131:8333 +83.85.139.94:8333 +83.99.245.20:8333 83.137.41.10:8333 -83.149.70.48:8333 -83.151.233.218:8333 -83.162.43.154:8333 -83.164.131.243:8333 -83.221.11.7:8333 -83.243.128.13:8333 -84.16.38.218:8333 +83.174.209.87:8333 +83.217.8.31:44420 84.38.3.249:8333 -84.75.26.172:8333 -84.200.106.128:8333 -84.212.250.219:8333 -84.215.134.195:8333 -84.245.27.209:8333 -84.254.40.152:8333 -84.255.193.28:8333 -85.10.112.194:8333 -85.93.2.76:54382 -85.94.172.33:8333 -85.129.0.126:8333 -85.145.168.159:8333 -85.170.238.26:8333 -85.195.232.197:8333 -85.214.68.122:8333 -85.214.235.137:8333 -85.218.48.146:8333 -85.220.165.205:8333 -85.229.134.98:8333 -85.241.49.242:8333 -86.25.32.77:8333 -86.41.89.170:8333 -86.50.143.43:8333 -86.61.67.183:8333 -86.137.26.210:8333 -86.177.194.215:8333 -87.157.177.58:8333 -87.224.163.66:8333 -87.236.196.169:8333 +84.38.185.122:8333 +84.92.92.247:8333 +84.192.16.234:8333 +84.194.158.124:8333 +84.212.145.24:8333 +84.212.244.95:8333 +84.216.51.36:8333 +84.255.249.163:8333 +85.25.255.147:8333 +85.70.156.209:8333 +85.145.142.46:8333 +85.170.233.95:8333 +85.184.138.108:8333 +85.190.0.5:8333 +85.191.200.51:8333 +85.192.191.6:18500 +85.194.238.131:8333 +85.195.54.110:8333 +85.214.161.252:8333 +85.214.185.51:8333 +85.241.106.203:8333 +85.246.168.252:8333 +86.56.238.247:8333 +87.61.90.230:8333 +87.79.68.86:8333 +87.79.94.221:8333 +87.120.8.5:20008 87.246.46.132:8333 -88.99.64.76:8333 -89.1.100.49:8333 -89.10.155.88:8333 -89.27.59.246:8333 -89.163.132.73:8333 -89.179.240.131:8333 -89.205.81.5:8333 -89.212.75.6:8333 -89.217.130.147:8333 -89.230.96.42:8333 +87.247.111.222:8333 +88.84.222.252:8333 +88.86.243.241:8333 +88.87.93.52:1691 +88.119.197.200:8333 +88.129.253.94:8333 +88.147.244.250:8333 +88.208.3.195:8333 +88.212.44.33:8333 +88.214.57.95:8333 +89.106.199.38:8333 +89.108.126.228:8333 +89.115.120.43:8333 +89.133.68.65:8333 +89.190.19.162:8333 89.248.172.10:8333 -90.46.57.17:8333 -90.110.11.101:8333 -90.240.37.163:8333 -91.65.4.21:8333 -91.65.192.159:8333 -91.83.237.185:8333 -91.110.125.26:8333 -91.121.160.59:8333 -91.135.0.187:8333 -91.143.109.68:8333 -91.195.42.134:8333 -91.221.70.137:8333 -92.35.132.5:8333 -92.42.37.141:8333 -92.54.16.144:8333 -92.62.34.184:8333 -92.186.231.240:8333 -93.123.80.47:8333 -93.170.13.15:8333 -93.171.201.68:8333 -93.179.197.152:8333 -93.190.206.151:8333 -93.191.131.177:8333 -93.208.132.214:8333 -94.104.97.247:8333 -94.156.35.8:8333 -94.199.173.113:8333 -95.42.2.113:8333 -95.94.225.61:8333 -95.154.237.24:8333 -95.158.39.64:8333 +90.146.153.21:8333 +90.182.165.18:8333 +91.106.188.229:8333 +91.193.237.116:8333 +91.204.99.178:8333 +91.204.149.5:8333 +91.214.70.63:8333 +91.228.152.236:8333 +92.12.154.115:8333 +92.249.143.44:8333 +93.12.66.98:8333 +93.46.54.4:8333 +93.115.20.130:8333 +93.123.180.164:8333 +93.189.145.169:8333 +93.241.228.102:8333 +94.19.7.55:8333 +94.19.128.204:8333 +94.52.112.227:8333 +94.154.96.130:8333 +94.156.174.201:8333 +94.158.246.183:8333 +94.177.171.73:8333 +94.199.178.233:8100 +94.237.125.30:8333 +94.247.134.77:8333 +95.48.228.45:8333 +95.69.249.63:8333 +95.82.146.70:8333 +95.83.73.31:8333 +95.84.164.43:8333 +95.87.226.56:8333 +95.110.234.93:8333 95.163.71.126:8333 -95.163.106.139:8333 -95.208.163.214:8333 -95.213.143.13:8333 -95.226.77.108:8333 -96.3.74.66:8333 -96.23.128.65:8333 -96.27.8.242:8333 -96.27.129.94:8333 -96.126.100.148:8333 -97.74.6.105:8333 -97.116.160.102:8333 -98.7.64.249:8333 -98.10.106.49:8333 -98.25.197.125:8333 -98.29.7.103:8333 -98.127.130.17:8333 -99.224.192.201:8333 -101.190.172.209:8333 -103.35.151.76:8334 -103.74.193.127:8333 -103.80.133.191:8333 -103.80.168.57:8333 -103.99.168.102:8333 -103.194.42.10:8333 -104.168.101.207:8333 -104.200.67.162:8333 -104.207.132.42:8333 -104.237.4.202:8333 -107.155.72.108:8333 -107.183.37.162:8333 -108.175.3.18:8333 -108.220.192.57:8333 -109.61.102.5:8333 -109.206.177.21:8333 -109.237.111.156:8333 -115.68.47.82:8333 -116.88.75.110:8333 -118.67.201.40:8333 -119.28.4.230:8333 -119.28.130.210:8333 -120.31.143.167:8333 -120.220.14.92:8333 -120.220.14.93:8333 -124.18.133.220:8333 -126.207.39.22:8333 -128.77.37.214:8333 -128.125.100.2:8333 -129.158.74.237:8333 -129.213.32.176:8333 -131.113.41.119:8333 -131.113.41.125:8333 -131.114.10.233:8333 +95.164.65.194:8333 +95.174.66.211:8333 +95.211.174.137:8333 +95.216.11.156:8433 +96.47.114.108:8333 +97.84.232.105:8333 +97.99.205.241:8333 +98.25.193.114:8333 +99.115.25.13:8333 +101.32.19.184:8333 +101.100.174.240:8333 +102.132.245.16:8333 +103.14.244.190:8333 +103.76.48.5:8333 +103.84.84.250:8335 +103.99.168.150:8333 +103.109.101.216:8333 +103.122.247.102:8333 +103.129.13.45:8333 +103.198.192.14:20008 +103.224.119.99:8333 +103.231.191.7:8333 +103.235.230.196:8333 +104.171.242.155:8333 +104.238.220.199:8333 +106.163.158.127:8333 +107.150.41.179:8333 +107.159.93.103:8333 +108.183.77.12:8333 +109.9.175.65:8333 +109.99.63.159:8333 +109.110.81.90:8333 +109.123.213.130:8333 +109.134.232.81:8333 +109.169.20.168:8333 +109.199.241.148:8333 +109.229.210.6:8333 +109.236.105.40:8333 +109.248.206.13:8333 +111.42.74.65:8333 +111.90.140.179:8333 +112.215.205.236:8333 +113.52.135.125:8333 +114.23.246.137:8333 +115.47.141.250:8885 +115.70.110.4:8333 +116.34.189.55:8333 +118.103.126.140:28333 +118.189.187.219:8333 +119.3.208.236:8333 +119.8.47.225:8333 +119.17.151.61:8333 +120.25.24.30:8333 +120.241.34.10:8333 +121.98.205.100:8333 +122.112.148.153:8339 +122.116.42.140:8333 +124.217.235.180:8333 +125.236.215.133:8333 +129.13.189.212:8333 +130.185.77.105:8333 131.188.40.191:8333 -131.188.42.36:8333 -134.0.112.92:8333 -134.3.26.190:8333 -135.23.196.24:8333 -135.84.207.4:8333 -136.59.129.125:8333 -136.61.239.7:8333 -137.117.164.18:8333 -139.130.41.82:8333 -141.134.71.188:8333 -141.213.6.57:8333 -141.223.82.139:8333 -142.0.130.49:8333 -142.0.130.53:8333 -144.118.141.232:8333 -148.66.58.146:8333 -150.95.130.17:8333 -150.187.36.233:8333 -150.249.76.102:8333 -153.125.129.187:8333 -153.125.224.107:8333 -154.48.236.250:8887 -154.66.207.126:8333 -155.143.140.186:8333 -157.131.142.164:8333 -158.64.79.182:8333 -158.85.93.163:8333 -158.140.128.239:8333 -158.174.131.171:8333 -159.8.4.19:8333 -159.217.144.68:8333 -159.217.144.252:8333 -159.253.47.202:8333 -162.155.64.226:8333 -162.222.100.118:8333 -162.255.168.27:8333 -162.255.168.30:8333 -163.158.228.125:8333 -165.227.96.38:8333 -169.229.238.17:8333 -171.25.165.145:8333 -171.33.177.9:8333 -172.72.228.93:8333 -172.96.161.244:8333 -172.102.228.150:8333 -172.118.136.98:8333 -173.46.65.8:8333 -173.212.193.35:8333 -173.239.33.85:8333 -173.243.64.48:8333 -174.115.129.37:8333 -176.12.6.59:8333 -176.107.184.29:8333 -176.123.10.192:8333 -176.126.167.10:8333 -176.185.235.163:8333 -176.223.130.254:8333 -178.0.71.136:8333 -178.12.32.39:8333 -178.85.64.212:8333 -178.124.162.209:8333 -178.128.192.21:8333 -178.151.133.56:8333 -178.193.96.201:8333 -178.248.200.126:8333 -178.254.7.88:8333 -180.233.106.171:8333 -181.166.168.210:8333 -183.66.227.70:12060 -183.111.108.56:8333 -184.70.33.190:8333 -184.105.70.100:8333 -184.105.70.101:8333 -185.12.7.38:8333 -185.21.216.134:8333 +131.193.220.15:8333 +135.23.124.239:8333 +136.33.185.32:8333 +136.56.170.96:8333 +137.226.34.46:8333 +138.229.26.42:8333 +139.9.249.234:8333 +141.101.8.36:8333 +143.176.224.104:8333 +144.2.69.224:8333 +144.34.161.65:18333 +144.91.116.44:8333 +144.137.29.181:8333 +148.66.50.50:8335 +148.72.150.231:8333 +148.170.212.44:8333 +149.167.99.190:8333 +154.92.16.191:8333 +154.221.27.21:8333 +156.19.19.90:8333 +156.241.5.190:8333 +157.13.61.76:8333 +157.13.61.80:8333 +157.230.166.98:14391 +158.75.203.2:8333 +158.181.125.150:8333 +158.181.226.33:8333 +159.100.242.254:8333 +159.100.248.234:8333 +159.138.87.18:8333 +160.16.0.30:8333 +162.0.227.54:8333 +162.0.227.56:8333 +162.62.18.226:8333 +162.209.1.233:8333 +162.243.175.86:8333 +162.244.80.208:8333 +162.250.188.87:8333 +162.250.189.53:8333 +163.158.202.112:8333 +163.158.243.230:8333 +165.73.62.31:8333 +166.62.82.103:32771 +166.70.94.106:8333 +167.86.90.239:8333 +169.44.34.203:8333 +172.93.101.73:8333 +172.105.7.47:8333 +173.23.103.30:8000 +173.53.79.6:8333 +173.70.12.86:8333 +173.89.28.137:8333 +173.176.184.54:8333 +173.208.128.10:8333 +173.254.204.69:8333 +173.255.204.124:8333 +174.94.155.224:8333 +174.114.102.41:8333 +174.114.124.12:8333 +176.10.227.59:8333 +176.31.224.214:8333 +176.74.136.237:8333 +176.99.2.207:8333 +176.106.191.2:8333 +176.160.228.9:8333 +176.191.182.3:8333 +176.212.185.153:8333 +176.241.137.183:8333 +177.38.215.73:8333 +178.16.222.146:8333 +178.132.2.246:8333 +178.143.191.171:8333 +178.148.172.209:8333 +178.148.226.180:8333 +178.150.96.46:8333 +178.182.227.50:8333 +178.236.137.63:8333 +178.255.42.126:8333 +180.150.52.37:8333 +181.39.32.99:8333 +181.48.77.26:8333 +181.52.223.52:8333 +181.238.51.152:8333 +183.88.223.208:8333 +183.110.220.210:30301 +184.95.58.166:8336 +184.164.147.82:41333 +184.171.208.109:8333 +185.25.48.39:8333 185.25.48.184:8333 -185.25.48.217:8333 -185.25.60.199:8333 -185.28.76.179:8333 -185.35.139.54:8333 -185.44.78.208:8333 -185.47.132.55:8333 -185.51.128.27:8333 -185.59.100.107:8333 -185.67.175.75:8333 -185.67.204.76:8333 -185.67.204.80:8333 -185.70.105.74:8339 +185.64.116.15:8333 +185.80.219.132:8333 185.85.3.140:8333 -185.86.15.23:8333 -185.86.15.25:8333 -185.102.71.6:8333 -185.117.74.21:8333 -185.121.173.223:8333 -185.128.40.122:8333 -185.145.131.218:8333 -185.147.237.169:8333 -185.162.128.83:8333 -185.165.76.220:8333 -185.172.165.130:8333 -185.177.5.4:8333 -185.183.131.75:8333 -185.186.208.208:8333 -185.215.224.22:8333 -185.224.80.108:8333 -185.225.16.4:8333 -185.243.112.214:8333 -185.244.193.18:8333 -185.248.160.66:8333 -186.19.136.144:8333 -188.68.38.243:8333 -188.68.240.89:8333 +185.95.219.53:8333 +185.108.244.41:8333 +185.134.233.121:8333 +185.145.128.21:8333 +185.148.3.227:8333 +185.153.196.240:8333 +185.158.114.184:8333 +185.165.168.196:8333 +185.181.230.74:8333 +185.185.26.141:8111 +185.186.208.162:8333 +185.189.132.178:57780 +185.211.59.50:8333 +185.233.148.146:8333 +185.238.129.113:8333 +185.249.199.106:8333 +185.251.161.54:8333 +187.189.153.136:8333 +188.37.24.190:8333 +188.42.40.234:18333 +188.61.46.36:8333 +188.68.45.143:8333 +188.127.229.105:8333 188.134.6.84:8333 -188.134.77.121:8333 -188.138.1.43:8333 -188.217.9.168:8333 -190.2.133.91:8333 -190.184.198.34:8333 +188.134.8.36:8333 +188.214.129.65:20012 +188.230.168.114:8333 +189.34.14.93:8333 +189.207.46.32:8333 190.211.204.68:8333 -192.139.35.143:8333 -192.162.100.156:8333 -192.162.101.250:8333 -192.206.202.6:8333 -192.207.12.244:8333 -192.207.12.245:8333 -192.228.101.157:8333 -193.112.192.73:8333 -193.170.166.12:8333 -194.15.231.236:8333 -194.165.16.33:8333 -194.181.80.77:8333 -194.186.160.253:8333 -194.247.13.7:8333 -194.247.13.32:8333 -195.0.203.21:8333 -195.38.168.114:8333 -195.43.141.28:8333 -195.95.225.248:8333 -195.123.224.7:8333 -195.154.235.79:8333 -195.169.99.82:8333 -195.201.0.81:8333 -197.155.6.43:8333 -198.44.231.160:6333 -198.58.102.35:8333 -198.137.202.175:8333 -199.127.224.50:8333 -199.182.129.26:8333 -199.188.204.102:8333 -199.188.204.155:8333 -199.244.49.224:8333 -199.249.230.37:15738 -200.83.123.46:8333 -200.109.67.71:8333 -200.122.128.185:8333 -202.153.199.182:8333 -202.159.136.54:8333 -202.168.16.232:8333 -203.11.71.1:8333 -203.162.80.219:8333 -203.178.143.13:8333 -204.15.11.4:8333 -206.125.169.162:8333 -206.174.55.164:8333 -207.182.146.18:8333 -208.93.66.198:8333 -208.98.196.249:8333 -208.107.224.202:8333 -208.110.65.114:8333 -208.118.235.190:8333 -209.122.208.131:8333 -209.126.110.198:8333 -209.131.238.80:8333 -212.56.108.81:8333 -212.73.150.132:8333 -212.77.224.145:8333 -212.85.90.194:8333 -212.92.101.30:8333 -212.112.133.92:8333 -212.227.132.167:8333 -213.10.100.182:8333 -213.57.240.69:8333 -213.91.205.134:8333 -213.125.67.108:8333 -213.152.161.170:45893 -213.155.3.216:8333 -213.180.70.138:8333 -213.185.226.225:8333 -216.71.203.79:8333 -216.194.164.211:8333 -216.240.168.226:8333 -217.20.130.72:8333 -217.23.9.180:8333 +191.209.21.188:8333 +192.3.11.20:8333 +192.3.185.210:8333 +192.65.170.15:8333 +192.65.170.50:8333 +192.146.137.18:8333 +192.157.202.178:8333 +192.227.80.83:8333 +193.10.203.23:8334 +193.25.6.206:8333 +193.42.110.30:8333 +193.58.196.212:8333 +193.106.28.8:8333 +193.189.190.123:8333 +193.194.163.35:8333 +193.194.163.53:8333 +194.14.246.205:8333 +194.36.91.253:8333 +194.126.113.135:8333 +194.135.135.69:8333 +195.56.63.4:8333 +195.56.63.5:8333 +195.67.139.54:8333 +195.135.194.8:8333 +195.202.169.149:8333 +195.206.105.42:8333 +195.209.249.164:8333 +198.1.231.6:8333 +198.200.43.215:8333 +199.182.184.204:8333 +199.247.7.208:8333 +199.247.249.188:8333 +200.7.252.118:8333 +200.20.186.254:8333 +200.83.166.136:8333 +202.55.87.45:8333 +202.79.167.65:8333 +202.108.211.135:8333 +202.169.102.73:8333 +203.130.48.117:8885 +203.132.95.10:8333 +203.151.166.123:8333 +204.93.113.108:8333 +204.111.241.195:8333 +206.124.149.66:8333 +207.115.102.98:8333 +207.229.46.150:8333 +208.76.252.198:8333 +208.100.13.56:8333 +208.100.178.175:8333 +208.110.99.105:8333 +209.6.210.179:8333 +209.133.220.74:8333 +209.141.57.57:8333 +211.27.147.67:8333 +212.34.225.118:8333 +212.89.173.216:8333 +212.99.226.36:9020 +212.237.96.98:8333 +213.89.131.53:8333 +216.38.129.164:8333 +216.134.165.55:8333 +216.146.251.8:8333 +216.189.190.95:8333 +216.226.128.189:8333 +216.236.164.82:8333 +217.19.216.210:8333 +217.26.32.10:8333 217.64.47.138:8333 -217.169.14.90:8333 -218.245.1.205:8333 -220.130.128.58:8333 +217.64.133.220:8333 +217.92.55.246:8333 +218.31.113.245:8333 +218.255.242.114:8333 220.133.39.61:8333 -222.239.193.116:8333 -222.239.193.120:8333 -[2001:0:4137:9e76:1cbd:3bc0:ade7:bf44]:8333 -[2001:0:4137:9e76:2046:150d:8d65:de4]:8333 -[2001:0:4137:9e76:2c99:3f36:d003:f47a]:8333 -[2001:0:4137:9e76:34b6:3910:a3dc:7bfa]:8333 -[2001:0:4137:9e76:3cec:2b5:525b:fb3c]:8333 -[2001:0:53aa:64c:c5:235d:a10d:e0]:8333 -[2001:0:53aa:64c:cbc:5ace:a625:39d1]:8333 -[2001:0:5ef5:79fb:38e5:36c1:d0ee:5d98]:8333 -[2001:0:5ef5:79fb:3c5c:c6c:39cf:69d3]:8333 -[2001:0:5ef5:79fb:896:ef4:ba63:8d15]:8333 -[2001:0:9d38:6ab8:106a:2112:e06b:b881]:8333 -[2001:0:9d38:6ab8:1c99:1655:e782:9340]:8333 -[2001:0:9d38:6ab8:20cd:1cd9:54e6:5a6e]:8333 -[2001:0:9d38:6ab8:245e:2b3:a300:317e]:8333 -[2001:0:9d38:6ab8:2814:215c:88e3:4ee0]:8333 -[2001:0:9d38:6ab8:30ac:3a51:b2da:712d]:8333 -[2001:0:9d38:6ab8:34a6:eeb:c3ed:5be7]:8333 -[2001:0:9d38:6ab8:c2f:16d5:525a:107e]:8333 -[2001:0:9d38:6ab8:cb1:2557:431c:f3e1]:8333 -[2001:0:9d38:6abd:1056:290d:a671:3d90]:8333 -[2001:0:9d38:6abd:1865:14fe:d0a7:1f72]:8333 -[2001:0:9d38:6abd:2c3c:3006:a486:93c3]:8333 -[2001:0:9d38:6abd:2c73:3313:f21a:96da]:8333 -[2001:0:9d38:6abd:3050:fbff:a250:3386]:8333 -[2001:0:9d38:6abd:3828:494:fdaa:56cd]:8333 -[2001:0:9d38:6abd:454:187d:3e75:b00b]:8333 -[2001:0:9d38:78cf:c2c:1dcc:fa42:41a3]:8333 -[2001:0:9d38:90d7:1c4a:20d4:4daa:eb5a]:8333 -[2001:0:9d38:90d7:1ca7:1612:9a18:31e5]:8333 -[2001:0:9d38:90d7:24c8:3a0a:a68d:f799]:8333 -[2001:0:9d38:90d7:2837:324e:d0cb:9f45]:22475 -[2001:0:9d38:90d7:28c1:361e:a69c:b099]:8333 -[2001:0:9d38:90d7:30fe:1c89:d0b4:4d18]:8333 -[2001:0:9d38:90d7:3474:1df1:e732:e5e3]:8333 -[2001:0:9d38:90d7:34a8:fb1:88e3:fb19]:8333 -[2001:0:9d38:90d7:3c19:3d23:d0b4:f831]:18652 -[2001:0:9d38:90d7:3c45:2342:d0cb:d6ca]:8333 -[2001:0:9d38:90d7:3c5f:3105:d0b4:60b6]:8333 -[2001:0:9d38:90d7:8a1:2fb:d0cb:1e8f]:8333 -[2001:0:9d38:90d7:a3:36e0:e020:53fa]:8333 -[2001:0:9d38:90d7:eb:3b30:d0a4:aa5]:8333 -[2001:0:9d38:953c:104e:8af:b3aa:f300]:8333 -[2001:0:9d38:953c:1434:71f:b850:bab1]:8333 -[2001:0:9d38:953c:144a:36e8:519a:bb69]:8333 -[2001:0:9d38:953c:20fc:26ef:ed26:c737]:8333 -[2001:0:9d38:953c:454:120:88e8:2fb]:8333 -[2001:0:9d38:953c:801:1620:bc22:95bc]:8333 -[2001:0:9d38:953c:8a0:1fdb:ab00:bc2]:8333 -[2001:0:9d38:953c:cf6:3d48:4386:4937]:8333 -[2001:13d8:1c01:1000::8]:8333 -[2001:1620:923:0:75be:ed92:1a01:641]:8333 -[2001:1680:101:8c::1]:8333 -[2001:1970:5ae2:2b00:30bd:7910:c84:7a8f]:8333 -[2001:1970:5d56:aa01:1e75:8ff:fead:da48]:8333 -[2001:19f0:300:1045:225:90ff:fec9:29b3]:8333 -[2001:19f0:5:1f93:5400:1ff:fe7a:c65a]:8333 -[2001:19f0:6c01:4bd:5400:1ff:fe76:4db6]:8333 -[2001:19f0:ac01:2fb:5400:ff:fe5b:c3ff]:8333 -[2001:1a48:7:af1a:75f8:2c47:3285:d50e]:8333 -[2001:1af8:4010:a094:3333::8c38]:8333 -[2001:1af8:4070:a016:3333::5afb]:8333 -[2001:1af8:4700:a071:4444::e26e]:8333 -[2001:200:0:8801:5054:ff:fef2:1d0]:8333 -[2001:4128:6135:2010:21e:bff:fee8:a3c0]:8333 -[2001:41d0:1000:1f98::]:8333 -[2001:41d0:1004:18c7::]:8333 -[2001:41d0:1004:19dc::]:18555 -[2001:41d0:1004:1f7c::]:8333 -[2001:41d0:1008:2bed::]:8333 -[2001:41d0:1:45d8::1]:8333 -[2001:41d0:1:5395::1]:8333 -[2001:41d0:1:85d3::1]:8333 -[2001:41d0:1:8649::1]:8333 -[2001:41d0:1:8b26::1]:8333 -[2001:41d0:1:a5b8::1]:8333 -[2001:41d0:1:ab6b::1]:8333 -[2001:41d0:1:d227::]:8333 -[2001:41d0:1:f897::1]:8333 -[2001:41d0:1:f932::1]:8333 -[2001:41d0:2:34b7::1]:8333 -[2001:41d0:2:4975::]:8333 -[2001:41d0:2:5c22::]:8333 -[2001:41d0:2:84d4::1]:8333 -[2001:41d0:2:ab38::]:8333 -[2001:41d0:2:c33c::]:8333 -[2001:41d0:303:193b::]:8333 -[2001:41d0:303:2505::1a]:8333 -[2001:41d0:303:41db::]:58333 -[2001:41d0:303:4c68::]:8333 -[2001:41d0:303:508::]:8333 -[2001:41d0:303:6767::]:8333 -[2001:41d0:303:68cd::]:8333 -[2001:41d0:602:17a4::]:8333 -[2001:41d0:602:1842::]:8333 -[2001:41d0:602:3b7::]:8333 -[2001:41d0:602:898::]:8333 -[2001:41d0:602:b1a::]:8333 -[2001:41d0:800:135::]:8333 -[2001:41d0:800:3d3::]:8333 -[2001:41d0:8:101d::1]:8333 -[2001:41d0:8:1b29::]:8333 -[2001:41d0:8:3f74::1]:8333 -[2001:41d0:8:43a0::]:8333 -[2001:41d0:8:bb32::1]:8333 -[2001:41d0:8:bed3::]:8333 -[2001:41d0:8:c67c::]:8333 -[2001:41d0:8:ca2d::]:8333 -[2001:41d0:8:d444::1]:8333 -[2001:41d0:8:ddb::1]:8333 -[2001:41d0:8:ea86::1]:8333 -[2001:41d0:a:1220::1]:8333 -[2001:41d0:a:27ed::1]:8333 -[2001:41d0:a:296c::]:8139 -[2001:41d0:a:2b18::1]:8333 -[2001:41d0:a:405c::]:8333 -[2001:41d0:a:42df::]:8312 -[2001:41d0:a:4c49::aca:7929]:8333 -[2001:41d0:a:6927::1]:8333 -[2001:41d0:a:69a2::1]:8333 -[2001:41d0:a:6a87::1]:8333 -[2001:41d0:a:6c29::1]:8333 -[2001:41d0:a:6c7d::1]:8333 -[2001:41d0:a:f243::1]:8333 -[2001:41d0:a:f9cd::1]:8333 -[2001:41d0:d:dc9::]:8333 -[2001:41d0:e:1146::1]:8333 -[2001:41d0:e:126::1]:8333 -[2001:41d0:e:12aa::1]:8333 -[2001:41d0:e:1388::1]:8333 -[2001:41d0:e:ec5::1]:8333 -[2001:41f0:0:4:62:6974:636f:696e]:8333 -[2001:470:18:be4::2]:8333 -[2001:470:1c62:b170:bbff:53f1:edbf:99df]:42434 -[2001:470:1f06:15b4::2]:8333 -[2001:470:1f06:cea::2]:8333 -[2001:470:1f07:803:20c:29ff:fe2d:5879]:8333 -[2001:470:1f08:3cc::2]:8333 -[2001:470:1f0a:18dd::2]:8333 -[2001:470:1f15:11f8::10]:8333 -[2001:470:1f15:cf7::14]:8333 -[2001:470:1f17:b5::10]:8333 -[2001:470:1f1a:172::2]:8333 -[2001:470:1f1b:5a6:216:3eff:fe24:1162]:8333 -[2001:470:28:365::7]:8333 -[2001:470:41:6::2]:8333 -[2001:470:6c80:101::1]:8333 -[2001:470:6c80:3::1]:8333 -[2001:470:7:63e::2]:8333 -[2001:470:7:b74::2]:8333 -[2001:470:8:bd3:4d25:ca57:a5b7:c6c4]:8333 +223.16.30.175:8333 +[2001:19f0:6001:306f:ec4:7aff:fe8f:66ec]:8333 +[2001:1bc0:cc::a001]:8333 +[2001:1c02:2f18:d00:b62e:99ff:fe49:d492]:8333 +[2001:4100:0:64::93]:8333 +[2001:4100:0:64:dcaf:afff:fe00:6707]:8333 [2001:470:a:c13::2]:8333 -[2001:470:c144:cafe::23]:8333 -[2001:470:c3c4:100:100::202]:8333 -[2001:470:e696::1]:8333 -[2001:48f8:1003::3ba]:8333 -[2001:48f8:9015:1422:3dc0:fcf2:772f:57bc]:8333 -[2001:4ba0:babe:832::]:8333 -[2001:628:22a0:9::12]:8333 +[2001:4801:7819:74:b745:b9d5:ff10:a61a]:8333 +[2001:4ba0:fffa:5d::93]:8333 +[2001:610:1908:ff01:f816:3eff:fe33:2e32]:8333 [2001:638:a000:4140::ffff:191]:8333 -[2001:638:a000:4142::ff10:bed6]:8333 -[2001:67c:21ec:1000::a]:8333 -[2001:8d8:90b:c000::21:2fc0]:8333 -[2001:8d8:91c:9200::5c:d425]:8333 -[2001:980:231b:1:8e89:a5ff:fee3:f8be]:8333 -[2001:980:ade8:1:14fc:fd6d:608c:f669]:8333 -[2001:981:bdbd:1:c506:7d38:4b47:da15]:8333 -[2001:982:27f2:1:7271:bcff:fe94:d5bb]:8333 -[2001:984:26b5::1]:8333 -[2001:984:aec7:1:dcb7:29a:7eda:b9a2]:8333 -[2001:985:79af:20::35]:8333 -[2001:985:cb69:0:20c:29ff:feaf:dd5e]:8333 -[2001:b011:300d:1870:9c87:d4ff:fe9c:2d0f]:8333 -[2001:b030:2422::208d]:8333 -[2001:bc8:31d7:100::1]:8333 -[2001:bc8:323c:100::]:8333 -[2001:bc8:33ac:19ff::26]:8333 -[2001:bc8:399f:f000::1]:8333 -[2001:bc8:3dc1:100::142]:8333 -[2001:bc8:4400:2000::463b]:8333 -[2001:bc8:4400:2400::1b35]:8333 -[2001:bc8:4700:2000::5823]:8333 -[2001:da8:8001:2303:1cf4:4466:3f1a:7edb]:8333 -[2001:da8:d800:741:652d:52db:5713:4515]:8333 -[2002:17e5:10ea::17e5:10ea]:8333 -[2002:1f2b:8cbe::1f2b:8cbe]:8333 -[2002:2f59:30f3::2f59:30f3]:8333 -[2002:2f5a:562a::2f5a:562a]:8333 -[2002:3e92:46d8::3e92:46d8]:8333 -[2002:3f62:e6bb::3f62:e6bb]:8333 -[2002:404e:a30a::404e:a30a]:8333 -[2002:43db:9616::43db:9616]:8333 -[2002:43e5:a1fa::43e5:a1fa]:8333 -[2002:5266:afb::5266:afb]:8333 -[2002:5dbd:91a9::5dbd:91a9]:8333 -[2002:627e:333d::627e:333d]:8333 -[2002:6b9b:486c::6b9b:486c]:8333 -[2002:6dcb:7cba::6dcb:7cba]:8333 -[2002:7cf8:e33e::7cf8:e33e]:8333 -[2002:8e00:8231::8e00:8231]:8333 -[2002:8e00:8233::8e00:8233]:8333 -[2002:b07e:a70a::b07e:a70a]:8333 -[2002:b2c9:e6fc:10:3d5c:e3ad:813:9c46]:8333 -[2002:b4b2:3612::b4b2:3612]:8333 -[2002:b610:1ca2::b610:1ca2]:8333 -[2002:b610:1ca3::b610:1ca3]:8333 -[2002:b845:3322::1]:8333 -[2002:b946:694a::b946:694a]:8339 -[2002:b960:5e18::b960:5e18]:8333 -[2002:c23f:8fc5::c23f:8fc5]:8333 -[2002:c2a5:1021::c2a5:1021]:8333 -[2002:c62c:e7a0::c62c:e7a0]:6333 -[2002:ca99:c7b6::ca99:c7b6]:8333 -[2002:d035:2734::d035:2734]:8333 -[2002:d06e:5d1a::d06e:5d1a]:8333 -[2002:d8da:b949::d8da:b949]:8333 -[2400:2410:a960:4800:18be:d624:7018:cd2f]:8333 -[2400:6180:0:d0::3e1:b001]:8333 -[2400:6180:0:d0::5cd2:a001]:8333 -[2400:6180:0:d1::4c6:8001]:8333 -[2400:6180:100:d0::797:a001]:8333 -[2400:8500:1302:817:150:95:130:17]:8333 -[2401:1800:7800:106:be76:4eff:fe1c:1879]:8333 +[2001:648:2800:131:4b1f:f6fc:20f7:f99f]:8333 +[2001:678:7dc:8::2]:8333 +[2001:678:cc8::1:10:88]:20008 +[2001:67c:1220:80c::93e5:dd2]:8333 +[2001:67c:1220:80c:e5dc:ad0c:9289:c28f]:8333 +[2001:67c:16dc:1201:5054:ff:fe17:4dac]:8333 +[2001:67c:2354:2::22]:8333 +[2001:67c:26b4:12:7ae3:b5ff:fe04:6f9c]:8333 +[2001:67c:2f0::20:fa]:8333 +[2001:718:801:311:5054:ff:fe19:c483]:8333 +[2001:8d8:87c:7c00::99:3c1]:8333 +[2001:8f1:1404:3700:8e49:715a:2e09:b634]:9444 +[2001:b07:5d29:99a5:194b:3874:d65e:a90d]:8333 +[2001:ba8:1f1:f0fe::2]:8333 +[2001:bc8:1200:0:dac4:97ff:fe2a:3554]:20008 +[2001:da8:100d:22:10fa:d85f:10f2:21fd]:8333 +[2001:da8:8001:7a39:f035:7d:b99f:eb79]:8333 +[2001:e42:103:100::30]:8333 +[2400:2412:103:c900:825:8f20:eaff:65c2]:8333 +[2400:4052:e20:4f00:69fe:bb33:7b1c:a1ca]:8333 +[2401:1800:7800:105:be76:4eff:fe1c:b35]:8333 [2401:3900:2:1::2]:8333 -[2401:a400:3200:5600:3c16:2deb:abce:70cd]:8333 -[2401:b140::43:100]:8333 -[2401:b140::43:102]:8333 -[2402:1f00:8100:21c::]:8333 -[2403:bd80:c000:1:103:202:216:182]:8333 -[2405:6580:c5c0:1700:6cd2:b72e:740e:4311]:8333 -[2405:800:1000:1:1000::2001]:8333 -[2405:9800:b560:96d:630:c28e:a79a:a182]:8333 +[2401:b140::44:150]:8333 +[2401:d002:4402:0:8f28:591a:6ea0:c683]:8333 +[2403:6200:8821:3d68:195b:87e9:6819:d5c8]:8333 +[2405:6580:2140:3a00:c28c:983:364b:5d70]:8333 +[2405:9800:b911:a18a:58eb:cd3c:9d82:ea4a]:8333 [2405:aa00:2::40]:8333 [2409:10:ca20:1df0:224:e8ff:fe1f:60d9]:8333 -[2600:1f16:625:e00:269a:3452:2edf:1011]:8333 -[2600:1f16:625:e00:7bc:5879:4463:15dd]:8333 -[2600:1f16:625:e00:a28b:5a16:849c:fe41]:8333 -[2600:1f16:625:e00:a70f:e728:e8e1:2c2e]:8333 -[2600:3c00::f03c:91ff:fe0c:4d74]:8333 -[2600:3c00::f03c:91ff:fe2b:bf38]:8333 -[2600:3c00::f03c:91ff:fe91:3e49]:8333 -[2600:3c00::f03c:91ff:feb6:19f2]:8333 -[2600:3c01::f03c:91ff:fe91:6a29]:8333 -[2600:3c01::f03c:91ff:fed8:85a2]:8333 -[2600:3c01::f03c:91ff:fed8:db38]:8333 -[2600:3c03::f03c:91ff:fe28:1445]:8333 -[2601:147:4300:e61::30c]:8333 -[2601:147:4300:e61::f91]:8333 -[2601:186:c100:6bcd:16bd:cea1:235d:1c19]:8333 -[2601:18d:4600:5f32:20e7:b3ff:fecf:a99]:8333 -[2601:240:4601:ecee:309a:f9de:b64d:87df]:8333 -[2601:240:8100:256b:20c:29ff:fe5e:d707]:8333 -[2601:646:c202:5301:101b:a096:efba:c10a]:8333 -[2601:807:8000:9508:9993:d2b3:1a:8225]:8333 -[2601:c8:4100:770:c37:807b:98cc:bd7e]:8333 -[2602:100:6154:d6e3:2c91:d0de:b032:b0a4]:8333 -[2602:100:6154:d6e3::60]:8333 -[2602:61:786c:2c00::1]:8333 -[2602:ff83:fff:fffe::75]:8333 -[2602:ff83:fff:fffe::76]:8333 -[2603:3005:3000:5000:bc5a:72ac:36e9:175e]:8333 -[2604:0:c1:100:6bc1:f98a:97f9:3845]:8333 -[2604:2d80:c808:857b:8d6:9e1c:7131:4bea]:8333 -[2604:4080:1008:0:96de:80ff:fe62:e650]:8333 -[2604:4300:a:104:b699:baff:feaa:5109]:8333 -[2604:5500:c226:7f00:2d96:ed64:ce45:9a6]:8333 -[2604:8d80:100::adf3:4030]:8333 -[2604:a880:2:d0::22f8:e001]:8333 -[2604:a880:2:d0::22f8:f001]:8333 -[2604:a880:2:d0::22f9:1]:8333 -[2604:a880:2:d0::22f9:1001]:8333 -[2604:a880:2:d0::22f9:c001]:8333 -[2604:a880:2:d0::22f9:d001]:8333 -[2604:a880:2:d0::22f9:e001]:8333 -[2604:a880:2:d0::22fa:1001]:8333 -[2604:a880:2:d0::22fa:2001]:8333 -[2604:a880:2:d0::22fa:3001]:8333 -[2604:a880:2:d0::38:f001]:8333 -[2604:a880:2:d0::662:c001]:8333 -[2604:a880:400:d0::1ac4:b001]:8333 -[2604:a880:400:d0::2004:4001]:8333 -[2604:a880:400:d0::2004:5001]:8333 -[2604:a880:400:d0::2004:6001]:8333 -[2604:a880:400:d0::2004:d001]:8333 -[2604:a880:400:d0::2004:e001]:8333 -[2604:a880:400:d0::2005:1]:8333 -[2604:a880:400:d0::2005:2001]:8333 -[2604:a880:400:d0::2005:3001]:8333 -[2604:a880:400:d0::cd7:4001]:8333 -[2604:a880:400:d1::729:b001]:8333 -[2604:a880:800:a1::11a9:8001]:8333 -[2604:a880:800:a1::59:9001]:8333 -[2604:a880:800:a1::cbb:f001]:8333 -[2604:a880:800:a1::ee8:e001]:8333 -[2604:a880:cad:d0::370:f001]:8333 -[2604:a880:cad:d0::a52:6001]:8333 +[2409:8a1e:a9af:3660:1c5a:5b6b:8a2d:9848]:8333 +[2409:8a1e:a9af:3660:404:39ba:88f2:e8df]:8333 +[240b:10:9141:400:49b4:3a2e:1e5:84c]:8333 +[240d:1a:759:6000:a7b1:451a:8874:e1ac]:8333 +[240d:1a:759:6000:ddab:3141:4da0:8878]:8333 +[2600:8805:2400:14e:12dd:b1ff:fef2:3013]:8333 +[2601:602:8d80:b63:dc3e:24ff:fe92:5eb]:8333 +[2602:ffb6:4:2798:f816:3eff:fe2f:5441]:8333 +[2602:ffb6:4:739e:f816:3eff:fe00:c2b3]:8333 +[2602:ffb8::208:72:57:200]:8333 +[2604:1380:4111:9300::1]:8333 +[2604:4300:a:2e:21b:21ff:fe11:392]:8333 +[2604:4500::2e06]:8112 +[2604:5500:706a:4000:fc79:b9bb:1d7:c325]:8333 +[2604:5500:c134:4000::3fc]:32797 +[2604:6800:5e11:162:5c8f:d2ff:fe26:146f]:8333 [2605:4d00::50]:8333 -[2605:9880:0:1cf:225:90ff:fec9:29b3]:8333 -[2605:9880:0:3::8333]:8333 -[2605:9880:201:17::4b7c]:8333 -[2605:a000:4a87:9501:d613:fbf8:1e82:8d3c]:8333 -[2605:a000:f343:b700:5054:ff:fea7:131]:8333 -[2605:a601:a41:1a00:a00:27ff:fefc:4759]:8333 +[2605:6400:20:13bf:df1d:181c:83bb:22e8]:8333 [2605:ae00:203::203]:8333 [2605:c000:2a0a:1::102]:8333 -[2605:e000:1c00:80e8:984e:a697:97a3:50ed]:8333 -[2605:e000:1c0d:437b:5054:ff:fe1b:2913]:8333 -[2605:e000:9093:a700:9853:4464:5f78:c484]:8333 -[2605:f700:100:400::104e:43bd]:8333 -[2605:f700:100:400::131:5b54]:8333 -[2605:f700:100:c10:5575:8e73:b07c:bf5a]:8333 -[2606:6000:c149:8830:5054:ff:fe78:66ff]:8333 -[2607:1c00:a:6:3c1c:1b0d:ba4:8ea9]:8333 -[2607:1c00:a:6::1000]:8333 -[2607:5300:120:a04::]:8333 -[2607:5300:203:2fac::]:8333 -[2607:5300:203:408::]:8333 -[2607:5300:203:6bc::]:18333 -[2607:5300:203:8d::]:8333 -[2607:5300:60:10aa::1]:8333 -[2607:5300:60:122a::1]:8333 -[2607:5300:60:13bb::1]:8333 -[2607:5300:60:3ddf::]:8333 -[2607:5300:60:5735::]:8333 -[2607:5300:60:714::1]:8333 -[2607:5300:60:981::1]:8333 -[2607:5300:60:cff1::]:28633 -[2607:9280:b:73b:250:56ff:fe21:bf32]:8333 -[2607:f178:0:8::106]:8333 -[2607:f1c0:823:af00::35:bbd1]:8333 -[2607:f2c0:f00e:300:201:2eff:fe67:9130]:8333 -[2607:fa18:0:beef::c012]:8333 -[2607:ff28:1:7::176e:c4a5]:8333 -[2607:ff28:1:7::65af:9afb]:8333 -[2620:71:4000:0:192:30:120:110]:8333 -[2801:84:0:1034:76d4:35ff:fe7f:5033]:8333 -[2803:1500:1200:c487::1]:8333 -[2804:14c:6582:60f0::1]:8333 -[2804:14d:baa6:962c:486:47f6:c161:a79d]:8333 +[2607:f2c0:f00e:300::54]:8333 +[2607:f2f8:ad40:bc1::1]:8333 +[2607:f470:8:1048:ae1f:6bff:fe70:7240]:8333 +[2607:ff28:800f:97:225:90ff:fe75:1110]:8333 +[2620:11c:5001:1118:d267:e5ff:fee9:e673]:8333 +[2620:6e:a000:2001::6]:8333 +[2804:14d:4c93:9809:9769:da80:1832:3480]:8333 +[2a00:1328:e101:c00::163]:8333 +[2a00:1398:4:2a03:215:5dff:fed6:1033]:8333 [2a00:13a0:3015:1:85:14:79:26]:8333 -[2a00:16d8:c::5b6a:c261]:8333 -[2a00:1768:2001:24::148:218]:8333 -[2a00:1838:36:2c::ed85]:8333 -[2a00:1a28:1157:2f8::946a]:8333 -[2a00:1c48:6:203:a60:6eff:fe44:8086]:8333 -[2a00:1f40:2::1126]:8333 -[2a00:7c80:0:5d::1d0e]:8333 +[2a00:1630:14::101]:8333 +[2a00:1768:2001:27::ef6a]:8333 +[2a00:1828:a004:2::666]:8333 +[2a00:1838:36:17::38cb]:8333 +[2a00:1838:36:7d::d3c6]:8333 +[2a00:1c10:2:709:58f7:e0ff:fe24:a0ba]:22220 +[2a00:1c10:2:709::217]:22220 +[2a00:1f40:5001:100::31]:8333 +[2a00:6020:1395:1400:baf7:2d43:60b3:198b]:8333 +[2a00:7c80:0:10b::3faf]:8333 [2a00:8a60:e012:a00::21]:8333 [2a00:ab00:603:84::3]:8333 -[2a00:bbe0:cc:0:6651:6ff:fe0e:9418]:8333 -[2a00:ca8:a1f:3025:4121:5ca1:3b:4469]:8333 -[2a00:ca8:a1f:9091:945e:80a3:830a:78cf]:8333 -[2a01:238:433c:5300:7a61:3e1a:27f4:9dc2]:8333 -[2a01:4240:a21:983b::c0a8:32]:8333 -[2a01:488:66:1000:53a9:21b8:0:1]:8333 -[2a01:4d60:3:1:5::1]:8333 -[2a01:4f8:10a:3524::2]:8333 -[2a01:4f8:10b:362::2]:8333 -[2a01:4f8:10b:d50::2]:8333 -[2a01:4f8:10b:f44::2]:8333 -[2a01:4f8:120:1391::2]:8333 -[2a01:4f8:120:70a3::2]:8333 -[2a01:4f8:120:93f8::2]:8333 -[2a01:4f8:121:2385::2]:8333 -[2a01:4f8:130:71d2::2]:8333 -[2a01:4f8:130:7422::2]:8333 -[2a01:4f8:13a:124f::2]:8333 -[2a01:4f8:13a:1dcb::2]:8333 -[2a01:4f8:13a:708::2]:21775 -[2a01:4f8:13a:723::2]:8333 -[2a01:4f8:13b:109e::2]:8333 -[2a01:4f8:13b:1a9e::201]:8333 -[2a01:4f8:13b:271c::2]:10731 -[2a01:4f8:13b:2d42::2]:8333 -[2a01:4f8:13b:2d94::2]:8333 -[2a01:4f8:13b:3810::2]:8333 -[2a01:4f8:13b:3da8::2]:8333 -[2a01:4f8:13b:41e6::2]:8333 -[2a01:4f8:13b:4281::2]:8333 -[2a01:4f8:13b:5c7::2]:8333 -[2a01:4f8:13b:81::2]:8333 -[2a01:4f8:140:236a:cafe::5]:8333 -[2a01:4f8:140:324e::2]:8333 -[2a01:4f8:140:5329::102]:8333 -[2a01:4f8:140:5329::50:109]:8333 -[2a01:4f8:140:931a::2]:8333 -[2a01:4f8:140:93b0::2]:8333 -[2a01:4f8:141:47::2]:8333 -[2a01:4f8:150:53a4::4]:8333 -[2a01:4f8:150:72ee::4202]:8333 -[2a01:4f8:160:41f0::1:33]:8333 -[2a01:4f8:160:4443::2]:8333 -[2a01:4f8:160:6092:d7bd:a39:3e52:b65d]:8333 -[2a01:4f8:160:60aa::2]:8333 -[2a01:4f8:160:636e::2]:8333 -[2a01:4f8:161:6091::2]:8333 -[2a01:4f8:161:6111::2]:8333 -[2a01:4f8:161:812e::2]:8333 -[2a01:4f8:162:2c6::2]:8333 -[2a01:4f8:162:33ac::2]:8333 -[2a01:4f8:171:1c3::2]:8333 -[2a01:4f8:171:2bdc::2]:8333 -[2a01:4f8:171:3248::2]:8333 -[2a01:4f8:171:4dc::2]:8333 -[2a01:4f8:171:d09::2]:8333 -[2a01:4f8:171:d4a::2]:8333 -[2a01:4f8:171:e0d::2]:8333 -[2a01:4f8:171:ecd::2]:8333 -[2a01:4f8:172:1823::2]:8333 -[2a01:4f8:173:1622::2]:8333 -[2a01:4f8:190:50b6::2]:8333 -[2a01:4f8:190:5176::123]:8333 -[2a01:4f8:191:268::2]:8333 -[2a01:4f8:192:216c::2]:8333 -[2a01:4f8:192:628a::83]:8333 -[2a01:4f8:1c0c:77af::1]:8333 -[2a01:4f8:200:1012::2]:8333 -[2a01:4f8:200:442d::2]:8333 -[2a01:4f8:201:1113::2]:8333 -[2a01:4f8:201:4f0::2]:8333 -[2a01:4f8:201:53cc::2]:8333 -[2a01:4f8:201:8026::1337]:8333 -[2a01:4f8:201:8026::2]:8333 -[2a01:4f8:202:32c6::2]:8333 -[2a01:4f8:211:309::2]:8333 -[2a01:4f8:211:f08::2]:8333 -[2a01:4f8:212:1e16::2]:8333 -[2a01:4f8:221:1808::2]:15000 -[2a01:4f8:221:2e18::2]:8333 -[2a01:4f8:221:2fcf::2]:8333 -[2a01:4f8:221:3441::2]:8333 -[2a01:4f8:221:3452::2]:8333 -[2a01:4f8:221:39c1::2]:8335 -[2a01:4f8:221:3c82::2]:8333 -[2a01:4f8:221:3c82:fea1::666]:8333 -[2a01:4f8:221:6cd::2]:8333 -[2a01:4f8:221:801::2]:8333 -[2a01:4f8:221:f59::2]:8333 -[2a01:4f8:a0:6147::2]:8333 -[2a01:4f8:c0c:4268::2]:8333 -[2a01:4f8:c0c:56a5::2]:8333 -[2a01:4f8:c17:e00::2]:8333 -[2a01:4f9:2a:10d4::2]:8333 -[2a01:4f9:2a:1827::2]:8333 -[2a01:4f9:2a:192c::2]:8333 -[2a01:4f9:2a:1c87::2]:8333 -[2a01:4f9:2a:2510::2]:8333 -[2a01:4f9:2a:2518::2]:8333 -[2a01:4f9:2a:2585::2]:8333 -[2a01:4f9:2a:2698::2]:8333 -[2a01:4f9:2a:2d0a::2]:8333 -[2a01:4f9:2a:2d17::2]:8333 -[2a01:4f9:2a:347::2]:8333 -[2a01:4f9:2a:650::2]:8333 -[2a01:4f9:2a:d54::2]:8333 -[2a01:4f9:c010:12e7::1]:8333 -[2a01:4f9:c010:1736::1]:8333 -[2a01:5d00:1:4b6:d2bf:9cff:fe45:b834]:8333 -[2a01:79c:cebe:70cc:1a03:73ff:fe48:e691]:8333 -[2a01:7a0:2:1374::7]:8333 -[2a01:7a7:2:1218:ec4:7aff:fe83:83c4]:8333 -[2a01:7a7:2:1288:ea39:35ff:fef0:c429]:8333 -[2a01:7c8:aaba:18:5054:ff:fe2b:df20]:8333 -[2a01:7c8:fffa:50e:3035:741b:be02:b5de]:8333 -[2a01:be00:10:201:0:80:cece:1]:8333 -[2a01:cb00:5be:d500:227:eff:fe28:c565]:8333 -[2a01:cb00:b3:d300:9276:8a8c:74bf:2a88]:8333 -[2a01:cb14:b8:a500:dd9d:80f5:d305:68f9]:8333 -[2a01:e0a:20:9120:7c3f:5643:9978:1825]:8333 -[2a01:e0a:d:6ea0:56:deab:1b2f:300b]:8333 -[2a01:e34:ec16:93f0:725d:d8d2:bb90:eabf]:8333 -[2a01:e34:ee33:1640:c418:3c3a:8ff6:3eab]:8333 -[2a01:e34:eed7:6670:28c0:183c:7783:7dc3]:8333 -[2a01:e35:2f7d:a0b0:59c2:3c8a:95a2:c4d1]:8333 -[2a01:e35:87ba:d0c0:75a2:9f39:efcb:f59f]:8333 -[2a02:120b:c3c5:cef0:ec82:a43d:4d6:dc2]:8333 -[2a02:120b:c3d1:f2d0:eea8:6bff:fefc:2265]:8333 -[2a02:168:404c:0:eea8:6bff:fef3:7d5c]:8333 -[2a02:180:1:1::517:10b6]:8333 +[2a00:bbe0:cc:0:62a4:4cff:fe23:7510]:8333 +[2a00:ca8:a1f:3025:f949:e442:c940:13e8]:8333 +[2a00:d2a0:a:3d00:1cdf:38bb:a7d6:c251]:8333 +[2a00:d880:11::20e]:8333 +[2a00:ec0:7207:9100:5f8f:25dd:2574:3982]:8333 +[2a00:f820:433::36]:8333 +[2a01:138:a017:b018::42]:8333 +[2a01:430:17:1::ffff:1153]:8333 +[2a01:490:16:301::2]:8333 +[2a01:4b00:807c:1b00:cda1:c6a:2bad:2418]:8333 +[2a01:4b00:80e7:5405::1]:8333 +[2a01:4f8:192:4212::2]:8433 +[2a01:7a0:2:137c::3]:8333 +[2a01:7a7:2:1467:ec4:7aff:fee2:5690]:8333 +[2a01:7c8:d002:10f:5054:ff:fe5c:dac7]:8333 +[2a01:7c8:d002:318:5054:ff:febe:cbb1]:8333 +[2a01:8740:1:ffc5::8c6a]:8333 +[2a01:cb00:f98:ca00:5054:ff:fed4:763d]:8333 +[2a01:cb14:cf6:bc00:21e5:f12e:32c8:145]:8333 +[2a01:d0:0:1c::245]:8333 +[2a01:d0:bef2::12]:8333 +[2a01:e35:2e40:6830:211:32ff:fea6:de3d]:8333 +[2a02:1205:c6aa:60c0:70d8:aaee:a82d:993c]:8333 +[2a02:169:502::614]:8333 [2a02:180:1:1::5b8f:538c]:8333 -[2a02:1b8:10:147::2]:8333 -[2a02:2168:d05:2c00:216:3eff:fef7:a099]:8333 -[2a02:2528:503:2::14]:8333 -[2a02:2528:fa:1400::1]:8333 -[2a02:2770:17:0:21a:4aff:fe7b:175f]:8333 -[2a02:2770:5:0:21a:4aff:fe44:8370]:8333 -[2a02:2808:5401:0:225:90ff:fe4e:ee42]:8333 +[2a02:348:62:5ef7::1]:8333 [2a02:390:9000:0:218:7dff:fe10:be33]:8333 -[2a02:750:7:c11:5054:ff:fe43:eb81]:8333 -[2a02:7aa0:1619::590:eba2]:8333 -[2a02:7b40:3e4d:9ed9::1]:8333 -[2a02:7b40:50d1:e04f::1]:8333 -[2a02:7b40:5928:f9e::1]:8333 -[2a02:7b40:592f:a590::1]:8333 -[2a02:7b40:b0df:82fe::1]:8333 +[2a02:7aa0:1619::adc:8de0]:8333 [2a02:7b40:b0df:8925::1]:8333 -[2a02:7b40:b0df:8b41::1]:8333 -[2a02:7b40:b0df:8d57::1]:8333 -[2a02:7b40:d418:6fcd::1]:8333 -[2a02:8108:2340:1c18:7a:231e:1430:7f12]:8333 -[2a02:8108:9c3f:dd18:922b:34ff:fe30:ac42]:8333 -[2a02:810d:8a40:36f8:9af2:b3ff:fee8:6d7a]:8333 -[2a02:8388:e301:7180:201:2eff:fe82:b3cc]:8333 -[2a02:908:213:54a0:39bf:d4aa:60b2:d9c3]:8333 -[2a02:908:4f0:7e1c:5054:ff:feb7:ce4b]:8333 -[2a02:930:1:0:250:56ff:fe8e:2819]:8333 -[2a02:a80:0:2052::2]:8333 -[2a02:c205:0:5145::1]:8333 -[2a02:c205:2008:272::1]:8333 -[2a02:c205:2010:6230::1]:8333 -[2a02:c205:2016:4327::1]:8333 -[2a02:c205:2017:2116::1]:8333 -[2a02:c205:2018:1754::1]:8333 -[2a02:c205:2018:8229::1]:8333 -[2a02:c205:3002:2787::1]:8333 -[2a02:c205:3002:6525::1]:8333 -[2a02:c207:0:3829::1]:8333 -[2a02:c207:2007:4699::1]:8333 -[2a02:c207:2009:213::1]:8333 -[2a02:c207:2010:7751::1]:8333 -[2a02:c207:2012:4826::1]:8333 -[2a02:c207:2014:4199::1]:8333 -[2a02:c207:2014:5639::1]:8333 -[2a02:c207:2014:9913::1]:18333 -[2a02:c207:2015:3799::1]:8333 -[2a02:c207:2015:3926::1]:8333 -[2a02:c207:2015:5919::1]:8333 -[2a02:c207:2015:6681::1]:8333 -[2a02:c207:2016:2394::1]:8333 -[2a02:c207:2016:9375::1]:8333 -[2a02:c207:2017:1988::1]:8333 -[2a02:c207:2017:3720::1]:8333 -[2a02:c207:2017:4486::1]:8333 -[2a02:c207:2017:4708::1]:8333 -[2a02:c207:2017:5828::1]:8333 -[2a02:c207:2017:7320::1]:8333 -[2a02:c207:2017:8175::1]:8333 -[2a02:c207:2017:8998::1]:8333 -[2a02:c207:2018:1462::1]:8333 -[2a02:c207:2018:3094::1]:8333 -[2a02:c207:2018:3275::1]:8333 -[2a02:c207:2018:3710::1]:8333 -[2a02:c207:2018:4790::1]:8333 -[2a02:c207:2018:7407::1]:8333 -[2a02:c207:2019:1067::1]:8333 -[2a02:c207:2019:1425::1]:8333 -[2a02:c207:2019:2041::1]:8333 -[2a02:c207:2019:248::1]:8333 -[2a02:c207:2019:3592::1]:8333 -[2a02:c207:3001:9320::1]:8333 -[2a02:c207:3002:1287::1]:8333 -[2a02:c207:3002:4187::1]:8333 -[2a02:c207:3002:5642::1]:8333 -[2a02:c207:3002:7150::1]:8333 -[2a02:c207:3002:7222::1]:8333 -[2a02:c207:3002:7610::1]:8333 -[2a02:c207:3002:8456::1]:8333 -[2a02:ce80:0:20::1]:8333 -[2a02:e00:fff0:1b9::1]:8333 -[2a02:e00:fff0:1b9::a]:8333 -[2a02:e00:fff0:1e2::1]:8333 -[2a03:b0c0:1:d0::69:3001]:8333 -[2a03:b0c0:2:d0::3ba:b001]:8333 -[2a03:b0c0:2:d0::8ce:4001]:8333 -[2a03:b0c0:3:d0::116:5001]:8333 -[2a03:b0c0:3:d0::12a:1]:8333 -[2a03:b0c0:3:d0::23fb:6001]:8333 -[2a03:b0c0:3:d0::409:1001]:8333 -[2a03:b0c0:3:d0::44b8:9001]:8333 -[2a03:b0c0:3:d0::44b8:a001]:8333 -[2a03:b0c0:3:d0::44b8:e001]:8333 -[2a03:b0c0:3:d0::44b8:f001]:8333 -[2a03:b0c0:3:d0::44b9:1]:8333 -[2a03:b0c0:3:d0::44b9:1001]:8333 -[2a03:b0c0:3:d0::44b9:2001]:8333 -[2a03:b0c0:3:d0::44b9:4001]:8333 -[2a03:b0c0:3:d0::5e48:d001]:8333 -[2a03:ee40:0:294:250:56ff:fe8d:4ad7]:8333 -[2a04:2180:1:c:f000::15]:8333 -[2a07:440:2000:20::ca0:1817]:8333 -[2a0a:c800:1:1::4]:8333 +[2a02:7b40:b905:37db::1]:8333 +[2a02:810d:8cbf:f3a8:96c6:91ff:fe17:ae1d]:8333 +[2a02:8389:1c0:9680:201:2eff:fe82:b3cc]:8333 +[2a02:a454:a516:1:517:928:7e0d:957c]:8333 +[2a02:af8:fab0:804:151:236:34:161]:8333 +[2a02:af8:fab0:808:85:234:145:132]:8333 +[2a02:e00:fff0:1e2::a]:8333 +[2a03:2260:3006:d:d307:5d1d:32ca:1fe8]:8333 +[2a03:6000:870:0:46:23:87:218]:8333 +[2a03:9da0:f6:1::2]:8333 +[2a03:c980:db:47::]:8333 +[2a03:e2c0:1ce::2]:8333 +[2a04:3544:1000:1510:706c:abff:fe6c:501c]:8333 +[2a04:52c0:101:383::2a87]:8333 +[2a04:52c0:101:3fb::4c27]:8333 +[2a04:ee41:83:50df:d908:f71d:2a86:b337]:8333 +[2a05:6d40:b94e:d100:225:90ff:fe0d:cfc2]:8333 +[2a05:e5c0:0:100:250:56ff:feb9:d6cb]:8333 +[2a05:fc87:1:6::2]:8333 +[2a05:fc87:4::8]:8333 +[2a07:5741:0:115d::1]:8333 +[2a07:a880:4601:1062:b4b4:bd2a:39d4:7acf]:51401 +[2a07:abc4::1:946]:8333 +[2a07:b400:1:34c::2:1002]:8333 +[2a0a:8c41::b4]:8333 +[2a0a:c801:1:7::183]:8333 +[2a0b:ae40:3:4a0a::15]:8333 +[2a0f:df00:0:254::46]:8333 +[2c0f:f598:5:1:1001::1]:8333 +[2c0f:fce8:0:400:b7c::1]:8333 226eupdnaouu4h2v.onion:8333 +22h7b6f3caabqqsu.onion:8333 23wdfqkzttmenvki.onion:8333 -2bfsxzluysybysnr.onion:8333 -2f4xg7m3g6vtxqcd.onion:8333 -2i5i6kvxoggngz67.onion:8333 -336lqgffb4tg5gpm.onion:8333 -342ouaetvqzgepjx.onion:8333 -3mutzniftca5w7ou.onion:8333 -3qpbpt4gkp3dxn2r.onion:8333 +23yi3frxymtwdgre.onion:8333 +2ajon3moyf4i2hbb.onion:8333 +2bfmlpk55hffpl6e.onion:8333 +2ckmbf6sglwydeth.onion:8333 +2hkusi5gcaautwqf.onion:8333 +2ivhmlbxbgnkcykl.onion:8333 +2mmxouhv6nebowkq.onion:8333 +2qsnv6exnuuiar7z.onion:8333 +2qudbhlnvqpli3sz.onion:8333 +2ujxdfovfyjpmdto.onion:8333 +2xdgeufrek3eumkw.onion:8333 +2xdzsruhsej4tsiw.onion:8333 +34ran2woq4easmss.onion:8333 +36q7khhej2lxd3wf.onion:8333 +373wjdspuo52utzq.onion:8333 +376klet5xqbrg2jv.onion:8333 +37kwd7fxop766l5k.onion:8333 +3e5t7hq4alt5tovx.onion:8333 +3gbxhebfhouuwgc3.onion:8333 +3hgbjze2nbwyuewf.onion:8333 +3iuuvrd2waha2cxo.onion:8333 +3jtxujdaiwh6iltu.onion:8333 +3l5eq2du7mvscj4a.onion:8333 +3nofngnqlqeehn7o.onion:8333 3r44ddzjitznyahw.onion:8333 -3xucqntxp5ddoaz5.onion:8333 -44walnmvlhcqa3c2.onion:8333 -4ehtdyvvzhbbo6c5.onion:8333 -4jekbh7cdlfda3ve.onion:8333 -4mewwo2bfxk6lg3f.onion:8333 -53tsjt6zq3iasv5q.onion:8333 -546esc6botbjfbxb.onion:8333 -55zzzsk7iqv6p3ew.onion:8333 -56stijc6kcgw6flk.onion:8333 -5elzwcg4xysogalo.onion:8333 -5f4ysqk4eed4jcvj.onion:8333 -5k3oxus2laabmyip.onion:8333 -5ptuzplawb3svsos.onion:8333 -5rmpsrrdb3vpfgzh.onion:8333 -5wnkqzjzjehmq7hn.onion:8333 -5xxsqhppii22pges.onion:8333 -5ygszbkbbauzjx7m.onion:8333 -5z2she4d6fvrdnme.onion:8333 -64qrhyxglyjjhkne.onion:8333 -6kn76kajckqg22ao.onion:8333 -6m2iqgnqjxh7ulyk.onion:8333 -6wcfnbb3vmaw6cwa.onion:8333 -6zynxbbupfmnvc3g.onion:8333 -7sns7raurpmllybi.onion:8333 -7whaszg22pdkvfck.onion:8333 -a3a6plzycomx5gqw.onion:8333 -acs7hylaadjkt7mk.onion:8333 -agpwcvixadbinyet.onion:8333 -ajqvsylg5xd5vs3y.onion:8333 -aktfeaqkbnk52bfx.onion:8333 -albsennsmbsgxls3.onion:8333 -alruzrdz7xcek67f.onion:8333 -am6aq3dluz3njcnt.onion:8333 -aoefyxgnpgaiw2xg.onion:8333 -ap2frg2maqxpmkkd.onion:8333 -ap4zz4imxbdl6plr.onion:8333 -apbbvhk32myudnyy.onion:8333 -arlocvowxtnlbpo3.onion:8333 -b5d6etfljm2lje5y.onion:8333 -bdwvcwafzpssqckj.onion:8333 -brwqezn6le54w2bb.onion:8333 -bxxvkb7czrxtvz2c.onion:8333 -c2tpqkaz4ihjzwgb.onion:8333 -cgcv32rbbbjyyzow.onion:8333 -ckkqplgkzof45h2y.onion:8333 -cpyfqbs4fs3vnbpf.onion:8333 -ctzuzxnvla5xvb7z.onion:8333 -cw4iqvcdy67b5tpw.onion:8333 -cyvpgt25274i5b7c.onion:8333 -dmudsr7x7edvyglt.onion:8333 -dsbn53f2dwphv5mx.onion:8333 -dssqdj6pxnzkth6i.onion:8333 -e3zbephvcqmzcqkr.onion:8333 -e63i7c7qazbdtjma.onion:8333 -eiuaj2qjvbn737ph.onion:8333 -ep2mjzox3kvb6ax4.onion:8333 -eyvfxeefr4eokefr.onion:8333 -f3nfioh27j2xlfe5.onion:8333 -f5ezxphghknfbrtg.onion:8333 -faewczjuzs4wfxhv.onion:8333 -fefisckqu5raqe3c.onion:8333 -fgbss353vsvandn7.onion:8333 -fnlkrowsyrfeub6s.onion:8333 -fno4aakpl6sg6y47.onion:8333 -fnpnjdk24pzgcplx.onion:8333 -foe4ymjz4hjhowud.onion:8333 -fql436nz7qdis3nk.onion:8333 -frhfucww5vghf7cv.onion:8333 -frrxefv5dir5hm7l.onion:8333 -fuckerolyuv7ebla.onion:8333 +3vtbuwmton7vq5qz.onion:8333 +46ohzttz4peki43g.onion:8333 +47fl3ivl4v56jstr.onion:8333 +47i6qrl2ijqcwlg6.onion:8333 +47uupgzcnrwahoto.onion:8333 +4c5cki37evofds6d.onion:8333 +4eq36jrx7xuytfpc.onion:8333 +4ewkdxvcg57adrni.onion:8333 +4flvgibnm2nld3na.onion:8333 +4iaontym47imawe4.onion:8333 +4jxz37oou5ag763c.onion:8333 +4mnkvj6ha73eqnbk.onion:8333 +4nnuyxm5k5tlyjq3.onion:8333 +4nz2yg4cnote3ej7.onion:8333 +4pozwh6564ygzddk.onion:8333 +4qgfb56rvpbmesx7.onion:8333 +4rsax23taqzwmimj.onion:8333 +4u5j5ay6rasowt4m.onion:8333 +4vorvtoyegh4zbvr.onion:8333 +52s4j5pldwlpzhtw.onion:8333 +5abpiiqfvekoejro.onion:8333 +5aydzxx6jyoz3nez.onion:8333 +5cxzdsrtok5dgo4a.onion:8333 +5eduikpudie3jyrf.onion:8333 +5epeafkmya4fv5d5.onion:8333 +5fyxlztic3t6notz.onion:8333 +5hd6eyew5ybnq6gb.onion:8333 +5jyfzhwksb6urrp2.onion:8333 +5nooqgct567ig57v.onion:8333 +5nsfm4nqqzzprjrp.onion:8333 +5oqstxspzhlgjef6.onion:8333 +5pzzmd4tfonrqzb2.onion:8333 +5sckmx4yucbnp4io.onion:8333 +5ue7worzbn6hon3e.onion:8333 +5wxhx2tozpovf6z3.onion:8333 +5xk3yun36e32e34i.onion:8333 +5zght2g7vcsapi65.onion:8333 +62dcdpvdolfzkdzl.onion:8333 +63bko2mhixnn2b7d.onion:8333 +67hjvfv6wictalm5.onion:8333 +6g6ko4klkf5atldi.onion:8333 +6k5zreexw4cadxi5.onion:8333 +6kf5ayhlpenywgas.onion:8333 +6maigxjvcet4pite.onion:8333 +6ressv4dvplb5ihh.onion:8333 +6rjex6gyuaui3c5e.onion:8333 +6skgnf43pphdvjua.onion:8333 +6stxaoduwisg5sqh.onion:8333 +6xqy4ts6bo6u5dgm.onion:8333 +7avnl3dqpgu23jva.onion:8333 +7ff4wk266no23txn.onion:8333 +7hipbuzfdcyzqkkg.onion:8333 +7sjmlzrthjlpfydk.onion:8333 +7tut3zt2akwrmw6x.onion:8333 +7uhsjzj6nx3dfnxt.onion:8333 +7wm4wso3wvatxnbt.onion:8333 +7ykmzuybwd2ptzg4.onion:8333 +a27bvhina4y23jxo.onion:8333 +a53vtdm7uiet5vdl.onion:8333 +a56572xjuofnt2dp.onion:8333 +abp25knifdsnc2rv.onion:8333 +aefx7ubzpal7clak.onion:8333 +ai5r2diozoe7rrdz.onion:8333 +aipupphit3enggpj.onion:8333 +algpjjygd3gtnmpp.onion:8333 +alihua7rhyc452hr.onion:8333 +am3gyyfynxzwyxhx.onion:8333 +ankozzfhl2r3uc6u.onion:8333 +at3twjlbtc2lqnq5.onion:8333 +avqobl72pmc64dyi.onion:8333 +awmdz2fs3b5h5ut5.onion:8333 +ayywpiy77butdjrj.onion:8333 +b2i3pj7c24cvprs7.onion:8333 +b4ilebyxcu6nttio.onion:8333 +b4vvkbqipcmkwp4v.onion:8333 +bddfqxps5ibd3ftw.onion:8333 +be5bgcpo4ooux5qy.onion:8333 +bgla4m6zetvtv7ls.onion:8333 +bh32gzw3nyckzqut.onion:8333 +bho4kodpehn7xr3x.onion:8333 +bitsend4rlfa4wqx.onion:8333 +biw7s6jf6r2mf3cu.onion:8333 +bk7yp6epnmcllq72.onion:8333 +blcktrgve5vetjsk.onion:8333 +blwbp7gfdffdsx4g.onion:8333 +bnxn6qqc55gvn5op.onion:8333 +bp7o22lvcjawelvv.onion:8333 +bqqyqucgj4tchn64.onion:8333 +bvdzmutcqf7gzzn5.onion:8333 +c36zmegjkinftmtf.onion:8333 +c4fn62gnltlgrptv.onion:8333 +caael5yedviooqzk.onion:8333 +caq54ablfbrnumdd.onion:8333 +cernrmrk5zomzozn.onion:8333 +chri6itgjaagof4t.onion:8333 +cncwik3tnd2ejm5z.onion:8333 +cuyjqoziemcmwaxl.onion:8333 +cx7qa2gpqyp7pld5.onion:8333 +czp7wgaus4gvio72.onion:8333 +d2fn54rfyjdangi4.onion:8333 +d2sk45u6ca64yeqh.onion:8333 +d3aowmngvktsziae.onion:8333 +d5iu4aiz3y2kgcgj.onion:8333 +d6zbw2sxnxgj5sv3.onion:8333 +db5rd5e46t7mgini.onion:8333 +dci2gulorl44yj55.onion:8333 +ddpth2mwt3rsvoog.onion:8333 +dfrwza7fcecknnms.onion:8333 +djwhjfj4rh3oz3yj.onion:8333 +dkk5mmpe5jtjodk5.onion:8333 +doj3zgmsbzurmqgp.onion:8333 +dpce4f3rcqddzbx5.onion:8333 +drwo3vnxch5ozfbo.onion:8333 +duikkidxip3lyexn.onion:8333 +duqdliptc22i6hf5.onion:8333 +duyp4coh5d7nh3ud.onion:8333 +duz5two3z7c55lxj.onion:8333 +dvu6dlar6ezc6xen.onion:8333 +dy6zqs46ycleayyp.onion:8333 +dz2ydmj3yqrcm4r7.onion:8333 +e2b2a5suvdawzxud.onion:8333 +e33h57j2ewkkqsn5.onion:8333 +e5kjiay7pzj5qpzv.onion:8333 +e7iko42d2wzcmvy4.onion:8333 +ea6boh4kotq56ws5.onion:8333 +efdx6gc4s5ezyqeg.onion:8333 +efrpuuic6ukeyqcs.onion:8333 +egruc3bi3itru6gq.onion:8333 +erc6tjs2ucyadl23.onion:8333 +eue2n5sk5tktg5bv.onion:8333 +ezkr7stq4w7ohjrt.onion:8333 +f3nyyjba6kpxznhk.onion:8333 +faq73vj4pcs73thu.onion:8333 +fdvtlj3pscbxuh75.onion:8333 +fgdpxov4nzxvhcpv.onion:8333 +fisqq6vzk3m6t225.onion:8333 +fkgp3qwegacrd2bj.onion:8333 +fo3tdfwx27takqq5.onion:8333 +fqkxtchwypispkpv.onion:8333 +fqunuhlwvd7rq6d5.onion:8333 +frwt5mscpyhiuwpe.onion:8333 +fta4gfjiuv6f2le2.onion:8333 +fuoy2ipuqrqwe5cf.onion:8333 fz6nsij6jiyuwlsc.onion:8333 -g4qfwcu5wm7ze5lg.onion:8333 -gb5ypqt63du3wfhn.onion:8333 -gcydj5id3jcxybzr.onion:8333 -gfvnnnwcddfzosav.onion:8333 -golevvyaydsduuw2.onion:8333 -gq4su6stjnosqu67.onion:8333 -hb4oreglor5x3xoa.onion:8333 -hbuair37dxnblurw.onion:8333 -hda7fvzq3voh7mu6.onion:8333 -hnvk3pgvieyixyc2.onion:8333 -ifwxwunja4pgwydg.onion:8333 -ijmbmziunbszzxtj.onion:8333 -in7r5ieo7ogkxbne.onion:8333 -inysvhakrulg6lts.onion:8333 -iwrwbwss7lfalfg4.onion:8333 -ja7dmgkri7fi47xk.onion:8333 +g3vlnaaaog5sgui5.onion:8333 +g44i6jwsutkwmspz.onion:8333 +g55t65d5ckjixcnw.onion:8333 +gajd6eyrl2qwkfmg.onion:8333 +gblue3hr53p4grx7.onion:8333 +gbpro5tzduiuff4v.onion:8333 +gc4l3tql32qhfgmi.onion:8333 +gcnlorvtpycuajc6.onion:8333 +gdsib2nk2eeoidgc.onion:8333 +ge5gm7c6w7yahpz7.onion:8333 +gegcteeep4cwftl5.onion:8333 +gfoyraudgv5qjdku.onion:8333 +ggpbuypmxgi26lc6.onion:8333 +ghqivye7cfckisnt.onion:8333 +girakxomne5fby64.onion:8333 +glz5gfk33tuug5ne.onion:8333 +gplatxoyg5nxl5rj.onion:8333 +gripl5xjwy2dcr6c.onion:8333 +gthhzlmqci22nxru.onion:8333 +gto2d64swosfmk6c.onion:8333 +guaciney52mgcbp2.onion:8333 +gwktgrmtwk6nv5sc.onion:8333 +gwoxnokdcwc7hy4p.onion:8333 +h333f4qnwe7mrymn.onion:8333 +h6a32n4blbwwyn4d.onion:8333 +hafwtrbooszoembm.onion:8333 +hbwhgsb3eeinnr6t.onion:8333 +hcv6foxh5mk7fhb5.onion:8333 +hd6hktcl6wamzlzm.onion:8333 +hda6msa4v4rt77gx.onion:8333 +hdgnxkuqsd6wjwwx.onion:8333 +hgh3azn3eesddvcg.onion:8333 +hhyxu6bwkjefejoz.onion:8333 +hizn6rmofsg3upmn.onion:8333 +hjqxxsy2osemfvev.onion:8333 +hkbp7mbgw6klls4s.onion:8333 +hlojuwiwbkoj4kdz.onion:8333 +hlzxsjr7ob3qzzqq.onion:8333 +hniuzplezebyhv7a.onion:8333 +hondewkj4s4rdcwf.onion:8333 +hql5nv6vhceid3bn.onion:8333 +hspjo7mqrre5gyxr.onion:8333 +hu64s2mdr3x7yxka.onion:8333 +hvwvq2swkqw3qvyo.onion:8333 +hwo2biyndrrvpl6f.onion:8333 +hzxj3dth3y2xt45o.onion:8333 +i3ufxuw3t7cxfdpq.onion:8333 +ia3n3q5u45gvpx7a.onion:8333 +icfgs3fctckd4yeo.onion:8333 +icpz6thqvdjcwlvb.onion:8333 +if32zo5u4mhdunfd.onion:8333 +ig4lguql6vxkbmmr.onion:8333 +ihhcr7fhczqdac4y.onion:8333 +ijm2tyxob7vkvazz.onion:8333 +ip3puuqghumfz5ww.onion:8333 +iq3ket72f3y2frpg.onion:8333 +iqagt5co4dt7h6hf.onion:8333 +iugw42ih6hprqr26.onion:8333 +ivf774v4t7k63i6d.onion:8333 +ivfacdf7cig2z2y2.onion:8333 +ivsxdwku5og2zj4l.onion:8333 +ixwgrhaklvu4g6o7.onion:8333 +iz56moo6mkp3g7xo.onion:8333 +j2cp5muw5j3lumcx.onion:8333 +j2lrkrwugldwewws.onion:8333 +j2qtmkd2dablssz4.onion:8333 +j5e2yuan57v2h5el.onion:8333 +j5jfrdthqt5g25xz.onion:8333 +j5lk2uv2bspfqxfk.onion:8333 +janvvzsmzcsj3fil.onion:8333 +jenn2tmyl3xxarmq.onion:8333 +jfoe5f2sczojfp32.onion:8333 +jgcgi6k2pxooi5q3.onion:8333 +jhana24s3dzkitzp.onion:8333 +jitgulb24mvfqrdg.onion:8333 +jjuvwbjfzljmn7t3.onion:8333 +jlcfomgr5xfexaif.onion:8333 +jlehs6ybb26qlnna.onion:8333 +jljzz4tmbqrxq3q5.onion:8333 +joc4oqceedkg77vf.onion:8333 +jr5y6njubcbv6g37.onion:8333 +jroaos6la4vieho4.onion:8333 +jsmphgkay7iihbkr.onion:8333 jtksnokusbzms7wl.onion:8333 -jwxyqhp42cmwhqf3.onion:8333 -jxrfatqtcevzwywz.onion:8333 -jy6mvzb2ntutiye6.onion:8333 -jydquxzliej6dm24.onion:8333 -k2gdzvryrx7v6ksw.onion:8333 -kkdas3qebkosygu5.onion:8333 -kswfyurnglm65u7b.onion:8333 -l2pruzr3mnhieuug.onion:8333 -lgkgcd4brjmhrqna.onion:8333 +ju5duo3r6p6diznc.onion:8333 +jw6zymxcnebahuuj.onion:8333 +jxalvhf7w7wevqzw.onion:8333 +jyzhe3ig44ickysb.onion:8333 +jze6ukn4idrh44eo.onion:8333 +k4glotlxnmttb6ct.onion:8333 +k7uy3iwmvguzygd2.onion:8333 +kl23ofag3ukb6hxl.onion:8333 +kokt2qr6d4pmyb2d.onion:8333 +kpalu3h5ydkoaivs.onion:8333 +krdpbdvtqw5c5lee.onion:8333 +kriw6kzjzarzgb3g.onion:8333 +krp2thcmwrpsoue6.onion:8333 +kvyvdwjwtae5mo77.onion:8333 +kyrxri5rbr6ipurs.onion:8333 +kz3oxg7745dxt62q.onion:8333 +l3w5fcki2wbro2qb.onion:8333 +l44bisuxhh7reb5q.onion:8333 +l565g523emjebusj.onion:8333 +l6w5kdeigwsgnf5t.onion:8333 +l7a4emryfxkjgmmb.onion:8333 +l7sloscjqqbifcsw.onion:8333 +laafjqvtog7djfl2.onion:8333 +lah676kxbgbgw3u2.onion:8333 +lbq2a7pnpmviw2qo.onion:8333 +lc4wnpql27vymi35.onion:8333 +ldoffbfpk3j6c7y7.onion:8333 +lehpmglkivobq2qo.onion:8333 +lgewpjz7ie7daqqr.onion:8333 lgkvbvro67jomosw.onion:8333 -llljnatksfgtlhko.onion:8333 -mdpt6w5sjwcnxtwy.onion:8333 -mhjcepzc4gyadw2w.onion:8333 -mn744hbioayn3ojs.onion:8333 -mpakpgzu7umgu3ze.onion:8333 -mvomwfdddqfqg3lq.onion:8333 -mx5kdfxwowc3ymzg.onion:8333 -n4m32zcp5hvomkt4.onion:8333 -n73steqcmjz5hwni.onion:8333 -nc2bgkhqohrmwbxr.onion:8333 -nc6zlswwqqg7c5yz.onion:8333 +liw5z4ngic6b7vnv.onion:8333 +ljs7gwrmmza6q6ga.onion:8333 +lmvax3e6awaxvhqi.onion:8333 +lrz77dwf7yq4cgnt.onion:8333 +lva54pnbq2nsmjyr.onion:8333 +lxc2uphxyyxflhnf.onion:8333 +lyjybdr4hmj3bqab.onion:8333 +lz2zlnmyynwtgwf2.onion:8333 +m6hcnpikimyh37yp.onion:8333 +md635omjnrgheed3.onion:8333 +mdb3oupwf4f2qyjb.onion:8333 +me6d4esx7ohdnxne.onion:8333 +mecfkik5ci47wckj.onion:8333 +mfrvevn7w6rwsp4r.onion:8333 +mimuutlew5srtduk.onion:8333 +mnysk3izxvra3huv.onion:8333 +mqu6gqtrhm6xzwwh.onion:8333 +mwuc6vom4ngijtb3.onion:8333 +mxdtrjhe2yfsx3pg.onion:8333 +n4ibet4piscv22nj.onion:8333 +n6d46vbzx43bevlb.onion:8333 +n6t6kfgzlvozxhfm.onion:8333 +n7rrochwerf2qxze.onion:8333 +ncsdiqmnxhnnjbsz.onion:8333 +nitxw3ilffngpumv.onion:8333 +njlsvubildehluwr.onion:8333 +njslfsivyyhixbsp.onion:8333 +nkf5e6b7pl4jfd4a.onion:8333 +nkppsb3t3ducje6m.onion:8333 +nlfwyqksmeqe45zz.onion:8333 +nlyjmpcmpaz5b4aa.onion:8333 +nnmv7z65k65mcesr.onion:8333 nrrfwdmrm3imuebn.onion:8333 nrrmkgmulpgsbwlt.onion:8333 -o2tku2dbsd6iumch.onion:8333 -o72zyzrv77ea2bwu.onion:8333 -ohgwa5y65z4eem7b.onion:8333 -olvdu57g7rxwpcr4.onion:8333 -onlzo775ogdpjn5x.onion:8333 -otshttbd6v2k3jlz.onion:8333 -owr5tm7ygw62z4vl.onion:8333 -pcfhsdqzs6q63ryu.onion:8333 -pffwqxvuldeq55zc.onion:8333 -pgnz7kwc36rcucpu.onion:8333 -ph4g7b4jsyuntvr4.onion:8333 -pjghcivzkoersesd.onion:8333 +nw4h7leckut7eapv.onion:8333 +nwky3wd3ihoidvb5.onion:8333 +ny4kkemmmqv4lptm.onion:8333 +o25wkcw7eorg2toi.onion:8333 +o2gumvbkw6pm45cf.onion:8333 +o4yjshdwlbshylqw.onion:8333 +ofx4qgw6lppnvtgv.onion:8333 +oketipl4gndqcaus.onion:8333 +oq5q4qrqijr2kpun.onion:8333 +oqw3mfoiobqcklxh.onion:8333 +orsy2v63ecrmdj55.onion:8333 +ot4tzmznyimmlszk.onion:8333 +owk6c2jfthwkyahe.onion:8333 +oy7ss3hm2okx4tun.onion:8333 +p2pc6wbaepvdi6ce.onion:8333 +p2x24gdhasmgcl5j.onion:8333 +p6couujr2ndhllv3.onion:8333 +pa7dw5bln5lqmu53.onion:8333 +pasmchtoooj2kchd.onion:8333 +pdapkkhk6pbcy2tj.onion:8333 +peh5ajouuw6mw4sr.onion:8333 +pkuuc5pwl5xygwhr.onion:8333 +pq4wjl7vg7tsfycc.onion:8333 +ptbwqhusps5qieql.onion:8333 +ptwpbwyj5lnyew2f.onion:8333 pu7w3jfyrzp7sxsi.onion:8333 -pxvkjp6sfb2f7foe.onion:8333 -qaxm5spmx5d2k3up.onion:8333 -qepth54daysmpy5y.onion:8333 -qj6irqn2i73edff5.onion:8333 -qjpejfzlwqqnzsol.onion:8333 -qxe3bqjmrcepxpx4.onion:8333 -rlonjm7ui6fdyz4h.onion:8333 -rs635ss24ymwyqkw.onion:8333 -sgiitogeoqslvkjv.onion:8333 -spidernetimmmkth.onion:8333 -tb7qlicrt6rdzxzd.onion:8333 -thbjka62axzuwtnt.onion:8333 -toguvy5upyuctudx.onion:8333 -u7mpvxotmnqntyn5.onion:8333 -uccmw67l4kgl646y.onion:8333 -ueo6royc3775ioq7.onion:8333 -ujsb2qcjk4t6234z.onion:8333 -uub43p3artmornv5.onion:8333 -uvb55mwvuy22mgm2.onion:8333 -uzzyjgqlf47ackbr.onion:8333 -v5fgr3fnz3nw663t.onion:8333 -v5zs2sgjyr3glh6c.onion:8333 -vk3qjdehyy4dwcxw.onion:8333 -voy6xbvejox4xbax.onion:8333 -vuiw75kgpcqke4mv.onion:8333 -w3q47ucyajtfic76.onion:8333 -wg6vwmbrzyyzapun.onion:8333 -wgpfwxgy2dowienn.onion:8333 -wjtmvsznvdclncau.onion:8333 -xab45bpmmrl5g3by.onion:8333 -xdlu3ujzieheouo7.onion:8333 -xgykmaa2jjay7cfu.onion:8333 +pwylbyvfuc62hhvx.onion:8333 +q2fhnnyt5b2ayvce.onion:8333 +q3i3apuionbazmfe.onion:8333 +qd6fcpu3pvbf2y3x.onion:8333 +qfewv3y7a3p4i3bd.onion:8333 +qhytdttflhbc4rsh.onion:8333 +qkn35rb3x2gxbwq4.onion:8333 +qlvlexs7pwac2f4b.onion:8333 +qogcqirtuta6rlxg.onion:8333 +qrzqfxkhrmu5v5ro.onion:8333 +qsyjasq46b2syiys.onion:8333 +quu4b2zjbnr2ue4y.onion:8333 +quycfj2wenz6bfyd.onion:8333 +qvdy3cmocnlv5v7c.onion:8333 +qvwhpqygan2xky5h.onion:8333 +qyutwc26ullujafb.onion:8333 +r45qg2d6iwfdhqwl.onion:8333 +r4xudr6u4r5nyga4.onion:8333 +r6apa5ssujxbwd34.onion:8333 +r6z2gcsu37k3gaah.onion:8333 +rbrjgfcca6v5b7yo.onion:8333 +rcifxibawqt6rxzz.onion:8333 +rdo3xctk3zkzjvln.onion:8333 +rdvlepy6ghgpapzo.onion:8333 +recs3a27chv2lg65.onion:8333 +rfmbiy5vztvn6hyn.onion:8333 +rli5lbje4k77inzw.onion:8333 +roqwnmepcj453vfh.onion:8333 +rpbnx54qniivrmh3.onion:8333 +rsvvogqdlijp77hv.onion:8333 +rwm5d4hg3hc77kdt.onion:8333 +s3yelkvc5f5xeysw.onion:8333 +s6rx52hitmpp4lge.onion:8333 +sa6m3rvycipgemky.onion:8333 +savebeesmkivmfbo.onion:8333 +sbyjr5npk2mlmfw7.onion:8333 +serwj42jme5xhhmw.onion:8333 +sg4vmubv3djrzvuh.onion:8333 +shsgksluz6jkgp6g.onion:8333 +sjyzmwwu6diiit3r.onion:8333 +sk3en3reudg3sdg5.onion:8333 +skoifp4oj7l4osu5.onion:8333 +sle2caplkln33e7y.onion:8333 +smdd7q7gonajdmjq.onion:8333 +spmhuxjb2cd7leun.onion:8333 +srkgyv5edn2pa7il.onion:8333 +sslnjjhnmwllysv4.onion:8333 +su66ygras6rkdtnl.onion:8333 +sundvmbjrtgdfahx.onion:8333 +svd65k5jpal2p3lt.onion:8333 +svua5hiqluw7o2sw.onion:8333 +sxqjubmum4rmfgpu.onion:8333 +t245vi742ti3tnka.onion:8333 +t4fbovvgzpnimd2p.onion:8333 +t4l4wv3erkhpde2p.onion:8333 +t5qchwbr6u5v2agk.onion:8333 +t7jlaj6ggyx7s5vy.onion:8333 +ta6sjeqyb27f4n4a.onion:8333 +tav7utpw4pfy7j6k.onion:8333 +taxg5z2sxfm5c4d6.onion:8333 +tekwvnbodbzrlufs.onion:8333 +tg4uwrjmtr2jlbjy.onion:8333 +th4cjvffjtw6vomu.onion:8333 +th6fxymtwnfifqeu.onion:8333 +thtchhl25u26nglq.onion:8333 +tiiah7csuoklcvi6.onion:8333 +tk63x5fk3337z3ud.onion:8333 +tkgootat6cqn7vyy.onion:8333 +tnj565wwqz5wpjvs.onion:8333 +ts6qx37mmpu6nj5y.onion:8333 +ttjisvxydgbtp56f.onion:8333 +twn54v7ra2xjgd55.onion:8333 +txem5meug24g2ezd.onion:8333 +tyiunn36lmfcq5lr.onion:8333 +tyv56xs6g6ndzqux.onion:8333 +u47f3hxwq65sgs4o.onion:8333 +u4r7fnholrdwwlni.onion:8333 +u556ofb3myarafwn.onion:8333 +u5q3gbz4qpz4wvlr.onion:8333 +uakly3ydrevvpxwi.onion:8333 +ug6hapi4qtekzc7v.onion:8333 +ui553qotd6ron3rf.onion:8333 +uir7f3wltoka6bbb.onion:8333 +ukrjjhwodl44wmof.onion:8333 +ul5gm2ixy7kqdfwg.onion:8333 +undd7rsj4pen3wo4.onion:8333 +uorwpzfehtykrg43.onion:8333 +uovsp2yltnaojq6l.onion:8333 +usazmdcs32ny24dy.onion:8333 +usazs7glm7geyxkl.onion:8333 +uss2kedg7qkwgdr5.onion:8333 +utgyrvw75wv2nymi.onion:8333 +uzwacms7kyzhehbl.onion:8333 +v2kdcetvslmdfcwr.onion:8333 +v5lhnzzv6nngfg5d.onion:8333 +vc44gb4veppobrt3.onion:8333 +vfwyhju43wxhzvux.onion:8333 +vgujufk53lqyolio.onion:8333 +vheejqq2v5dkb4xr.onion:8333 +vj64edev4jnqfdsb.onion:8333 +vmai5uigezr2khkj.onion:8333 +vmuykd7sxbmi7w57.onion:8333 +vomeacttinx3mpml.onion:8333 +vpow2xofg3fwzsdq.onion:8333 +vsawli4l5ifxdzaw.onion:8333 +vunubqkfms7sifok.onion:8333 +vuombnevwul4bqsb.onion:8333 +vxcpvdng65aefz6t.onion:8333 +vyxoizdzavp3obau.onion:8333 +wbeon2ci7lfio6ay.onion:8333 +wbwevew62mgsrrdz.onion:8333 +wfaydlg6zyfzjcu5.onion:8333 +wfz56s5lyn5dysez.onion:8333 +wg3mq4ugyy2gx32b.onion:8333 +whky54bctkf2n4p3.onion:8333 +whmjanqoyzizzc4t.onion:8333 +wlhou2wxgqyi3x3f.onion:8333 +wlvkfrplfiioz22o.onion:8333 +x3ngb3va7dovuenw.onion:8333 +x57x62bmmnylvo7r.onion:8333 +xgvm57mhgv564dka.onion:8333 +xhs3glfwnwiumivn.onion:8333 +xje5fwvyfdue2u6k.onion:8333 +xlgubgyly2blvsg5.onion:8333 xnlu3tvakngy7tkp.onion:8333 -xsn5icce45gs3qy7.onion:8333 -ydonogjpjd3me45v.onion:8333 -ykn7vof37bavxetd.onion:8333 -yl525dwhvqis7ryc.onion:8333 -yrbaccpbyge6xaba.onion:8333 -yyuxafli7fqdizhq.onion:8333 +xo5marilhuyo7but.onion:8333 +xsaaxihdygnwxrix.onion:8333 +xu5mlugdsmzfkvzh.onion:8333 +xvrxqcptqvieedb2.onion:8333 +xwzhrrygftq3q4w4.onion:8333 +y4swmsaxdcos2bnu.onion:8333 +y5tl4lqi365pplud.onion:8333 +y5wzeqyaets5na6t.onion:8333 +y73qk2mzkjkhoky7.onion:8333 +y7oz3ydnvib4xhbb.onion:8333 +yah7qgfqqrteoche.onion:8333 +yba4brm555denlt7.onion:8333 +ygeqkg4inplsace3.onion:8333 +yjhnfu75lazbi34h.onion:8333 +yjw7kqapxx5vggoj.onion:8333 +ym7inmovbrna4gco.onion:8333 +yq5cusnuokscy64z.onion:8333 +yrcaioqrqrdwokqt.onion:8333 +yrcr7pgjuazad254.onion:8333 +yrksvon3tmvoohdv.onion:8333 +ytpus4vx5w7j6wp2.onion:8333 +ytqcigk2hhdl45ho.onion:8333 +yxojl3xmjus3dik2.onion:8333 +yzdqdsqx4fdung6w.onion:8333 z33nukt7ngik3cpe.onion:8333 -zon2bbc2q2ihqt4c.onion:8333 -zqjvtxskxonu4kzv.onion:8333 +z3ywbadw46ndnxgh.onion:8333 +z6mbqq7llxlrn4kq.onion:8333 +zb3lrcksn4rzhzje.onion:8333 +ze7odp7pzarjplsr.onion:8333 +zgbmhtbja4fy2373.onion:8333 +zh7hvalcgvjpoaqm.onion:8333 +ziztvxehmj5mehpg.onion:8333 +zjii3yecdrmq73y3.onion:8333 +zkrwmgjuvsza6ye2.onion:8333 +zoz2aopwi3wfuqwg.onion:8333 +ztdcfnh46773bivu.onion:8333 +zuxhc6d3nwpgc4af.onion:8333 +zuytrfevzjcpizli.onion:8333 +zvq6dpt3i2ofdp3g.onion:8333 +zwwm6ga7u2hqe2sd.onion:8333 +zyqb4lenfspntj5m.onion:8333 diff --git a/contrib/seeds/nodes_test.txt b/contrib/seeds/nodes_test.txt old mode 100755 new mode 100644 diff --git a/contrib/seeds/suspicious_hosts.txt b/contrib/seeds/suspicious_hosts.txt new file mode 100644 index 00000000..13385cc8 --- /dev/null +++ b/contrib/seeds/suspicious_hosts.txt @@ -0,0 +1,16 @@ +130.211.129.106 +148.251.238.178 +176.9.46.6 +178.63.107.226 +54.173.72.127 +54.174.10.182 +54.183.64.54 +54.194.231.211 +54.66.214.167 +54.66.220.137 +54.67.33.14 +54.77.251.214 +54.94.195.96 +54.94.200.247 +83.81.130.26 +88.198.17.7 \ No newline at end of file diff --git a/contrib/testgen/README.md b/contrib/testgen/README.md old mode 100755 new mode 100644 index c76273c5..491b8039 --- a/contrib/testgen/README.md +++ b/contrib/testgen/README.md @@ -1,8 +1,8 @@ ### TestGen ### -Utilities to generate test vectors for the data-driven Bitsend tests. +Utilities to generate test vectors for the data-driven BitSend tests. -Usage: +Usage: - gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json - gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json \ No newline at end of file + 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 diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py old mode 100755 new mode 100644 index 9993b8c1..b489b10e --- a/contrib/testgen/base58.py +++ b/contrib/testgen/base58.py @@ -1,10 +1,10 @@ -# Copyright (c) 2012-2018 The Bitsend Core developers +# Copyright (c) 2012-2018 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' -Bitsend base58 encoding and decoding. +BitSend base58 encoding and decoding. -Based on https://bitcointalk.org/index.php?topic=1026.0 (public domain) +Based on https://bitsendtalk.org/index.php?topic=1026.0 (public domain) ''' import hashlib @@ -39,7 +39,7 @@ def b58encode(v): long_value = div result = __b58chars[long_value] + result - # Bitsend does a little leading-zero-compression: + # BitSend does a little leading-zero-compression: # leading 0-bytes in the input become leading-1s nPad = 0 for c in v: @@ -107,7 +107,7 @@ def get_bcaddress_version(strAddress): if __name__ == '__main__': # Test case (from http://gitorious.org/bitsend/python-base58.git) - assert get_bcaddress_version('15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC') is 0 + assert get_bcaddress_version('15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC') == 0 _ohai = 'o hai'.encode('ascii') _tmp = b58encode(_ohai) assert _tmp == 'DYB3oMS' diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py deleted file mode 100755 index b42dc3da..00000000 --- a/contrib/testgen/gen_base58_test_vectors.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2012-2018 The Bitsend 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 address and private key test vectors. - -Usage: - gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json - gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_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 -import random -from binascii import b2a_hex - -# key types -PUBKEY_ADDRESS = 0 -SCRIPT_ADDRESS = 5 -PUBKEY_ADDRESS_TEST = 111 -SCRIPT_ADDRESS_TEST = 196 -PRIVKEY = 128 -PRIVKEY_TEST = 239 - -metadata_keys = ['isPrivkey', 'isTestnet', 'addrType', 'isCompressed'] -# templates for valid sequences -templates = [ - # prefix, payload_size, suffix, metadata - # None = N/A - ((PUBKEY_ADDRESS,), 20, (), (False, False, 'pubkey', None)), - ((SCRIPT_ADDRESS,), 20, (), (False, False, 'script', None)), - ((PUBKEY_ADDRESS_TEST,), 20, (), (False, True, 'pubkey', None)), - ((SCRIPT_ADDRESS_TEST,), 20, (), (False, True, 'script', None)), - ((PRIVKEY,), 32, (), (True, False, None, False)), - ((PRIVKEY,), 32, (1,), (True, False, None, True)), - ((PRIVKEY_TEST,), 32, (), (True, True, None, False)), - ((PRIVKEY_TEST,), 32, (1,), (True, True, None, True)) -] - -def is_valid(v): - '''Check vector v for validity''' - result = b58decode_chk(v) - if result is None: - return False - for template in templates: - prefix = bytearray(template[0]) - suffix = bytearray(template[2]) - if result.startswith(prefix) and result.endswith(suffix): - if (len(result) - len(prefix) - len(suffix)) == template[1]: - return True - return False - -def gen_valid_vectors(): - '''Generate valid test vectors''' - while True: - for template in templates: - prefix = bytearray(template[0]) - payload = bytearray(os.urandom(template[1])) - suffix = bytearray(template[2]) - rv = b58encode_chk(prefix + payload + suffix) - assert is_valid(rv) - metadata = {x: y for x, y in zip(metadata_keys,template[3]) if y is not None} - hexrepr = b2a_hex(payload) - if isinstance(hexrepr, bytes): - hexrepr = hexrepr.decode('utf8') - yield (rv, hexrepr, metadata) - -def gen_invalid_vector(template, corrupt_prefix, randomize_payload_size, corrupt_suffix): - '''Generate possibly invalid vector''' - 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]) - - return b58encode_chk(prefix + payload + suffix) - -def randbool(p = 0.5): - '''Return True with P(p)''' - return random.random() < p - -def gen_invalid_vectors(): - '''Generate invalid test vectors''' - # start with some manual edge-cases - yield "", - yield "x", - while True: - # kinds of invalid vectors: - # invalid prefix - # invalid payload length - # invalid (randomized) suffix (add random data) - # corrupt checksum - for template in templates: - val = gen_invalid_vector(template, randbool(0.2), randbool(0.2), randbool(0.2)) - 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:] - if not is_valid(val): - yield val, - -if __name__ == '__main__': - import sys - import json - iters = {'valid':gen_valid_vectors, 'invalid':gen_invalid_vectors} - try: - uiter = iters[sys.argv[1]] - except IndexError: - uiter = gen_valid_vectors - try: - count = int(sys.argv[2]) - except IndexError: - count = 0 - - data = list(islice(uiter(), count)) - json.dump(data, sys.stdout, sort_keys=True, indent=4) - sys.stdout.write('\n') - 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 00000000..a7e7d971 --- /dev/null +++ b/contrib/testgen/gen_key_io_test_vectors.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python3 +# Copyright (c) 2012-2018 The BitSend 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 +import random +from segwit_addr import bech32_encode, decode_segwit_address, convertbits, CHARSET, Encoding + +# key types +PUBKEY_ADDRESS = 0 +SCRIPT_ADDRESS = 5 +PUBKEY_ADDRESS_TEST = 111 +SCRIPT_ADDRESS_TEST = 196 +PUBKEY_ADDRESS_REGTEST = 111 +SCRIPT_ADDRESS_REGTEST = 196 +PRIVKEY = 128 +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), + ((PUBKEY_ADDRESS_TEST,), 20, (), (False, 'test', None, None), pubkey_prefix, pubkey_suffix), + ((SCRIPT_ADDRESS_TEST,), 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 + ('bc', 0, 20, (False, 'main', None, True), Encoding.BECH32, p2wpkh_prefix), + ('bc', 0, 32, (False, 'main', None, True), Encoding.BECH32, p2wsh_prefix), + ('bc', 1, 32, (False, 'main', None, True), Encoding.BECH32M, p2tr_prefix), + ('bc', 2, 2, (False, 'main', None, True), Encoding.BECH32M, (OP_2, 2)), + ('tb', 0, 20, (False, 'test', None, True), Encoding.BECH32, p2wpkh_prefix), + ('tb', 0, 32, (False, 'test', None, True), Encoding.BECH32, p2wsh_prefix), + ('tb', 1, 32, (False, 'test', None, True), Encoding.BECH32M, p2tr_prefix), + ('tb', 3, 16, (False, 'test', None, True), Encoding.BECH32M, (OP_3, 16)), + ('tb', 0, 20, (False, 'signet', None, True), Encoding.BECH32, p2wpkh_prefix), + ('tb', 0, 32, (False, 'signet', None, True), Encoding.BECH32, p2wsh_prefix), + ('tb', 1, 32, (False, 'signet', None, True), Encoding.BECH32M, p2tr_prefix), + ('tb', 3, 32, (False, 'signet', None, True), Encoding.BECH32M, (OP_3, 32)), + ('bcrt', 0, 20, (False, 'regtest', None, True), Encoding.BECH32, p2wpkh_prefix), + ('bcrt', 0, 32, (False, 'regtest', None, True), Encoding.BECH32, p2wsh_prefix), + ('bcrt', 1, 32, (False, 'regtest', None, True), Encoding.BECH32M, p2tr_prefix), + ('bcrt', 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), + ('tb', 17, 32, Encoding.BECH32M, False, False, False), + ('bcrt', 3, 1, Encoding.BECH32M, False, False, False), + ('bc', 15, 41, Encoding.BECH32M, False, False, False), + ('tb', 0, 16, Encoding.BECH32, False, False, False), + ('bcrt', 0, 32, Encoding.BECH32, True, False, False), + ('bc', 0, 16, Encoding.BECH32, True, False, False), + ('tb', 0, 32, Encoding.BECH32, False, True, False), + ('bcrt', 0, 20, Encoding.BECH32, False, False, True), + ('bc', 0, 20, Encoding.BECH32M, False, False, False), + ('tb', 0, 32, Encoding.BECH32M, False, False, False), + ('bcrt', 0, 20, Encoding.BECH32M, False, False, False), + ('bc', 1, 32, Encoding.BECH32, False, False, False), + ('tb', 2, 16, Encoding.BECH32, False, False, False), + ('bcrt', 16, 20, Encoding.BECH32, False, False, False), +] + +def is_valid(v): + '''Check vector v for validity''' + if len(set(v) - set(b58chars)) > 0: + return is_valid_bech32(v) + result = b58decode_chk(v) + if result is None: + return is_valid_bech32(v) + for template in templates: + prefix = bytearray(template[0]) + suffix = bytearray(template[2]) + if result.startswith(prefix) and result.endswith(suffix): + if (len(result) - len(prefix) - len(suffix)) == template[1]: + return True + return is_valid_bech32(v) + +def is_valid_bech32(v): + '''Check vector v for bech32 validity''' + for hrp in ['bc', 'tb', 'bcrt']: + if decode_segwit_address(hrp, v) != (None, None): + return True + return 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_valid_bech32_vector(template): + '''Generate valid bech32 vector''' + hrp = template[0] + witver = template[1] + witprog = bytearray(os.urandom(template[2])) + encoding = template[4] + dst_prefix = bytearray(template[5]) + rv = bech32_encode(encoding, hrp, [witver] + convertbits(witprog, 8, 5)) + return rv, dst_prefix + witprog + +def gen_valid_vectors(): + '''Generate valid test vectors''' + glist = [gen_valid_base58_vector, gen_valid_bech32_vector] + tlist = [templates, bech32_templates] + while True: + for template, valid_vector_generator in [(t, g) for g, l in zip(glist, tlist) for t in l]: + rv, payload = valid_vector_generator(template) + assert is_valid(rv) + metadata = {x: y for x, y in zip(metadata_keys,template[3]) if y is not None} + hexrepr = payload.hex() + yield (rv, hexrepr, metadata) + +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 no_data: + rv = bech32_encode(encoding, hrp, []) + else: + data = [witver] + convertbits(witprog, 8, 5) + if template[4] and not no_data: + if template[2] % 5 in {2, 4}: + data[-1] |= 1 + else: + data.append(0) + rv = bech32_encode(encoding, hrp, data) + + 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 + +def gen_invalid_vectors(): + '''Generate invalid test vectors''' + # start with some manual edge-cases + yield "", + yield "x", + glist = [gen_invalid_base58_vector, gen_invalid_bech32_vector] + tlist = [templates, bech32_ng_templates] + while True: + for template, invalid_vector_generator in [(t, g) for g, l in zip(glist, tlist) for t in l]: + val = invalid_vector_generator(template) + if not is_valid(val): + yield val, + +if __name__ == '__main__': + import sys + import json + iters = {'valid':gen_valid_vectors, 'invalid':gen_invalid_vectors} + try: + uiter = iters[sys.argv[1]] + except IndexError: + uiter = gen_valid_vectors + try: + count = int(sys.argv[2]) + except IndexError: + count = 0 + + data = list(islice(uiter(), count)) + json.dump(data, sys.stdout, sort_keys=True, indent=4) + sys.stdout.write('\n') + diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp old mode 100755 new mode 100644 index 6047e98e..ccfe6060 --- a/contrib/valgrind.supp +++ b/contrib/valgrind.supp @@ -1,12 +1,20 @@ -# Valgrind suppressions file for Bitsend. -# -# Includes known Valgrind warnings in our dependencies that cannot be fixed -# in-tree. +# 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_bitsend # $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ -# --show-leak-kinds=all src/test/test_bitsend --log_level=test_suite +# --show-leak-kinds=all src/test/test_bitsend +# +# 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_bitsend +# +# 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 @@ -23,8 +31,56 @@ 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 - fun:__log_put_record +} +{ + 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 @@ -41,3 +97,89 @@ ... 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/README.md b/contrib/verify-commits/README.md old mode 100755 new mode 100644 index eb5246ad..a1809575 --- a/contrib/verify-commits/README.md +++ b/contrib/verify-commits/README.md @@ -3,7 +3,7 @@ Tooling for verification of PGP signed commits This is an incomplete work in progress, but currently includes a pre-push hook script (`pre-push-hook.sh`) for maintainers to ensure that their own commits -are PGP signed (nearly always merge commits), as well as a script to verify +are PGP signed (nearly always merge commits), as well as a Python 3 script to verify commits against a trusted keys list. @@ -17,9 +17,11 @@ be backdoored. Instead, you need to use a trusted version of verify-commits prior to checkout to make sure you're checking out only code signed by trusted keys: - git fetch origin && \ - ./contrib/verify-commits/verify-commits.py origin/master && \ - git checkout origin/master + ```sh + git fetch origin && \ + ./contrib/verify-commits/verify-commits.py origin/master && \ + git checkout origin/master + ``` Note that the above isn't a good UI/UX yet, and needs significant improvements to make it more convenient and reduce the chance of errors; pull-reqs @@ -33,6 +35,14 @@ Configuration files * `trusted-keys`: This file should contain a \n-delimited list of all PGP fingerprints of authorized commit signers (primary, not subkeys). * `allow-revsig-commits`: This file should contain a \n-delimited list of git commit hashes. See next section for more info. +Import trusted keys +------------------- +In order to check the commit signatures, you must add the trusted PGP keys to your machine. [GnuPG](https://gnupg.org/) may be used to import the trusted keys by running the following command: + +```sh +gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys $( /dev/stderr @@ -35,7 +35,7 @@ else done [ "$GPG_RES" = "" ] && GPG_RES="$(printf '%s\n' "$INPUT" | gpg --trust-model always --weak-digest sha1 "$@" 2>/dev/null)" fi -for LINE in $(echo "$GPG_RES"); do +for LINE in $GPG_RES; do case "$LINE" in "[GNUPG:] VALIDSIG "*) while read KEY; do diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh index e2ca9fb7..3f4218fe 100755 --- a/contrib/verify-commits/pre-push-hook.sh +++ b/contrib/verify-commits/pre-push-hook.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2014-2015 The Bitsend Core developers +# Copyright (c) 2014-2020 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root old mode 100755 new mode 100644 diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys old mode 100755 new mode 100644 index 56106926..27fede62 --- a/contrib/verify-commits/trusted-keys +++ b/contrib/verify-commits/trusted-keys @@ -2,3 +2,5 @@ 133EAC179436F14A5CF1B794860FEB804E669320 32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC B8B3F1C0E58C15DB6A81D30C3648A882F4316B9B +CA03882CB1FC067B5D3ACFE4D300116E1C875A3D +E777299FC265DD04793070EB944D35F9AC3DB76A diff --git a/contrib/verify-commits/trusted-sha512-root-commit b/contrib/verify-commits/trusted-sha512-root-commit old mode 100755 new mode 100644 diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py index 1407b898..8144a693 100755 --- a/contrib/verify-commits/verify-commits.py +++ b/contrib/verify-commits/verify-commits.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -# Copyright (c) 2018 The Bitsend Core developers +# Copyright (c) 2018-2019 The BitSend 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 @@ -15,7 +16,7 @@ def tree_sha512sum(commit='HEAD'): """Calculate the Tree-sha512 for the commit. - This is copied from github-merge.py.""" + This is copied from github-merge.py. See https://github.com/bitsend-core/bitsend-maintainer-tools.""" # request metadata for entire tree, recursively files = [] @@ -66,6 +67,11 @@ def tree_sha512sum(commit='HEAD'): 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') @@ -91,10 +97,14 @@ def main(): no_sha1 = True prev_commit = "" initial_commit = current_commit - branch = subprocess.check_output([GIT, 'show', '-s', '--format=%H', initial_commit], universal_newlines=True).splitlines()[0] + 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) @@ -112,7 +122,7 @@ def main(): 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], universal_newlines=True).splitlines()[0].split(' ') + 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: @@ -122,25 +132,25 @@ def main(): # 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], universal_newlines=True).splitlines(): + 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], universal_newlines=True).splitlines()[0].split(' ') + 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], universal_newlines=True).splitlines()[0]) + 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], universal_newlines=True).splitlines()[0] + 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', parents[1]], stdout=subprocess.DEVNULL) - recreated_tree = subprocess.check_output([GIT, 'show', '--format=format:%T', 'HEAD'], universal_newlines=True).splitlines()[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]) diff --git a/contrib/verifybinaries/README.md b/contrib/verifybinaries/README.md old mode 100755 new mode 100644 index 55f9b01f..daa7c7dd --- a/contrib/verifybinaries/README.md +++ b/contrib/verifybinaries/README.md @@ -5,15 +5,15 @@ Make sure you obtain the proper release signing key and verify the fingerprint with several independent sources. ```sh -$ gpg --fingerprint "Bitsend Core binary release signing key" -pub 4096R/36C2E964 2015-06-24 [expires: 2017-02-13] +$ gpg --fingerprint "BitSend Core binary release signing key" +pub 4096R/36C2E964 2015-06-24 [expires: YYYY-MM-DD] Key fingerprint = 01EA 5486 DE18 A882 D4C2 6845 90C8 019E 36C2 E964 -uid Wladimir J. van der Laan (Bitsend Core binary release signing key) +uid Wladimir J. van der Laan (BitSend Core binary release signing key) ``` #### Usage: -This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org. +This script attempts to download the signature file `SHA256SUMS.asc` from https://bitsend.org. It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file. @@ -21,21 +21,21 @@ The script returns 0 if everything passes the checks. It returns 1 if either the ```sh -./verify.sh bitcoin-core-0.11.2 -./verify.sh bitcoin-core-0.12.0 -./verify.sh bitcoin-core-0.13.0-rc3 +./verify.sh bitsend-core-0.11.2 +./verify.sh bitsend-core-0.12.0 +./verify.sh bitsend-core-0.13.0-rc3 ``` If you only want to download the binaries of certain platform, add the corresponding suffix, e.g.: ```sh -./verify.sh bitcoin-core-0.11.2-osx +./verify.sh bitsend-core-0.11.2-osx ./verify.sh 0.12.0-linux -./verify.sh bitcoin-core-0.13.0-rc3-win64 +./verify.sh bitsend-core-0.13.0-rc3-win64 ``` If you do not want to keep the downloaded binaries, specify anything as the second parameter. ```sh -./verify.sh bitcoin-core-0.13.0 delete +./verify.sh bitsend-core-0.13.0 delete ``` diff --git a/contrib/verifybinaries/verify.sh b/contrib/verifybinaries/verify.sh index a79334e1..e070215f 100755 --- a/contrib/verifybinaries/verify.sh +++ b/contrib/verifybinaries/verify.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash -# Copyright (c) 2016 The Bitsend Core developers +# Copyright (c) 2016-2019 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ### This script attempts to download the signature file SHA256SUMS.asc from -### bitcoincore.org and bitcoin.org and compares them. +### bitsendcore.org and bitsend.org and compares them. ### It first checks if the signature passes, and then downloads the files specified in ### the file, and checks if the hashes of these files match those that are specified ### in the signature file. @@ -13,7 +13,7 @@ export LC_ALL=C function clean_up { - for file in $* + for file in "$@" do rm "$file" 2> /dev/null done @@ -24,10 +24,10 @@ TMPFILE="hashes.tmp" SIGNATUREFILENAME="SHA256SUMS.asc" RCSUBDIR="test" -HOST1="https://bitcoincore.org" -HOST2="https://bitcoin.org" +HOST1="https://bitsendcore.org" +HOST2="https://bitsend.org" BASEDIR="/bin/" -VERSIONPREFIX="bitcoin-core-" +VERSIONPREFIX="bitsend-core-" RCVERSIONSTRING="rc" if [ ! -d "$WORKINGDIR" ]; then @@ -82,22 +82,20 @@ else exit 2 fi -#first we fetch the file containing the signature -WGETOUT=$(wget -N "$HOST1$BASEDIR$SIGNATUREFILENAME" 2>&1) - -#and then see if wget completed successfully -if [ $? -ne 0 ]; then +if ! WGETOUT=$(wget -N "$HOST1$BASEDIR$SIGNATUREFILENAME" 2>&1); then echo "Error: couldn't fetch signature file. Have you specified the version number in the following format?" + # shellcheck disable=SC1087 echo "[$VERSIONPREFIX]-[$RCVERSIONSTRING[0-9]] (example: ${VERSIONPREFIX}0.10.4-${RCVERSIONSTRING}1)" echo "wget output:" + # shellcheck disable=SC2001 echo "$WGETOUT"|sed 's/^/\t/g' exit 2 fi -WGETOUT=$(wget -N -O "$SIGNATUREFILENAME.2" "$HOST2$BASEDIR$SIGNATUREFILENAME" 2>&1) -if [ $? -ne 0 ]; then - echo "bitcoin.org failed to provide signature file, but bitsend.cc did?" +if ! WGETOUT=$(wget -N -O "$SIGNATUREFILENAME.2" "$HOST2$BASEDIR$SIGNATUREFILENAME" 2>&1); then + echo "bitsend.org failed to provide signature file, but bitsendcore.org did?" echo "wget output:" + # shellcheck disable=SC2001 echo "$WGETOUT"|sed 's/^/\t/g' clean_up $SIGNATUREFILENAME exit 3 @@ -105,7 +103,7 @@ fi SIGFILEDIFFS="$(diff $SIGNATUREFILENAME $SIGNATUREFILENAME.2)" if [ "$SIGFILEDIFFS" != "" ]; then - echo "bitcoin.org and bitsend.cc signature files were not equal?" + echo "bitsend.org and bitsendcore.org signature files were not equal?" clean_up $SIGNATUREFILENAME $SIGNATUREFILENAME.2 exit 4 fi @@ -124,10 +122,11 @@ if [ $RET -ne 0 ]; then echo "Bad signature." elif [ $RET -eq 2 ]; then #or if a gpg error has occurred - echo "gpg error. Do you have the Bitsend Core binary release signing key installed?" + echo "gpg error. Do you have the BitSend Core binary release signing key installed?" fi echo "gpg output:" + # shellcheck disable=SC2001 echo "$GPGOUT"|sed 's/^/\t/g' clean_up $SIGNATUREFILENAME $SIGNATUREFILENAME.2 $TMPFILE exit "$RET" diff --git a/contrib/windeploy/detached-sig-create.sh b/contrib/windeploy/detached-sig-create.sh index 886c836c..37ea93d7 100755 --- a/contrib/windeploy/detached-sig-create.sh +++ b/contrib/windeploy/detached-sig-create.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2015 The Bitsend Core developers +# Copyright (c) 2014-2019 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,7 +8,7 @@ if [ -z "$OSSLSIGNCODE" ]; then OSSLSIGNCODE=osslsigncode fi -if [ ! -n "$1" ]; then +if [ -z "$1" ]; then echo "usage: $0 " echo "example: $0 -key codesign.key" exit 1 @@ -23,7 +23,7 @@ TIMESERVER=http://timestamp.comodoca.com CERTFILE="win-codesign.cert" mkdir -p "${OUTSUBDIR}" -basename -a `ls -1 "${SRCDIR}"/*-unsigned.exe` | while read UNSIGNED; do +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}" diff --git a/contrib/windeploy/win-codesign.cert b/contrib/windeploy/win-codesign.cert old mode 100755 new mode 100644 index 200b30a3..4023a5b6 --- a/contrib/windeploy/win-codesign.cert +++ b/contrib/windeploy/win-codesign.cert @@ -1,99 +1,100 @@ -----BEGIN CERTIFICATE----- -MIIFTTCCBDWgAwIBAgIRALlW05RLwG2hMQMX5d/o5J8wDQYJKoZIhvcNAQELBQAw -fTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxIzAhBgNV -BAMTGkNPTU9ETyBSU0EgQ29kZSBTaWduaW5nIENBMB4XDTE2MDIwMzAwMDAwMFoX -DTE5MDMwNTIzNTk1OVowgbUxCzAJBgNVBAYTAlVTMQ4wDAYDVQQRDAU5ODEwNDEL -MAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAkMB1N0ZSAzMDAx -FzAVBgNVBAkMDjcxIENvbHVtYmlhIFN0MSUwIwYDVQQKDBxUaGUgQml0Y29pbiBG -b3VuZGF0aW9uLCBJbmMuMSUwIwYDVQQDDBxUaGUgQml0Y29pbiBGb3VuZGF0aW9u -LCBJbmMuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw37Vrv9Gbku0 -+kuV0t89TuyxtAcmT7QE4GcwESKKjmkxfzD9a0qlhqk8GfQ+fw4DHNN+nLKNv7xB -bk6aS7J2v2DcXkOjrP99P9jqgTkp7MC04VtG3OqVRGB+gum0pptRovYZUQXIdkY7 -GJOok/NDagwKiiUe2V2meZ7UctsZNvYeilQdTgKIIhrMB9NowCOhT8ocVL4Ki55/ -l7hukJn3fueCM3fHTwY2/1gaGsOHoCkFRsD7vokjAVpiY+8rUgvHjb0gxgojiVGd -6a6/F5XJwKJacvUyN4Hfc2K5lRMQjTTmo4aWNWIa0iJ3TK9BHpdSLJBqerMPvmnM -kkapS+ZTNQIDAQABo4IBjTCCAYkwHwYDVR0jBBgwFoAUKZFg/4pN+uv5pmq4z/nm -S71JzhIwHQYDVR0OBBYEFONpQ+cV82URVe+V8G57377KxxexMA4GA1UdDwEB/wQE -AwIHgDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMBEGCWCGSAGG -+EIBAQQEAwIEEDBGBgNVHSAEPzA9MDsGDCsGAQQBsjEBAgEDAjArMCkGCCsGAQUF -BwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8ubmV0L0NQUzBDBgNVHR8EPDA6MDig -NqA0hjJodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDb2RlU2lnbmlu -Z0NBLmNybDB0BggrBgEFBQcBAQRoMGYwPgYIKwYBBQUHMAKGMmh0dHA6Ly9jcnQu -Y29tb2RvY2EuY29tL0NPTU9ET1JTQUNvZGVTaWduaW5nQ0EuY3J0MCQGCCsGAQUF -BzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQELBQADggEB -AGnBSi9K/9rgTAyKFKrfGWSfNOwAghmsnsvpZSQ7QyoGWBFKSgCs/70kErl18oHA -g7Y8loQB1yukZmJaCa3OvGud7smn45TCh0TMf4EpP20Wxf4rMQTxwAatasHL3+vi -I+Nl5bsRZ09kWjvayqLII5upjS/yq0JfpmyGl5k2C/fIpztq0iOLvqWlXcL4+51r -cMUAfX6E6EaZQm//ikp+w2+7MEXTKguOuV3gwsrTy0DsvkZl4YDgx/FA4ImzXopv -d+3KJPLvO+OSBqUD3JPwXHnuJqGAbLBFyyCa/feGUjLlR8cxcNWLWdp4qxtoIUPG -3wTsC9YgrglS0F7FKMXlNRY= +MIIFdDCCBFygAwIBAgIRAL98pqZb/N9LuNaNxKsHNGQwDQYJKoZIhvcNAQELBQAw +fDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYDVQQD +ExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcgQ0EwHhcNMjAwMzI0MDAwMDAwWhcN +MjEwMzI0MjM1OTU5WjCBtzELMAkGA1UEBhMCQ0gxDTALBgNVBBEMBDgwMDUxDjAM +BgNVBAgMBVN0YXRlMRAwDgYDVQQHDAdaw7xyaWNoMRcwFQYDVQQJDA5NYXR0ZW5n +YXNzZSAyNzEuMCwGA1UECgwlQml0Y29pbiBDb3JlIENvZGUgU2lnbmluZyBBc3Nv +Y2lhdGlvbjEuMCwGA1UEAwwlQml0Y29pbiBDb3JlIENvZGUgU2lnbmluZyBBc3Nv +Y2lhdGlvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMtxC8N4r/jE +OGOdFy/0UtiUvEczPZf9WYZz/7paAkc75XopHIE5/ssmoEX27gG9K00tf3Q62QAx +inZUPWkNTh8X0l+6uSGiIBFIV7dDgztIxnPcxaqw0k7Q2TEqKJvb5qm16zX6WfXJ +R2r6O5utUdQ3AarHnQq9fwdM1j5+ywS5u52te74ENgDMTMKUuB2J3KH1ASg5PAtO +CjPqPL+ZXJ7eT3M0Z+Lbu5ISZSqZB48BcCwOo/fOO0dAiLT9FE1iVtaCpBKHqGmd +glRjPzZdgDv8g28etRmk8wQ5pQmfL2gBjt/LtIgMPTdHHETKLxJO5H3y0CNx1vzL +ql7xNMxELxkCAwEAAaOCAbMwggGvMB8GA1UdIwQYMBaAFA7hOqhTOjHVir7Bu61n +GgOFrTQOMB0GA1UdDgQWBBSHBbl82FUJiUkXyyYJog1awYRsxjAOBgNVHQ8BAf8E +BAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAzARBglghkgB +hvhCAQEEBAMCBBAwQAYDVR0gBDkwNzA1BgwrBgEEAbIxAQIBAwIwJTAjBggrBgEF +BQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwQwYDVR0fBDwwOjA4oDagNIYy +aHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBQ29kZVNpZ25pbmdDQS5j +cmwwcwYIKwYBBQUHAQEEZzBlMD4GCCsGAQUFBzAChjJodHRwOi8vY3J0LnNlY3Rp +Z28uY29tL1NlY3RpZ29SU0FDb2RlU2lnbmluZ0NBLmNydDAjBggrBgEFBQcwAYYX +aHR0cDovL29jc3Auc2VjdGlnby5jb20wKwYDVR0RBCQwIoEgam9uYXNAYml0Y29p +bmNvcmVjb2Rlc2lnbmluZy5vcmcwDQYJKoZIhvcNAQELBQADggEBAAU59qJzQ2ED +aTMIQTsU01zIhZJ/xwQh78i0v2Mnr46RvzYrZOev+btF3SyUYD8veNnbYlY6yEYq +Vb+/PQnE3t1xlqR80qiTZCk/Wmxx/qKvQuWeRL5QQgvsCmWBpycQ7PNfwzOWxbPE +b0Hb2/VFFZfR9iltkfeInRUrzS96CJGYtm7dMf2JtnXYBcwpn1N8BSMH4nXVyN8g +VEE5KyjE7+/awYiSST7+e6Y7FE5AJ4f3FjqnRm+2XetTVqITwMLKZMoV283nSEeH +fA4FNAMGz9QeV38ol65NNqFP2vSSgVoPK79orqH9OOW2LSobt2qun+euddJIQeYV +CMP90b/2WPc= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIF4DCCA8igAwIBAgIQLnyHzA6TSlL+lP0ct800rzANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTMwNTA5 -MDAwMDAwWhcNMjgwNTA4MjM1OTU5WjB9MQswCQYDVQQGEwJHQjEbMBkGA1UECBMS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD -T01PRE8gQ0EgTGltaXRlZDEjMCEGA1UEAxMaQ09NT0RPIFJTQSBDb2RlIFNpZ25p -bmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmmJBjd5E0f4rR -3elnMRHrzB79MR2zuWJXP5O8W+OfHiQyESdrvFGRp8+eniWzX4GoGA8dHiAwDvth -e4YJs+P9omidHCydv3Lj5HWg5TUjjsmK7hoMZMfYQqF7tVIDSzqwjiNLS2PgIpQ3 -e9V5kAoUGFEs5v7BEvAcP2FhCoyi3PbDMKrNKBh1SMF5WgjNu4xVjPfUdpA6M0ZQ -c5hc9IVKaw+A3V7Wvf2pL8Al9fl4141fEMJEVTyQPDFGy3CuB6kK46/BAW+QGiPi -XzjbxghdR7ODQfAuADcUuRKqeZJSzYcPe9hiKaR+ML0btYxytEjy4+gh+V5MYnmL -Agaff9ULAgMBAAGjggFRMIIBTTAfBgNVHSMEGDAWgBS7r34CPfqm8TyEjq3uOJjs -2TIy1DAdBgNVHQ4EFgQUKZFg/4pN+uv5pmq4z/nmS71JzhIwDgYDVR0PAQH/BAQD -AgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEQYD -VR0gBAowCDAGBgRVHSAAMEwGA1UdHwRFMEMwQaA/oD2GO2h0dHA6Ly9jcmwuY29t -b2RvY2EuY29tL0NPTU9ET1JTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHEG -CCsGAQUFBwEBBGUwYzA7BggrBgEFBQcwAoYvaHR0cDovL2NydC5jb21vZG9jYS5j -b20vQ09NT0RPUlNBQWRkVHJ1c3RDQS5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v -Y3NwLmNvbW9kb2NhLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAAj8COcPu+Mo7id4M -bU2x8U6ST6/COCwEzMVjEasJY6+rotcCP8xvGcM91hoIlP8l2KmIpysQGuCbsQci -GlEcOtTh6Qm/5iR0rx57FjFuI+9UUS1SAuJ1CAVM8bdR4VEAxof2bO4QRHZXavHf -WGshqknUfDdOvf+2dVRAGDZXZxHNTwLk/vPa/HUX2+y392UJI0kfQ1eD6n4gd2HI -TfK7ZU2o94VFB696aSdlkClAi997OlE5jKgfcHmtbUIgos8MbAOMTM1zB5TnWo46 -BLqioXwfy2M6FafUFRunUkcyqfS/ZEfRqh9TTjIwc8Jvt3iCnVz/RrtrIh2IC/gb -qjSm/Iz13X9ljIwxVzHQNuxHoc/Li6jvHBhYxQZ3ykubUa9MCEp6j+KjUuKOjswm -5LLY5TjCqO3GgZw1a6lYYUoKl7RLQrZVnb6Z53BtWfhtKgx/GWBfDJqIbDCsUgmQ -Fhv/K53b0CDKieoofjKOGd97SDMe12X4rsn4gxSTdn1k0I7OvjV9/3IxTZ+evR5s -L6iPDAZQ+4wns3bJ9ObXwzTijIchhmH+v1V04SF3AwpobLvkyanmz1kl63zsRQ55 -ZmjoIs2475iFTZYRPAmK0H+8KCgT+2rKVI2SXM3CZZgGns5IW9S1N5NGQXwH3c/6 -Q++6Z2H/fUnguzB9XIDj5hY5S6c= +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 +MIIF9TCCA92gAwIBAgIQHaJIMG+bJhjQguCWfTPTajANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx +MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjB8MQswCQYDVQQGEwJHQjEbMBkGA1UE +CBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQK +Ew9TZWN0aWdvIExpbWl0ZWQxJDAiBgNVBAMTG1NlY3RpZ28gUlNBIENvZGUgU2ln +bmluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIYijTKFehif +SfCWL2MIHi3cfJ8Uz+MmtiVmKUCGVEZ0MWLFEO2yhyemmcuVMMBW9aR1xqkOUGKl +UZEQauBLYq798PgYrKf/7i4zIPoMGYmobHutAMNhodxpZW0fbieW15dRhqb0J+V8 +aouVHltg1X7XFpKcAC9o95ftanK+ODtj3o+/bkxBXRIgCFnoOc2P0tbPBrRXBbZO +oT5Xax+YvMRi1hsLjcdmG0qfnYHEckC14l/vC0X/o84Xpi1VsLewvFRqnbyNVlPG +8Lp5UEks9wO5/i9lNfIi6iwHr0bZ+UYc3Ix8cSjz/qfGFN1VkW6KEQ3fBiSVfQ+n +oXw62oY1YdMCAwEAAaOCAWQwggFgMB8GA1UdIwQYMBaAFFN5v1qqK0rPVIDh2JvA +nfKyA2bLMB0GA1UdDgQWBBQO4TqoUzox1Yq+wbutZxoDha00DjAOBgNVHQ8BAf8E +BAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggrBgEFBQcDAwYI +KwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAAMFAGA1UdHwRJMEcwRaBDoEGGP2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6 +Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAl +BggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0B +AQwFAAOCAgEATWNQ7Uc0SmGk295qKoyb8QAAHh1iezrXMsL2s+Bjs/thAIiaG20Q +BwRPvrjqiXgi6w9G7PNGXkBGiRL0C3danCpBOvzW9Ovn9xWVM8Ohgyi33i/klPeF +M4MtSkBIv5rCT0qxjyT0s4E307dksKYjalloUkJf/wTr4XRleQj1qZPea3FAmZa6 +ePG5yOLDCBaxq2NayBWAbXReSnV+pbjDbLXP30p5h1zHQE1jNfYw08+1Cg4LBH+g +S667o6XQhACTPlNdNKUANWlsvp8gJRANGftQkGG+OY96jk32nw4e/gdREmaDJhlI +lc5KycF/8zoFm/lv34h/wCOe0h5DekUxwZxNqfBZslkZ6GqNKQQCd3xLS81wvjqy +VVp4Pry7bwMQJXcVNIr5NsxDkuS6T/FikyglVyn7URnHoSVAaoRXxrKdsbwcCtp8 +Z359LukoTBh+xHsxQXGaSynsCz1XUNLK3f2eBVHlRHjdAd6xdZgNVCT98E7j4viD +vXK6yz067vBeF5Jobchh+abxKgoLpbn0nu6YMgWFnuv5gynTxix9vTp3Los3QqBq +gu07SqqUEKThDfgXxbZaeTMYkuO1dfih6Y4KJR7kHvGfWocj/5+kUZ77OYARzdu1 +xKeogG/lU9Tg46LC0lsa+jImLWpXcBw8pFguo/NbSwfcMlnzh6cabVg= -----END CERTIFICATE----- diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 4c07f879..69bda563 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,17 +1,18 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2018 The Bitsend Core developers +# Copyright (c) 2014-2018 The BitSend Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """ ZMQ example using python3's asyncio - Bitsend should be started with the command line arguments: + BitSend should be started with the command line arguments: bitsendd -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 + -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 @@ -19,7 +20,7 @@ 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 + https://github.com/bitsend/bitsend/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py """ import binascii @@ -42,20 +43,19 @@ def __init__(self): self.zmqContext = zmq.asyncio.Context() self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt(zmq.RCVHWM, 0) self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock") self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx") self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock") self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "sequence") self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) async def handle(self) : - msg = await self.zmqSubSocket.recv_multipart() - topic = msg[0] - body = msg[1] + topic, body, seq = await self.zmqSubSocket.recv_multipart() sequence = "Unknown" - if len(msg[-1]) == 4: - msgSequence = struct.unpack('/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) -qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) -wallet_packages_$(NO_WALLET) = $(wallet_packages) +ifneq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +build_id_string+=system_clang +$(host_arch)_$(host_os)_id_string+=system_clang +endif + +qrencode_packages_$(NO_QR) = $(qrencode_packages) + +qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) $(qrencode_packages_) + +bdb_packages_$(NO_BDB) = $(bdb_packages) +sqlite_packages_$(NO_SQLITE) = $(sqlite_packages) +wallet_packages_$(NO_WALLET) = $(bdb_packages_) $(sqlite_packages_) + upnp_packages_$(NO_UPNP) = $(upnp_packages) +zmq_packages_$(NO_ZMQ) = $(zmq_packages) +multiprocess_packages_$(MULTIPROCESS) = $(multiprocess_packages) packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) -ifneq ($(qt_packages_),) -native_packages += $(qt_native_packages) +ifneq ($(zmq_packages_),) +packages += $(zmq_packages) +endif + +ifeq ($(multiprocess_packages_),) +packages += $(multiprocess_packages) +native_packages += $(multiprocess_native_packages) endif all_packages = $(packages) $(native_packages) meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk +$(host_arch)_$(host_os)_native_binutils?=$($(host_os)_native_binutils) $(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) @@ -124,10 +184,10 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ $(AT)sed -e 's|@HOST@|$(host)|' \ -e 's|@CC@|$(toolchain_path)$(host_CC)|' \ -e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \ - -e 's|@AR@|$(toolchain_path)$(host_AR)|' \ - -e 's|@RANLIB@|$(toolchain_path)$(host_RANLIB)|' \ - -e 's|@NM@|$(toolchain_path)$(host_NM)|' \ - -e 's|@STRIP@|$(toolchain_path)$(host_STRIP)|' \ + -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|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ @@ -136,8 +196,11 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \ -e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \ -e 's|@no_qt@|$(NO_QT)|' \ + -e 's|@no_qr@|$(NO_QR)|' \ + -e 's|@no_zmq@|$(NO_ZMQ)|' \ -e 's|@no_wallet@|$(NO_WALLET)|' \ -e 's|@no_upnp@|$(NO_UPNP)|' \ + -e 's|@multiprocess@|$(MULTIPROCESS)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ $(AT)touch $@ @@ -167,7 +230,7 @@ $(host_prefix)/share/config.site: check-packages check-packages: check-sources clean-all: clean - @rm -rf $(SOURCES_PATH) x86_64* i686* mips* arm* aarch64* riscv32* riscv64* + @rm -rf $(SOURCES_PATH) x86_64* i686* mips* arm* aarch64* powerpc* riscv32* riscv64* s390x* clean: @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) @@ -185,4 +248,6 @@ download-win: @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one 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 diff --git a/depends/README.md b/depends/README.md old mode 100755 new mode 100644 index 9eccc2b9..fb4f0e49 --- a/depends/README.md +++ b/depends/README.md @@ -12,70 +12,140 @@ For example: make HOST=x86_64-w64-mingw32 -j4 -A prefix will be generated that's suitable for plugging into Bitsend's -configure. In the above example, a dir named x86_64-w64-mingw32 will be -created. To use it for Bitsend: +**BitSend 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 BitSend: - ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32 + ./configure --prefix=$PWD/depends/x86_64-w64-mingw32 Common `host-platform-triplets` for cross compilation are: -- `i686-w64-mingw32` for Win32 +- `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-darwin14` for macOS +- `x86_64-apple-darwin16` 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) +- `powerpc64le-linux-gnu` for Linux POWER 64-bit (little endian) - `riscv32-linux-gnu` for Linux RISC-V 32 bit - `riscv64-linux-gnu` for Linux RISC-V 64 bit +- `s390x-linux-gnu` for Linux S390X +- `armv7a-linux-android` for Android ARM 32 bit +- `aarch64-linux-android` for Android ARM 64 bit +- `i686-linux-android` for Android x86 32 bit +- `x86_64-linux-android` for Android x86 64 bit -No other options are needed, the paths are automatically configured. +The paths are automatically configured and no other options are needed unless targeting [Android](#Android). -Install the required dependencies: Ubuntu & Debian --------------------------------------------------- +### Install the required dependencies: Ubuntu & Debian -For macOS cross compilation: +#### For macOS cross compilation - sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python-setuptools + sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools libtinfo5 -For Win32/Win64 cross compilation: +#### For Win64 cross compilation - see [build-windows.md](../doc/build-windows.md#cross-compilation-for-ubuntu-and-windows-subsystem-for-linux) -For linux (including i386, ARM) cross compilation: +#### For linux (including i386, ARM) cross compilation - sudo apt-get install 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 bsdmainutils +Common linux dependencies: + + sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch + +For linux ARM cross compilation: + + sudo apt-get install g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf + +For linux AARCH64 cross compilation: + + sudo apt-get install g++-aarch64-linux-gnu binutils-aarch64-linux-gnu + +For linux POWER 64-bit cross compilation (there are no packages for 32-bit): + + sudo apt-get install g++-powerpc64-linux-gnu binutils-powerpc64-linux-gnu g++-powerpc64le-linux-gnu binutils-powerpc64le-linux-gnu For linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): - sudo apt-get install curl g++-riscv64-linux-gnu binutils-riscv64-linux-gnu + sudo apt-get install g++-riscv64-linux-gnu binutils-riscv64-linux-gnu -RISC-V known issue: gcc-7.3.0 and gcc-7.3.1 result in a broken `test_bitsend` executable (see https://github.com/bitcoin/bitcoin/pull/13543), +RISC-V known issue: gcc-7.3.0 and gcc-7.3.1 result in a broken `test_bitsend` executable (see https://github.com/bitsend/bitsend/pull/13543), this is apparently fixed in gcc-8.1.0. -Dependency Options: -The following can be set when running make: make FOO=bar - - SOURCES_PATH: downloaded sources will be placed here - BASE_CACHE: built packages will be placed here - SDK_PATH: Path where sdk's can be found (used by macOS) - FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up - NO_QT: Don't download/build/cache qt and its dependencies - NO_WALLET: Don't download/build/cache libs needed to enable the wallet - NO_UPNP: Don't download/build/cache packages needed for enabling upnp - DEBUG: disable some optimizations and enable more runtime checking - HOST_ID_SALT: Optional salt to use when generating host package ids - BUILD_ID_SALT: Optional salt to use when generating build package ids +For linux S390X cross compilation: + + sudo apt-get install g++-s390x-linux-gnu binutils-s390x-linux-gnu + +### Dependency Options +The following can be set when running make: `make FOO=bar` + +
+
SOURCES_PATH
+
downloaded sources will be placed here
+
BASE_CACHE
+
built packages will be placed here
+
SDK_PATH
+
Path where sdk's can be found (used by macOS)
+
FALLBACK_DOWNLOAD_PATH
+
If a source file can't be fetched, try here before giving up
+
NO_QT
+
Don't download/build/cache qt and its dependencies
+
NO_QR
+
Don't download/build/cache packages needed for enabling qrencode
+
NO_ZMQ
+
Don't download/build/cache packages needed for enabling zeromq
+
NO_WALLET
+
Don't download/build/cache libs needed to enable the wallet
+
NO_BDB
+
Don't download/build/cache BerkeleyDB
+
NO_SQLITE
+
Don't download/build/cache SQLite
+
NO_UPNP
+
Don't download/build/cache packages needed for enabling upnp
+
ALLOW_HOST_PACKAGES
+
Packages that are missed in dependencies (due to `NO_*` option or +build script logic) are searched for among the host system packages using +`pkg-config`. It allows building with packages of other (newer) versions
+
MULTIPROCESS
+
build libmultiprocess (experimental, requires cmake)
+
DEBUG
+
disable some optimizations and enable more runtime checking
+
HOST_ID_SALT
+
Optional salt to use when generating host package ids
+
BUILD_ID_SALT
+
Optional salt to use when generating build package ids
+
FORCE_USE_SYSTEM_CLANG
+
(EXPERTS ONLY) When cross-compiling for macOS, use Clang found in the +system's $PATH rather than the default prebuilt release of Clang +from llvm.org. Clang 8 or later is required.
+
If some packages are not built, for example `make NO_WALLET=1`, the appropriate options will be passed to bitsend's configure. In this case, `--disable-wallet`. -Additional targets: +### Additional targets download: run 'make download' to fetch all sources without building them download-osx: run 'make download-osx' to fetch all sources needed for macOS builds download-win: run 'make download-win' to fetch all sources needed for win builds download-linux: run 'make download-linux' to fetch all sources needed for linux builds + +### Android + +Before proceeding with an Android build one needs to get the [Android SDK](https://developer.android.com/studio) and use the "SDK Manager" tool to download the NDK and one or more "Platform packages" (these are Android versions and have a corresponding API level). +In order to build `ANDROID_API_LEVEL` (API level corresponding to the Android version targeted, e.g. Android 9.0 Pie is 28 and its "Platform package" needs to be available) and `ANDROID_TOOLCHAIN_BIN` (path to toolchain binaries depending on the platform the build is being performed on) need to be set. + +API levels from 24 to 29 have been tested to work. + +If the build includes Qt, environment variables `ANDROID_SDK` and `ANDROID_NDK` need to be set as well but can otherwise be omitted. +This is an example command for a default build with no disabled dependencies: + + ANDROID_SDK=/home/user/Android/Sdk ANDROID_NDK=/home/user/Android/Sdk/ndk-bundle make HOST=aarch64-linux-android ANDROID_API_LEVEL=28 ANDROID_TOOLCHAIN_BIN=/home/user/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin + ### Other documentation - [description.md](description.md): General description of the depends system diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk old mode 100755 new mode 100644 index 27f550ab..f4103fc1 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -1,17 +1,17 @@ -build_darwin_CC: = $(shell xcrun -f clang) -build_darwin_CXX: = $(shell xcrun -f clang++) -build_darwin_AR: = $(shell xcrun -f ar) -build_darwin_RANLIB: = $(shell xcrun -f ranlib) -build_darwin_STRIP: = $(shell xcrun -f strip) -build_darwin_OTOOL: = $(shell xcrun -f otool) -build_darwin_NM: = $(shell xcrun -f nm) +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_AR:=$(shell xcrun -f ar) +build_darwin_RANLIB:=$(shell xcrun -f ranlib) +build_darwin_STRIP:=$(shell xcrun -f strip) +build_darwin_OTOOL:=$(shell xcrun -f otool) +build_darwin_NM:=$(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) -build_darwin_SHA256SUM = shasum -a 256 -build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o +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) -darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -stdlib=libc++ +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_AR:=$(shell xcrun -f ar) darwin_RANLIB:=$(shell xcrun -f ranlib) darwin_STRIP:=$(shell xcrun -f strip) @@ -19,4 +19,5 @@ darwin_LIBTOOL:=$(shell xcrun -f libtool) darwin_OTOOL:=$(shell xcrun -f otool) darwin_NM:=$(shell xcrun -f nm) darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) +darwin_native_binutils= darwin_native_toolchain= diff --git a/depends/builders/default.mk b/depends/builders/default.mk old mode 100755 new mode 100644 diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk old mode 100755 new mode 100644 diff --git a/depends/config.guess b/depends/config.guess index 2b79f6d8..7f9ebbe3 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2018-07-06' +timestamp='2019-09-10' # 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 @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2019 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." @@ -84,8 +84,6 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -96,34 +94,38 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/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 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in - ,,) echo "int x;" > "$dummy.c" ; - for c in cc gcc c89 c99 ; do - if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { 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 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi @@ -138,7 +140,7 @@ Linux|GNU|GNU/*) # We could probably try harder. LIBC=gnu - eval "$set_cc_for_build" + set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) @@ -199,7 +201,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval "$set_cc_for_build" + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -260,6 +262,9 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" + exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; @@ -269,12 +274,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -389,7 +397,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval "$set_cc_for_build" + set_cc_for_build SUN_ARCH=i386 # 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. @@ -482,7 +490,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ @@ -579,7 +587,7 @@ EOF exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include @@ -660,7 +668,7 @@ EOF esac fi if [ "$HP_ARCH" = "" ]; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE @@ -700,7 +708,7 @@ EOF esac if [ "$HP_ARCH" = hppa2.0w ] then - eval "$set_cc_for_build" + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -726,7 +734,7 @@ EOF echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int @@ -840,6 +848,17 @@ EOF *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; + arm:FreeBSD:*:*) + 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 + else + 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 @@ -881,7 +900,7 @@ EOF echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" @@ -922,7 +941,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then @@ -971,23 +990,51 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" - test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + 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:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1100,7 +1147,7 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then @@ -1284,38 +1331,39 @@ EOF echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval "$set_cc_for_build" - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then - if [ "$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 - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi + if [ "$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 + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; @@ -1358,6 +1406,7 @@ 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 UNAME_MACHINE=i386 else @@ -1414,8 +1463,148 @@ EOF amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; esac +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + 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 + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$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. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in diff --git a/depends/config.site.in b/depends/config.site.in old mode 100755 new mode 100644 index 8444dc26..87a33793 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -16,15 +16,22 @@ fi if test -z $with_qt_bindir && test -z "@no_qt@"; then with_qt_bindir=$depends_prefix/native/bin fi -if test -z $with_protoc_bindir && test -z "@no_qt@"; then - with_protoc_bindir=$depends_prefix/native/bin +if test -z $with_mpgen && test -n "@multiprocess@"; then + with_mpgen=$depends_prefix/native fi +if test -z $with_qrencode && test -n "@no_qr@"; then + with_qrencode=no +fi if test -z $enable_wallet && test -n "@no_wallet@"; then enable_wallet=no fi +if test -z $enable_multiprocess && test -n "@multiprocess@"; then + enable_multiprocess=yes +fi + if test -z $with_miniupnpc && test -n "@no_upnp@"; then with_miniupnpc=no fi @@ -33,20 +40,15 @@ if test -z $with_gui && test -n "@no_qt@"; then with_gui=no fi +if test -z $enable_zmq && test -n "@no_zmq@"; then + enable_zmq=no +fi + if test x@host_os@ = xdarwin; 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 PKG_CONFIG="`which pkg-config` --static" @@ -55,16 +57,19 @@ PKG_CONFIG="`which pkg-config` --static" # avoid ruining the cache. Sigh. export PKG_CONFIG_PATH=$depends_prefix/share/pkgconfig:$depends_prefix/lib/pkgconfig if test -z "@allow_host_packages@"; then - export PKGCONFIG_LIBDIR= + export PKG_CONFIG_LIBDIR=$depends_prefix/lib/pkgconfig fi CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS" LDFLAGS="-L$depends_prefix/lib $LDFLAGS" -CC="@CC@" -CXX="@CXX@" -OBJC="${CC}" -PYTHONPATH=$depends_prefix/native/lib/python/dist-packages:$PYTHONPATH +if test -n "@CC@" -a -z "${CC}"; then + CC="@CC@" +fi +if test -n "@CXX@" -a -z "${CXX}"; then + CXX="@CXX@" +fi +PYTHONPATH=$depends_prefix/native/lib/python3/dist-packages:$PYTHONPATH if test -n "@AR@"; then AR=@AR@ diff --git a/depends/config.sub b/depends/config.sub index c95acc68..a318a468 100755 --- a/depends/config.sub +++ b/depends/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2018-07-03' +timestamp='2019-06-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 @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2019 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." @@ -89,7 +89,7 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) @@ -111,7 +111,8 @@ case $# in esac # Split fields of configuration type -IFS="-" read -r field1 field2 field3 field4 <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1356,9 +1345,9 @@ case $os in | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* \ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ - | clix* | riscos* | uniplus* | iris* | rtu* | xenix* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ | knetbsd* | mirbsd* | netbsd* \ - | bitrig* | openbsd* | solidbsd* | libertybsd* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ @@ -1376,12 +1365,13 @@ case $os in | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ | skyos* | haiku* | rdos* | toppers* | drops* | es* \ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd*) + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix) # Remember, each alternative MUST END IN *, to match a version number. ;; qnx*) - case $basic_machine in - x86-* | i*86-*) + case $cpu in + x86 | i*86) ;; *) os=nto-$os @@ -1460,9 +1450,6 @@ case $os in ns2) os=nextstep2 ;; - nsk*) - os=nsk - ;; # Preserve the version number of sinix5. sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` @@ -1507,7 +1494,7 @@ case $os in # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. - case $basic_machine in + case $cpu in arm*) os=eabi ;; @@ -1541,7 +1528,7 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +case $cpu-$vendor in score-*) os=elf ;; @@ -1722,9 +1709,8 @@ fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) +case $vendor in + unknown) case $os in riscix*) vendor=acorn @@ -1793,11 +1779,10 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo "$basic_machine-$os" +echo "$cpu-$vendor-$os" exit # Local variables: diff --git a/depends/description.md b/depends/description.md old mode 100755 new mode 100644 index 5e80fee0..a0481e36 --- a/depends/description.md +++ b/depends/description.md @@ -1,4 +1,4 @@ -This is a system of building and caching dependencies necessary for building Bitsend. +This is a system of building and caching dependencies necessary for building BitSend. There are several features that make it different from most similar systems: ### It is designed to be builder and host agnostic @@ -26,7 +26,7 @@ Before building, a unique build-id is generated for each package. This id consists of a hash of all files used to build the package (Makefiles, packages, etc), and as well as a hash of the same data for each recursive dependency. If any portion of a package's build recipe changes, it will be rebuilt as well as -any other package that depends on it. If any of the main makefiles (Makefile, +any other package that depends on it. If any of the main makefiles (Makefile, funcs.mk, etc) are changed, all packages will be rebuilt. After building, the results are cached into a tarball that can be re-used and distributed. diff --git a/depends/funcs.mk b/depends/funcs.mk old mode 100755 new mode 100644 index 15e404e4..58d882eb --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -41,7 +41,7 @@ endef 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)_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:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) @@ -76,8 +76,9 @@ $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) #default commands +# The default behavior for tar will try to set ownership when running as uid 0 and may not succeed, --no-same-owner disables this behavior $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash)) -$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --strip-components=1 -xf $$($(1)_source) +$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --no-same-owner --strip-components=1 -xf $$($(1)_source) $(1)_preprocess_cmds ?= $(1)_build_cmds ?= $(1)_config_cmds ?= @@ -129,11 +130,11 @@ $(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$( $(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig $(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig +$(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) --disable-dependency-tracking --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" - +$(1)_autoconf=./configure --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 @@ -155,6 +156,20 @@ endif ifneq ($($(1)_ldflags),) $(1)_autoconf += LDFLAGS="$$($(1)_ldflags)" endif + +$(1)_cmake=env CC="$$($(1)_cc)" \ + CFLAGS="$$($(1)_cppflags) $$($(1)_cflags)" \ + CXX="$$($(1)_cxx)" \ + CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \ + LDFLAGS="$$($(1)_ldflags)" \ + cmake -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" +ifneq ($($(1)_type),build) +ifneq ($(host),$(build)) +$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system) +$(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host) +$(1)_cmake += -DCMAKE_CXX_COMPILER_TARGET=$(host) +endif +endif endef define int_add_cmds @@ -170,15 +185,15 @@ $($(1)_extracted): | $($(1)_fetched) $(AT)mkdir -p $$(@D) $(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1)) $(AT)touch $$@ -$($(1)_preprocessed): | $($(1)_dependencies) $($(1)_extracted) +$($(1)_preprocessed): | $($(1)_extracted) $(AT)echo Preprocessing $(1)... $(AT)mkdir -p $$(@D) $($(1)_patch_dir) $(AT)$(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) $(AT)cd $$(@D); $(call $(1)_preprocess_cmds, $(1)) $(AT)touch $$@ -$($(1)_configured): | $($(1)_preprocessed) +$($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed) $(AT)echo Configuring $(1)... - $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar xf $($(package)_cached); ) + $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar --no-same-owner -xf $($(package)_cached); ) $(AT)mkdir -p $$(@D) $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) $(AT)touch $$@ @@ -213,6 +228,14 @@ $(1): | $($(1)_cached_checksum) endef +stages = fetched extracted preprocessed configured built staged postprocessed cached cached_checksum + +define ext_add_stages +$(foreach stage,$(stages), + $(1)_$(stage): $($(1)_$(stage)) + .PHONY: $(1)_$(stage)) +endef + # These functions create the build targets for each package. They must be # broken down into small steps so that each part is done for all packages # before moving on to the next step. Otherwise, a package's info @@ -242,4 +265,4 @@ $(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$ $(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package)))) #special exception: if a toolchain package exists, all non-native packages depend on it -$(foreach package,$(packages),$(eval $($(package)_unpacked): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) )) +$(foreach package,$(packages),$(eval $($(package)_extracted): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) $($($(host_arch)_$(host_os)_native_binutils)_cached) )) diff --git a/depends/hosts/android.mk b/depends/hosts/android.mk new file mode 100644 index 00000000..eabd84bb --- /dev/null +++ b/depends/hosts/android.mk @@ -0,0 +1,12 @@ +ifeq ($(HOST),armv7a-linux-android) +android_AR=$(ANDROID_TOOLCHAIN_BIN)/arm-linux-androideabi-ar +android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)eabi$(ANDROID_API_LEVEL)-clang++ +android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)eabi$(ANDROID_API_LEVEL)-clang +android_RANLIB=$(ANDROID_TOOLCHAIN_BIN)/arm-linux-androideabi-ranlib +else +android_AR=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ar +android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang++ +android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang +android_RANLIB=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ranlib +endif +android_cmake_system=Android diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk old mode 100755 new mode 100644 index a1c943d6..a44ee542 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,9 +1,35 @@ -OSX_MIN_VERSION=10.10 -OSX_SDK_VERSION=10.11 -OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -LD64_VERSION=253.9 -darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ +OSX_MIN_VERSION=10.12 +OSX_SDK_VERSION=10.15.1 +XCODE_VERSION=11.3.1 +XCODE_BUILD_ID=11C505 +LD64_VERSION=530 + +OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers + +# Flag explanations: +# +# -mlinker-version +# +# Ensures that modern linker features are enabled. See here for more +# details: https://github.com/bitsend/bitsend/pull/19407. +# +# -B$(build_prefix)/bin +# +# 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 +# +# 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. +# +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_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) @@ -14,4 +40,11 @@ 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 diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk old mode 100755 new mode 100644 index 144e5f88..258619a9 --- a/depends/hosts/default.mk +++ b/depends/hosts/default.mk @@ -13,9 +13,18 @@ default_host_OTOOL = $(host_toolchain)otool default_host_NM = $(host_toolchain)nm define add_host_tool_func +ifneq ($(filter $(origin $1),undefined default),) +# Do not consider the well-known var $1 if it is undefined or is taking a value +# that is predefined by "make" (e.g. the make variable "CC" has a predefined +# value of "cc") $(host_os)_$1?=$$(default_host_$1) $(host_arch)_$(host_os)_$1?=$$($(host_os)_$1) $(host_arch)_$(host_os)_$(release_type)_$1?=$$($(host_os)_$1) +else +$(host_os)_$1=$(or $($1),$($(host_os)_$1),$(default_host_$1)) +$(host_arch)_$(host_os)_$1=$(or $($1),$($(host_arch)_$(host_os)_$1),$$($(host_os)_$1)) +$(host_arch)_$(host_os)_$(release_type)_$1=$(or $($1),$($(host_arch)_$(host_os)_$(release_type)_$1),$$($(host_os)_$1)) +endif host_$1=$$($(host_arch)_$(host_os)_$1) endef diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk old mode 100755 new mode 100644 index b13a0f1a..8ab448ce --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -29,3 +29,4 @@ i686_linux_CXX=$(default_host_CXX) -m32 x86_64_linux_CC=$(default_host_CC) -m64 x86_64_linux_CXX=$(default_host_CXX) -m64 endif +linux_cmake_system=Linux diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk old mode 100755 new mode 100644 index dbfb62fd..be5fec57 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -8,3 +8,5 @@ mingw32_debug_CFLAGS=-O1 mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS) mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC + +mingw_cmake_system=Windows diff --git a/depends/packages.md b/depends/packages.md old mode 100755 new mode 100644 index 7c803625..38eaa8ff --- a/depends/packages.md +++ b/depends/packages.md @@ -5,6 +5,10 @@ The package "mylib" will be used here as an example General tips: - mylib_foo is written as $(package)_foo in order to make recipes more similar. +- Secondary dependency packages relative to the bitsend binaries/libraries (i.e. + those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't + need to be shared and should be built statically whenever possible. See + [below](#secondary-dependencies) for more details. ## Identifiers Each package is required to define at least these variables: @@ -14,8 +18,9 @@ Each package is required to define at least these variables: placeholder such as 1.0 can be used. $(package)_download_path: - Location of the upstream source, without the file-name. Usually http or - ftp. + Location of the upstream source, without the file-name. Usually http, https + or ftp. Secure transmission options like https should be preferred if + available. $(package)_file_name: The upstream source filename available at the download path. @@ -27,15 +32,15 @@ These variables are optional: $(package)_build_subdir: cd to this dir before running configure/build/stage commands. - + $(package)_download_file: The file-name of the upstream source if it differs from how it should be stored locally. This can be used to avoid storing file-names with strange characters. - + $(package)_dependencies: Names of any other packages that this one depends on. - + $(package)_patches: Filenames of any patches needed to build the package @@ -129,7 +134,7 @@ the user. Other variables may be defined as needed. Stage the build results. If undefined, does nothing. The following variables are available for each recipe: - + $(1)_staging_dir: package's destination sysroot path $(1)_staging_prefix_dir: prefix path inside of the package's staging dir $(1)_extract_dir: path to the package's extracted sources @@ -145,3 +150,49 @@ $($(package)_config_opts) will be appended. Most autotools projects can be properly staged using: $(MAKE) DESTDIR=$($(package)_staging_dir) install + +## Build outputs: + +In general, the output of a depends package should not contain any libtool +archives. Instead, the package should output `.pc` (`pkg-config`) files where +possible. + +From the [Gentoo Wiki entry](https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Handling_Libtool_Archives): + +> Libtool pulls in all direct and indirect dependencies into the .la files it +> creates. This leads to massive overlinking, which is toxic to the Gentoo +> ecosystem, as it leads to a massive number of unnecessary rebuilds. + +## Secondary dependencies: + +Secondary dependency packages relative to the bitsend binaries/libraries (i.e. +those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't +need to be shared and should be built statically whenever possible. This +improves general build reliability as illustrated by the following example: + +When linking an executable against a shared library `libprimary` that has its +own shared dependency `libsecondary`, we may need to specify the path to +`libsecondary` on the link command using the `-rpath/-rpath-link` options, it is +not sufficient to just say `libprimary`. + +For us, it's much easier to just link a static `libsecondary` into a shared +`libprimary`. Especially because in our case, we are linking against a dummy +`libprimary` anyway that we'll throw away. We don't care if the end-user has a +static or dynamic `libseconday`, that's not our concern. With a static +`libseconday`, when we need to link `libprimary` into our executable, there's no +dependency chain to worry about as `libprimary` has all the symbols. + +## Build targets: + +To build an individual package (useful for debugging), following build targets are available. + + make ${package} + make ${package}_fetched + make ${package}_extracted + make ${package}_preprocessed + make ${package}_configured + make ${package}_built + make ${package}_staged + make ${package}_postprocessed + make ${package}_cached + make ${package}_cached_checksum diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk old mode 100755 new mode 100644 index 6c9876c2..5953341d --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -1,20 +1,22 @@ package=bdb $(package)_version=4.8.30 -$(package)_download_path=http://download.oracle.com/berkeley-db +$(package)_download_path=https://download.oracle.com/berkeley-db $(package)_file_name=db-$($(package)_version).NC.tar.gz $(package)_sha256_hash=12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef $(package)_build_subdir=build_unix +$(package)_patches=clang_cxx_11.patch define $(package)_set_vars -$(package)_config_opts=--disable-shared --enable-cxx --disable-replication +$(package)_config_opts=--disable-shared --enable-cxx --disable-replication --enable-option-checking $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic +$(package)_cflags+=-Wno-error=implicit-function-declaration $(package)_cxxflags=-std=c++11 +$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef define $(package)_preprocess_cmds - sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h && \ - sed -i.old 's/atomic_init/atomic_init_db/' dbinc/atomic.h mp/mp_region.c mp/mp_mvcc.c mp/mp_fget.c mutex/mut_method.c mutex/mut_tas.c && \ + patch -p1 < $($(package)_patch_dir)/clang_cxx_11.patch && \ cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub dist endef diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk old mode 100755 new mode 100644 index 61806c75..d8bce108 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,41 +1,50 @@ package=boost -$(package)_version=1_64_0 -$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/ -$(package)_file_name=$(package)_$($(package)_version).tar.bz2 -$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332 +$(package)_version=1_70_0 +$(package)_download_path=https://dl.bintray.com/boostorg/release/1.70.0/source/ +$(package)_file_name=boost_$($(package)_version).tar.bz2 +$(package)_sha256_hash=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 +$(package)_patches=unused_var_in_process.patch 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_linux=threadapi=pthread runtime-link=shared -$(package)_config_opts_darwin=--toolset=darwin-4.2.1 runtime-link=shared -$(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static +$(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)_config_opts_i686_android=address-model=32 +$(package)_config_opts_aarch64_android=address-model=64 +$(package)_config_opts_x86_64_android=address-model=64 +$(package)_config_opts_armv7a_android=address-model=32 $(package)_toolset_$(host_os)=gcc +$(package)_toolset_darwin=clang +ifneq (,$(findstring clang,$($(package)_cxx))) + $(package)_toolset_$(host_os)=clang +endif $(package)_archiver_$(host_os)=$($(package)_ar) -$(package)_toolset_darwin=darwin -$(package)_archiver_darwin=$($(package)_libtool) -$(package)_config_libraries=chrono,filesystem,system,thread,test +$(package)_config_libraries=filesystem,system,thread,test $(package)_cxxflags=-std=c++11 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC +$(package)_cxxflags_android=-fPIC endef define $(package)_preprocess_cmds - echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cxxflags) $($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$(boost_archiver_$(host_os))\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam + 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 endef define $(package)_config_cmds - ./bootstrap.sh --without-icu --with-libraries=$(boost_config_libraries) + ./bootstrap.sh --without-icu --with-libraries=$($(package)_config_libraries) --with-toolset=$($(package)_toolset_$(host_os)) endef define $(package)_build_cmds - ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) 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) 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 00000000..abeb2654 --- /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 deleted file mode 100755 index bbe03754..00000000 --- a/depends/packages/dbus.mk +++ /dev/null @@ -1,23 +0,0 @@ -package=dbus -$(package)_version=1.10.18 -$(package)_download_path=https://dbus.freedesktop.org/releases/dbus -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=6049ddd5f3f3e2618f615f1faeda0a115104423a7996b7aa73e2f36e38cc514a -$(package)_dependencies=expat - -define $(package)_set_vars - $(package)_config_opts=--disable-tests --disable-doxygen-docs --disable-xml-docs --disable-static --without-x -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C dbus libdbus-1.la -endef - -define $(package)_stage_cmds - $(MAKE) -C dbus DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-dbusincludeHEADERS install-nodist_dbusarchincludeHEADERS && \ - $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA -endef diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk old mode 100755 new mode 100644 index acbc60ee..902fe43b --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,11 +1,13 @@ package=expat -$(package)_version=2.2.5 -$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_5/ +$(package)_version=2.2.7 +$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_7/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=d9dc32efba7e74f788fcc4f212a43216fc37cf5f23f4c2339664d473353aedf6 +$(package)_sha256_hash=cbc9102f4a31a8dafd42d642e9a3aa31e79a0aedaa1f6efd2795ebc83174ec18 define $(package)_set_vars -$(package)_config_opts=--disable-static + $(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 define $(package)_config_cmds @@ -19,3 +21,7 @@ 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/fontconfig.mk b/depends/packages/fontconfig.mk old mode 100755 new mode 100644 index 12695db4..0d5f94f3 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -1,28 +1,33 @@ package=fontconfig $(package)_version=2.12.1 -$(package)_download_path=http://www.freedesktop.org/software/fontconfig/release/ +$(package)_download_path=https://www.freedesktop.org/software/fontconfig/release/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=b449a3e10c47e1d1c7a6ec6e2016cca73d3bd68fbbd4f0ae5cc6b573f7d6c7f3 $(package)_dependencies=freetype expat +$(package)_patches=remove_char_width_usage.patch gperf_header_regen.patch define $(package)_set_vars - $(package)_config_opts=--disable-docs --disable-static + $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking +endef + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/remove_char_width_usage.patch && \ + patch -p1 < $($(package)_patch_dir)/gperf_header_regen.patch endef define $(package)_config_cmds $($(package)_autoconf) endef -# 2.12.1 uses CHAR_WIDTH which is reserved and clashes with some glibc versions, but newer versions of fontconfig -# have broken makefiles which needlessly attempt to re-generate headers with gperf. -# Instead, change all uses of CHAR_WIDTH, and disable the rule that forces header re-generation. -# This can be removed once the upstream build is fixed. define $(package)_build_cmds - sed -i 's/CHAR_WIDTH/CHARWIDTH/g' fontconfig/fontconfig.h src/fcobjshash.gperf src/fcobjs.h src/fcobjshash.h && \ - sed -i 's/fcobjshash.h: fcobjshash.gperf/fcobjshash.h:/' src/Makefile && \ $(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/freetype.mk b/depends/packages/freetype.mk old mode 100755 new mode 100644 index 76b025c4..a1584608 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -1,11 +1,12 @@ package=freetype $(package)_version=2.7.1 -$(package)_download_path=http://download.savannah.gnu.org/releases/$(package) +$(package)_download_path=https://download.savannah.gnu.org/releases/$(package) $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=3a3bb2c4e15ffb433f2032f50a5b5a92558206822e22bfe8cbe339af4aa82f88 define $(package)_set_vars - $(package)_config_opts=--without-zlib --without-png --disable-static + $(package)_config_opts=--without-zlib --without-png --without-harfbuzz --without-bzip2 --disable-static + $(package)_config_opts += --enable-option-checking $(package)_config_opts_linux=--with-pic endef @@ -20,3 +21,7 @@ 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/libICE.mk b/depends/packages/libICE.mk deleted file mode 100755 index fc60323b..00000000 --- a/depends/packages/libICE.mk +++ /dev/null @@ -1,23 +0,0 @@ -package=libICE -$(package)_version=1.0.9 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=8f7032f2c1c64352b5423f6b48a8ebdc339cc63064af34d66a6c9aa79759e202 -$(package)_dependencies=xtrans xproto - -define $(package)_set_vars - $(package)_config_opts=--disable-static --disable-docs --disable-specs --without-xsltproc - $(package)_config_opts_linux=--with-pic -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 diff --git a/depends/packages/libSM.mk b/depends/packages/libSM.mk deleted file mode 100755 index 0f9307ca..00000000 --- a/depends/packages/libSM.mk +++ /dev/null @@ -1,23 +0,0 @@ -package=libSM -$(package)_version=1.2.2 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=0baca8c9f5d934450a70896c4ad38d06475521255ca63b717a6510fdb6e287bd -$(package)_dependencies=xtrans xproto libICE - -define $(package)_set_vars - $(package)_config_opts=--without-libuuid --without-xsltproc --disable-docs --disable-static - $(package)_config_opts_linux=--with-pic -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 diff --git a/depends/packages/libX11.mk b/depends/packages/libX11.mk deleted file mode 100755 index 178d592e..00000000 --- a/depends/packages/libX11.mk +++ /dev/null @@ -1,23 +0,0 @@ -package=libX11 -$(package)_version=1.6.2 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=2aa027e837231d2eeea90f3a4afe19948a6eb4c8b2bec0241eba7dbc8106bd16 -$(package)_dependencies=libxcb xtrans xextproto xproto - -define $(package)_set_vars -$(package)_config_opts=--disable-xkb --disable-static -$(package)_config_opts_linux=--with-pic -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 diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk old mode 100755 new mode 100644 index e87df2e4..4c55c2df --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -1,15 +1,22 @@ package=libXau $(package)_version=1.0.8 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ +$(package)_download_path=https://xorg.freedesktop.org/releases/individual/lib/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=fdd477320aeb5cdd67272838722d6b7d544887dfe7de46e1e7cc0c27c2bea4f2 $(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 +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + define $(package)_config_cmds $($(package)_autoconf) endef @@ -21,3 +28,7 @@ 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/libXext.mk b/depends/packages/libXext.mk deleted file mode 100755 index 4db83606..00000000 --- a/depends/packages/libXext.mk +++ /dev/null @@ -1,22 +0,0 @@ -package=libXext -$(package)_version=1.3.2 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=f829075bc646cdc085fa25d98d5885d83b1759ceb355933127c257e8e50432e0 -$(package)_dependencies=xproto xextproto libX11 libXau - -define $(package)_set_vars - $(package)_config_opts=--disable-static -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 diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk old mode 100755 new mode 100644 index 5f622f8e..1cd5a174 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -1,17 +1,25 @@ package=libevent -$(package)_version=2.1.8-stable +$(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=316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d +$(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 +# 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 +# is also required to enable support for ipv6. See #19375. define $(package)_set_vars $(package)_config_opts=--disable-shared --disable-openssl --disable-libevent-regress --disable-samples + $(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)_config_cmds @@ -27,4 +35,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds + rm lib/*.la endef diff --git a/depends/packages/libmultiprocess.mk b/depends/packages/libmultiprocess.mk new file mode 100644 index 00000000..3e5cf5f1 --- /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 old mode 100755 new mode 100644 index 28f2bd6f..2204b381 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -1,15 +1,29 @@ package=libxcb $(package)_version=1.10 -$(package)_download_path=http://xcb.freedesktop.org/dist +$(package)_download_path=https://xcb.freedesktop.org/dist $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c3f2d5b5 -$(package)_dependencies=xcb_proto libXau xproto +$(package)_dependencies=xcb_proto libXau define $(package)_set_vars -$(package)_config_opts=--disable-static +$(package)_config_opts=--disable-static --disable-build-docs --without-doxygen --without-launchd +$(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 +$(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-xevie --disable-xfixes --disable-xfree86-dri +$(package)_config_opts += --disable-xinerama --disable-xinput --disable-xkb +$(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 &&\ sed "s/pthread-stubs//" -i configure endef @@ -31,5 +45,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share/man share/doc + rm -rf share/man share/doc lib/*.la endef diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk old mode 100755 new mode 100644 index 5ad2b580..49a584e4 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,9 @@ package=miniupnpc $(package)_version=2.0.20180203 -$(package)_download_path=http://miniupnp.free.fr/files +$(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 define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" @@ -14,7 +15,7 @@ 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 && \ - sed -i.old "s|miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings|miniupnpcstrings.h: miniupnpcstrings.h.in|" Makefile.mingw + patch -p1 < $($(package)_patch_dir)/dont_use_wingen.patch endef define $(package)_build_cmds diff --git a/depends/packages/native_biplist.mk b/depends/packages/native_biplist.mk old mode 100755 new mode 100644 index 5f247e9b..c3054cbd --- a/depends/packages/native_biplist.mk +++ b/depends/packages/native_biplist.mk @@ -3,13 +3,13 @@ $(package)_version=1.0.3 $(package)_download_path=https://bitbucket.org/wooster/biplist/downloads $(package)_file_name=biplist-$($(package)_version).tar.gz $(package)_sha256_hash=4c0549764c5fe50b28042ec21aa2e14fe1a2224e239a1dae77d9e7f3932aa4c6 -$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages define $(package)_build_cmds - python setup.py build + python3 setup.py build endef define $(package)_stage_cmds mkdir -p $($(package)_install_libdir) && \ - python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) + python3 setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) endef diff --git a/depends/packages/native_capnp.mk b/depends/packages/native_capnp.mk new file mode 100644 index 00000000..ed5a6dee --- /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_cctools.mk b/depends/packages/native_cctools.mk old mode 100755 new mode 100644 index 44d238cc..d56b6366 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,45 +1,86 @@ package=native_cctools -$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6 -$(package)_download_path=https://github.com/theuni/cctools-port/archive +$(package)_version=55562e4073dea0fbfd0b20e0bf69ffe6390c7f97 +$(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a +$(package)_sha256_hash=e51995a843533a3dac155dd0c71362dd471597a2d23f13dff194c6285362f875 $(package)_build_subdir=cctools -$(package)_clang_version=3.7.1 -$(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version) +$(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-14.04.tar.xz $(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz -$(package)_clang_sha256_hash=99b28a6b48e793705228a390471991386daa33a9717cd9ca007fcdde69608fd9 -$(package)_extra_sources=$($(package)_clang_file_name) +$(package)_clang_sha256_hash=9ef854b71949f825362a119bf2597f744836cb571131ae6b721cd102ffea8cd0 +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)_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/3.5/include && \ - tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ + 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* && \ - echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \ - echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \ - chmod +x toolchain/bin/$(host)-dsymutil && \ - tar --strip-components=1 -xf $($(package)_source) + 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 define $(package)_set_vars -$(package)_config_opts=--target=$(host) --disable-lto-support -$(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib -$(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang -$(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ + $(package)_config_opts=--target=$(host) --with-libtapi=$($(package)_extract_dir) + $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib + ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) + $(package)_config_opts+=--enable-lto-support --with-llvm-config=$($(package)_extract_dir)/toolchain/bin/llvm-config + $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang + $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ + else + $(package)_cc=clang + $(package)_cxx=clang++ + endif endef define $(package)_preprocess_cmds - cd $($(package)_build_subdir); ./autogen.sh && \ - sed -i.old "/define HAVE_PTHREADS/d" ld64/src/ld/InputFiles.h + 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 endef define $(package)_config_cmds @@ -50,8 +91,12 @@ 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 && \ @@ -59,7 +104,13 @@ define $(package)_stage_cmds 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/llvm-dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ - if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \ - if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi + cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil +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/ endef +endif diff --git a/depends/packages/native_cdrkit.mk b/depends/packages/native_cdrkit.mk old mode 100755 new mode 100644 index cf694edb..7bdf2d7d --- a/depends/packages/native_cdrkit.mk +++ b/depends/packages/native_cdrkit.mk @@ -1,6 +1,6 @@ package=native_cdrkit $(package)_version=1.1.11 -$(package)_download_path=http://distro.ibiblio.org/fatdog/source/600/c +$(package)_download_path=https://distro.ibiblio.org/fatdog/source/600/c $(package)_file_name=cdrkit-$($(package)_version).tar.bz2 $(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564 $(package)_patches=cdrkit-deterministic.patch @@ -9,8 +9,10 @@ define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/cdrkit-deterministic.patch endef +# Starting with 10.1, GCC defaults to -fno-common, resulting in linking errors. +# Pass -fcommon to retain the legacy behaviour. define $(package)_config_cmds - cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix) + $($(package)_cmake) -DCMAKE_C_FLAGS="$$($(1)_cflags) -fcommon" endef define $(package)_build_cmds diff --git a/depends/packages/native_ds_store.mk b/depends/packages/native_ds_store.mk old mode 100755 new mode 100644 index 116fa25d..f99b689e --- a/depends/packages/native_ds_store.mk +++ b/depends/packages/native_ds_store.mk @@ -3,14 +3,14 @@ $(package)_version=1.1.2 $(package)_download_path=https://github.com/al45tair/ds_store/archive/ $(package)_file_name=v$($(package)_version).tar.gz $(package)_sha256_hash=3b3ecb7bf0a5157f5b6010bc3af7c141fb0ad3527084e63336220d22744bc20c -$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages $(package)_dependencies=native_biplist define $(package)_build_cmds - python setup.py build + python3 setup.py build endef define $(package)_stage_cmds mkdir -p $($(package)_install_libdir) && \ - python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) + python3 setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) endef diff --git a/depends/packages/native_libdmg-hfsplus.mk b/depends/packages/native_libdmg-hfsplus.mk old mode 100755 new mode 100644 index a4ffb604..035b7671 --- a/depends/packages/native_libdmg-hfsplus.mk +++ b/depends/packages/native_libdmg-hfsplus.mk @@ -1,16 +1,18 @@ package=native_libdmg-hfsplus -$(package)_version=0.1 -$(package)_download_path=https://github.com/theuni/libdmg-hfsplus/archive -$(package)_file_name=libdmg-hfsplus-v$($(package)_version).tar.gz -$(package)_sha256_hash=6569a02eb31c2827080d7d59001869ea14484c281efab0ae7f2b86af5c3120b3 +$(package)_version=7ac55ec64c96f7800d9818ce64c79670e7f02b67 +$(package)_download_path=https://github.com/planetbeing/libdmg-hfsplus/archive +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=56fbdc48ec110966342f0ecddd6f8f89202f4143ed2a3336e42bbf88f940850c $(package)_build_subdir=build +$(package)_patches=remove-libcrypto-dependency.patch define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/remove-libcrypto-dependency.patch && \ mkdir build endef define $(package)_config_cmds - cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix)/bin .. + $($(package)_cmake) -DCMAKE_C_FLAGS="$$($(1)_cflags) -Wl,--build-id=none" .. endef define $(package)_build_cmds diff --git a/depends/packages/native_libmultiprocess.mk b/depends/packages/native_libmultiprocess.mk new file mode 100644 index 00000000..c50fdc3f --- /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_mac_alias.mk b/depends/packages/native_mac_alias.mk old mode 100755 new mode 100644 index 306c8356..e60b99dc --- a/depends/packages/native_mac_alias.mk +++ b/depends/packages/native_mac_alias.mk @@ -3,13 +3,13 @@ $(package)_version=2.0.7 $(package)_download_path=https://github.com/al45tair/mac_alias/archive/ $(package)_file_name=v$($(package)_version).tar.gz $(package)_sha256_hash=6f606d3b6bccd2112aeabf1a063f5b5ece87005a5d7e97c8faca23b916e88838 -$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages define $(package)_build_cmds - python setup.py build + python3 setup.py build endef define $(package)_stage_cmds mkdir -p $($(package)_install_libdir) && \ - python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) + python3 setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) endef diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk deleted file mode 100755 index ce50b366..00000000 --- a/depends/packages/native_protobuf.mk +++ /dev/null @@ -1,25 +0,0 @@ -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 - -define $(package)_set_vars -$(package)_config_opts=--disable-shared -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C src protoc -endef - -define $(package)_stage_cmds - $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install-strip -endef - -define $(package)_postprocess_cmds - rm -rf lib include -endef diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk deleted file mode 100755 index db47113b..00000000 --- a/depends/packages/openssl.mk +++ /dev/null @@ -1,81 +0,0 @@ -package=openssl -$(package)_version=1.0.1k -$(package)_download_path=https://www.openssl.org/source -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c - -define $(package)_set_vars -$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" -$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl -$(package)_config_opts+=no-camellia -$(package)_config_opts+=no-capieng -$(package)_config_opts+=no-cast -$(package)_config_opts+=no-comp -$(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-idea -$(package)_config_opts+=no-jpake -$(package)_config_opts+=no-krb5 -$(package)_config_opts+=no-libunbound -$(package)_config_opts+=no-md2 -$(package)_config_opts+=no-mdc2 -$(package)_config_opts+=no-rc4 -$(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-seed -$(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-whirlpool -$(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_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_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 -endef - -define $(package)_preprocess_cmds - sed -i.old "/define DATE/d" util/mkbuildinf.pl && \ - sed -i.old "s|engines apps test|engines|" Makefile.org -endef - -define $(package)_config_cmds - ./Configure $($(package)_config_opts) -endef - -define $(package)_build_cmds - $(MAKE) -j1 build_libs libcrypto.pc libssl.pc openssl.pc -endef - -define $(package)_stage_cmds - $(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw -endef - -define $(package)_postprocess_cmds - rm -rf share bin etc -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk old mode 100755 new mode 100644 index 5fe6f98d..4627acb5 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,17 +1,25 @@ -packages:=boost openssl libevent zeromq +packages:=boost libevent -qt_native_packages = native_protobuf -qt_packages = qrencode protobuf zlib +qt_packages = zlib -qt_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans +qrencode_packages = qrencode + +qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig +qt_android_packages=qt qt_darwin_packages=qt qt_mingw32_packages=qt -wallet_packages=bdb +bdb_packages=bdb +sqlite_packages=sqlite + +zmq_packages=zeromq upnp_packages=miniupnpc +multiprocess_packages = libmultiprocess capnp +multiprocess_native_packages = native_libmultiprocess native_capnp + darwin_native_packages = native_biplist native_ds_store native_mac_alias ifneq ($(build_os),darwin) diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk deleted file mode 100755 index 54d3fd92..00000000 --- a/depends/packages/protobuf.mk +++ /dev/null @@ -1,29 +0,0 @@ -package=protobuf -$(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) -$(package)_cxxflags=-std=c++11 - -define $(package)_set_vars - $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C src libprotobuf.la -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install-libLTLIBRARIES install-nobase_includeHEADERS &&\ - $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA -endef - -define $(package)_postprocess_cmds - rm lib/libprotoc.a -endef diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk old mode 100755 new mode 100644 index 44fdf1c2..d1687883 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -5,8 +5,15 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19cde1fa5 define $(package)_set_vars -$(package)_config_opts=--disable-shared -without-tools --disable-sdltest +$(package)_config_opts=--disable-shared --without-tools --without-tests --disable-sdltest +$(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 + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub use endef define $(package)_config_cmds @@ -20,3 +27,7 @@ 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/qt.mk b/depends/packages/qt.mk old mode 100755 new mode 100644 index ecc66e22..2937c2a4 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,20 +1,25 @@ PACKAGE=qt -$(package)_version=5.9.6 +$(package)_version=5.9.8 $(package)_download_path=https://download.qt.io/official_releases/qt/5.9/$($(package)_version)/submodules $(package)_suffix=opensource-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=eed620cb268b199bd83b3fc6a471c51d51e1dc2dbb5374fc97a0cc75facbe36f -$(package)_dependencies=openssl zlib -$(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext +$(package)_sha256_hash=9b9dec1f67df1f94bce2955c5604de992d529dde72050239154c56352da0907d +$(package)_dependencies=zlib +$(package)_linux_dependencies=freetype fontconfig libxcb $(package)_build_subdir=qtbase $(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 fix_rcc_determinism.patch xkb-default.patch +$(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 +$(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch +$(package)_patches+= freetype_back_compat.patch drop_lrelease_dependency.patch fix_powerpc_libpng.patch +$(package)_patches+= fix_qpainter_non_determinism.patch +# Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=9822084f8e2d2939ba39f4af4c0c2320e45d5996762a9423f833055607604ed8 +$(package)_qttranslations_sha256_hash=fb5a47799754af73d3bf501fe513342cfe2fc37f64e80df5533f6110e804220c $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=50e75417ec0c74bb8b1989d1d8e981ee83690dce7dfc0c2169f7c00f397e5117 +$(package)_qttools_sha256_hash=a97556eb7b2f30252cdd8a598c396cfce2b2f79d2bae883af6d3b26a2cdcc63c $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) @@ -25,8 +30,8 @@ $(package)_config_opts_debug = -debug $(package)_config_opts += -bindir $(build_prefix)/bin $(package)_config_opts += -c++std c++11 $(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 @@ -34,14 +39,20 @@ $(package)_config_opts += -no-freetype $(package)_config_opts += -no-gif $(package)_config_opts += -no-glib $(package)_config_opts += -no-icu +$(package)_config_opts += -no-ico $(package)_config_opts += -no-iconv $(package)_config_opts += -no-kms $(package)_config_opts += -no-linuxfb +$(package)_config_opts += -no-libjpeg +$(package)_config_opts += -no-libproxy $(package)_config_opts += -no-libudev $(package)_config_opts += -no-mtdev +$(package)_config_opts += -no-openssl $(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 @@ -51,49 +62,113 @@ $(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 += -opensource -$(package)_config_opts += -openssl-linked -$(package)_config_opts += -optimized-qmake +$(package)_config_opts += -optimized-tools $(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 += -static $(package)_config_opts += -silent $(package)_config_opts += -v -$(package)_config_opts += -no-feature-printer -$(package)_config_opts += -no-feature-printdialog +$(package)_config_opts += -no-feature-bearermanagement +$(package)_config_opts += -no-feature-colordialog +$(package)_config_opts += -no-feature-commandlineparser $(package)_config_opts += -no-feature-concurrent +$(package)_config_opts += -no-feature-dial +$(package)_config_opts += -no-feature-fontcombobox +$(package)_config_opts += -no-feature-ftp +$(package)_config_opts += -no-feature-http +$(package)_config_opts += -no-feature-image_heuristic_mask +$(package)_config_opts += -no-feature-keysequenceedit +$(package)_config_opts += -no-feature-lcdnumber +$(package)_config_opts += -no-feature-networkdiskcache +$(package)_config_opts += -no-feature-networkproxy +$(package)_config_opts += -no-feature-pdf +$(package)_config_opts += -no-feature-printdialog +$(package)_config_opts += -no-feature-printer +$(package)_config_opts += -no-feature-printpreviewdialog +$(package)_config_opts += -no-feature-printpreviewwidget +$(package)_config_opts += -no-feature-regularexpression +$(package)_config_opts += -no-feature-sessionmanager +$(package)_config_opts += -no-feature-socks5 +$(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-topleveldomain +$(package)_config_opts += -no-feature-udpsocket +$(package)_config_opts += -no-feature-undocommand +$(package)_config_opts += -no-feature-undogroup +$(package)_config_opts += -no-feature-undostack +$(package)_config_opts += -no-feature-undoview +$(package)_config_opts += -no-feature-vnc +$(package)_config_opts += -no-feature-wizard $(package)_config_opts += -no-feature-xml +$(package)_config_opts_darwin = -no-dbus +$(package)_config_opts_darwin += -no-opengl + ifneq ($(build_os),darwin) -$(package)_config_opts_darwin = -xplatform macx-clang-linux +$(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 MAC_LD64_VERSION=$(LD64_VERSION) endif $(package)_config_opts_linux = -qt-xkbcommon-x11 $(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 += -dbus-runtime $(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitsend-linux-g++ $(package)_config_opts_i686_linux = -xplatform linux-g++-32 $(package)_config_opts_x86_64_linux = -xplatform linux-g++-64 $(package)_config_opts_aarch64_linux = -xplatform linux-aarch64-gnu-g++ -$(package)_config_opts_mingw32 = -no-opengl -xplatform win32-g++ -device-option CROSS_COMPILE="$(host)-" +$(package)_config_opts_powerpc64_linux = -platform linux-g++ -xplatform bitsend-linux-g++ +$(package)_config_opts_powerpc64le_linux = -platform linux-g++ -xplatform bitsend-linux-g++ +$(package)_config_opts_riscv64_linux = -platform linux-g++ -xplatform bitsend-linux-g++ +$(package)_config_opts_s390x_linux = -platform linux-g++ -xplatform bitsend-linux-g++ + +$(package)_config_opts_mingw32 = -no-opengl +$(package)_config_opts_mingw32 += -no-dbus +$(package)_config_opts_mingw32 += -xplatform win32-g++ +$(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-" + +$(package)_config_opts_android = -xplatform android-clang +$(package)_config_opts_android += -android-sdk $(ANDROID_SDK) +$(package)_config_opts_android += -android-ndk $(ANDROID_NDK) +$(package)_config_opts_android += -android-ndk-platform android-$(ANDROID_API_LEVEL) +$(package)_config_opts_android += -device-option CROSS_COMPILE="$(host)-" +$(package)_config_opts_android += -egl +$(package)_config_opts_android += -qpa xcb +$(package)_config_opts_android += -no-eglfs +$(package)_config_opts_android += -no-dbus +$(package)_config_opts_android += -opengl es2 +$(package)_config_opts_android += -qt-freetype +$(package)_config_opts_android += -no-fontconfig +$(package)_config_opts_android += -L $(host_prefix)/lib +$(package)_config_opts_android += -I $(host_prefix)/include + +$(package)_config_opts_aarch64_android += -android-arch arm64-v8a +$(package)_config_opts_armv7a_android += -android-arch armeabi-v7a +$(package)_config_opts_x86_64_android += -android-arch x86_64 +$(package)_config_opts_i686_android += -android-arch i686 + $(package)_build_env = QT_RCC_TEST=1 $(package)_build_env += QT_RCC_SOURCE_DATE_OVERRIDE=1 endef @@ -111,21 +186,20 @@ define $(package)_extract_cmds echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ mkdir qtbase && \ - tar --strip-components=1 -xf $($(package)_source) -C qtbase && \ + tar --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ mkdir qttranslations && \ - tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ + tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ mkdir qttools && \ - tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools + tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools endef define $(package)_preprocess_cmds - sed -i.old "s|FT_Get_Font_Format|FT_Get_X11_Font_Format|" qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp && \ + patch -p1 -i $($(package)_patch_dir)/freetype_back_compat.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_powerpc_libpng.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch &&\ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ - sed -i.old "/updateqm.depends =/d" qttranslations/translations/translations.pro && \ - sed -i.old "s/src_plugins.depends = src_sql src_network/src_plugins.depends = src_network/" qtbase/src/src.pro && \ - sed -i.old "s|X11/extensions/XIproto.h|X11/X.h|" qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp && \ - sed -i.old 's/if \[ "$$$$XPLATFORM_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/if \[ "$$$$BUILD_ON_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/' qtbase/configure && \ - sed -i.old 's/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0)/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft)/' qtbase/src/plugins/platforms/cocoa/qcocoacursor.mm && \ + patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \ + patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.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/ &&\ @@ -138,14 +212,21 @@ define $(package)_preprocess_cmds 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 &&\ + patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch &&\ + patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.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 &&\ + patch -p1 -i $($(package)_patch_dir)/no-xlib.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_LFLAGS = |!host_build: QMAKE_LFLAGS = $($(package)_ldflags) |" 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 "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/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf endef define $(package)_config_cmds diff --git a/depends/packages/sqlite.mk b/depends/packages/sqlite.mk new file mode 100644 index 00000000..5b3a61b2 --- /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 old mode 100755 new mode 100644 index 0c7c958d..01203a07 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -1,14 +1,9 @@ package=xcb_proto $(package)_version=1.10 -$(package)_download_path=http://xcb.freedesktop.org/dist +$(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 - define $(package)_config_cmds $($(package)_autoconf) endef diff --git a/depends/packages/xextproto.mk b/depends/packages/xextproto.mk deleted file mode 100755 index 7065237b..00000000 --- a/depends/packages/xextproto.mk +++ /dev/null @@ -1,25 +0,0 @@ -package=xextproto -$(package)_version=7.3.0 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/proto -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=f3f4b23ac8db9c3a9e0d8edb591713f3d70ef9c3b175970dd8823dfc92aa5bb0 - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . -endef - -define $(package)_set_vars -$(package)_config_opts=--disable-shared -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 diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk old mode 100755 new mode 100644 index 50a90b26..6bd867d0 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -1,11 +1,16 @@ package=xproto $(package)_version=7.0.26 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/proto +$(package)_download_path=https://xorg.freedesktop.org/releases/individual/proto $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f 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 + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . endef define $(package)_config_cmds diff --git a/depends/packages/xtrans.mk b/depends/packages/xtrans.mk deleted file mode 100755 index 99eefa6d..00000000 --- a/depends/packages/xtrans.mk +++ /dev/null @@ -1,22 +0,0 @@ -package=xtrans -$(package)_version=1.3.4 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=054d4ee3efd52508c753e9f7bc655ef185a29bd2850dd9e2fc2ccc33544f583a -$(package)_dependencies= - -define $(package)_set_vars -$(package)_config_opts_linux=--with-pic --disable-static -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 diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk old mode 100755 new mode 100644 index d5fd1f39..c93aa1a7 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,20 +1,23 @@ package=zeromq -$(package)_version=4.2.3 +$(package)_version=4.3.1 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=8f1e2b2aade4dbfde98d82366d61baef2f62e812530160d2e6d0a5bb24e40bc0 -$(package)_patches=0001-fix-build-with-older-mingw64.patch 0002-disable-pthread_set_name_np.patch +$(package)_sha256_hash=bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d835cd21eb +$(package)_patches=remove_libstd_link.patch define $(package)_set_vars - $(package)_config_opts=--without-docs --disable-shared --without-libsodium --disable-curve --disable-curve-keygen --disable-perf --disable-Werror + $(package)_config_opts=--without-docs --disable-shared --disable-curve --disable-curve-keygen --disable-perf + $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci + $(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)_config_opts_android=--with-pic $(package)_cxxflags=-std=c++11 endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/0001-fix-build-with-older-mingw64.patch && \ - patch -p1 < $($(package)_patch_dir)/0002-disable-pthread_set_name_np.patch && \ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config + patch -p1 < $($(package)_patch_dir)/remove_libstd_link.patch && \ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config endef define $(package)_config_cmds @@ -30,6 +33,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - sed -i.old "s/ -lstdc++//" lib/pkgconfig/libzmq.pc && \ - rm -rf bin share + rm -rf bin share lib/*.la endef diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk old mode 100755 new mode 100644 index 58949080..acb02020 --- a/depends/packages/zlib.mk +++ b/depends/packages/zlib.mk @@ -1,27 +1,31 @@ package=zlib $(package)_version=1.2.11 -$(package)_download_path=http://www.zlib.net +$(package)_download_path=https://www.zlib.net $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 define $(package)_set_vars -$(package)_build_opts= CC="$($(package)_cc)" -$(package)_build_opts+=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -fPIC" -$(package)_build_opts+=RANLIB="$($(package)_ranlib)" -$(package)_build_opts+=AR="$($(package)_ar)" -$(package)_build_opts_darwin+=AR="$($(package)_libtool)" -$(package)_build_opts_darwin+=ARFLAGS="-o" +$(package)_config_opts= CC="$($(package)_cc)" +$(package)_config_opts+=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -fPIC" +$(package)_config_opts+=RANLIB="$($(package)_ranlib)" +$(package)_config_opts+=AR="$($(package)_ar)" +$(package)_config_opts_darwin+=AR="$($(package)_libtool)" +$(package)_config_opts_darwin+=ARFLAGS="-o" +$(package)_config_opts_android+=CHOST=$(host) endef +# zlib has its own custom configure script that takes in options like CC, +# CFLAGS, RANLIB, AR, and ARFLAGS from the environment rather than from +# command-line arguments. define $(package)_config_cmds - ./configure --static --prefix=$(host_prefix) + env $($(package)_config_opts) ./configure --static --prefix=$(host_prefix) endef define $(package)_build_cmds - $(MAKE) $($(package)_build_opts) libz.a + $(MAKE) libz.a endef define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install $($(package)_build_opts) + $(MAKE) DESTDIR=$($(package)_staging_dir) install endef diff --git a/depends/patches/bdb/clang_cxx_11.patch b/depends/patches/bdb/clang_cxx_11.patch new file mode 100644 index 00000000..58f7ddc7 --- /dev/null +++ b/depends/patches/bdb/clang_cxx_11.patch @@ -0,0 +1,147 @@ +commit 3311d68f11d1697565401eee6efc85c34f022ea7 +Author: fanquake +Date: Mon Aug 17 20:03:56 2020 +0800 + + Fix C++11 compatibility + +diff --git a/dbinc/atomic.h b/dbinc/atomic.h +index 0034dcc..7c11d4a 100644 +--- a/dbinc/atomic.h ++++ b/dbinc/atomic.h +@@ -70,7 +70,7 @@ typedef struct { + * These have no memory barriers; the caller must include them when necessary. + */ + #define atomic_read(p) ((p)->value) +-#define atomic_init(p, val) ((p)->value = (val)) ++#define atomic_init_db(p, val) ((p)->value = (val)) + + #ifdef HAVE_ATOMIC_SUPPORT + +@@ -144,7 +144,7 @@ typedef LONG volatile *interlocked_val; + #define atomic_inc(env, p) __atomic_inc(p) + #define atomic_dec(env, p) __atomic_dec(p) + #define atomic_compare_exchange(env, p, o, n) \ +- __atomic_compare_exchange((p), (o), (n)) ++ __atomic_compare_exchange_db((p), (o), (n)) + static inline int __atomic_inc(db_atomic_t *p) + { + int temp; +@@ -176,7 +176,7 @@ static inline int __atomic_dec(db_atomic_t *p) + * http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html + * which configure could be changed to use. + */ +-static inline int __atomic_compare_exchange( ++static inline int __atomic_compare_exchange_db( + db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval) + { + atomic_value_t was; +@@ -206,7 +206,7 @@ static inline int __atomic_compare_exchange( + #define atomic_dec(env, p) (--(p)->value) + #define atomic_compare_exchange(env, p, oldval, newval) \ + (DB_ASSERT(env, atomic_read(p) == (oldval)), \ +- atomic_init(p, (newval)), 1) ++ atomic_init_db(p, (newval)), 1) + #else + #define atomic_inc(env, p) __atomic_inc(env, p) + #define atomic_dec(env, p) __atomic_dec(env, p) +diff --git a/mp/mp_fget.c b/mp/mp_fget.c +index 5fdee5a..0b75f57 100644 +--- a/mp/mp_fget.c ++++ b/mp/mp_fget.c +@@ -617,7 +617,7 @@ alloc: /* Allocate a new buffer header and data space. */ + + /* Initialize enough so we can call __memp_bhfree. */ + alloc_bhp->flags = 0; +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + #ifdef DIAGNOSTIC + if ((uintptr_t)alloc_bhp->buf & (sizeof(size_t) - 1)) { + __db_errx(env, +@@ -911,7 +911,7 @@ alloc: /* Allocate a new buffer header and data space. */ + MVCC_MPROTECT(bhp->buf, mfp->stat.st_pagesize, + PROT_READ); + +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + MUTEX_LOCK(env, alloc_bhp->mtx_buf); + alloc_bhp->priority = bhp->priority; + alloc_bhp->pgno = bhp->pgno; +diff --git a/mp/mp_mvcc.c b/mp/mp_mvcc.c +index 34467d2..f05aa0c 100644 +--- a/mp/mp_mvcc.c ++++ b/mp/mp_mvcc.c +@@ -276,7 +276,7 @@ __memp_bh_freeze(dbmp, infop, hp, bhp, need_frozenp) + #else + memcpy(frozen_bhp, bhp, SSZA(BH, buf)); + #endif +- atomic_init(&frozen_bhp->ref, 0); ++ atomic_init_db(&frozen_bhp->ref, 0); + if (mutex != MUTEX_INVALID) + frozen_bhp->mtx_buf = mutex; + else if ((ret = __mutex_alloc(env, MTX_MPOOL_BH, +@@ -428,7 +428,7 @@ __memp_bh_thaw(dbmp, infop, hp, frozen_bhp, alloc_bhp) + #endif + alloc_bhp->mtx_buf = mutex; + MUTEX_LOCK(env, alloc_bhp->mtx_buf); +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + F_CLR(alloc_bhp, BH_FROZEN); + } + +diff --git a/mp/mp_region.c b/mp/mp_region.c +index e6cece9..ddbe906 100644 +--- a/mp/mp_region.c ++++ b/mp/mp_region.c +@@ -224,7 +224,7 @@ __memp_init(env, dbmp, reginfo_off, htab_buckets, max_nreg) + MTX_MPOOL_FILE_BUCKET, 0, &htab[i].mtx_hash)) != 0) + return (ret); + SH_TAILQ_INIT(&htab[i].hash_bucket); +- atomic_init(&htab[i].hash_page_dirty, 0); ++ atomic_init_db(&htab[i].hash_page_dirty, 0); + } + + /* +@@ -269,7 +269,7 @@ __memp_init(env, dbmp, reginfo_off, htab_buckets, max_nreg) + hp->mtx_hash = (mtx_base == MUTEX_INVALID) ? MUTEX_INVALID : + mtx_base + i; + SH_TAILQ_INIT(&hp->hash_bucket); +- atomic_init(&hp->hash_page_dirty, 0); ++ atomic_init_db(&hp->hash_page_dirty, 0); + #ifdef HAVE_STATISTICS + hp->hash_io_wait = 0; + hp->hash_frozen = hp->hash_thawed = hp->hash_frozen_freed = 0; +diff --git a/mutex/mut_method.c b/mutex/mut_method.c +index 2588763..5c6d516 100644 +--- a/mutex/mut_method.c ++++ b/mutex/mut_method.c +@@ -426,7 +426,7 @@ atomic_compare_exchange(env, v, oldval, newval) + MUTEX_LOCK(env, mtx); + ret = atomic_read(v) == oldval; + if (ret) +- atomic_init(v, newval); ++ atomic_init_db(v, newval); + MUTEX_UNLOCK(env, mtx); + + return (ret); +diff --git a/mutex/mut_tas.c b/mutex/mut_tas.c +index f3922e0..e40fcdf 100644 +--- a/mutex/mut_tas.c ++++ b/mutex/mut_tas.c +@@ -46,7 +46,7 @@ __db_tas_mutex_init(env, mutex, flags) + + #ifdef HAVE_SHARED_LATCHES + if (F_ISSET(mutexp, DB_MUTEX_SHARED)) +- atomic_init(&mutexp->sharecount, 0); ++ atomic_init_db(&mutexp->sharecount, 0); + else + #endif + if (MUTEX_INIT(&mutexp->tas)) { +@@ -486,7 +486,7 @@ __db_tas_mutex_unlock(env, mutex) + F_CLR(mutexp, DB_MUTEX_LOCKED); + /* Flush flag update before zeroing count */ + MEMBAR_EXIT(); +- atomic_init(&mutexp->sharecount, 0); ++ atomic_init_db(&mutexp->sharecount, 0); + } else { + DB_ASSERT(env, sharecount > 0); + MEMBAR_EXIT(); diff --git a/depends/patches/boost/unused_var_in_process.patch b/depends/patches/boost/unused_var_in_process.patch new file mode 100644 index 00000000..722f7bb5 --- /dev/null +++ b/depends/patches/boost/unused_var_in_process.patch @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..7401b83d --- /dev/null +++ b/depends/patches/fontconfig/gperf_header_regen.patch @@ -0,0 +1,24 @@ +commit 7b6eb33ecd88768b28c67ce5d2d68a7eed5936b6 +Author: fanquake +Date: Tue Aug 25 14:34:53 2020 +0800 + + Remove rule that causes inadvertant 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. + + See #10851. + +diff --git a/src/Makefile.in b/src/Makefile.in +index f4626ad..4ae1b00 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -903,7 +903,7 @@ fcobjshash.gperf: fcobjshash.gperf.h fcobjs.h + ' - > $@.tmp && \ + mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) + +-fcobjshash.h: fcobjshash.gperf ++fcobjshash.h: + $(AM_V_GEN) $(GPERF) -m 100 $< > $@.tmp && \ + mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) + diff --git a/depends/patches/fontconfig/remove_char_width_usage.patch b/depends/patches/fontconfig/remove_char_width_usage.patch new file mode 100644 index 00000000..9f690818 --- /dev/null +++ b/depends/patches/fontconfig/remove_char_width_usage.patch @@ -0,0 +1,62 @@ +commit 28165a9b078583dc8e9e5c344510e37582284cef +Author: fanquake +Date: Mon Aug 17 20:35:42 2020 +0800 + + Remove usage of CHAR_WIDTH + + CHAR_WIDTH which is reserved and clashes with glibc 2.25+ + + See #10851. + +diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h +index 5c72b22..843c532 100644 +--- a/fontconfig/fontconfig.h ++++ b/fontconfig/fontconfig.h +@@ -128,7 +128,7 @@ typedef int FcBool; + #define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION + + /* Adjust outline rasterizer */ +-#define FC_CHAR_WIDTH "charwidth" /* Int */ ++#define FC_CHARWIDTH "charwidth" /* Int */ + #define FC_CHAR_HEIGHT "charheight"/* Int */ + #define FC_MATRIX "matrix" /* FcMatrix */ + +diff --git a/src/fcobjs.h b/src/fcobjs.h +index 1fc4f65..d27864b 100644 +--- a/src/fcobjs.h ++++ b/src/fcobjs.h +@@ -51,7 +51,7 @@ FC_OBJECT (DPI, FcTypeDouble, NULL) + FC_OBJECT (RGBA, FcTypeInteger, NULL) + FC_OBJECT (SCALE, FcTypeDouble, NULL) + FC_OBJECT (MINSPACE, FcTypeBool, NULL) +-FC_OBJECT (CHAR_WIDTH, FcTypeInteger, NULL) ++FC_OBJECT (CHARWIDTH, FcTypeInteger, NULL) + FC_OBJECT (CHAR_HEIGHT, FcTypeInteger, NULL) + FC_OBJECT (MATRIX, FcTypeMatrix, NULL) + FC_OBJECT (CHARSET, FcTypeCharSet, FcCompareCharSet) +diff --git a/src/fcobjshash.gperf b/src/fcobjshash.gperf +index 80a0237..eb4ad84 100644 +--- a/src/fcobjshash.gperf ++++ b/src/fcobjshash.gperf +@@ -44,7 +44,7 @@ int id; + "rgba",FC_RGBA_OBJECT + "scale",FC_SCALE_OBJECT + "minspace",FC_MINSPACE_OBJECT +-"charwidth",FC_CHAR_WIDTH_OBJECT ++"charwidth",FC_CHARWIDTH_OBJECT + "charheight",FC_CHAR_HEIGHT_OBJECT + "matrix",FC_MATRIX_OBJECT + "charset",FC_CHARSET_OBJECT +diff --git a/src/fcobjshash.h b/src/fcobjshash.h +index 5a4d1ea..4e66bb0 100644 +--- a/src/fcobjshash.h ++++ b/src/fcobjshash.h +@@ -284,7 +284,7 @@ FcObjectTypeLookup (register const char *str, register unsigned int len) + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_CHARSET_OBJECT}, + {-1}, + #line 47 "fcobjshash.gperf" +- {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHAR_WIDTH_OBJECT}, ++ {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHARWIDTH_OBJECT}, + #line 48 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_CHAR_HEIGHT_OBJECT}, + #line 55 "fcobjshash.gperf" diff --git a/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch b/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch new file mode 100644 index 00000000..a98cd90b --- /dev/null +++ b/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch @@ -0,0 +1,15 @@ +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_use_wingen.patch b/depends/patches/miniupnpc/dont_use_wingen.patch new file mode 100644 index 00000000..a1cc9b50 --- /dev/null +++ b/depends/patches/miniupnpc/dont_use_wingen.patch @@ -0,0 +1,26 @@ +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 new file mode 100644 index 00000000..d6c58c10 --- /dev/null +++ b/depends/patches/native_cctools/ld64_disable_threading.patch @@ -0,0 +1,26 @@ +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/native_cdrkit/cdrkit-deterministic.patch b/depends/patches/native_cdrkit/cdrkit-deterministic.patch old mode 100755 new mode 100644 diff --git a/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch b/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch new file mode 100644 index 00000000..f346c8f2 --- /dev/null +++ b/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch @@ -0,0 +1,45 @@ +From 3e5fd3fb56bc9ff03beb535979e33dcf83fe1f70 Mon Sep 17 00:00:00 2001 +From: Cory Fields +Date: Thu, 8 May 2014 12:39:42 -0400 +Subject: [PATCH] dmg: remove libcrypto dependency + +--- + dmg/CMakeLists.txt | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/dmg/CMakeLists.txt b/dmg/CMakeLists.txt +index eec62d6..3969f64 100644 +--- a/dmg/CMakeLists.txt ++++ b/dmg/CMakeLists.txt +@@ -1,12 +1,5 @@ +-INCLUDE(FindOpenSSL) + INCLUDE(FindZLIB) + +-FIND_LIBRARY(CRYPTO_LIBRARIES crypto +- PATHS +- /usr/lib +- /usr/local/lib +- ) +- + IF(NOT ZLIB_FOUND) + message(FATAL_ERROR "zlib is required for dmg!") + ENDIF(NOT ZLIB_FOUND) +@@ -18,15 +11,6 @@ link_directories(${PROJECT_BINARY_DIR}/common ${PROJECT_BINARY_DIR}/hfs) + + add_library(dmg adc.c base64.c checksum.c dmgfile.c dmglib.c filevault.c io.c partition.c resources.c udif.c) + +-IF(OPENSSL_FOUND) +- add_definitions(-DHAVE_CRYPT) +- include_directories(${OPENSSL_INCLUDE_DIR}) +- target_link_libraries(dmg ${CRYPTO_LIBRARIES}) +- IF(WIN32) +- TARGET_LINK_LIBRARIES(dmg gdi32) +- ENDIF(WIN32) +-ENDIF(OPENSSL_FOUND) +- + target_link_libraries(dmg common hfs z) + + add_executable(dmg-bin dmg.c) +-- +2.22.0 + diff --git a/depends/patches/qt/dont_hardcode_pwd.patch b/depends/patches/qt/dont_hardcode_pwd.patch new file mode 100644 index 00000000..a74e9cb0 --- /dev/null +++ b/depends/patches/qt/dont_hardcode_pwd.patch @@ -0,0 +1,27 @@ +commit 0e953866fc4672486e29e1ba6d83b4207e7b2f0b +Author: fanquake +Date: Tue Aug 18 15:09:06 2020 +0800 + + Don't hardcode pwd path + + Let a man use his builtins if he wants to! Also, removes the unnecessary + assumption that pwd lives under /bin/pwd. + + See #15581. + +diff --git a/qtbase/configure b/qtbase/configure +index 08b49a8d..faea5b55 100755 +--- a/qtbase/configure ++++ b/qtbase/configure +@@ -36,9 +36,9 @@ + relconf=`basename $0` + # the directory of this script is the "source tree" + relpath=`dirname $0` +-relpath=`(cd "$relpath"; /bin/pwd)` ++relpath=`(cd "$relpath"; pwd)` + # the current directory is the "build tree" or "object tree" +-outpath=`/bin/pwd` ++outpath=`pwd` + + WHICH="which" + diff --git a/depends/patches/qt/drop_lrelease_dependency.patch b/depends/patches/qt/drop_lrelease_dependency.patch new file mode 100644 index 00000000..f6b2c9fc --- /dev/null +++ b/depends/patches/qt/drop_lrelease_dependency.patch @@ -0,0 +1,20 @@ +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_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch new file mode 100644 index 00000000..2f6ff00f --- /dev/null +++ b/depends/patches/qt/fix_android_jni_static.patch @@ -0,0 +1,18 @@ +--- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp ++++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp +@@ -890,6 +890,14 @@ + __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); + return -1; + } ++ ++ const jint ret = QT_PREPEND_NAMESPACE(QtAndroidPrivate::initJNI(vm, env)); ++ if (ret != 0) ++ { ++ __android_log_print(ANDROID_LOG_FATAL, "Qt", "initJNI failed"); ++ return ret; ++ } ++ + QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); + + m_javaVM = vm; + diff --git a/depends/patches/qt/fix_android_qmake_conf.patch b/depends/patches/qt/fix_android_qmake_conf.patch new file mode 100644 index 00000000..13bfff97 --- /dev/null +++ b/depends/patches/qt/fix_android_qmake_conf.patch @@ -0,0 +1,20 @@ +--- 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 + + 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 diff --git a/depends/patches/qt/fix_configure_mac.patch b/depends/patches/qt/fix_configure_mac.patch old mode 100755 new mode 100644 diff --git a/depends/patches/qt/fix_no_printer.patch b/depends/patches/qt/fix_no_printer.patch old mode 100755 new mode 100644 diff --git a/depends/patches/qt/fix_powerpc_libpng.patch b/depends/patches/qt/fix_powerpc_libpng.patch new file mode 100644 index 00000000..d37b6c77 --- /dev/null +++ b/depends/patches/qt/fix_powerpc_libpng.patch @@ -0,0 +1,23 @@ +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_qpainter_non_determinism.patch b/depends/patches/qt/fix_qpainter_non_determinism.patch new file mode 100644 index 00000000..3cfcc22f --- /dev/null +++ b/depends/patches/qt/fix_qpainter_non_determinism.patch @@ -0,0 +1,63 @@ +commit 2a8f7dc6ddfc414a66491522501c1574a1343ee1 +Author: Andrew Chow +Date: Sat Nov 21 01:11:04 2020 -0500 + + build: Fix determinism issue when building with Clang 8 + + When building Qt with LLVM/Clang 8 under -O3 (the default), we run into + a determinism issue in `qt_interset_spans`. The issue has been fixed for + LLVM/Clang 9, see + https://github.com/llvm/llvm-project/commit/db101864bdc938deb1d63fe4f7da761bd38e5cae + and https://reviews.llvm.org/D64601, however this fix was not backported + to 8.x. Once LLVM/Clang 9 is used, this patch can be dropped. + + The particular issue appears to be an optimization done by -O3 which + adds a temporary variable for `spans->y` in `qt_intersect_spans`. When + it does this, sometimes it chooses to use a 32-bit movs instruction + (movswl), and other times it chooses a 64-bit movs instruction (movswq). + By patching `qt_intersect_spans` to always make a temporary variable for + `spans->y`, we are able to sidestep this problem. + +diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp +index 92ab6e8375..f018009e0b 100644 +--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp ++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp +@@ -3971,22 +3971,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + const QSpan *clipEnd = clip->m_spans + clip->count; + + while (available && spans < end ) { ++ const short spans_y = spans->y; + if (clipSpans >= clipEnd) { + spans = end; + break; + } +- if (clipSpans->y > spans->y) { ++ if (clipSpans->y > spans_y) { + ++spans; + continue; + } +- if (spans->y != clipSpans->y) { +- if (spans->y < clip->count && clip->m_clipLines[spans->y].spans) +- clipSpans = clip->m_clipLines[spans->y].spans; ++ if (spans_y != clipSpans->y) { ++ if (spans_y < clip->count && clip->m_clipLines[spans_y].spans) ++ clipSpans = clip->m_clipLines[spans_y].spans; + else + ++clipSpans; + continue; + } +- Q_ASSERT(spans->y == clipSpans->y); ++ Q_ASSERT(spans_y == clipSpans->y); + + int sx1 = spans->x; + int sx2 = sx1 + spans->len; +@@ -4005,7 +4006,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + if (len) { + out->x = qMax(sx1, cx1); + out->len = qMin(sx2, cx2) - out->x; +- out->y = spans->y; ++ out->y = spans_y; + out->coverage = qt_div_255(spans->coverage * clipSpans->coverage); + ++out; + --available; + diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch old mode 100755 new mode 100644 index 34302a9f..8c722ffb --- a/depends/patches/qt/fix_qt_pkgconfig.patch +++ b/depends/patches/qt/fix_qt_pkgconfig.patch @@ -1,11 +1,23 @@ --- old/qtbase/mkspecs/features/qt_module.prf +++ new/qtbase/mkspecs/features/qt_module.prf -@@ -245,7 +245,7 @@ +@@ -264,7 +264,7 @@ load(qt_targets) # this builds on top of qt_common -!internal_module:!lib_bundle:if(unix|mingw) { -+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 + 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() + for(i, MODULE_DEPENDS): \ +- QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0)) ++ 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 diff --git a/depends/patches/qt/fix_rcc_determinism.patch b/depends/patches/qt/fix_rcc_determinism.patch old mode 100755 new mode 100644 diff --git a/depends/patches/qt/fix_riscv64_arch.patch b/depends/patches/qt/fix_riscv64_arch.patch new file mode 100644 index 00000000..e7f29f01 --- /dev/null +++ b/depends/patches/qt/fix_riscv64_arch.patch @@ -0,0 +1,14 @@ +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 new file mode 100644 index 00000000..b0f1c98a --- /dev/null +++ b/depends/patches/qt/freetype_back_compat.patch @@ -0,0 +1,28 @@ +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 old mode 100755 new mode 100644 index 337d0eb9..4cd96df2 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -18,7 +18,7 @@ QMAKE_APPLE_DEVICE_ARCHS=x86_64 !host_build: QMAKE_CFLAGS += -target $${MAC_TARGET} !host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS !host_build: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS -!host_build: QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION} +!host_build: QMAKE_LFLAGS += -target $${MAC_TARGET} QMAKE_AR = $${CROSS_COMPILE}ar cq QMAKE_RANLIB=$${CROSS_COMPILE}ranlib QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool diff --git a/depends/patches/qt/no-xlib.patch b/depends/patches/qt/no-xlib.patch new file mode 100644 index 00000000..fe82c2c7 --- /dev/null +++ b/depends/patches/qt/no-xlib.patch @@ -0,0 +1,69 @@ +From 9563cef873ae82e06f60708d706d054717e801ce Mon Sep 17 00:00:00 2001 +From: Carl Dong +Date: Thu, 18 Jul 2019 17:22:05 -0400 +Subject: [PATCH] Wrap xlib related code blocks in #if's + +They are not necessary to compile QT. +--- + qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp b/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp +index 7c62c2e2b3..c05c6c0a07 100644 +--- a/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp ++++ b/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp +@@ -49,7 +49,9 @@ + #include + #include + #include ++#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) + #include ++#endif + #include + #include + +@@ -384,6 +386,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) + w->setCursor(c, isBitmapCursor); + } + ++#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) + } + return cursorId; + } ++#endif + + xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape) + { +@@ -558,7 +562,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) + xcb_cursor_t QXcbCursor::createFontCursor(int cshape) + { + xcb_connection_t *conn = xcb_connection(); ++#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) + int cursorId = cursorIdForShape(cshape); ++#endif + xcb_cursor_t cursor = XCB_NONE; + + // Try Xcursor first +@@ -589,6 +595,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) + cursorId, cursorId + 1, + 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0); + } ++#endif + + if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) { + const char *name = cursorNames[cshape]; +-- +2.22.0 + diff --git a/depends/patches/qt/xkb-default.patch b/depends/patches/qt/xkb-default.patch old mode 100755 new mode 100644 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 100755 index a6c508fb..00000000 --- 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 100755 index d220b54f..00000000 --- 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/depends/patches/zeromq/remove_libstd_link.patch b/depends/patches/zeromq/remove_libstd_link.patch new file mode 100644 index 00000000..ddf91e6a --- /dev/null +++ b/depends/patches/zeromq/remove_libstd_link.patch @@ -0,0 +1,25 @@ +commit 47d4cd12a2c051815ddda78adebdb3923b260d8a +Author: fanquake +Date: Tue Aug 18 14:45:40 2020 +0800 + + Remove needless linking against libstdc++ + + This is broken for a number of reasons, including: + - g++ understands "static-libstdc++ -lstdc++" to mean "link against + whatever libstdc++ exists, probably shared", which in itself is buggy. + - another stdlib (libc++ for example) may be in use + + See #11981. + +diff --git a/src/libzmq.pc.in b/src/libzmq.pc.in +index 233bc3a..3c2bf0d 100644 +--- a/src/libzmq.pc.in ++++ b/src/libzmq.pc.in +@@ -7,6 +7,6 @@ Name: libzmq + Description: 0MQ c++ library + Version: @VERSION@ + Libs: -L${libdir} -lzmq +-Libs.private: -lstdc++ @pkg_config_libs_private@ ++Libs.private: @pkg_config_libs_private@ + Requires.private: @pkg_config_names_private@ + Cflags: -I${includedir} @pkg_config_defines@ diff --git a/doc/.gitignore b/doc/.gitignore old mode 100755 new mode 100644 diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in old mode 100755 new mode 100644 index a4005217..807d5e48 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "Bitsend Core" +PROJECT_NAME = "BitSend Core" # 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 @@ -453,7 +453,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. -EXTRACT_STATIC = NO +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, @@ -790,7 +790,7 @@ WARN_LOGFILE = # 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. Doxygen uses @@ -861,7 +861,8 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = src/leveldb \ +EXCLUDE = src/crc32c \ + src/leveldb \ src/json \ src/test \ src/qt/test @@ -974,7 +975,7 @@ FILTER_SOURCE_PATTERNS = # (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. -USE_MDFILE_AS_MAINPAGE = +USE_MDFILE_AS_MAINPAGE = doc/README_doxygen.md #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -1265,7 +1266,7 @@ DOCSET_FEEDNAME = "Doxygen generated docs" # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_BUNDLE_ID = org.bitsend.Bitsend-Core +DOCSET_BUNDLE_ID = org.bitsend.BitSend-Core # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style @@ -1273,7 +1274,7 @@ DOCSET_BUNDLE_ID = org.bitsend.Bitsend-Core # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_PUBLISHER_ID = org.bitsend.Bitsend-Core +DOCSET_PUBLISHER_ID = org.bitsend.BitSend-Core # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. @@ -2072,7 +2073,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = HAVE_BOOST_PROCESS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/doc/JSON-RPC-interface.md b/doc/JSON-RPC-interface.md new file mode 100644 index 00000000..e7301403 --- /dev/null +++ b/doc/JSON-RPC-interface.md @@ -0,0 +1,140 @@ +# JSON-RPC Interface + +The headless daemon `bitsendd` has the JSON-RPC API enabled by default, the GUI +`bitsend-qt` has it disabled by default. This can be changed with the `-server` +option. In the GUI it is possible to execute RPC methods in the Debug Console +Dialog. + +## Versioning + +The RPC interface might change from one major version of BitSend Core to the +next. This makes the RPC interface implicitly versioned on the major version. +The version tuple can be retrieved by e.g. the `getnetworkinfo` RPC in +`version`. + +Usually deprecated features can be re-enabled during the grace-period of one +major version via the `-deprecatedrpc=` command line option. The release notes +of a new major release come with detailed instructions on what RPC features +were deprecated and how to re-enable them temporarily. + +## Security + +The RPC interface allows other programs to control BitSend Core, +including the ability to spend funds from your wallets, affect consensus +verification, read private data, and otherwise perform operations that +can cause loss of money, data, or privacy. This section suggests how +you should use and configure BitSend Core to reduce the risk that its +RPC interface will be abused. + +- **Securing the executable:** Anyone with physical or remote access to + the computer, container, or virtual machine running BitSend Core can + compromise either the whole program or just the RPC interface. This + includes being able to record any passphrases you enter for unlocking + your encrypted wallets or changing settings so that your BitSend Core + program tells you that certain transactions have multiple + confirmations even when they aren't part of the best block chain. For + this reason, you should not use BitSend Core for security sensitive + operations on systems you do not exclusively control, such as shared + computers or virtual private servers. + +- **Securing local network access:** By default, the RPC interface can + only be accessed by a client running on the same computer and only + after the client provides a valid authentication credential (username + and passphrase). Any program on your computer with access to the file + system and local network can obtain this level of access. + Additionally, other programs on your computer can attempt to provide + an RPC interface on the same port as used by BitSend Core in order to + trick you into revealing your authentication credentials. For this + reason, it is important to only use BitSend Core for + security-sensitive operations on a computer whose other programs you + trust. + +- **Securing remote network access:** You may optionally allow other + computers to remotely control BitSend Core by setting the `rpcallowip` + and `rpcbind` configuration parameters. These settings are only meant + for enabling connections over secure private networks or connections + that have been otherwise secured (e.g. using a VPN or port forwarding + with SSH or stunnel). **Do not enable RPC connections over the public + Internet.** Although BitSend Core's RPC interface does use + authentication, it does not use encryption, so your login credentials + are sent as clear text that can be read by anyone on your network + path. Additionally, the RPC interface has not been hardened to + withstand arbitrary Internet traffic, so changing the above settings + to expose it to the Internet (even using something like a Tor onion + service) could expose you to unconsidered vulnerabilities. See + `bitsendd -help` for more information about these settings and other + settings described in this document. + + Related, if you use BitSend Core inside a Docker container, you may + need to expose the RPC port to the host system. The default way to + do this in Docker also exposes the port to the public Internet. + Instead, expose it only on the host system's localhost, for example: + `-p 127.0.0.1:8332:8332` + +- **Secure authentication:** By default, BitSend Core generates unique + login credentials each time it restarts and puts them into a file + readable only by the user that started BitSend Core, allowing any of + that user's RPC clients with read access to the file to login + automatically. The file is `.cookie` in the BitSend Core + configuration directory, and using these credentials is the preferred + RPC authentication method. If you need to generate static login + credentials for your programs, you can use the script in the + `share/rpcauth` directory in the BitSend Core source tree. As a final + fallback, you can directly use manually-chosen `rpcuser` and + `rpcpassword` configuration parameters---but you must ensure that you + choose a strong and unique passphrase (and still don't use insecure + networks, as mentioned above). + +- **Secure string handling:** The RPC interface does not guarantee any + escaping of data beyond what's necessary to encode it as JSON, + although it does usually provide serialized data using a hex + representation of the bytes. If you use RPC data in your programs or + provide its data to other programs, you must ensure any problem + strings are properly escaped. For example, multiple websites have + been manipulated because they displayed decoded hex strings that + included HTML `" - << "
" - << ""; + std::cout << "Created '" << filename << "'" << std::endl; } +} // namespace benchmark::BenchRunner::BenchmarkMap& benchmark::BenchRunner::benchmarks() { - static std::map benchmarks_map; + static std::map benchmarks_map; return benchmarks_map; } -benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func, uint64_t num_iters_for_one_second) +benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func) { - benchmarks().insert(std::make_pair(name, Bench{func, num_iters_for_one_second})); + benchmarks().insert(std::make_pair(name, func)); } -void benchmark::BenchRunner::RunAll(Printer& printer, uint64_t num_evals, double scaling, const std::string& filter, bool is_list_only) +void benchmark::BenchRunner::RunAll(const Args& args) { - if (!std::ratio_less_equal::value) { - std::cerr << "WARNING: Clock precision is worse than microsecond - benchmarks may be less accurate!\n"; - } -#ifdef DEBUG - std::cerr << "WARNING: This is a debug build - may result in slower benchmarks.\n"; -#endif - - std::regex reFilter(filter); + std::regex reFilter(args.regex_filter); std::smatch baseMatch; - printer.header(); - + std::vector benchmarkResults; for (const auto& p : benchmarks()) { if (!std::regex_match(p.first, baseMatch, reFilter)) { continue; } - uint64_t num_iters = static_cast(p.second.num_iters_for_one_second * scaling); - if (0 == num_iters) { - num_iters = 1; - } - State state(p.first, num_evals, num_iters, printer); - if (!is_list_only) { - p.second.func(state); + if (args.is_list_only) { + std::cout << p.first << std::endl; + continue; } - printer.result(state); - } - printer.footer(); -} - -bool benchmark::State::UpdateTimer(const benchmark::time_point current_time) -{ - if (m_start_time != time_point()) { - std::chrono::duration diff = current_time - m_start_time; - m_elapsed_results.push_back(diff.count() / m_num_iters); + Bench bench; + bench.name(p.first); + if (args.asymptote.empty()) { + p.second(bench); + } else { + for (auto n : args.asymptote) { + bench.complexityN(n); + p.second(bench); + } + std::cout << bench.complexityBigO() << std::endl; + } - if (m_elapsed_results.size() == m_num_evals) { - return false; + if (!bench.results().empty()) { + benchmarkResults.push_back(bench.results().back()); } } - m_num_iters_left = m_num_iters - 1; - return true; + GenerateTemplateResults(benchmarkResults, args.output_csv, "# Benchmark, evals, iterations, total, min, max, median\n" + "{{#result}}{{name}}, {{epochs}}, {{average(iterations)}}, {{sumProduct(iterations, elapsed)}}, {{minimum(elapsed)}}, {{maximum(elapsed)}}, {{median(elapsed)}}\n" + "{{/result}}"); + GenerateTemplateResults(benchmarkResults, args.output_json, ankerl::nanobench::templates::json()); } diff --git a/src/bench/bench.h b/src/bench/bench.h old mode 100755 new mode 100644 index c498077e..ec66dc9d --- a/src/bench/bench.h +++ b/src/bench/bench.h @@ -1,142 +1,63 @@ -// Copyright (c) 2015-2018 The Bitsend Core developers +// Copyright (c) 2015-2020 The BitSend Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITSEND_BENCH_BENCH_H #define BITSEND_BENCH_BENCH_H +#include #include -#include #include #include #include -#include +#include #include #include -// Simple micro-benchmarking framework; API mostly matches a subset of the Google Benchmark -// framework (see https://github.com/google/benchmark) -// Why not use the Google Benchmark framework? Because adding Yet Another Dependency -// (that uses cmake as its build system and has lots of features we don't need) isn't -// worth it. - /* * Usage: -static void CODE_TO_TIME(benchmark::State& state) +static void CODE_TO_TIME(benchmark::Bench& bench) { ... do any setup needed... - while (state.KeepRunning()) { + nanobench::Config().run([&] { ... do stuff you want to time... - } + }); ... do any cleanup needed... } -// default to running benchmark for 5000 iterations -BENCHMARK(CODE_TO_TIME, 5000); +BENCHMARK(CODE_TO_TIME); */ namespace benchmark { -// In case high_resolution_clock is steady, prefer that, otherwise use steady_clock. -struct best_clock { - using hi_res_clock = std::chrono::high_resolution_clock; - using steady_clock = std::chrono::steady_clock; - using type = std::conditional::type; -}; -using clock = best_clock::type; -using time_point = clock::time_point; -using duration = clock::duration; -class Printer; - -class State -{ -public: - std::string m_name; - uint64_t m_num_iters_left; - const uint64_t m_num_iters; - const uint64_t m_num_evals; - std::vector m_elapsed_results; - time_point m_start_time; +using ankerl::nanobench::Bench; - bool UpdateTimer(time_point finish_time); +typedef std::function BenchFunction; - State(std::string name, uint64_t num_evals, double num_iters, Printer& printer) : m_name(name), m_num_iters_left(0), m_num_iters(num_iters), m_num_evals(num_evals) - { - } - - inline bool KeepRunning() - { - if (m_num_iters_left--) { - return true; - } - - bool result = UpdateTimer(clock::now()); - // measure again so runtime of UpdateTimer is not included - m_start_time = clock::now(); - return result; - } +struct Args { + std::string regex_filter; + bool is_list_only; + std::vector asymptote; + std::string output_csv; + std::string output_json; }; -typedef std::function BenchFunction; - class BenchRunner { - struct Bench { - BenchFunction func; - uint64_t num_iters_for_one_second; - }; - typedef std::map BenchmarkMap; + typedef std::map BenchmarkMap; static BenchmarkMap& benchmarks(); public: - BenchRunner(std::string name, BenchFunction func, uint64_t num_iters_for_one_second); + BenchRunner(std::string name, BenchFunction func); - static void RunAll(Printer& printer, uint64_t num_evals, double scaling, const std::string& filter, bool is_list_only); -}; - -// interface to output benchmark results. -class Printer -{ -public: - virtual ~Printer() {} - virtual void header() = 0; - virtual void result(const State& state) = 0; - virtual void footer() = 0; -}; - -// default printer to console, shows min, max, median. -class ConsolePrinter : public Printer -{ -public: - void header() override; - void result(const State& state) override; - void footer() override; -}; - -// creates box plot with plotly.js -class PlotlyPrinter : public Printer -{ -public: - PlotlyPrinter(std::string plotly_url, int64_t width, int64_t height); - void header() override; - void result(const State& state) override; - void footer() override; - -private: - std::string m_plotly_url; - int64_t m_width; - int64_t m_height; + static void RunAll(const Args& args); }; } - - -// BENCHMARK(foo, num_iters_for_one_second) expands to: benchmark::BenchRunner bench_11foo("foo", num_iterations); -// Choose a num_iters_for_one_second that takes roughly 1 second. The goal is that all benchmarks should take approximately -// the same time, and scaling factor can be used that the total time is appropriate for your system. -#define BENCHMARK(n, num_iters_for_one_second) \ - benchmark::BenchRunner BOOST_PP_CAT(bench_, BOOST_PP_CAT(__LINE__, n))(BOOST_PP_STRINGIZE(n), n, (num_iters_for_one_second)); +// BENCHMARK(foo) expands to: benchmark::BenchRunner bench_11foo("foo"); +#define BENCHMARK(n) \ + benchmark::BenchRunner BOOST_PP_CAT(bench_, BOOST_PP_CAT(__LINE__, n))(BOOST_PP_STRINGIZE(n), n); #endif // BITSEND_BENCH_BENCH_H diff --git a/src/bench/bench_bitsend.cpp b/src/bench/bench_bitsend.cpp old mode 100755 new mode 100644 index 4391f09b..2a72a128 --- a/src/bench/bench_bitsend.cpp +++ b/src/bench/bench_bitsend.cpp @@ -1,99 +1,66 @@ -// Copyright (c) 2015-2018 The Bitsend Core developers +// Copyright (c) 2015-2020 The BitSend Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include -#include -#include -#include -#include -#include +#include +#include #include -static const int64_t DEFAULT_BENCH_EVALUATIONS = 5; static const char* DEFAULT_BENCH_FILTER = ".*"; -static const char* DEFAULT_BENCH_SCALING = "1.0"; -static const char* DEFAULT_BENCH_PRINTER = "console"; -static const char* DEFAULT_PLOT_PLOTLYURL = "https://cdn.plot.ly/plotly-latest.min.js"; -static const int64_t DEFAULT_PLOT_WIDTH = 1024; -static const int64_t DEFAULT_PLOT_HEIGHT = 768; -static void SetupBenchArgs() +static void SetupBenchArgs(ArgsManager& argsman) { - gArgs.AddArg("-?", "Print this help message and exit", false, OptionsCategory::OPTIONS); - gArgs.AddArg("-list", "List benchmarks without executing them. Can be combined with -scaling and -filter", false, OptionsCategory::OPTIONS); - gArgs.AddArg("-evals=", strprintf("Number of measurement evaluations to perform. (default: %u)", DEFAULT_BENCH_EVALUATIONS), false, OptionsCategory::OPTIONS); - gArgs.AddArg("-filter=", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), false, OptionsCategory::OPTIONS); - gArgs.AddArg("-scaling=", strprintf("Scaling factor for benchmark's runtime (default: %u)", DEFAULT_BENCH_SCALING), false, OptionsCategory::OPTIONS); - gArgs.AddArg("-printer=(console|plot)", strprintf("Choose printer format. console: print data to console. plot: Print results as HTML graph (default: %s)", DEFAULT_BENCH_PRINTER), false, OptionsCategory::OPTIONS); - gArgs.AddArg("-plot-plotlyurl=", strprintf("URL to use for plotly.js (default: %s)", DEFAULT_PLOT_PLOTLYURL), false, OptionsCategory::OPTIONS); - gArgs.AddArg("-plot-width=", strprintf("Plot width in pixel (default: %u)", DEFAULT_PLOT_WIDTH), false, OptionsCategory::OPTIONS); - gArgs.AddArg("-plot-height=", strprintf("Plot height in pixel (default: %u)", DEFAULT_PLOT_HEIGHT), false, OptionsCategory::OPTIONS); + SetupHelpOptions(argsman); - // Hidden - gArgs.AddArg("-h", "", false, OptionsCategory::HIDDEN); - gArgs.AddArg("-help", "", false, OptionsCategory::HIDDEN); + argsman.AddArg("-list", "List benchmarks without executing them", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-filter=", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-asymptote=n1,n2,n3,...", strprintf("Test asymptotic growth of the runtime of an algorithm, if supported by the benchmark"), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-output_csv=", "Generate CSV file with the most important benchmark results.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-output_json=", "Generate JSON file with all benchmark results.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); } -static fs::path SetDataDir() -{ - fs::path ret = fs::temp_directory_path() / "bench_bitsend" / fs::unique_path(); - fs::create_directories(ret); - gArgs.ForceSetArg("-datadir", ret.string()); - return ret; +// parses a comma separated list like "10,20,30,50" +static std::vector parseAsymptote(const std::string& str) { + std::stringstream ss(str); + std::vector numbers; + double d; + char c; + while (ss >> d) { + numbers.push_back(d); + ss >> c; + } + return numbers; } int main(int argc, char** argv) { - SetupBenchArgs(); + ArgsManager argsman; + SetupBenchArgs(argsman); + SHA256AutoDetect(); std::string error; - if (!gArgs.ParseParameters(argc, argv, error)) { - fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str()); + if (!argsman.ParseParameters(argc, argv, error)) { + tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error); return EXIT_FAILURE; } - if (HelpRequested(gArgs)) { - std::cout << gArgs.GetHelpMessage(); + if (HelpRequested(argsman)) { + std::cout << argsman.GetHelpMessage(); return EXIT_SUCCESS; } - // Set the datadir after parsing the bench options - const fs::path bench_datadir{SetDataDir()}; - - SHA256AutoDetect(); - RandomInit(); - ECC_Start(); - SetupEnvironment(); - - int64_t evaluations = gArgs.GetArg("-evals", DEFAULT_BENCH_EVALUATIONS); - std::string regex_filter = gArgs.GetArg("-filter", DEFAULT_BENCH_FILTER); - std::string scaling_str = gArgs.GetArg("-scaling", DEFAULT_BENCH_SCALING); - bool is_list_only = gArgs.GetBoolArg("-list", false); - - double scaling_factor; - if (!ParseDouble(scaling_str, &scaling_factor)) { - fprintf(stderr, "Error parsing scaling factor as double: %s\n", scaling_str.c_str()); - return EXIT_FAILURE; - } - - std::unique_ptr printer(new benchmark::ConsolePrinter()); - std::string printer_arg = gArgs.GetArg("-printer", DEFAULT_BENCH_PRINTER); - if ("plot" == printer_arg) { - printer.reset(new benchmark::PlotlyPrinter( - gArgs.GetArg("-plot-plotlyurl", DEFAULT_PLOT_PLOTLYURL), - gArgs.GetArg("-plot-width", DEFAULT_PLOT_WIDTH), - gArgs.GetArg("-plot-height", DEFAULT_PLOT_HEIGHT))); - } - - benchmark::BenchRunner::RunAll(*printer, evaluations, scaling_factor, regex_filter, is_list_only); - - fs::remove_all(bench_datadir); + benchmark::Args args; + args.regex_filter = argsman.GetArg("-filter", DEFAULT_BENCH_FILTER); + args.is_list_only = argsman.GetBoolArg("-list", false); + args.asymptote = parseAsymptote(argsman.GetArg("-asymptote", "")); + args.output_csv = argsman.GetArg("-output_csv", ""); + args.output_json = argsman.GetArg("-output_json", ""); - ECC_Stop(); + benchmark::BenchRunner::RunAll(args); return EXIT_SUCCESS; } diff --git a/src/bench/block_assemble.cpp b/src/bench/block_assemble.cpp old mode 100755 new mode 100644 index 407ae018..cf8508f4 --- a/src/bench/block_assemble.cpp +++ b/src/bench/block_assemble.cpp @@ -1,58 +1,29 @@ -// Copyright (c) 2011-2018 The Bitsend Core developers +// Copyright (c) 2011-2019 The BitSend Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -#include -#include -#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include #include -#include -#include -#include #include -static std::shared_ptr PrepareBlock(const CScript& coinbase_scriptPubKey) +static void AssembleBlock(benchmark::Bench& bench) { - auto block = std::make_shared( - BlockAssembler{Params()} - .CreateNewBlock(coinbase_scriptPubKey, /* fMineWitnessTx */ true) - ->block); + TestingSetup test_setup{ + CBaseChainParams::REGTEST, + /* extra_args */ { + "-nodebuglogfile", + "-nodebug", + }, + }; - block->nTime = ::chainActive.Tip()->GetMedianTimePast() + 1; - block->hashMerkleRoot = BlockMerkleRoot(*block); - - return block; -} - - -static CTxIn MineBlock(const CScript& coinbase_scriptPubKey) -{ - auto block = PrepareBlock(coinbase_scriptPubKey); - - while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) { - assert(++block->nNonce); - } - - bool processed{ProcessNewBlock(Params(), block, true, nullptr)}; - assert(processed); - - return CTxIn{block->vtx[0]->GetHash(), 0}; -} - - -static void AssembleBlock(benchmark::State& state) -{ const std::vector op_true{OP_TRUE}; CScriptWitness witness; witness.stack.push_back(op_true); @@ -62,36 +33,12 @@ static void AssembleBlock(benchmark::State& state) const CScript SCRIPT_PUB{CScript(OP_0) << std::vector{witness_program.begin(), witness_program.end()}}; - // Switch to regtest so we can mine faster - // Also segwit is active, so we can include witness transactions - SelectParams(CBaseChainParams::REGTEST); - - InitScriptExecutionCache(); - - boost::thread_group thread_group; - CScheduler scheduler; - { - ::pblocktree.reset(new CBlockTreeDB(1 << 20, true)); - ::pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true)); - ::pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get())); - - const CChainParams& chainparams = Params(); - thread_group.create_thread(boost::bind(&CScheduler::serviceQueue, &scheduler)); - GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); - LoadGenesisBlock(chainparams); - CValidationState state; - ActivateBestChain(state, chainparams); - assert(::chainActive.Tip() != nullptr); - const bool witness_enabled{IsWitnessEnabled(::chainActive.Tip(), chainparams.GetConsensus())}; - assert(witness_enabled); - } - // Collect some loose transactions that spend the coinbases of our mined blocks - constexpr size_t NUM_BLOCKS{290}; + constexpr size_t NUM_BLOCKS{200}; std::array txs; for (size_t b{0}; b < NUM_BLOCKS; ++b) { CMutableTransaction tx; - tx.vin.push_back(MineBlock(SCRIPT_PUB)); + tx.vin.push_back(MineBlock(test_setup.m_node, SCRIPT_PUB)); tx.vin.back().scriptWitness = witness; tx.vout.emplace_back(1337, SCRIPT_PUB); if (NUM_BLOCKS - b >= COINBASE_MATURITY) @@ -101,20 +48,15 @@ static void AssembleBlock(benchmark::State& state) LOCK(::cs_main); // Required for ::AcceptToMemoryPool. for (const auto& txr : txs) { - CValidationState state; - bool ret{::AcceptToMemoryPool(::mempool, state, txr, nullptr /* pfMissingInputs */, nullptr /* plTxnReplaced */, false /* bypass_limits */, /* nAbsurdFee */ 0)}; + TxValidationState state; + bool ret{::AcceptToMemoryPool(*test_setup.m_node.mempool, state, txr, nullptr /* plTxnReplaced */, false /* bypass_limits */)}; assert(ret); } } - while (state.KeepRunning()) { - PrepareBlock(SCRIPT_PUB); - } - - thread_group.interrupt_all(); - thread_group.join_all(); - GetMainSignals().FlushBackgroundCallbacks(); - GetMainSignals().UnregisterBackgroundSignalScheduler(); + bench.run([&] { + PrepareBlock(test_setup.m_node, SCRIPT_PUB); + }); } -BENCHMARK(AssembleBlock, 700); +BENCHMARK(AssembleBlock); diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp old mode 100755 new mode 100644 index 0eab1ac5..3f1b7cdd --- a/src/bench/ccoins_caching.cpp +++ b/src/bench/ccoins_caching.cpp @@ -1,64 +1,31 @@ -// Copyright (c) 2016-2018 The Bitsend Core developers +// Copyright (c) 2016-2020 The BitSend Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include -#include +#include + + + +
+ + + +)DELIM"; +} + +char const* json() noexcept { + return R"DELIM({ + "results": [ +{{#result}} { + "title": "{{title}}", + "name": "{{name}}", + "unit": "{{unit}}", + "batch": {{batch}}, + "complexityN": {{complexityN}}, + "epochs": {{epochs}}, + "clockResolution": {{clockResolution}}, + "clockResolutionMultiple": {{clockResolutionMultiple}}, + "maxEpochTime": {{maxEpochTime}}, + "minEpochTime": {{minEpochTime}}, + "minEpochIterations": {{minEpochIterations}}, + "epochIterations": {{epochIterations}}, + "warmup": {{warmup}}, + "relative": {{relative}}, + "median(elapsed)": {{median(elapsed)}}, + "medianAbsolutePercentError(elapsed)": {{medianAbsolutePercentError(elapsed)}}, + "median(instructions)": {{median(instructions)}}, + "medianAbsolutePercentError(instructions)": {{medianAbsolutePercentError(instructions)}}, + "median(cpucycles)": {{median(cpucycles)}}, + "median(contextswitches)": {{median(contextswitches)}}, + "median(pagefaults)": {{median(pagefaults)}}, + "median(branchinstructions)": {{median(branchinstructions)}}, + "median(branchmisses)": {{median(branchmisses)}}, + "totalTime": {{sumProduct(iterations, elapsed)}}, + "measurements": [ +{{#measurement}} { + "iterations": {{iterations}}, + "elapsed": {{elapsed}}, + "pagefaults": {{pagefaults}}, + "cpucycles": {{cpucycles}}, + "contextswitches": {{contextswitches}}, + "instructions": {{instructions}}, + "branchinstructions": {{branchinstructions}}, + "branchmisses": {{branchmisses}} + }{{^-last}},{{/-last}} +{{/measurement}} ] + }{{^-last}},{{/-last}} +{{/result}} ] +})DELIM"; +} + +ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) +struct Node { + enum class Type { tag, content, section, inverted_section }; + + char const* begin; + char const* end; + std::vector children; + Type type; + + template + // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) + bool operator==(char const (&str)[N]) const noexcept { + return static_cast(std::distance(begin, end) + 1) == N && 0 == strncmp(str, begin, N - 1); + } +}; +ANKERL_NANOBENCH(IGNORE_PADDED_POP) + +static std::vector parseMustacheTemplate(char const** tpl) { + std::vector nodes; + + while (true) { + auto begin = std::strstr(*tpl, "{{"); + auto end = begin; + if (begin != nullptr) { + begin += 2; + end = std::strstr(begin, "}}"); + } + + if (begin == nullptr || end == nullptr) { + // nothing found, finish node + nodes.emplace_back(Node{*tpl, *tpl + std::strlen(*tpl), std::vector{}, Node::Type::content}); + return nodes; + } + + nodes.emplace_back(Node{*tpl, begin - 2, std::vector{}, Node::Type::content}); + + // we found a tag + *tpl = end + 2; + switch (*begin) { + case '/': + // finished! bail out + return nodes; + + case '#': + nodes.emplace_back(Node{begin + 1, end, parseMustacheTemplate(tpl), Node::Type::section}); + break; + + case '^': + nodes.emplace_back(Node{begin + 1, end, parseMustacheTemplate(tpl), Node::Type::inverted_section}); + break; + + default: + nodes.emplace_back(Node{begin, end, std::vector{}, Node::Type::tag}); + break; + } + } +} + +static bool generateFirstLast(Node const& n, size_t idx, size_t size, std::ostream& out) { + bool matchFirst = n == "-first"; + bool matchLast = n == "-last"; + if (!matchFirst && !matchLast) { + return false; + } + + bool doWrite = false; + if (n.type == Node::Type::section) { + doWrite = (matchFirst && idx == 0) || (matchLast && idx == size - 1); + } else if (n.type == Node::Type::inverted_section) { + doWrite = (matchFirst && idx != 0) || (matchLast && idx != size - 1); + } + + if (doWrite) { + for (auto const& child : n.children) { + if (child.type == Node::Type::content) { + out.write(child.begin, std::distance(child.begin, child.end)); + } + } + } + return true; +} + +static bool matchCmdArgs(std::string const& str, std::vector& matchResult) { + matchResult.clear(); + auto idxOpen = str.find('('); + auto idxClose = str.find(')', idxOpen); + if (idxClose == std::string::npos) { + return false; + } + + matchResult.emplace_back(str.substr(0, idxOpen)); + + // split by comma + matchResult.emplace_back(std::string{}); + for (size_t i = idxOpen + 1; i != idxClose; ++i) { + if (str[i] == ' ' || str[i] == '\t') { + // skip whitespace + continue; + } + if (str[i] == ',') { + // got a comma => new string + matchResult.emplace_back(std::string{}); + continue; + } + // no whitespace no comma, append + matchResult.back() += str[i]; + } + return true; +} + +static bool generateConfigTag(Node const& n, Config const& config, std::ostream& out) { + using detail::d; + + if (n == "title") { + out << config.mBenchmarkTitle; + return true; + } else if (n == "name") { + out << config.mBenchmarkName; + return true; + } else if (n == "unit") { + out << config.mUnit; + return true; + } else if (n == "batch") { + out << config.mBatch; + return true; + } else if (n == "complexityN") { + out << config.mComplexityN; + return true; + } else if (n == "epochs") { + out << config.mNumEpochs; + return true; + } else if (n == "clockResolution") { + out << d(detail::clockResolution()); + return true; + } else if (n == "clockResolutionMultiple") { + out << config.mClockResolutionMultiple; + return true; + } else if (n == "maxEpochTime") { + out << d(config.mMaxEpochTime); + return true; + } else if (n == "minEpochTime") { + out << d(config.mMinEpochTime); + return true; + } else if (n == "minEpochIterations") { + out << config.mMinEpochIterations; + return true; + } else if (n == "epochIterations") { + out << config.mEpochIterations; + return true; + } else if (n == "warmup") { + out << config.mWarmup; + return true; + } else if (n == "relative") { + out << config.mIsRelative; + return true; + } + return false; +} + +static std::ostream& generateResultTag(Node const& n, Result const& r, std::ostream& out) { + if (generateConfigTag(n, r.config(), out)) { + return out; + } + // match e.g. "median(elapsed)" + // g++ 4.8 doesn't implement std::regex :( + // static std::regex const regOpArg1("^([a-zA-Z]+)\\(([a-zA-Z]*)\\)$"); + // std::cmatch matchResult; + // if (std::regex_match(n.begin, n.end, matchResult, regOpArg1)) { + std::vector matchResult; + if (matchCmdArgs(std::string(n.begin, n.end), matchResult)) { + if (matchResult.size() == 2) { + auto m = Result::fromString(matchResult[1]); + if (m == Result::Measure::_size) { + return out << 0.0; + } + + if (matchResult[0] == "median") { + return out << r.median(m); + } + if (matchResult[0] == "average") { + return out << r.average(m); + } + if (matchResult[0] == "medianAbsolutePercentError") { + return out << r.medianAbsolutePercentError(m); + } + if (matchResult[0] == "sum") { + return out << r.sum(m); + } + if (matchResult[0] == "minimum") { + return out << r.minimum(m); + } + if (matchResult[0] == "maximum") { + return out << r.maximum(m); + } + } else if (matchResult.size() == 3) { + auto m1 = Result::fromString(matchResult[1]); + auto m2 = Result::fromString(matchResult[2]); + if (m1 == Result::Measure::_size || m2 == Result::Measure::_size) { + return out << 0.0; + } + + if (matchResult[0] == "sumProduct") { + return out << r.sumProduct(m1, m2); + } + } + } + + // match e.g. "sumProduct(elapsed, iterations)" + // static std::regex const regOpArg2("^([a-zA-Z]+)\\(([a-zA-Z]*)\\s*,\\s+([a-zA-Z]*)\\)$"); + + // nothing matches :( + throw std::runtime_error("command '" + std::string(n.begin, n.end) + "' not understood"); +} + +static void generateResultMeasurement(std::vector const& nodes, size_t idx, Result const& r, std::ostream& out) { + for (auto const& n : nodes) { + if (!generateFirstLast(n, idx, r.size(), out)) { + ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); + switch (n.type) { + case Node::Type::content: + out.write(n.begin, std::distance(n.begin, n.end)); + break; + + case Node::Type::inverted_section: + throw std::runtime_error("got a inverted section inside measurement"); + + case Node::Type::section: + throw std::runtime_error("got a section inside measurement"); + + case Node::Type::tag: { + auto m = Result::fromString(std::string(n.begin, n.end)); + if (m == Result::Measure::_size || !r.has(m)) { + out << 0.0; + } else { + out << r.get(idx, m); + } + break; + } + } + } + } +} + +static void generateResult(std::vector const& nodes, size_t idx, std::vector const& results, std::ostream& out) { + auto const& r = results[idx]; + for (auto const& n : nodes) { + if (!generateFirstLast(n, idx, results.size(), out)) { + ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); + switch (n.type) { + case Node::Type::content: + out.write(n.begin, std::distance(n.begin, n.end)); + break; + + case Node::Type::inverted_section: + throw std::runtime_error("got a inverted section inside result"); + + case Node::Type::section: + if (n == "measurement") { + for (size_t i = 0; i < r.size(); ++i) { + generateResultMeasurement(n.children, i, r, out); + } + } else { + throw std::runtime_error("got a section inside result"); + } + break; + + case Node::Type::tag: + generateResultTag(n, r, out); + break; + } + } + } +} + +} // namespace templates + +// helper stuff that only intended to be used internally +namespace detail { + +char const* getEnv(char const* name); +bool isEndlessRunning(std::string const& name); + +template +T parseFile(std::string const& filename); + +void gatherStabilityInformation(std::vector& warnings, std::vector& recommendations); +void printStabilityInformationOnce(std::ostream* os); + +// remembers the last table settings used. When it changes, a new table header is automatically written for the new entry. +uint64_t& singletonHeaderHash() noexcept; + +// determines resolution of the given clock. This is done by measuring multiple times and returning the minimum time difference. +Clock::duration calcClockResolution(size_t numEvaluations) noexcept; + +// formatting utilities +namespace fmt { + +// adds thousands separator to numbers +ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) +class NumSep : public std::numpunct { +public: + explicit NumSep(char sep); + char do_thousands_sep() const override; + std::string do_grouping() const override; + +private: + char mSep; +}; +ANKERL_NANOBENCH(IGNORE_PADDED_POP) + +// RAII to save & restore a stream's state +ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) +class StreamStateRestorer { +public: + explicit StreamStateRestorer(std::ostream& s); + ~StreamStateRestorer(); + + // sets back all stream info that we remembered at construction + void restore(); + + // don't allow copying / moving + StreamStateRestorer(StreamStateRestorer const&) = delete; + StreamStateRestorer& operator=(StreamStateRestorer const&) = delete; + StreamStateRestorer(StreamStateRestorer&&) = delete; + StreamStateRestorer& operator=(StreamStateRestorer&&) = delete; + +private: + std::ostream& mStream; + std::locale mLocale; + std::streamsize const mPrecision; + std::streamsize const mWidth; + std::ostream::char_type const mFill; + std::ostream::fmtflags const mFmtFlags; +}; +ANKERL_NANOBENCH(IGNORE_PADDED_POP) + +// Number formatter +class Number { +public: + Number(int width, int precision, double value); + Number(int width, int precision, int64_t value); + std::string to_s() const; + +private: + friend std::ostream& operator<<(std::ostream& os, Number const& n); + std::ostream& write(std::ostream& os) const; + + int mWidth; + int mPrecision; + double mValue; +}; + +// helper replacement for std::to_string of signed/unsigned numbers so we are locale independent +std::string to_s(uint64_t s); + +std::ostream& operator<<(std::ostream& os, Number const& n); + +class MarkDownColumn { +public: + MarkDownColumn(int w, int prec, std::string const& tit, std::string const& suff, double val); + std::string title() const; + std::string separator() const; + std::string invalid() const; + std::string value() const; + +private: + int mWidth; + int mPrecision; + std::string mTitle; + std::string mSuffix; + double mValue; +}; + +// Formats any text as markdown code, escaping backticks. +class MarkDownCode { +public: + explicit MarkDownCode(std::string const& what); + +private: + friend std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode); + std::ostream& write(std::ostream& os) const; + + std::string mWhat{}; +}; + +std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode); + +} // namespace fmt +} // namespace detail +} // namespace nanobench +} // namespace ankerl + +// implementation ///////////////////////////////////////////////////////////////////////////////// + +namespace ankerl { +namespace nanobench { + +void render(char const* mustacheTemplate, std::vector const& results, std::ostream& out) { + detail::fmt::StreamStateRestorer restorer(out); + + out.precision(std::numeric_limits::digits10); + auto nodes = templates::parseMustacheTemplate(&mustacheTemplate); + + for (auto const& n : nodes) { + ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); + switch (n.type) { + case templates::Node::Type::content: + out.write(n.begin, std::distance(n.begin, n.end)); + break; + + case templates::Node::Type::inverted_section: + throw std::runtime_error("unknown list '" + std::string(n.begin, n.end) + "'"); + + case templates::Node::Type::section: + if (n == "result") { + const size_t nbResults = results.size(); + for (size_t i = 0; i < nbResults; ++i) { + generateResult(n.children, i, results, out); + } + } else { + throw std::runtime_error("unknown section '" + std::string(n.begin, n.end) + "'"); + } + break; + + case templates::Node::Type::tag: + // This just uses the last result's config. + if (!generateConfigTag(n, results.back().config(), out)) { + throw std::runtime_error("unknown tag '" + std::string(n.begin, n.end) + "'"); + } + break; + } + } +} + +void render(char const* mustacheTemplate, const Bench& bench, std::ostream& out) { + render(mustacheTemplate, bench.results(), out); +} + +namespace detail { + +PerformanceCounters& performanceCounters() { +# if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +# endif + static PerformanceCounters pc; +# if defined(__clang__) +# pragma clang diagnostic pop +# endif + return pc; +} + +// Windows version of doNotOptimizeAway +// see https://github.com/google/benchmark/blob/master/include/benchmark/benchmark.h#L307 +// see https://github.com/facebook/folly/blob/master/folly/Benchmark.h#L280 +// see https://docs.microsoft.com/en-us/cpp/preprocessor/optimize +# if defined(_MSC_VER) +# pragma optimize("", off) +void doNotOptimizeAwaySink(void const*) {} +# pragma optimize("", on) +# endif + +template +T parseFile(std::string const& filename) { + std::ifstream fin(filename); + T num{}; + fin >> num; + return num; +} + +char const* getEnv(char const* name) { +# if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable : 4996) // getenv': This function or variable may be unsafe. +# endif + return std::getenv(name); +# if defined(_MSC_VER) +# pragma warning(pop) +# endif +} + +bool isEndlessRunning(std::string const& name) { + auto endless = getEnv("NANOBENCH_ENDLESS"); + return nullptr != endless && endless == name; +} + +void gatherStabilityInformation(std::vector& warnings, std::vector& recommendations) { + warnings.clear(); + recommendations.clear(); + + bool recommendCheckFlags = false; + +# if defined(DEBUG) + warnings.emplace_back("DEBUG defined"); + recommendCheckFlags = true; +# endif + + bool recommendPyPerf = false; +# if defined(__linux__) + auto nprocs = sysconf(_SC_NPROCESSORS_CONF); + if (nprocs <= 0) { + warnings.emplace_back("couldn't figure out number of processors - no governor, turbo check possible"); + } else { + + // check frequency scaling + for (long id = 0; id < nprocs; ++id) { + auto idStr = detail::fmt::to_s(static_cast(id)); + auto sysCpu = "/sys/devices/system/cpu/cpu" + idStr; + auto minFreq = parseFile(sysCpu + "/cpufreq/scaling_min_freq"); + auto maxFreq = parseFile(sysCpu + "/cpufreq/scaling_max_freq"); + if (minFreq != maxFreq) { + auto minMHz = static_cast(minFreq) / 1000.0; + auto maxMHz = static_cast(maxFreq) / 1000.0; + warnings.emplace_back("CPU frequency scaling enabled: CPU " + idStr + " between " + + detail::fmt::Number(1, 1, minMHz).to_s() + " and " + detail::fmt::Number(1, 1, maxMHz).to_s() + + " MHz"); + recommendPyPerf = true; + break; + } + } + + auto currentGovernor = parseFile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"); + if ("performance" != currentGovernor) { + warnings.emplace_back("CPU governor is '" + currentGovernor + "' but should be 'performance'"); + recommendPyPerf = true; + } + + if (0 == parseFile("/sys/devices/system/cpu/intel_pstate/no_turbo")) { + warnings.emplace_back("Turbo is enabled, CPU frequency will fluctuate"); + recommendPyPerf = true; + } + } +# endif + + if (recommendCheckFlags) { + recommendations.emplace_back("Make sure you compile for Release"); + } + if (recommendPyPerf) { + recommendations.emplace_back("Use 'pyperf system tune' before benchmarking. See https://github.com/vstinner/pyperf"); + } +} + +void printStabilityInformationOnce(std::ostream* outStream) { + static bool shouldPrint = true; + if (shouldPrint && outStream) { + auto& os = *outStream; + shouldPrint = false; + std::vector warnings; + std::vector recommendations; + gatherStabilityInformation(warnings, recommendations); + if (warnings.empty()) { + return; + } + + os << "Warning, results might be unstable:" << std::endl; + for (auto const& w : warnings) { + os << "* " << w << std::endl; + } + + os << std::endl << "Recommendations" << std::endl; + for (auto const& r : recommendations) { + os << "* " << r << std::endl; + } + } +} + +// remembers the last table settings used. When it changes, a new table header is automatically written for the new entry. +uint64_t& singletonHeaderHash() noexcept { + static uint64_t sHeaderHash{}; + return sHeaderHash; +} + +ANKERL_NANOBENCH_NO_SANITIZE("integer") +inline uint64_t fnv1a(std::string const& str) noexcept { + auto val = UINT64_C(14695981039346656037); + for (auto c : str) { + val = (val ^ static_cast(c)) * UINT64_C(1099511628211); + } + return val; +} + +ANKERL_NANOBENCH_NO_SANITIZE("integer") +inline uint64_t hash_combine(uint64_t seed, uint64_t val) { + return seed ^ (val + UINT64_C(0x9e3779b9) + (seed << 6U) + (seed >> 2U)); +} + +// determines resolution of the given clock. This is done by measuring multiple times and returning the minimum time difference. +Clock::duration calcClockResolution(size_t numEvaluations) noexcept { + auto bestDuration = Clock::duration::max(); + Clock::time_point tBegin; + Clock::time_point tEnd; + for (size_t i = 0; i < numEvaluations; ++i) { + tBegin = Clock::now(); + do { + tEnd = Clock::now(); + } while (tBegin == tEnd); + bestDuration = (std::min)(bestDuration, tEnd - tBegin); + } + return bestDuration; +} + +// Calculates clock resolution once, and remembers the result +Clock::duration clockResolution() noexcept { + static Clock::duration sResolution = calcClockResolution(20); + return sResolution; +} + +ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) +struct IterationLogic::Impl { + enum class State { warmup, upscaling_runtime, measuring, endless }; + + explicit Impl(Bench const& bench) + : mBench(bench) + , mResult(bench.config()) { + printStabilityInformationOnce(mBench.output()); + + // determine target runtime per epoch + mTargetRuntimePerEpoch = detail::clockResolution() * mBench.clockResolutionMultiple(); + if (mTargetRuntimePerEpoch > mBench.maxEpochTime()) { + mTargetRuntimePerEpoch = mBench.maxEpochTime(); + } + if (mTargetRuntimePerEpoch < mBench.minEpochTime()) { + mTargetRuntimePerEpoch = mBench.minEpochTime(); + } + + if (isEndlessRunning(mBench.name())) { + std::cerr << "NANOBENCH_ENDLESS set: running '" << mBench.name() << "' endlessly" << std::endl; + mNumIters = (std::numeric_limits::max)(); + mState = State::endless; + } else if (0 != mBench.warmup()) { + mNumIters = mBench.warmup(); + mState = State::warmup; + } else if (0 != mBench.epochIterations()) { + // exact number of iterations + mNumIters = mBench.epochIterations(); + mState = State::measuring; + } else { + mNumIters = mBench.minEpochIterations(); + mState = State::upscaling_runtime; + } + } + + // directly calculates new iters based on elapsed&iters, and adds a 10% noise. Makes sure we don't underflow. + ANKERL_NANOBENCH(NODISCARD) uint64_t calcBestNumIters(std::chrono::nanoseconds elapsed, uint64_t iters) noexcept { + auto doubleElapsed = d(elapsed); + auto doubleTargetRuntimePerEpoch = d(mTargetRuntimePerEpoch); + auto doubleNewIters = doubleTargetRuntimePerEpoch / doubleElapsed * d(iters); + + auto doubleMinEpochIters = d(mBench.minEpochIterations()); + if (doubleNewIters < doubleMinEpochIters) { + doubleNewIters = doubleMinEpochIters; + } + doubleNewIters *= 1.0 + 0.2 * mRng.uniform01(); + + // +0.5 for correct rounding when casting + // NOLINTNEXTLINE(bugprone-incorrect-roundings) + return static_cast(doubleNewIters + 0.5); + } + + ANKERL_NANOBENCH_NO_SANITIZE("integer") void upscale(std::chrono::nanoseconds elapsed) { + if (elapsed * 10 < mTargetRuntimePerEpoch) { + // we are far below the target runtime. Multiply iterations by 10 (with overflow check) + if (mNumIters * 10 < mNumIters) { + // overflow :-( + showResult("iterations overflow. Maybe your code got optimized away?"); + mNumIters = 0; + return; + } + mNumIters *= 10; + } else { + mNumIters = calcBestNumIters(elapsed, mNumIters); + } + } + + void add(std::chrono::nanoseconds elapsed, PerformanceCounters const& pc) noexcept { +# if defined(ANKERL_NANOBENCH_LOG_ENABLED) + auto oldIters = mNumIters; +# endif + + switch (mState) { + case State::warmup: + if (isCloseEnoughForMeasurements(elapsed)) { + // if elapsed is close enough, we can skip upscaling and go right to measurements + // still, we don't add the result to the measurements. + mState = State::measuring; + mNumIters = calcBestNumIters(elapsed, mNumIters); + } else { + // not close enough: switch to upscaling + mState = State::upscaling_runtime; + upscale(elapsed); + } + break; + + case State::upscaling_runtime: + if (isCloseEnoughForMeasurements(elapsed)) { + // if we are close enough, add measurement and switch to always measuring + mState = State::measuring; + mTotalElapsed += elapsed; + mTotalNumIters += mNumIters; + mResult.add(elapsed, mNumIters, pc); + mNumIters = calcBestNumIters(mTotalElapsed, mTotalNumIters); + } else { + upscale(elapsed); + } + break; + + case State::measuring: + // just add measurements - no questions asked. Even when runtime is low. But we can't ignore + // that fluctuation, or else we would bias the result + mTotalElapsed += elapsed; + mTotalNumIters += mNumIters; + mResult.add(elapsed, mNumIters, pc); + if (0 != mBench.epochIterations()) { + mNumIters = mBench.epochIterations(); + } else { + mNumIters = calcBestNumIters(mTotalElapsed, mTotalNumIters); + } + break; + + case State::endless: + mNumIters = (std::numeric_limits::max)(); + break; + } + + if (static_cast(mResult.size()) == mBench.epochs()) { + // we got all the results that we need, finish it + showResult(""); + mNumIters = 0; + } + + ANKERL_NANOBENCH_LOG(mBench.name() << ": " << detail::fmt::Number(20, 3, static_cast(elapsed.count())) << " elapsed, " + << detail::fmt::Number(20, 3, static_cast(mTargetRuntimePerEpoch.count())) + << " target. oldIters=" << oldIters << ", mNumIters=" << mNumIters + << ", mState=" << static_cast(mState)); + } + + void showResult(std::string const& errorMessage) const { + ANKERL_NANOBENCH_LOG(errorMessage); + + if (mBench.output() != nullptr) { + // prepare column data /////// + std::vector columns; + + auto rMedian = mResult.median(Result::Measure::elapsed); + + if (mBench.relative()) { + double d = 100.0; + if (!mBench.results().empty()) { + d = rMedian <= 0.0 ? 0.0 : mBench.results().front().median(Result::Measure::elapsed) / rMedian * 100.0; + } + columns.emplace_back(11, 1, "relative", "%", d); + } + + if (mBench.complexityN() > 0) { + columns.emplace_back(14, 0, "complexityN", "", mBench.complexityN()); + } + + columns.emplace_back(22, 2, "ns/" + mBench.unit(), "", 1e9 * rMedian / mBench.batch()); + columns.emplace_back(22, 2, mBench.unit() + "/s", "", rMedian <= 0.0 ? 0.0 : mBench.batch() / rMedian); + + double rErrorMedian = mResult.medianAbsolutePercentError(Result::Measure::elapsed); + columns.emplace_back(10, 1, "err%", "%", rErrorMedian * 100.0); + + double rInsMedian = -1.0; + if (mResult.has(Result::Measure::instructions)) { + rInsMedian = mResult.median(Result::Measure::instructions); + columns.emplace_back(18, 2, "ins/" + mBench.unit(), "", rInsMedian / mBench.batch()); + } + + double rCycMedian = -1.0; + if (mResult.has(Result::Measure::cpucycles)) { + rCycMedian = mResult.median(Result::Measure::cpucycles); + columns.emplace_back(18, 2, "cyc/" + mBench.unit(), "", rCycMedian / mBench.batch()); + } + if (rInsMedian > 0.0 && rCycMedian > 0.0) { + columns.emplace_back(9, 3, "IPC", "", rCycMedian <= 0.0 ? 0.0 : rInsMedian / rCycMedian); + } + if (mResult.has(Result::Measure::branchinstructions)) { + double rBraMedian = mResult.median(Result::Measure::branchinstructions); + columns.emplace_back(17, 2, "bra/" + mBench.unit(), "", rBraMedian / mBench.batch()); + if (mResult.has(Result::Measure::branchmisses)) { + double p = 0.0; + if (rBraMedian >= 1e-9) { + p = 100.0 * mResult.median(Result::Measure::branchmisses) / rBraMedian; + } + columns.emplace_back(10, 1, "miss%", "%", p); + } + } + + columns.emplace_back(12, 2, "total", "", mResult.sum(Result::Measure::elapsed)); + + // write everything + auto& os = *mBench.output(); + + uint64_t hash = 0; + hash = hash_combine(fnv1a(mBench.unit()), hash); + hash = hash_combine(fnv1a(mBench.title()), hash); + hash = hash_combine(mBench.relative(), hash); + hash = hash_combine(mBench.performanceCounters(), hash); + + if (hash != singletonHeaderHash()) { + singletonHeaderHash() = hash; + + // no result yet, print header + os << std::endl; + for (auto const& col : columns) { + os << col.title(); + } + os << "| " << mBench.title() << std::endl; + + for (auto const& col : columns) { + os << col.separator(); + } + os << "|:" << std::string(mBench.title().size() + 1U, '-') << std::endl; + } + + if (!errorMessage.empty()) { + for (auto const& col : columns) { + os << col.invalid(); + } + os << "| :boom: " << fmt::MarkDownCode(mBench.name()) << " (" << errorMessage << ')' << std::endl; + } else { + for (auto const& col : columns) { + os << col.value(); + } + os << "| "; + auto showUnstable = rErrorMedian >= 0.05; + if (showUnstable) { + os << ":wavy_dash: "; + } + os << fmt::MarkDownCode(mBench.name()); + if (showUnstable) { + auto avgIters = static_cast(mTotalNumIters) / static_cast(mBench.epochs()); + // NOLINTNEXTLINE(bugprone-incorrect-roundings) + auto suggestedIters = static_cast(avgIters * 10 + 0.5); + + os << " (Unstable with ~" << detail::fmt::Number(1, 1, avgIters) + << " iters. Increase `minEpochIterations` to e.g. " << suggestedIters << ")"; + } + os << std::endl; + } + } + } + + ANKERL_NANOBENCH(NODISCARD) bool isCloseEnoughForMeasurements(std::chrono::nanoseconds elapsed) const noexcept { + return elapsed * 3 >= mTargetRuntimePerEpoch * 2; + } + + uint64_t mNumIters = 1; + Bench const& mBench; + std::chrono::nanoseconds mTargetRuntimePerEpoch{}; + Result mResult; + Rng mRng{123}; + std::chrono::nanoseconds mTotalElapsed{}; + uint64_t mTotalNumIters = 0; + + State mState = State::upscaling_runtime; +}; +ANKERL_NANOBENCH(IGNORE_PADDED_POP) + +IterationLogic::IterationLogic(Bench const& bench) noexcept + : mPimpl(new Impl(bench)) {} + +IterationLogic::~IterationLogic() { + if (mPimpl) { + delete mPimpl; + } +} + +uint64_t IterationLogic::numIters() const noexcept { + ANKERL_NANOBENCH_LOG(mPimpl->mBench.name() << ": mNumIters=" << mPimpl->mNumIters); + return mPimpl->mNumIters; +} + +void IterationLogic::add(std::chrono::nanoseconds elapsed, PerformanceCounters const& pc) noexcept { + mPimpl->add(elapsed, pc); +} + +void IterationLogic::moveResultTo(std::vector& results) noexcept { + results.emplace_back(std::move(mPimpl->mResult)); +} + +# if ANKERL_NANOBENCH(PERF_COUNTERS) + +ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) +class LinuxPerformanceCounters { +public: + struct Target { + Target(uint64_t* targetValue_, bool correctMeasuringOverhead_, bool correctLoopOverhead_) + : targetValue(targetValue_) + , correctMeasuringOverhead(correctMeasuringOverhead_) + , correctLoopOverhead(correctLoopOverhead_) {} + + uint64_t* targetValue{}; + bool correctMeasuringOverhead{}; + bool correctLoopOverhead{}; + }; + + ~LinuxPerformanceCounters(); + + // quick operation + inline void start() {} + + inline void stop() {} + + bool monitor(perf_sw_ids swId, Target target); + bool monitor(perf_hw_id hwId, Target target); + + bool hasError() const noexcept { + return mHasError; + } + + // Just reading data is faster than enable & disabling. + // we subtract data ourselves. + inline void beginMeasure() { + if (mHasError) { + return; + } + + // NOLINTNEXTLINE(hicpp-signed-bitwise) + mHasError = -1 == ioctl(mFd, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP); + if (mHasError) { + return; + } + + // NOLINTNEXTLINE(hicpp-signed-bitwise) + mHasError = -1 == ioctl(mFd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP); + } + + inline void endMeasure() { + if (mHasError) { + return; + } + + // NOLINTNEXTLINE(hicpp-signed-bitwise) + mHasError = (-1 == ioctl(mFd, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP)); + if (mHasError) { + return; + } + + auto const numBytes = sizeof(uint64_t) * mCounters.size(); + auto ret = read(mFd, mCounters.data(), numBytes); + mHasError = ret != static_cast(numBytes); + } + + void updateResults(uint64_t numIters); + + // rounded integer division + template + static inline T divRounded(T a, T divisor) { + return (a + divisor / 2) / divisor; + } + + template + ANKERL_NANOBENCH_NO_SANITIZE("integer") + void calibrate(Op&& op) { + // clear current calibration data, + for (auto& v : mCalibratedOverhead) { + v = UINT64_C(0); + } + + // create new calibration data + auto newCalibration = mCalibratedOverhead; + for (auto& v : newCalibration) { + v = (std::numeric_limits::max)(); + } + for (size_t iter = 0; iter < 100; ++iter) { + beginMeasure(); + op(); + endMeasure(); + if (mHasError) { + return; + } + + for (size_t i = 0; i < newCalibration.size(); ++i) { + auto diff = mCounters[i]; + if (newCalibration[i] > diff) { + newCalibration[i] = diff; + } + } + } + + mCalibratedOverhead = std::move(newCalibration); + + { + // calibrate loop overhead. For branches & instructions this makes sense, not so much for everything else like cycles. + // marsaglia's xorshift: mov, sal/shr, xor. Times 3. + // This has the nice property that the compiler doesn't seem to be able to optimize multiple calls any further. + // see https://godbolt.org/z/49RVQ5 + uint64_t const numIters = 100000U + (std::random_device{}() & 3); + uint64_t n = numIters; + uint32_t x = 1234567; + auto fn = [&]() { + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + }; + + beginMeasure(); + while (n-- > 0) { + fn(); + } + endMeasure(); + detail::doNotOptimizeAway(x); + auto measure1 = mCounters; + + n = numIters; + beginMeasure(); + while (n-- > 0) { + // we now run *twice* so we can easily calculate the overhead + fn(); + fn(); + } + endMeasure(); + detail::doNotOptimizeAway(x); + auto measure2 = mCounters; + + for (size_t i = 0; i < mCounters.size(); ++i) { + // factor 2 because we have two instructions per loop + auto m1 = measure1[i] > mCalibratedOverhead[i] ? measure1[i] - mCalibratedOverhead[i] : 0; + auto m2 = measure2[i] > mCalibratedOverhead[i] ? measure2[i] - mCalibratedOverhead[i] : 0; + auto overhead = m1 * 2 > m2 ? m1 * 2 - m2 : 0; + + mLoopOverhead[i] = divRounded(overhead, numIters); + } + } + } + +private: + bool monitor(uint32_t type, uint64_t eventid, Target target); + + std::map mIdToTarget{}; + + // start with minimum size of 3 for read_format + std::vector mCounters{3}; + std::vector mCalibratedOverhead{3}; + std::vector mLoopOverhead{3}; + + uint64_t mTimeEnabledNanos = 0; + uint64_t mTimeRunningNanos = 0; + int mFd = -1; + bool mHasError = false; +}; +ANKERL_NANOBENCH(IGNORE_PADDED_POP) + +LinuxPerformanceCounters::~LinuxPerformanceCounters() { + if (-1 != mFd) { + close(mFd); + } +} + +bool LinuxPerformanceCounters::monitor(perf_sw_ids swId, LinuxPerformanceCounters::Target target) { + return monitor(PERF_TYPE_SOFTWARE, swId, target); +} + +bool LinuxPerformanceCounters::monitor(perf_hw_id hwId, LinuxPerformanceCounters::Target target) { + return monitor(PERF_TYPE_HARDWARE, hwId, target); +} + +// overflow is ok, it's checked +ANKERL_NANOBENCH_NO_SANITIZE("integer") +void LinuxPerformanceCounters::updateResults(uint64_t numIters) { + // clear old data + for (auto& id_value : mIdToTarget) { + *id_value.second.targetValue = UINT64_C(0); + } + + if (mHasError) { + return; + } + + mTimeEnabledNanos = mCounters[1] - mCalibratedOverhead[1]; + mTimeRunningNanos = mCounters[2] - mCalibratedOverhead[2]; + + for (uint64_t i = 0; i < mCounters[0]; ++i) { + auto idx = static_cast(3 + i * 2 + 0); + auto id = mCounters[idx + 1U]; + + auto it = mIdToTarget.find(id); + if (it != mIdToTarget.end()) { + + auto& tgt = it->second; + *tgt.targetValue = mCounters[idx]; + if (tgt.correctMeasuringOverhead) { + if (*tgt.targetValue >= mCalibratedOverhead[idx]) { + *tgt.targetValue -= mCalibratedOverhead[idx]; + } else { + *tgt.targetValue = 0U; + } + } + if (tgt.correctLoopOverhead) { + auto correctionVal = mLoopOverhead[idx] * numIters; + if (*tgt.targetValue >= correctionVal) { + *tgt.targetValue -= correctionVal; + } else { + *tgt.targetValue = 0U; + } + } + } + } +} + +bool LinuxPerformanceCounters::monitor(uint32_t type, uint64_t eventid, Target target) { + *target.targetValue = (std::numeric_limits::max)(); + if (mHasError) { + return false; + } + + auto pea = perf_event_attr(); + std::memset(&pea, 0, sizeof(perf_event_attr)); + pea.type = type; + pea.size = sizeof(perf_event_attr); + pea.config = eventid; + pea.disabled = 1; // start counter as disabled + pea.exclude_kernel = 1; + pea.exclude_hv = 1; + + // NOLINTNEXTLINE(hicpp-signed-bitwise) + pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; + + const int pid = 0; // the current process + const int cpu = -1; // all CPUs +# if defined(PERF_FLAG_FD_CLOEXEC) // since Linux 3.14 + const unsigned long flags = PERF_FLAG_FD_CLOEXEC; +# else + const unsigned long flags = 0; +# endif + + auto fd = static_cast(syscall(__NR_perf_event_open, &pea, pid, cpu, mFd, flags)); + if (-1 == fd) { + return false; + } + if (-1 == mFd) { + // first call: set to fd, and use this from now on + mFd = fd; + } + uint64_t id = 0; + // NOLINTNEXTLINE(hicpp-signed-bitwise) + if (-1 == ioctl(fd, PERF_EVENT_IOC_ID, &id)) { + // couldn't get id + return false; + } + + // insert into map, rely on the fact that map's references are constant. + mIdToTarget.emplace(id, target); + + // prepare readformat with the correct size (after the insert) + auto size = 3 + 2 * mIdToTarget.size(); + mCounters.resize(size); + mCalibratedOverhead.resize(size); + mLoopOverhead.resize(size); + + return true; +} + +PerformanceCounters::PerformanceCounters() + : mPc(new LinuxPerformanceCounters()) + , mVal() + , mHas() { + + mHas.pageFaults = mPc->monitor(PERF_COUNT_SW_PAGE_FAULTS, LinuxPerformanceCounters::Target(&mVal.pageFaults, true, false)); + mHas.cpuCycles = mPc->monitor(PERF_COUNT_HW_REF_CPU_CYCLES, LinuxPerformanceCounters::Target(&mVal.cpuCycles, true, false)); + mHas.contextSwitches = + mPc->monitor(PERF_COUNT_SW_CONTEXT_SWITCHES, LinuxPerformanceCounters::Target(&mVal.contextSwitches, true, false)); + mHas.instructions = mPc->monitor(PERF_COUNT_HW_INSTRUCTIONS, LinuxPerformanceCounters::Target(&mVal.instructions, true, true)); + mHas.branchInstructions = + mPc->monitor(PERF_COUNT_HW_BRANCH_INSTRUCTIONS, LinuxPerformanceCounters::Target(&mVal.branchInstructions, true, false)); + mHas.branchMisses = mPc->monitor(PERF_COUNT_HW_BRANCH_MISSES, LinuxPerformanceCounters::Target(&mVal.branchMisses, true, false)); + // mHas.branchMisses = false; + + mPc->start(); + mPc->calibrate([] { + auto before = ankerl::nanobench::Clock::now(); + auto after = ankerl::nanobench::Clock::now(); + (void)before; + (void)after; + }); + + if (mPc->hasError()) { + // something failed, don't monitor anything. + mHas = PerfCountSet{}; + } +} + +PerformanceCounters::~PerformanceCounters() { + if (nullptr != mPc) { + delete mPc; + } +} + +void PerformanceCounters::beginMeasure() { + mPc->beginMeasure(); +} + +void PerformanceCounters::endMeasure() { + mPc->endMeasure(); +} + +void PerformanceCounters::updateResults(uint64_t numIters) { + mPc->updateResults(numIters); +} + +# else + +PerformanceCounters::PerformanceCounters() = default; +PerformanceCounters::~PerformanceCounters() = default; +void PerformanceCounters::beginMeasure() {} +void PerformanceCounters::endMeasure() {} +void PerformanceCounters::updateResults(uint64_t) {} + +# endif + +ANKERL_NANOBENCH(NODISCARD) PerfCountSet const& PerformanceCounters::val() const noexcept { + return mVal; +} +ANKERL_NANOBENCH(NODISCARD) PerfCountSet const& PerformanceCounters::has() const noexcept { + return mHas; +} + +// formatting utilities +namespace fmt { + +// adds thousands separator to numbers +NumSep::NumSep(char sep) + : mSep(sep) {} + +char NumSep::do_thousands_sep() const { + return mSep; +} + +std::string NumSep::do_grouping() const { + return "\003"; +} + +// RAII to save & restore a stream's state +StreamStateRestorer::StreamStateRestorer(std::ostream& s) + : mStream(s) + , mLocale(s.getloc()) + , mPrecision(s.precision()) + , mWidth(s.width()) + , mFill(s.fill()) + , mFmtFlags(s.flags()) {} + +StreamStateRestorer::~StreamStateRestorer() { + restore(); +} + +// sets back all stream info that we remembered at construction +void StreamStateRestorer::restore() { + mStream.imbue(mLocale); + mStream.precision(mPrecision); + mStream.width(mWidth); + mStream.fill(mFill); + mStream.flags(mFmtFlags); +} + +Number::Number(int width, int precision, int64_t value) + : mWidth(width) + , mPrecision(precision) + , mValue(static_cast(value)) {} + +Number::Number(int width, int precision, double value) + : mWidth(width) + , mPrecision(precision) + , mValue(value) {} + +std::ostream& Number::write(std::ostream& os) const { + StreamStateRestorer restorer(os); + os.imbue(std::locale(os.getloc(), new NumSep(','))); + os << std::setw(mWidth) << std::setprecision(mPrecision) << std::fixed << mValue; + return os; +} + +std::string Number::to_s() const { + std::stringstream ss; + write(ss); + return ss.str(); +} + +std::string to_s(uint64_t n) { + std::string str; + do { + str += static_cast('0' + static_cast(n % 10)); + n /= 10; + } while (n != 0); + std::reverse(str.begin(), str.end()); + return str; +} + +std::ostream& operator<<(std::ostream& os, Number const& n) { + return n.write(os); +} + +MarkDownColumn::MarkDownColumn(int w, int prec, std::string const& tit, std::string const& suff, double val) + : mWidth(w) + , mPrecision(prec) + , mTitle(tit) + , mSuffix(suff) + , mValue(val) {} + +std::string MarkDownColumn::title() const { + std::stringstream ss; + ss << '|' << std::setw(mWidth - 2) << std::right << mTitle << ' '; + return ss.str(); +} + +std::string MarkDownColumn::separator() const { + std::string sep(static_cast(mWidth), '-'); + sep.front() = '|'; + sep.back() = ':'; + return sep; +} + +std::string MarkDownColumn::invalid() const { + std::string sep(static_cast(mWidth), ' '); + sep.front() = '|'; + sep[sep.size() - 2] = '-'; + return sep; +} + +std::string MarkDownColumn::value() const { + std::stringstream ss; + auto width = mWidth - 2 - static_cast(mSuffix.size()); + ss << '|' << Number(width, mPrecision, mValue) << mSuffix << ' '; + return ss.str(); +} + +// Formats any text as markdown code, escaping backticks. +MarkDownCode::MarkDownCode(std::string const& what) { + mWhat.reserve(what.size() + 2); + mWhat.push_back('`'); + for (char c : what) { + mWhat.push_back(c); + if ('`' == c) { + mWhat.push_back('`'); + } + } + mWhat.push_back('`'); +} + +std::ostream& MarkDownCode::write(std::ostream& os) const { + return os << mWhat; +} + +std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode) { + return mdCode.write(os); +} +} // namespace fmt +} // namespace detail + +// provide implementation here so it's only generated once +Config::Config() = default; +Config::~Config() = default; +Config& Config::operator=(Config const&) = default; +Config& Config::operator=(Config&&) = default; +Config::Config(Config const&) = default; +Config::Config(Config&&) noexcept = default; + +// provide implementation here so it's only generated once +Result::~Result() = default; +Result& Result::operator=(Result const&) = default; +Result& Result::operator=(Result&&) = default; +Result::Result(Result const&) = default; +Result::Result(Result&&) noexcept = default; + +namespace detail { +template +inline constexpr typename std::underlying_type::type u(T val) noexcept { + return static_cast::type>(val); +} +} // namespace detail + +// Result returned after a benchmark has finished. Can be used as a baseline for relative(). +Result::Result(Config const& benchmarkConfig) + : mConfig(benchmarkConfig) + , mNameToMeasurements{detail::u(Result::Measure::_size)} {} + +void Result::add(Clock::duration totalElapsed, uint64_t iters, detail::PerformanceCounters const& pc) { + using detail::d; + using detail::u; + + double dIters = d(iters); + mNameToMeasurements[u(Result::Measure::iterations)].push_back(dIters); + + mNameToMeasurements[u(Result::Measure::elapsed)].push_back(d(totalElapsed) / dIters); + if (pc.has().pageFaults) { + mNameToMeasurements[u(Result::Measure::pagefaults)].push_back(d(pc.val().pageFaults) / dIters); + } + if (pc.has().cpuCycles) { + mNameToMeasurements[u(Result::Measure::cpucycles)].push_back(d(pc.val().cpuCycles) / dIters); + } + if (pc.has().contextSwitches) { + mNameToMeasurements[u(Result::Measure::contextswitches)].push_back(d(pc.val().contextSwitches) / dIters); + } + if (pc.has().instructions) { + mNameToMeasurements[u(Result::Measure::instructions)].push_back(d(pc.val().instructions) / dIters); + } + if (pc.has().branchInstructions) { + double branchInstructions = 0.0; + // correcting branches: remove branch introduced by the while (...) loop for each iteration. + if (pc.val().branchInstructions > iters + 1U) { + branchInstructions = d(pc.val().branchInstructions - (iters + 1U)); + } + mNameToMeasurements[u(Result::Measure::branchinstructions)].push_back(branchInstructions / dIters); + + if (pc.has().branchMisses) { + // correcting branch misses + double branchMisses = d(pc.val().branchMisses); + if (branchMisses > branchInstructions) { + // can't have branch misses when there were branches... + branchMisses = branchInstructions; + } + + // assuming at least one missed branch for the loop + branchMisses -= 1.0; + if (branchMisses < 1.0) { + branchMisses = 1.0; + } + mNameToMeasurements[u(Result::Measure::branchmisses)].push_back(branchMisses / dIters); + } + } +} + +Config const& Result::config() const noexcept { + return mConfig; +} + +inline double calcMedian(std::vector& data) { + if (data.empty()) { + return 0.0; + } + std::sort(data.begin(), data.end()); + + auto midIdx = data.size() / 2U; + if (1U == (data.size() & 1U)) { + return data[midIdx]; + } + return (data[midIdx - 1U] + data[midIdx]) / 2U; +} + +double Result::median(Measure m) const { + // create a copy so we can sort + auto data = mNameToMeasurements[detail::u(m)]; + return calcMedian(data); +} + +double Result::average(Measure m) const { + using detail::d; + auto const& data = mNameToMeasurements[detail::u(m)]; + if (data.empty()) { + return 0.0; + } + + // create a copy so we can sort + return sum(m) / d(data.size()); +} + +double Result::medianAbsolutePercentError(Measure m) const { + // create copy + auto data = mNameToMeasurements[detail::u(m)]; + + // calculates MdAPE which is the median of percentage error + // see https://www.spiderfinancial.com/support/documentation/numxl/reference-manual/forecasting-performance/mdape + auto med = calcMedian(data); + + // transform the data to absolute error + for (auto& x : data) { + x = (x - med) / x; + if (x < 0) { + x = -x; + } + } + return calcMedian(data); +} + +double Result::sum(Measure m) const noexcept { + auto const& data = mNameToMeasurements[detail::u(m)]; + return std::accumulate(data.begin(), data.end(), 0.0); +} + +double Result::sumProduct(Measure m1, Measure m2) const noexcept { + auto const& data1 = mNameToMeasurements[detail::u(m1)]; + auto const& data2 = mNameToMeasurements[detail::u(m2)]; + + if (data1.size() != data2.size()) { + return 0.0; + } + + double result = 0.0; + for (size_t i = 0, s = data1.size(); i != s; ++i) { + result += data1[i] * data2[i]; + } + return result; +} + +bool Result::has(Measure m) const noexcept { + return !mNameToMeasurements[detail::u(m)].empty(); +} + +double Result::get(size_t idx, Measure m) const { + auto const& data = mNameToMeasurements[detail::u(m)]; + return data.at(idx); +} + +bool Result::empty() const noexcept { + return 0U == size(); +} + +size_t Result::size() const noexcept { + auto const& data = mNameToMeasurements[detail::u(Measure::elapsed)]; + return data.size(); +} + +double Result::minimum(Measure m) const noexcept { + auto const& data = mNameToMeasurements[detail::u(m)]; + if (data.empty()) { + return 0.0; + } + + // here its save to assume that at least one element is there + return *std::min_element(data.begin(), data.end()); +} + +double Result::maximum(Measure m) const noexcept { + auto const& data = mNameToMeasurements[detail::u(m)]; + if (data.empty()) { + return 0.0; + } + + // here its save to assume that at least one element is there + return *std::max_element(data.begin(), data.end()); +} + +Result::Measure Result::fromString(std::string const& str) { + if (str == "elapsed") { + return Measure::elapsed; + } else if (str == "iterations") { + return Measure::iterations; + } else if (str == "pagefaults") { + return Measure::pagefaults; + } else if (str == "cpucycles") { + return Measure::cpucycles; + } else if (str == "contextswitches") { + return Measure::contextswitches; + } else if (str == "instructions") { + return Measure::instructions; + } else if (str == "branchinstructions") { + return Measure::branchinstructions; + } else if (str == "branchmisses") { + return Measure::branchmisses; + } else { + // not found, return _size + return Measure::_size; + } +} + +// Configuration of a microbenchmark. +Bench::Bench() { + mConfig.mOut = &std::cout; +} + +Bench::Bench(Bench&&) = default; +Bench& Bench::operator=(Bench&&) = default; +Bench::Bench(Bench const&) = default; +Bench& Bench::operator=(Bench const&) = default; +Bench::~Bench() noexcept = default; + +double Bench::batch() const noexcept { + return mConfig.mBatch; +} + +double Bench::complexityN() const noexcept { + return mConfig.mComplexityN; +} + +// Set a baseline to compare it to. 100% it is exactly as fast as the baseline, >100% means it is faster than the baseline, <100% +// means it is slower than the baseline. +Bench& Bench::relative(bool isRelativeEnabled) noexcept { + mConfig.mIsRelative = isRelativeEnabled; + return *this; +} +bool Bench::relative() const noexcept { + return mConfig.mIsRelative; +} + +Bench& Bench::performanceCounters(bool showPerformanceCounters) noexcept { + mConfig.mShowPerformanceCounters = showPerformanceCounters; + return *this; +} +bool Bench::performanceCounters() const noexcept { + return mConfig.mShowPerformanceCounters; +} + +// Operation unit. Defaults to "op", could be e.g. "byte" for string processing. +// If u differs from currently set unit, the stored results will be cleared. +// Use singular (byte, not bytes). +Bench& Bench::unit(char const* u) { + if (u != mConfig.mUnit) { + mResults.clear(); + } + mConfig.mUnit = u; + return *this; +} + +Bench& Bench::unit(std::string const& u) { + return unit(u.c_str()); +} + +std::string const& Bench::unit() const noexcept { + return mConfig.mUnit; +} + +// If benchmarkTitle differs from currently set title, the stored results will be cleared. +Bench& Bench::title(const char* benchmarkTitle) { + if (benchmarkTitle != mConfig.mBenchmarkTitle) { + mResults.clear(); + } + mConfig.mBenchmarkTitle = benchmarkTitle; + return *this; +} +Bench& Bench::title(std::string const& benchmarkTitle) { + if (benchmarkTitle != mConfig.mBenchmarkTitle) { + mResults.clear(); + } + mConfig.mBenchmarkTitle = benchmarkTitle; + return *this; +} + +std::string const& Bench::title() const noexcept { + return mConfig.mBenchmarkTitle; +} + +Bench& Bench::name(const char* benchmarkName) { + mConfig.mBenchmarkName = benchmarkName; + return *this; +} + +Bench& Bench::name(std::string const& benchmarkName) { + mConfig.mBenchmarkName = benchmarkName; + return *this; +} + +std::string const& Bench::name() const noexcept { + return mConfig.mBenchmarkName; +} + +// Number of epochs to evaluate. The reported result will be the median of evaluation of each epoch. +Bench& Bench::epochs(size_t numEpochs) noexcept { + mConfig.mNumEpochs = numEpochs; + return *this; +} +size_t Bench::epochs() const noexcept { + return mConfig.mNumEpochs; +} + +// Desired evaluation time is a multiple of clock resolution. Default is to be 1000 times above this measurement precision. +Bench& Bench::clockResolutionMultiple(size_t multiple) noexcept { + mConfig.mClockResolutionMultiple = multiple; + return *this; +} +size_t Bench::clockResolutionMultiple() const noexcept { + return mConfig.mClockResolutionMultiple; +} + +// Sets the maximum time each epoch should take. Default is 100ms. +Bench& Bench::maxEpochTime(std::chrono::nanoseconds t) noexcept { + mConfig.mMaxEpochTime = t; + return *this; +} +std::chrono::nanoseconds Bench::maxEpochTime() const noexcept { + return mConfig.mMaxEpochTime; +} + +// Sets the maximum time each epoch should take. Default is 100ms. +Bench& Bench::minEpochTime(std::chrono::nanoseconds t) noexcept { + mConfig.mMinEpochTime = t; + return *this; +} +std::chrono::nanoseconds Bench::minEpochTime() const noexcept { + return mConfig.mMinEpochTime; +} + +Bench& Bench::minEpochIterations(uint64_t numIters) noexcept { + mConfig.mMinEpochIterations = (numIters == 0) ? 1 : numIters; + return *this; +} +uint64_t Bench::minEpochIterations() const noexcept { + return mConfig.mMinEpochIterations; +} + +Bench& Bench::epochIterations(uint64_t numIters) noexcept { + mConfig.mEpochIterations = numIters; + return *this; +} +uint64_t Bench::epochIterations() const noexcept { + return mConfig.mEpochIterations; +} + +Bench& Bench::warmup(uint64_t numWarmupIters) noexcept { + mConfig.mWarmup = numWarmupIters; + return *this; +} +uint64_t Bench::warmup() const noexcept { + return mConfig.mWarmup; +} + +Bench& Bench::config(Config const& benchmarkConfig) { + mConfig = benchmarkConfig; + return *this; +} +Config const& Bench::config() const noexcept { + return mConfig; +} + +Bench& Bench::output(std::ostream* outstream) noexcept { + mConfig.mOut = outstream; + return *this; +} + +ANKERL_NANOBENCH(NODISCARD) std::ostream* Bench::output() const noexcept { + return mConfig.mOut; +} + +std::vector const& Bench::results() const noexcept { + return mResults; +} + +Bench& Bench::render(char const* templateContent, std::ostream& os) { + ::ankerl::nanobench::render(templateContent, *this, os); + return *this; +} + +std::vector Bench::complexityBigO() const { + std::vector bigOs; + auto rangeMeasure = BigO::collectRangeMeasure(mResults); + bigOs.emplace_back("O(1)", rangeMeasure, [](double) { + return 1.0; + }); + bigOs.emplace_back("O(n)", rangeMeasure, [](double n) { + return n; + }); + bigOs.emplace_back("O(log n)", rangeMeasure, [](double n) { + return std::log2(n); + }); + bigOs.emplace_back("O(n log n)", rangeMeasure, [](double n) { + return n * std::log2(n); + }); + bigOs.emplace_back("O(n^2)", rangeMeasure, [](double n) { + return n * n; + }); + bigOs.emplace_back("O(n^3)", rangeMeasure, [](double n) { + return n * n * n; + }); + std::sort(bigOs.begin(), bigOs.end()); + return bigOs; +} + +Rng::Rng() + : mX(0) + , mY(0) { + std::random_device rd; + std::uniform_int_distribution dist; + do { + mX = dist(rd); + mY = dist(rd); + } while (mX == 0 && mY == 0); +} + +ANKERL_NANOBENCH_NO_SANITIZE("integer") +uint64_t splitMix64(uint64_t& state) noexcept { + uint64_t z = (state += UINT64_C(0x9e3779b97f4a7c15)); + z = (z ^ (z >> 30U)) * UINT64_C(0xbf58476d1ce4e5b9); + z = (z ^ (z >> 27U)) * UINT64_C(0x94d049bb133111eb); + return z ^ (z >> 31U); +} + +// Seeded as described in romu paper (update april 2020) +Rng::Rng(uint64_t seed) noexcept + : mX(splitMix64(seed)) + , mY(splitMix64(seed)) { + for (size_t i = 0; i < 10; ++i) { + operator()(); + } +} + +// only internally used to copy the RNG. +Rng::Rng(uint64_t x, uint64_t y) noexcept + : mX(x) + , mY(y) {} + +Rng Rng::copy() const noexcept { + return Rng{mX, mY}; +} + +BigO::RangeMeasure BigO::collectRangeMeasure(std::vector const& results) { + BigO::RangeMeasure rangeMeasure; + for (auto const& result : results) { + if (result.config().mComplexityN > 0.0) { + rangeMeasure.emplace_back(result.config().mComplexityN, result.median(Result::Measure::elapsed)); + } + } + return rangeMeasure; +} + +BigO::BigO(std::string const& bigOName, RangeMeasure const& rangeMeasure) + : mName(bigOName) { + + // estimate the constant factor + double sumRangeMeasure = 0.0; + double sumRangeRange = 0.0; + + for (size_t i = 0; i < rangeMeasure.size(); ++i) { + sumRangeMeasure += rangeMeasure[i].first * rangeMeasure[i].second; + sumRangeRange += rangeMeasure[i].first * rangeMeasure[i].first; + } + mConstant = sumRangeMeasure / sumRangeRange; + + // calculate root mean square + double err = 0.0; + double sumMeasure = 0.0; + for (size_t i = 0; i < rangeMeasure.size(); ++i) { + auto diff = mConstant * rangeMeasure[i].first - rangeMeasure[i].second; + err += diff * diff; + + sumMeasure += rangeMeasure[i].second; + } + + auto n = static_cast(rangeMeasure.size()); + auto mean = sumMeasure / n; + mNormalizedRootMeanSquare = std::sqrt(err / n) / mean; +} + +BigO::BigO(const char* bigOName, RangeMeasure const& rangeMeasure) + : BigO(std::string(bigOName), rangeMeasure) {} + +std::string const& BigO::name() const noexcept { + return mName; +} + +double BigO::constant() const noexcept { + return mConstant; +} + +double BigO::normalizedRootMeanSquare() const noexcept { + return mNormalizedRootMeanSquare; +} + +bool BigO::operator<(BigO const& other) const noexcept { + return std::tie(mNormalizedRootMeanSquare, mName) < std::tie(other.mNormalizedRootMeanSquare, other.mName); +} + +std::ostream& operator<<(std::ostream& os, BigO const& bigO) { + return os << bigO.constant() << " * " << bigO.name() << ", rms=" << bigO.normalizedRootMeanSquare(); +} + +std::ostream& operator<<(std::ostream& os, std::vector const& bigOs) { + detail::fmt::StreamStateRestorer restorer(os); + os << std::endl << "| coefficient | err% | complexity" << std::endl << "|--------------:|-------:|------------" << std::endl; + for (auto const& bigO : bigOs) { + os << "|" << std::setw(14) << std::setprecision(7) << std::scientific << bigO.constant() << " "; + os << "|" << detail::fmt::Number(6, 1, bigO.normalizedRootMeanSquare() * 100.0) << "% "; + os << "| " << bigO.name(); + os << std::endl; + } + return os; +} + +} // namespace nanobench +} // namespace ankerl + +#endif // ANKERL_NANOBENCH_IMPLEMENT +#endif // ANKERL_NANOBENCH_H_INCLUDED diff --git a/src/bench/poly1305.cpp b/src/bench/poly1305.cpp new file mode 100644 index 00000000..b4d5c750 --- /dev/null +++ b/src/bench/poly1305.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2019 The BitSend Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +#include +#include + +/* Number of bytes to process per iteration */ +static constexpr uint64_t BUFFER_SIZE_TINY = 64; +static constexpr uint64_t BUFFER_SIZE_SMALL = 256; +static constexpr uint64_t BUFFER_SIZE_LARGE = 1024*1024; + +static void POLY1305(benchmark::Bench& bench, size_t buffersize) +{ + std::vector tag(POLY1305_TAGLEN, 0); + std::vector key(POLY1305_KEYLEN, 0); + std::vector in(buffersize, 0); + bench.batch(in.size()).unit("byte").run([&] { + poly1305_auth(tag.data(), in.data(), in.size(), key.data()); + }); +} + +static void POLY1305_64BYTES(benchmark::Bench& bench) +{ + POLY1305(bench, BUFFER_SIZE_TINY); +} + +static void POLY1305_256BYTES(benchmark::Bench& bench) +{ + POLY1305(bench, BUFFER_SIZE_SMALL); +} + +static void POLY1305_1MB(benchmark::Bench& bench) +{ + POLY1305(bench, BUFFER_SIZE_LARGE); +} + +BENCHMARK(POLY1305_64BYTES); +BENCHMARK(POLY1305_256BYTES); +BENCHMARK(POLY1305_1MB); diff --git a/src/bench/prevector.cpp b/src/bench/prevector.cpp old mode 100755 new mode 100644 index 55cf6362..26764859 --- a/src/bench/prevector.cpp +++ b/src/bench/prevector.cpp @@ -1,20 +1,26 @@ -// Copyright (c) 2015-2018 The Bitsend Core developers +// Copyright (c) 2015-2018 The BitSend Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include #include #include +#include #include +// GCC 4.8 is missing some C++11 type_traits, +// https://www.gnu.org/software/gcc/gcc-5/changes.html +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 +#define IS_TRIVIALLY_CONSTRUCTIBLE std::has_trivial_default_constructor +#else +#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_default_constructible +#endif + struct nontrivial_t { int x; nontrivial_t() :x(-1) {} - ADD_SERIALIZE_METHODS - template - inline void SerializationOp(Stream& s, Operation ser_action) {READWRITE(x);} + SERIALIZE_METHODS(nontrivial_t, obj) { READWRITE(obj.x); } }; static_assert(!IS_TRIVIALLY_CONSTRUCTIBLE::value, "expected nontrivial_t to not be trivially constructible"); @@ -24,51 +30,44 @@ static_assert(IS_TRIVIALLY_CONSTRUCTIBLE::value, "expected trivial_t to be trivially constructible"); template -static void PrevectorDestructor(benchmark::State& state) +static void PrevectorDestructor(benchmark::Bench& bench) { - while (state.KeepRunning()) { - for (auto x = 0; x < 1000; ++x) { - prevector<28, T> t0; - prevector<28, T> t1; - t0.resize(28); - t1.resize(29); - } - } + bench.batch(2).run([&] { + prevector<28, T> t0; + prevector<28, T> t1; + t0.resize(28); + t1.resize(29); + }); } template -static void PrevectorClear(benchmark::State& state) +static void PrevectorClear(benchmark::Bench& bench) { - - while (state.KeepRunning()) { - for (auto x = 0; x < 1000; ++x) { - prevector<28, T> t0; - prevector<28, T> t1; - t0.resize(28); - t0.clear(); - t1.resize(29); - t1.clear(); - } - } + prevector<28, T> t0; + prevector<28, T> t1; + bench.batch(2).run([&] { + t0.resize(28); + t0.clear(); + t1.resize(29); + t1.clear(); + }); } template -static void PrevectorResize(benchmark::State& state) +static void PrevectorResize(benchmark::Bench& bench) { - while (state.KeepRunning()) { - prevector<28, T> t0; - prevector<28, T> t1; - for (auto x = 0; x < 1000; ++x) { - t0.resize(28); - t0.resize(0); - t1.resize(29); - t1.resize(0); - } - } + prevector<28, T> t0; + prevector<28, T> t1; + bench.batch(4).run([&] { + t0.resize(28); + t0.resize(0); + t1.resize(29); + t1.resize(0); + }); } template -static void PrevectorDeserialize(benchmark::State& state) +static void PrevectorDeserialize(benchmark::Bench& bench) { CDataStream s0(SER_NETWORK, 0); prevector<28, T> t0; @@ -80,26 +79,28 @@ static void PrevectorDeserialize(benchmark::State& state) for (auto x = 0; x < 101; ++x) { s0 << t0; } - while (state.KeepRunning()) { + bench.batch(1000).run([&] { prevector<28, T> t1; for (auto x = 0; x < 1000; ++x) { s0 >> t1; } s0.Init(SER_NETWORK, 0); - } + }); } -#define PREVECTOR_TEST(name, nontrivops, trivops) \ - static void Prevector ## name ## Nontrivial(benchmark::State& state) { \ - Prevector ## name(state); \ - } \ - BENCHMARK(Prevector ## name ## Nontrivial, nontrivops); \ - static void Prevector ## name ## Trivial(benchmark::State& state) { \ - Prevector ## name(state); \ - } \ - BENCHMARK(Prevector ## name ## Trivial, trivops); +#define PREVECTOR_TEST(name) \ + static void Prevector##name##Nontrivial(benchmark::Bench& bench) \ + { \ + Prevector##name(bench); \ + } \ + BENCHMARK(Prevector##name##Nontrivial); \ + static void Prevector##name##Trivial(benchmark::Bench& bench) \ + { \ + Prevector##name(bench); \ + } \ + BENCHMARK(Prevector##name##Trivial); -PREVECTOR_TEST(Clear, 28300, 88600) -PREVECTOR_TEST(Destructor, 28800, 88900) -PREVECTOR_TEST(Resize, 28900, 90300) -PREVECTOR_TEST(Deserialize, 6800, 52000) +PREVECTOR_TEST(Clear) +PREVECTOR_TEST(Destructor) +PREVECTOR_TEST(Resize) +PREVECTOR_TEST(Deserialize) diff --git a/src/bench/rollingbloom.cpp b/src/bench/rollingbloom.cpp old mode 100755 new mode 100644 index 4e45b190..48e66722 --- a/src/bench/rollingbloom.cpp +++ b/src/bench/rollingbloom.cpp @@ -1,19 +1,17 @@ -// Copyright (c) 2016-2018 The Bitsend Core developers +// Copyright (c) 2016-2019 The BitSend Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include #include -static void RollingBloom(benchmark::State& state) +static void RollingBloom(benchmark::Bench& bench) { CRollingBloomFilter filter(120000, 0.000001); std::vector data(32); uint32_t count = 0; - uint64_t match = 0; - while (state.KeepRunning()) { + bench.run([&] { count++; data[0] = count; data[1] = count >> 8; @@ -25,8 +23,17 @@ static void RollingBloom(benchmark::State& state) data[1] = count >> 16; data[2] = count >> 8; data[3] = count; - match += filter.contains(data); - } + filter.contains(data); + }); } -BENCHMARK(RollingBloom, 1500 * 1000); +static void RollingBloomReset(benchmark::Bench& bench) +{ + CRollingBloomFilter filter(120000, 0.000001); + bench.run([&] { + filter.reset(); + }); +} + +BENCHMARK(RollingBloom); +BENCHMARK(RollingBloomReset); diff --git a/src/bench/rpc_blockchain.cpp b/src/bench/rpc_blockchain.cpp new file mode 100644 index 00000000..9ebc2999 --- /dev/null +++ b/src/bench/rpc_blockchain.cpp @@ -0,0 +1,33 @@ +// Copyright (c) 2016-2020 The BitSend Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include +#include +#include + +#include + +static void BlockToJsonVerbose(benchmark::Bench& bench) +{ + CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION); + char a = '\0'; + stream.write(&a, 1); // Prevent compaction + + CBlock block; + stream >> block; + + CBlockIndex blockindex; + const uint256 blockHash = block.GetHash(); + blockindex.phashBlock = &blockHash; + blockindex.nBits = 403014710; + + bench.run([&] { + (void)blockToJSON(block, &blockindex, &blockindex, /*verbose*/ true); + }); +} + +BENCHMARK(BlockToJsonVerbose); diff --git a/src/bench/rpc_mempool.cpp b/src/bench/rpc_mempool.cpp new file mode 100644 index 00000000..bd0b31a5 --- /dev/null +++ b/src/bench/rpc_mempool.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2011-2019 The BitSend Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include + +#include + + +static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs) +{ + LockPoints lp; + pool.addUnchecked(CTxMemPoolEntry(tx, fee, /* time */ 0, /* height */ 1, /* spendsCoinbase */ false, /* sigOpCost */ 4, lp)); +} + +static void RpcMempool(benchmark::Bench& bench) +{ + CTxMemPool pool; + LOCK2(cs_main, pool.cs); + + for (int i = 0; i < 1000; ++i) { + CMutableTransaction tx = CMutableTransaction(); + tx.vin.resize(1); + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vin[0].scriptWitness.stack.push_back({1}); + tx.vout.resize(1); + tx.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; + tx.vout[0].nValue = i; + const CTransactionRef tx_r{MakeTransactionRef(tx)}; + AddTx(tx_r, /* fee */ i, pool); + } + + bench.run([&] { + (void)MempoolToJSON(pool, /*verbose*/ true); + }); +} + +BENCHMARK(RpcMempool); diff --git a/src/bench/util_time.cpp b/src/bench/util_time.cpp new file mode 100644 index 00000000..c98f3942 --- /dev/null +++ b/src/bench/util_time.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2019 The BitSend Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +static void BenchTimeDeprecated(benchmark::Bench& bench) +{ + bench.run([&] { + (void)GetTime(); + }); +} + +static void BenchTimeMock(benchmark::Bench& bench) +{ + SetMockTime(111); + bench.run([&] { + (void)GetTime(); + }); + SetMockTime(0); +} + +static void BenchTimeMillis(benchmark::Bench& bench) +{ + bench.run([&] { + (void)GetTime(); + }); +} + +static void BenchTimeMillisSys(benchmark::Bench& bench) +{ + bench.run([&] { + (void)GetTimeMillis(); + }); +} + +BENCHMARK(BenchTimeDeprecated); +BENCHMARK(BenchTimeMillis); +BENCHMARK(BenchTimeMillisSys); +BENCHMARK(BenchTimeMock); diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp old mode 100755 new mode 100644 index 82340ba8..d5b955b1 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 The Bitsend Core developers +// Copyright (c) 2016-2020 The BitSend Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,51 +8,19 @@ #include