diff --git a/.cargo/config.toml.offline b/.cargo/config.toml.offline new file mode 100644 index 000000000000..82e141e0bcc4 --- /dev/null +++ b/.cargo/config.toml.offline @@ -0,0 +1,32 @@ +# Linux +[target.aarch64-unknown-linux-musl] +linker = "aarch64-linux-gnu-gcc" + +[target.armv7-unknown-linux-musleabihf] +linker = "arm-linux-gnueabihf-gcc" + +[target.powerpc64le-unknown-linux-musl] +linker = "powerpc64le-linux-gnu-gcc" + +[target.riscv64gc-unknown-linux-musl] +linker = "riscv64-linux-gnu-gcc" + +[target.x86_64-unknown-linux-musl] +linker = "x86-64-linux-gnu-gcc" + +# Windows +[target.x86_64-pc-windows-gnu] +linker = "x86_64-w64-mingw32-gcc" + +# macOS +# [target.aarch64-apple-darwin] +# linker = "aarch64-apple-darwin-gcc" + +# [target.x86_64-apple-darwin] +# linker = "x86_64-apple-darwin-gcc" + +[source.crates-io] +replace-with = "vendored-sources" + +[source.vendored-sources] +# The directory for this source is set to RUST_VENDORED_SOURCES by rust/Makefile.am diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0228e46af380..b5d486d32327 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,13 +63,13 @@ jobs: file: ./contrib/containers/ci/ci-slim.Dockerfile name: dashcore-ci-slim - depends-arm-linux: - name: arm-linux-gnueabihf + depends-aarch64-linux: + name: aarch64-linux-gnu uses: ./.github/workflows/build-depends.yml needs: [container, cache-sources] if: ${{ vars.SKIP_ARM_LINUX == '' }} with: - build-target: arm-linux + build-target: aarch64-linux container-path: ${{ needs.container.outputs.path }} depends-linux64: @@ -131,16 +131,16 @@ jobs: with: container-path: ${{ needs.container-slim.outputs.path }} - src-arm-linux: - name: arm-linux-build + src-aarch64-linux: + name: aarch64-linux-build uses: ./.github/workflows/build-src.yml - needs: [container, depends-arm-linux] + needs: [container, depends-aarch64-linux] with: - build-target: arm-linux + build-target: aarch64-linux container-path: ${{ needs.container.outputs.path }} - depends-key: ${{ needs.depends-arm-linux.outputs.key }} - depends-host: ${{ needs.depends-arm-linux.outputs.host }} - depends-dep-opts: ${{ needs.depends-arm-linux.outputs.dep-opts }} + depends-key: ${{ needs.depends-aarch64-linux.outputs.key }} + depends-host: ${{ needs.depends-aarch64-linux.outputs.host }} + depends-dep-opts: ${{ needs.depends-aarch64-linux.outputs.dep-opts }} src-linux64: name: linux64-build diff --git a/.github/workflows/guix-build.yml b/.github/workflows/guix-build.yml index ba2f0a35e268..c03c927d2a90 100644 --- a/.github/workflows/guix-build.yml +++ b/.github/workflows/guix-build.yml @@ -71,7 +71,7 @@ jobs: runs-on: ubuntu-24.04-arm strategy: matrix: - build_target: [x86_64-linux-gnu, arm-linux-gnueabihf, aarch64-linux-gnu, riscv64-linux-gnu, powerpc64-linux-gnu, x86_64-w64-mingw32, x86_64-apple-darwin, arm64-apple-darwin] + build_target: [x86_64-linux-gnu, aarch64-linux-gnueabihf, aarch64-linux-gnu, riscv64-linux-gnu, powerpc64-linux-gnu, x86_64-w64-mingw32, x86_64-apple-darwin, arm64-apple-darwin] timeout-minutes: 480 steps: diff --git a/.gitignore b/.gitignore index 8c13e82b2289..74ad90f09469 100644 --- a/.gitignore +++ b/.gitignore @@ -175,3 +175,26 @@ test/lint/.cppcheck/* # Editor and tooling .vscode/ compile_commands.json + +# Generated by Cargo +# will have compiled files and executables +debug +target + +# Cargo configuration +.cargo/.configured-for-* +.cargo/config +.cargo/config.toml + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Generated by cargo mutants +# Contains mutation testing data +**/mutants.out*/ + +# FFI bridge +gen diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000000..0baf0e1fce0a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,297 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "built" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" + +[[package]] +name = "cc" +version = "1.2.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "chirp" +version = "0.1.0" +dependencies = [ + "built", + "cxx", +] + +[[package]] +name = "clap" +version = "4.5.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +dependencies = [ + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" + +[[package]] +name = "codespan-reporting" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + +[[package]] +name = "cxx" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbda285ba6e5866529faf76352bdf73801d9b44a6308d7cd58ca2379f378e994" +dependencies = [ + "cc", + "cxx-build", + "cxxbridge-cmd", + "cxxbridge-flags", + "cxxbridge-macro", + "foldhash", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9efde466c5d532d57efd92f861da3bdb7f61e369128ce8b4c3fe0c9de4fa4d" +dependencies = [ + "cc", + "codespan-reporting", + "indexmap", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-cmd" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3efb93799095bccd4f763ca07997dc39a69e5e61ab52d2c407d4988d21ce144d" +dependencies = [ + "clap", + "codespan-reporting", + "indexmap", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3092010228026e143b32a4463ed9fa8f86dca266af4bf5f3b2a26e113dbe4e45" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d72ebfcd351ae404fb00ff378dfc9571827a00722c9e735c9181aec320ba0a" +dependencies = [ + "indexmap", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "find-msvc-tools" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" +dependencies = [ + "cc", +] + +[[package]] +name = "proc-macro2" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "scratch" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000000..68133a4d0d6d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[workspace] +members = [ + "rust/chirp", +] +resolver = "2" + +[profile.release] +codegen-units = 1 +lto = true +panic = "abort" + +[profile.dev] +codegen-units = 1 +panic = "abort" diff --git a/Makefile.am b/Makefile.am index 8124d7909a1f..97a2fd35bea0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,7 +8,7 @@ print-%: FORCE @echo '$*'='$($*)' ACLOCAL_AMFLAGS = -I build-aux/m4 -SUBDIRS = src +SUBDIRS = rust src if ENABLE_MAN SUBDIRS += doc/man endif @@ -53,8 +53,8 @@ DIST_SHARE = \ $(top_srcdir)/share/genbuild.sh \ $(top_srcdir)/share/rpcauth -BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ - $(top_srcdir)/contrib/devtools/security-check.py \ +BIN_CHECKS=$(top_srcdir)/contrib/guix/symbol-check.py \ + $(top_srcdir)/contrib/guix/security-check.py \ $(top_srcdir)/contrib/devtools/utils.py WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/dash.ico \ @@ -321,17 +321,3 @@ clean-local: clean-docs rm -rf coverage_percent.txt test_dash.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 dist/ - -test-security-check: -if TARGET_DARWIN - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO -endif -if TARGET_WINDOWS - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE -endif -if TARGET_LINUX - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF -endif diff --git a/ci/dash/build_src.sh b/ci/dash/build_src.sh index 637396a2c224..86b229c1155e 100755 --- a/ci/dash/build_src.sh +++ b/ci/dash/build_src.sh @@ -57,7 +57,3 @@ fi if [ "${RUN_TIDY}" = "true" ] && [ "${GITHUB_ACTIONS}" != "true" ]; then "${BASE_ROOT_DIR}/ci/dash/lint-tidy.sh" fi - -if [ "$RUN_SECURITY_TESTS" = "true" ]; then - make test-security-check -fi diff --git a/ci/dash/matrix.sh b/ci/dash/matrix.sh index 2ffe70623311..56c78bea3004 100755 --- a/ci/dash/matrix.sh +++ b/ci/dash/matrix.sh @@ -16,8 +16,8 @@ export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/l export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1" export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" -if [ "$BUILD_TARGET" = "arm-linux" ]; then - source ./ci/test/00_setup_env_arm.sh +if [ "$BUILD_TARGET" = "aarch64-linux" ]; then + source ./ci/test/00_setup_env_aarch64.sh elif [ "$BUILD_TARGET" = "linux64" ]; then source ./ci/test/00_setup_env_native_qt5.sh elif [ "$BUILD_TARGET" = "linux64_asan" ]; then diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh index fc4944ae1d35..4207615a1a94 100755 --- a/ci/test/00_setup_env.sh +++ b/ci/test/00_setup_env.sh @@ -39,7 +39,6 @@ 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_TIDY=${RUN_TIDY:-false} -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. diff --git a/ci/test/00_setup_env_arm.sh b/ci/test/00_setup_env_aarch64.sh similarity index 51% rename from ci/test/00_setup_env_arm.sh rename to ci/test/00_setup_env_aarch64.sh index edbc9334928f..ea458c1e520c 100755 --- a/ci/test/00_setup_env_arm.sh +++ b/ci/test/00_setup_env_aarch64.sh @@ -6,23 +6,20 @@ export LC_ALL=C.UTF-8 -export HOST=arm-linux-gnueabihf +export HOST=aarch64-linux-gnu # 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 the host is arm64 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-aarch64 -L /usr/aarch64-linux-gnu/"}"; fi +export DPKG_ADD_ARCH="arm64" +export PACKAGES="python3-zmq g++-arm64-linux-gnu busybox libc6:arm64 libstdc++6:arm64 libfontconfig1:arm64 libxcb1:arm64" 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 +export CONTAINER_NAME=ci_aarch64_linux # Use debian to avoid 404 apt errors when cross compiling export CHECK_DOC=0 export USE_BUSY_BOX=true export RUN_UNIT_TESTS=false 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 BITCOIN_CONFIG="--enable-reduce-exports CXXFLAGS=-Wno-psabi" diff --git a/ci/test/00_setup_env_mac.sh b/ci/test/00_setup_env_mac.sh index ca04e916fc2a..244ec7138044 100755 --- a/ci/test/00_setup_env_mac.sh +++ b/ci/test/00_setup_env_mac.sh @@ -8,9 +8,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_macos_cross export HOST=x86_64-apple-darwin -export PACKAGES="clang cmake lld llvm zip" -export XCODE_VERSION=15.0 -export XCODE_BUILD_ID=15A240d +export PACKAGES="clang cmake lld llvm zip" +export XCODE_VERSION=16.0 +export XCODE_BUILD_ID=16A242d export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="all deploy" diff --git a/ci/test/00_setup_env_mac_native_x86_64.sh b/ci/test/00_setup_env_mac_native_x86_64.sh index b20efb2bde37..f38c74603807 100755 --- a/ci/test/00_setup_env_mac_native_x86_64.sh +++ b/ci/test/00_setup_env_mac_native_x86_64.sh @@ -15,5 +15,3 @@ export CI_OS_NAME="macos" export NO_DEPENDS=1 export OSX_SDK="" export CCACHE_MAXSIZE=300M - -export RUN_SECURITY_TESTS="true" diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh index 2010c111818d..74e80dd148eb 100755 --- a/ci/test/00_setup_env_win64.sh +++ b/ci/test/00_setup_env_win64.sh @@ -11,7 +11,6 @@ export HOST=x86_64-w64-mingw32 export DPKG_ADD_ARCH="i386" export PACKAGES="python3 nsis g++-mingw-w64-x86-64-posix wine-binfmt wine64 wine32 file" export RUN_FUNCTIONAL_TESTS=false -export RUN_SECURITY_TESTS="false" export GOAL="deploy" # Prior to 11.0.0, the mingw-w64 headers were missing noreturn attributes, causing warnings when # cross-compiling for Windows. https://sourceforge.net/p/mingw-w64/bugs/306/ diff --git a/configure.ac b/configure.ac index 3798c0222614..19fd341b3f76 100644 --- a/configure.ac +++ b/configure.ac @@ -47,6 +47,7 @@ if test "${ARFLAGS+set}" != "set"; then ARFLAGS="cr" fi +AC_CANONICAL_BUILD AC_CANONICAL_HOST AH_TOP([#ifndef DASH_CONFIG_H]) @@ -59,7 +60,9 @@ AM_INIT_AUTOMAKE([1.13 no-define subdir-objects foreign]) AM_MAINTAINER_MODE([enable]) dnl make the compilation flags quiet unless V=1 is used -AM_SILENT_RULES([yes]) +m4_pattern_allow([AM_DEFAULT_VERBOSITY]) +m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],[AM_DEFAULT_VERBOSITY=1]) +AM_CONDITIONAL([SILENT_RULES], [test "$AM_DEFAULT_VERBOSITY" = '0']) dnl Compiler checks (here before libtool). if test "${CXXFLAGS+set}" = "set"; then @@ -124,6 +127,38 @@ AC_PATH_TOOL([DSYMUTIL], [dsymutil]) AC_PATH_PROG([DOXYGEN], [doxygen]) AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"]) +dnl Check/return PATH for Rust dependencies +AC_DEFUN( + RS_REQUIRE_PROG, + [ + AC_PATH_PROG($1, $2, $2_notfound) + if test x${$1} = x$2_notfound + then + AC_MSG_ERROR("Required program $2 was not found") + fi + ] +) +RS_REQUIRE_PROG([CARGO], cargo) +RS_REQUIRE_PROG([CXXBRIDGE], cxxbridge) +RS_REQUIRE_PROG([RUSTC], rustc) + +AC_ARG_VAR([CARGO_INCREMENTAL], [Enable incremental compilation for Rust]) +if test "${CARGO_INCREMENTAL+set}" != "set"; then + CARGO_INCREMENTAL="0" +fi + +AC_ARG_VAR([RUSTFLAGS], [Flags for Rust compiler]) +if test "${RUSTFLAGS+set}" != "set"; then + RUSTFLAGS="-C embed-bitcode=yes -C relocation-model=pic" +fi + +AC_ARG_ENABLE([online-rust], + [AS_HELP_STRING([--enable-online-rust], + [allow Cargo to fetch Rust dependencies from the internet (default is no, using vendored dependencies offline)])], + [enable_online_rust=$enableval], + [enable_online_rust=no]) +AM_CONDITIONAL([ENABLE_ONLINE_RUST], [test "$enable_online_rust" != "no"]) + AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], [disable wallet (enabled by default)])], @@ -274,6 +309,7 @@ AC_ARG_ENABLE([debug], [use compiler flags and macros suited for debugging (default is no)])], [enable_debug=$enableval], [enable_debug=no]) +AM_CONDITIONAL([ENABLE_DEBUG], [test "$enable_debug" = "yes"]) dnl Enable exception stacktraces AC_ARG_ENABLE([stacktraces], @@ -815,7 +851,7 @@ case $host in AC_MSG_ERROR([windres not found]) fi - CORE_CPPFLAGS="$CORE_CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN" + CORE_CPPFLAGS="$CORE_CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -D_WIN32_WINNT=0x0A00 -D_WIN32_IE=0x0A00 -DWIN32_LEAN_AND_MEAN" dnl Prevent the definition of min/max macros. dnl We always want to use the standard library. CORE_CPPFLAGS="$CORE_CPPFLAGS -DNOMINMAX" @@ -828,8 +864,10 @@ 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], [CORE_LDFLAGS="$CORE_LDFLAGS -Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,1"], [], [$LDFLAG_WERROR]) + dnl We support Windows 10+, however it's not possible to set these values accordingly, + dnl due to a bug in mingw-w64. See https://sourceforge.net/p/mingw-w64/bugs/968/. + dnl As a best effort, target Windows 8. + AX_CHECK_LINK_FLAG([-Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,2], [CORE_LDFLAGS="$CORE_LDFLAGS -Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,2"], [], [$LDFLAG_WERROR]) dnl Avoid the use of aligned vector instructions when building for Windows. dnl See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54412. @@ -1073,8 +1111,7 @@ if test "$use_hardening" != "no"; then case $host in *mingw*) - dnl stack-clash-protection doesn't compile with GCC 10 and earlier. - dnl In any case, it is a no-op for Windows. + dnl stack-clash-protection is a no-op for Windows. dnl See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 for more details. ;; *) @@ -1703,6 +1740,108 @@ if test "$use_zmq" = "yes"; then esac fi +RUST_LIBS="" +case $host in + *mingw*) + RUST_LIBS="$RUST_LIBS -luserenv -lntdll" + ;; + *) + RUST_LIBS="$RUST_LIBS -ldl" + ;; +esac + +RUST_MACOS_DEPLOYMENT_TARGET="" +case $host in + *darwin*) + AC_MSG_CHECKING([for target macOS version]) + RUST_MACOS_DEPLOYMENT_TARGET="${OSX_MIN_VERSION:-$(sw_vers -productVersion)}" + AC_MSG_RESULT([$RUST_MACOS_DEPLOYMENT_TARGET]) + ;; +esac + +AC_DEFUN([RS_SET_TRIPLE], [ + case $2 in + x86_64-*-freebsd*) $1="x86_64-unknown-freebsd" ;; + aarch64-*-linux*|arm64-*-linux*) + $1="aarch64-unknown-linux-$3" ;; + arm-*-linux*) $1="armv7-unknown-linux-$3eabihf" ;; + powerpc64-*-linux*) $1="powerpc64-unknown-linux-$3" ;; + powerpc64le-*-linux*) $1="powerpc64le-unknown-linux-$3" ;; + riscv64-*-linux*) $1="riscv64gc-unknown-linux-$3" ;; + x86_64-*-linux*) $1="x86_64-unknown-linux-$3" ;; + x86_64-*-darwin*) $1="x86_64-apple-darwin" ;; + aarch64-*-darwin*|arm64-*-darwin*) + $1="aarch64-apple-darwin" ;; + x86_64-*-mingw*) $1="x86_64-pc-windows-gnu" ;; + *) $1="" ;; + esac +]) + +AC_MSG_CHECKING([for Rust target]) +RS_SET_TRIPLE([RUST_TARGET], [$host], [musl]) +if test "$RUST_TARGET" = ""; then + AC_MSG_RESULT([unknown]) + AC_MSG_ERROR([Unsupported target for Rust: $host]) +fi +AC_MSG_RESULT([$RUST_TARGET]) + +RUST_OSX_SDK="" +case $host in + *darwin*) + AC_MSG_CHECKING([for Xcode SDK]) + if test -z "$OSX_SDK"; then + if test "$cross_compiling" = "yes"; then + AC_MSG_ERROR([Cross-compilation requires OSX_SDK to be set to path of Xcode SDK, cannot continue!]) + fi + fi + RUST_OSX_SDK="${OSX_SDK:-$(xcrun --sdk macosx --show-sdk-path)}" + AC_MSG_RESULT([$RUST_OSX_SDK]) + ;; +esac + +AC_MSG_CHECKING([for Rust host]) +RS_SET_TRIPLE([RUST_NATIVE], [$build], [gnu]) +if test "$RUST_NATIVE" = ""; then + if test "$cross_compiling" = "yes"; then + AC_MSG_RESULT([unknown]) + AC_MSG_ERROR([Unsupported host for Rust: $build]) + fi + $RUST_NATIVE="$RUST_TARGET" +fi +AC_MSG_RESULT([$RUST_NATIVE]) + +AC_MSG_CHECKING([for host archiver]) +if test -z "$NATIVE_AR"; then + if test "$cross_compiling" = "yes"; then + AC_MSG_ERROR([Cross-compilation requires NATIVE_AR to be set to host archiver, cannot continue!]) + fi + NATIVE_AR="$AR" +fi +AC_MSG_RESULT([$NATIVE_AR]) + +AC_MSG_CHECKING([for host C compiler]) +if test -z "$NATIVE_CC"; then + if test "$cross_compiling" = "yes"; then + AC_MSG_ERROR([Cross-compilation requires NATIVE_CC to be set to host C compiler, cannot continue!]) + fi + NATIVE_CC="$CC" +fi +AC_MSG_RESULT([$NATIVE_CC]) + +AC_MSG_CHECKING([for host C++ compiler]) +if test -z "$NATIVE_CXX"; then + if test "$cross_compiling" = "yes"; then + AC_MSG_ERROR([Cross-compilation requires NATIVE_CXX to be set to host C++ compiler, cannot continue!]) + fi + NATIVE_CXX="$CXX" +fi +AC_MSG_RESULT([$NATIVE_CXX]) + +if test -n "$depends_prefix"; then + RUSTUP_TOOLCHAIN="" +fi +AC_SUBST(RUSTUP_TOOLCHAIN) + dnl check if libgmp is present TEMP_CPPFLAGS="$CPPFLAGS" TEMP_LDFLAGS="$LDFLAGS" @@ -1993,6 +2132,17 @@ AC_SUBST(BITCOIN_WALLET_TOOL_NAME) AC_SUBST(BITCOIN_MP_NODE_NAME) AC_SUBST(BITCOIN_MP_GUI_NAME) +AC_SUBST(NATIVE_AR) +AC_SUBST(NATIVE_CC) +AC_SUBST(NATIVE_CXX) +AC_SUBST(RUST_LIBS) +AC_SUBST(RUST_MACOS_DEPLOYMENT_TARGET) +AC_SUBST(RUST_NATIVE) +AC_SUBST(RUST_OSX_SDK) +AC_SUBST(RUST_TARGET) +AC_SUBST(RUST_VENDORED_SOURCES) +AC_SUBST(RUSTUP_TOOLCHAIN) + AC_SUBST(RELDFLAGS) AC_SUBST(CORE_LDFLAGS) AC_SUBST(CORE_CPPFLAGS) @@ -2048,7 +2198,7 @@ AC_SUBST(HAVE_MM_PREFETCH) AC_SUBST(HAVE_STRONG_GETAUXVAL) AC_SUBST(ANDROID_ARCH) AC_SUBST(HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR) -AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini]) +AC_CONFIG_FILES([Makefile rust/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/filter-lcov.py:contrib/filter-lcov.py]) @@ -2138,3 +2288,17 @@ echo " LDFLAGS = $PTHREAD_LIBS $HARDENED_LDFLAGS $GPROF_LDFLAGS $CORE_L echo " AR = $AR" echo " ARFLAGS = $ARFLAGS" echo +echo " CARGO = $CARGO" +echo " CARGO_INCREMENTAL = $CARGO_INCREMENTAL" +echo " CXXBRIDGE = $CXXBRIDGE" +echo " NATIVE_AR = $NATIVE_AR" +echo " NATIVE_CC = $NATIVE_CC" +echo " NATIVE_CXX = $NATIVE_CXX" +echo " RUSTC = $RUSTC" +echo " RUSTFLAGS = $RUSTFLAGS" +echo " RUST_MACOS_DEPLOYMENT_TARGET = $RUST_MACOS_DEPLOYMENT_TARGET" +echo " RUST_NATIVE = $RUST_NATIVE" +echo " RUST_OSX_SDK = $RUST_OSX_SDK" +echo " RUST_TARGET = $RUST_TARGET" +echo " RUST_VENDORED_SOURCES = $RUST_VENDORED_SOURCES" +echo diff --git a/contrib/containers/ci/ci.Dockerfile b/contrib/containers/ci/ci.Dockerfile index 2f0659cbf01f..49e6dc608940 100644 --- a/contrib/containers/ci/ci.Dockerfile +++ b/contrib/containers/ci/ci.Dockerfile @@ -19,8 +19,9 @@ RUN set -ex; \ cmake \ g++-11 \ g++-14 \ - g++-arm-linux-gnueabihf \ + g++-aarch64-linux-gnu \ g++-mingw-w64-x86-64 \ + g++-x86-64-linux-gnu \ gawk \ gettext \ libtool \ @@ -57,6 +58,7 @@ RUN set -ex; \ # LD_LIBRARY_PATH is empty by default, this is the first entry ENV LD_LIBRARY_PATH="/usr/lib/llvm-${LLVM_VERSION}/lib" +# Install IWYU RUN set -ex; \ git clone --depth=1 "https://github.com/include-what-you-use/include-what-you-use" -b "clang_${LLVM_VERSION}" /opt/iwyu; \ cd /opt/iwyu; \ diff --git a/contrib/containers/deploy/Dockerfile.GitHubActions.Dispatch b/contrib/containers/deploy/Dockerfile.GitHubActions.Dispatch index 4db05ed6c25f..c6452786809b 100644 --- a/contrib/containers/deploy/Dockerfile.GitHubActions.Dispatch +++ b/contrib/containers/deploy/Dockerfile.GitHubActions.Dispatch @@ -9,7 +9,7 @@ RUN apt-get update && \ build-essential \ ca-certificates \ curl \ - g++-arm-linux-gnueabihf \ + g++-aarch64-linux-gnu \ libtool \ pkg-config \ python3 \ @@ -23,14 +23,14 @@ COPY . . ARG TARGETPLATFORM RUN case "$TARGETPLATFORM" in \ - "linux/arm64") make HOST=arm-linux-gnueabihf -C depends -j`nproc | awk '{x=$1/2; print x}'` ;; \ + "linux/arm64") make HOST=aarch64-linux-gnu -C depends -j`nproc | awk '{x=$1/2; print x}'` ;; \ "linux/amd64") make HOST=x86_64-pc-linux-gnu -C depends -j`nproc | awk '{x=$1/2; print x}'` ;; \ *) exit 1 ;; \ esac RUN ./autogen.sh && \ case "$TARGETPLATFORM" in \ - "linux/arm64") ./configure --prefix=`pwd`/depends/arm-linux-gnueabihf ;; \ + "linux/arm64") ./configure --prefix=`pwd`/depends/aarch64-linux-gnu ;; \ "linux/amd64") ./configure --prefix=`pwd`/depends/x86_64-pc-linux-gnu ;; \ esac @@ -38,7 +38,7 @@ RUN make -j`nproc | awk '{x=$1/2; print x}'` && make install RUN mkdir built-target && \ case "$TARGETPLATFORM" in \ - "linux/arm64") cp depends/arm-linux-gnueabihf/bin/dash* /home/dash/built-target ;; \ + "linux/arm64") cp depends/aarch64-linux-gnu/bin/dash* /home/dash/built-target ;; \ "linux/amd64") cp depends/x86_64-pc-linux-gnu/bin/dash* /home/dash/built-target ;; \ esac diff --git a/contrib/containers/guix/scripts/setup-sdk b/contrib/containers/guix/scripts/setup-sdk index 9781ce07285d..316dc8ad145a 100755 --- a/contrib/containers/guix/scripts/setup-sdk +++ b/contrib/containers/guix/scripts/setup-sdk @@ -10,8 +10,8 @@ set -eo pipefail SDK_URL="${SDK_URL:-https://bitcoincore.org/depends-sources/sdks}" SDK_PATH="${SDK_PATH:-depends/SDKs}" SDK_SOURCES="${SDK_SOURCES:-depends/sdk-sources}" -XCODE_VERSION="${XCODE_VERSION:-15.0}" -XCODE_RELEASE="${XCODE_RELEASE:-15A240d}" +XCODE_VERSION="${XCODE_VERSION:-16.0}" +XCODE_RELEASE="${XCODE_RELEASE:-16A242d}" XCODE_ARCHIVE="Xcode-${XCODE_VERSION}-${XCODE_RELEASE}-extracted-SDK-with-libcxx-headers" XCODE_AR_PATH="${SDK_SOURCES}/${XCODE_ARCHIVE}.tar.gz" diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 31cc1f032c77..c7dbad85e8be 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -171,35 +171,6 @@ optimize-pngs.py A script to optimize png files in the dash repository (requires pngcrush). -security-check.py and test-security-check.py -============================================ - -Perform basic security checks on a series of executables. - -symbol-check.py -=============== - -A script to check that release executables 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: - - find ../path/to/executables -type f -executable | xargs python3 contrib/devtools/symbol-check.py - -If no errors occur the return value will be 0 and the output will be empty. - -If there are any errors the return value will be 1 and output like this will be printed: - - .../64/test_dash: symbol memcpy from unsupported version GLIBC_2.14 - .../64/test_dash: symbol __fdelt_chk from unsupported version GLIBC_2.15 - .../64/test_dash: symbol std::out_of_range::~out_of_range() from unsupported version GLIBCXX_3.4.15 - .../64/test_dash: symbol _ZNSt8__detail15_List_nod from unsupported version GLIBCXX_3.4.15 - update-translations.py ====================== diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py deleted file mode 100755 index d64d08fb732f..000000000000 --- a/contrib/devtools/test-security-check.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2015-2021 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' -Test script for security-check.py -''' -import lief -import os -import subprocess -from typing import List -import unittest - -from utils import determine_wellknown_cmd - -def write_testcode(filename): - with open(filename, 'w', encoding="utf8") as f: - f.write(''' - #include - int main() - { - std::printf("the quick brown fox jumps over the lazy god\\n"); - return 0; - } - ''') - -def clean_files(source, executable): - os.remove(source) - os.remove(executable) - -def env_flags() -> List[str]: - # This should behave the same as AC_TRY_LINK, so arrange well-known flags - # in the same order as autoconf would. - # - # See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for - # reference. - flags: List[str] = [] - for var in ['CXXFLAGS', 'CPPFLAGS', 'LDFLAGS']: - flags += filter(None, os.environ.get(var, '').split(' ')) - return flags - -def call_security_check(cxx, source, executable, options): - subprocess.run([*cxx,source,'-o',executable] + env_flags() + options, check=True) - p = subprocess.run([os.path.join(os.path.dirname(__file__), 'security-check.py'), executable], stdout=subprocess.PIPE, universal_newlines=True) - return (p.returncode, p.stdout.rstrip()) - -def get_arch(cxx, source, executable): - subprocess.run([*cxx, source, '-o', executable] + env_flags(), check=True) - binary = lief.parse(executable) - arch = binary.abstract.header.architecture - os.remove(executable) - return arch - -class TestSecurityChecks(unittest.TestCase): - def test_ELF(self): - source = 'test1.cpp' - executable = 'test1' - cxx = determine_wellknown_cmd('CXX', 'g++') - write_testcode(source) - arch = get_arch(cxx, source, executable) - - if arch == lief.ARCHITECTURES.X86: - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-zexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE NX RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), - (1, executable+': failed RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), - (1, executable+': failed separate_code CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), - (1, executable+': failed CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code', '-fcf-protection=full']), - (0, '')) - else: - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-zexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE NX RELRO')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), - (1, executable+': failed RELRO')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), - (1, executable+': failed separate_code')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), - (0, '')) - - clean_files(source, executable) - - def test_PE(self): - source = 'test1.cpp' - executable = 'test1.exe' - cxx = determine_wellknown_cmd('CXX', 'x86_64-w64-mingw32-g++') - write_testcode(source) - - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,--disable-nxcompat','-Wl,--disable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE','-fno-stack-protector']), - (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION CONTROL_FLOW Canary')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,--nxcompat','-Wl,--disable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE','-fstack-protector-all', '-lssp']), - (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE','-fstack-protector-all', '-lssp']), - (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-pie','-fPIE','-fstack-protector-all', '-lssp']), - (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA CONTROL_FLOW')) # -pie -fPIE does nothing unless --dynamicbase is also supplied - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--disable-high-entropy-va','-pie','-fPIE','-fstack-protector-all', '-lssp']), - (1, executable+': failed HIGH_ENTROPY_VA CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE','-fstack-protector-all', '-lssp']), - (1, executable+': failed CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE', '-fcf-protection=full','-fstack-protector-all', '-lssp']), - (0, '')) - - clean_files(source, executable) - - def test_MACHO(self): - source = 'test1.cpp' - executable = 'test1' - cxx = determine_wellknown_cmd('CXX', 'clang++') - write_testcode(source) - arch = get_arch(cxx, source, executable) - - if arch == lief.ARCHITECTURES.X86: - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-no_fixup_chains']), - (1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS PIE CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-fixup_chains']), - (1, executable+': failed NOUNDEFS Canary CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains']), - (1, executable+': failed NOUNDEFS CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-fstack-protector-all', '-Wl,-fixup_chains']), - (1, executable+': failed CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']), - (0, '')) - else: - # arm64 darwin doesn't support non-PIE binaries, control flow or executable stacks - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-no_fixup_chains']), - (1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS BRANCH_PROTECTION')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-fixup_chains', '-mbranch-protection=bti']), - (1, executable+': failed NOUNDEFS Canary')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains', '-mbranch-protection=bti']), - (1, executable+': failed NOUNDEFS')) - self.assertEqual(call_security_check(cxx, source, executable, ['-fstack-protector-all', '-Wl,-fixup_chains', '-mbranch-protection=bti']), - (0, '')) - - - clean_files(source, executable) - -if __name__ == '__main__': - unittest.main() diff --git a/contrib/devtools/test-symbol-check.py b/contrib/devtools/test-symbol-check.py deleted file mode 100755 index 92966000406b..000000000000 --- a/contrib/devtools/test-symbol-check.py +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2020-2021 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' -Test script for symbol-check.py -''' -import os -import subprocess -from typing import List -import unittest - -from utils import determine_wellknown_cmd - -def call_symbol_check(cxx: List[str], source, executable, options): - # This should behave the same as AC_TRY_LINK, so arrange well-known flags - # in the same order as autoconf would. - # - # See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for - # reference. - env_flags: List[str] = [] - for var in ['CXXFLAGS', 'CPPFLAGS', 'LDFLAGS']: - env_flags += filter(None, os.environ.get(var, '').split(' ')) - - subprocess.run([*cxx,source,'-o',executable] + env_flags + options, check=True) - p = subprocess.run([os.path.join(os.path.dirname(__file__), 'symbol-check.py'), executable], stdout=subprocess.PIPE, universal_newlines=True) - os.remove(source) - os.remove(executable) - return (p.returncode, p.stdout.rstrip()) - -class TestSymbolChecks(unittest.TestCase): - def test_ELF(self): - source = 'test1.cpp' - executable = 'test1' - cxx = determine_wellknown_cmd('CXX', 'g++') - - # -lutil is part of the libc6 package so a safe bet that it's installed - # it's also out of context enough that it's unlikely to ever become a real dependency - source = 'test2.cpp' - executable = 'test2' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - login(0); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-lutil']), - (1, executable + ': libutil.so.1 is not in ALLOWED_LIBRARIES!\n' + - executable + ': failed LIBRARY_DEPENDENCIES')) - - # finally, check a simple conforming binary - source = 'test3.cpp' - executable = 'test3' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - std::printf("42"); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, []), - (0, '')) - - def test_MACHO(self): - source = 'test1.cpp' - executable = 'test1' - cxx = determine_wellknown_cmd('CXX', 'clang++') - - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - XML_ExpatVersion(); - return 0; - } - - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-lexpat', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']), - (1, 'libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' + - f'{executable}: failed DYNAMIC_LIBRARIES MIN_OS SDK')) - - source = 'test2.cpp' - executable = 'test2' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - CGMainDisplayID(); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-framework', 'CoreGraphics', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']), - (1, f'{executable}: failed MIN_OS SDK')) - - source = 'test3.cpp' - executable = 'test3' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - int main() - { - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,11.0', '-Wl,11.4']), - (1, f'{executable}: failed SDK')) - - def test_PE(self): - source = 'test1.cpp' - executable = 'test1.exe' - cxx = determine_wellknown_cmd('CXX', 'x86_64-w64-mingw32-g++') - - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - PdhConnectMachineA(NULL); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-lpdh', '-Wl,--major-subsystem-version', '-Wl,6', '-Wl,--minor-subsystem-version', '-Wl,1']), - (1, 'pdh.dll is not in ALLOWED_LIBRARIES!\n' + - executable + ': failed DYNAMIC_LIBRARIES')) - - source = 'test2.cpp' - executable = 'test2.exe' - - with open(source, 'w', encoding="utf8") as f: - f.write(''' - int main() - { - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-Wl,--major-subsystem-version', '-Wl,9', '-Wl,--minor-subsystem-version', '-Wl,9']), - (1, executable + ': failed SUBSYSTEM_VERSION')) - - source = 'test3.cpp' - executable = 'test3.exe' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - CoFreeUnusedLibrariesEx(0,0); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-lole32', '-Wl,--major-subsystem-version', '-Wl,6', '-Wl,--minor-subsystem-version', '-Wl,1']), - (0, '')) - - -if __name__ == '__main__': - unittest.main() diff --git a/contrib/devtools/update-native-cxxbridge.py b/contrib/devtools/update-native-cxxbridge.py new file mode 100755 index 000000000000..2628912612e0 --- /dev/null +++ b/contrib/devtools/update-native-cxxbridge.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import re +import shutil +import subprocess +import sys +import tarfile +import tempfile +from pathlib import Path + +def get_cxx_version(makefile_path: Path) -> str: + content = makefile_path.read_text() + match = re.search(r"\$\(package\)_version:=(.+)", content) + if not match: + raise RuntimeError("Could not find cxx version in makefile") + return match.group(1).strip() + + +def main() -> int: + script_dir = Path(__file__).resolve().parent + repo_root = script_dir / "../.." + repo_root = repo_root.resolve() + + makefile_path = repo_root / "depends/packages/native_cxxbridge.mk" + if not makefile_path.exists(): + print(f"Error: {makefile_path} not found", file=sys.stderr) + return 1 + + version = get_cxx_version(makefile_path) + print(f"cxx version: {version}") + + tarball_path = repo_root / f"depends/sources/native_cxxbridge-{version}.tar.gz" + if not tarball_path.exists(): + print(f"Error: {tarball_path} not found", file=sys.stderr) + print("Run 'make -C depends download-one PKG=native_cxxbridge' first", file=sys.stderr) + return 1 + + toolchain_path = repo_root / "rust-toolchain.toml" + if not toolchain_path.exists(): + print(f"Error: {toolchain_path} not found", file=sys.stderr) + return 1 + + with tempfile.TemporaryDirectory() as tmp_dir: + tmp_path = Path(tmp_dir) + print(f"Working in {tmp_path}") + + # Copy rust-toolchain.toml + shutil.copy(toolchain_path, tmp_path / "rust-toolchain.toml") + + # Extract tarball + print(f"Extracting {tarball_path}") + with tarfile.open(tarball_path, "r:gz") as tar: + tar.extractall(tmp_path) + + cxx_dir = tmp_path / f"cxx-{version}" + if not cxx_dir.exists(): + print(f"Error: Expected directory {cxx_dir} not found after extraction", file=sys.stderr) + return 1 + + # Copy rust-toolchain.toml into cxx directory + shutil.copy(toolchain_path, cxx_dir / "rust-toolchain.toml") + + # Run cargo check + print("Running cargo check --release --package=cxxbridge-cmd --bin=cxxbridge") + result = subprocess.run( + ["cargo", "check", "--release", "--package=cxxbridge-cmd", "--bin=cxxbridge"], + cwd=cxx_dir, + ) + if result.returncode != 0: + print("Error: cargo check failed", file=sys.stderr) + return 1 + + # Copy Cargo.lock to patches directory + cargo_lock_src = cxx_dir / "Cargo.lock" + cargo_lock_dst = repo_root / "depends/patches/native_cxxbridge/Cargo.lock" + if not cargo_lock_src.exists(): + print(f"Error: {cargo_lock_src} not found after cargo check", file=sys.stderr) + return 1 + + cargo_lock_dst.parent.mkdir(parents=True, exist_ok=True) + shutil.copy(cargo_lock_src, cargo_lock_dst) + print(f"Copied Cargo.lock to {cargo_lock_dst}") + + print("\nDone!") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/contrib/devtools/update-rust-hashes.py b/contrib/devtools/update-rust-hashes.py new file mode 100755 index 000000000000..04fef67f9513 --- /dev/null +++ b/contrib/devtools/update-rust-hashes.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2021-2022 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import hashlib +import re +import sys +import urllib.request +from pathlib import Path + +# Corresponds to 'hosts/*.mk' +CROSS_TARGETS = [ + # FreeBSD + "x86_64-unknown-freebsd", + # Linux + "aarch64-unknown-linux-musl", + "armv7-unknown-linux-musleabihf", + "powerpc64le-unknown-linux-musl", + "riscv64gc-unknown-linux-musl", + "x86_64-unknown-linux-musl", + # Windows + "x86_64-pc-windows-gnu", + # macOS + "aarch64-apple-darwin", + "x86_64-apple-darwin", +] + +# Corresponds to 'builders/*.mk' +NATIVE_TARGETS = [ + # FreeBSD + ("x86_64-unknown-freebsd", "x86_64_freebsd"), + # Linux + ("aarch64-unknown-linux-gnu", "aarch64_linux"), + ("x86_64-unknown-linux-gnu", "x86_64_linux"), + # macOS + ("aarch64-apple-darwin", "aarch64_darwin"), + ("x86_64-apple-darwin", "x86_64_darwin"), +] + +def get_rust_version(makefile_path: Path) -> str: + content = makefile_path.read_text() + match = re.search(r"\$\(package\)_version:=(.+)", content) + if not match: + raise RuntimeError("Could not find Rust version in makefile") + return match.group(1).strip() + + +def compute_sha256(url: str) -> str: + hasher = hashlib.sha256() + with urllib.request.urlopen(url) as response: + while chunk := response.read(8192): + hasher.update(chunk) + return hasher.hexdigest() + + +def update_hash_in_file(makefile_path: Path, pattern: str, new_hash: str) -> None: + content = makefile_path.read_text() + regex = re.compile(rf"^(\$\(package\)_{pattern}:=).*$", re.MULTILINE) + if not regex.search(content): + raise RuntimeError(f"Could not find pattern {pattern} in makefile") + new_content = regex.sub(rf"\g<1>{new_hash}", content) + makefile_path.write_text(new_content) + + +def update_rust_hash(makefile_path: Path, rust_version: str, rust_target: str, makefile_id: str) -> None: + url = f"https://static.rust-lang.org/dist/rust-{rust_version}-{rust_target}.tar.gz" + hash_value = compute_sha256(url) + update_hash_in_file(makefile_path, f"sha256_hash_{makefile_id}", hash_value) + print(f" Updated sha256_hash_{makefile_id}") + + +def update_stdlib_hash(makefile_path: Path, rust_version: str, rust_target: str) -> None: + url = f"https://static.rust-lang.org/dist/rust-std-{rust_version}-{rust_target}.tar.gz" + hash_value = compute_sha256(url) + update_hash_in_file(makefile_path, f"sha256_hash_{rust_target}", hash_value) + print(f" Updated sha256_hash_{rust_target}") + + +def main() -> int: + script_dir = Path(__file__).resolve().parent + native_rust_path = script_dir / "../../depends/packages/native_rust.mk" + native_rust_path = native_rust_path.resolve() + rust_stdlib_path = script_dir / "../../depends/packages/rust_stdlib.mk" + rust_stdlib_path = rust_stdlib_path.resolve() + + if not native_rust_path.exists(): + print(f"Error: {native_rust_path} not found", file=sys.stderr) + return 1 + + if not rust_stdlib_path.exists(): + print(f"Error: {rust_stdlib_path} not found", file=sys.stderr) + return 1 + + rust_version = get_rust_version(native_rust_path) + + print(f"Rust version: {rust_version}\n") + print("Updating native compiler hashes:") + + for rust_target, makefile_id in NATIVE_TARGETS: + update_rust_hash(native_rust_path, rust_version, rust_target, makefile_id) + + print("\nUpdating stdlib hashes:") + for rust_target in CROSS_TARGETS: + update_stdlib_hash(rust_stdlib_path, rust_version, rust_target) + + print("\nDone!") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/contrib/guix/README.md b/contrib/guix/README.md index 5e468c783977..366ba7dfc951 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -249,7 +249,7 @@ details. Set the path where _extracted_ SDKs can be found. This is passed through to the depends tree. Note that this is should be set to the _parent_ directory of the actual SDK (e.g. `SDK_PATH=$HOME/Downloads/macOS-SDKs` instead of - `$HOME/Downloads/macOS-SDKs/Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers`). + `$HOME/Downloads/macOS-SDKs/Xcode-16.0-16A242d-extracted-SDK-with-libcxx-headers`). The path that this environment variable points to **must be a directory**, and **NOT a symlink to a directory**. diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index 80b719eb29d8..21afa5c7dbbd 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -301,9 +301,11 @@ mkdir -p "$OUTDIR_BASE" # Download the depends sources now as we won't have internet access in the build # container +depends_cmds="download-rust-std vendor-crates" for host in $HOSTS; do - make -C "${PWD}/depends" -j"$JOBS" download-"$(host_to_commonname "$host")" ${V:+V=1} ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} + depends_cmds+=" download-$(host_to_commonname "$host")" done +make -C "${PWD}/depends" -j"$JOBS" ${depends_cmds} ${V:+V=1} ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} # Usage: outdir_for_host HOST SUFFIX # diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 4e378b000979..63d9ac598e30 100755 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -86,6 +86,9 @@ case "$HOST" in ;; esac +# Rust build scripts need LD_LIBRARY_PATH to find libgcc_s.so.1 at runtime +export LD_LIBRARY_PATH="${LIBRARY_PATH}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + # Set environment variables to point the CROSS toolchain to the right # includes/libs for $HOST case "$HOST" in @@ -192,6 +195,9 @@ case "$HOST" in ;; esac +# Make $HOST-specific native binaries from depends available in $PATH +export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" + ########################### # Source Tarball Building # ########################### @@ -238,6 +244,11 @@ case "$HOST" in *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; esac +case "$HOST" in + *darwin*) export NATIVE_AR="llvm-ar" NATIVE_CC="clang" NATIVE_CXX="clang++" ;; + *) export NATIVE_AR="ar" NATIVE_CC="gcc" NATIVE_CXX="g++" ;; +esac + mkdir -p "$DISTSRC" ( cd "$DISTSRC" @@ -272,8 +283,6 @@ mkdir -p "$DISTSRC" ;; esac - # Check that symbol/security checks tools are sane. - make test-security-check ${V:+V=1} # Perform basic security checks on a series of executables. make -C src --jobs=1 check-security ${V:+V=1} # Check that executables only contain allowed version symbols. diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 3a327e63e137..285d8baeea5d 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -8,6 +8,7 @@ (gnu packages commencement) (gnu packages compression) (gnu packages cross-base) + ((gnu packages elf) #:select (patchelf)) (gnu packages file) (gnu packages gawk) (gnu packages gcc) @@ -433,6 +434,7 @@ inspecting signatures in Mach-O binaries.") ;; https://gcc.gnu.org/install/configure.html (list "--enable-threads=posix", "--enable-default-ssp=yes", + "--disable-gcov", building-on))))))) (define-public linux-base-gcc @@ -448,6 +450,7 @@ inspecting signatures in Mach-O binaries.") "--enable-default-pie=yes", "--enable-standard-branch-protection=yes", "--enable-cet=yes", + "--disable-gcov", building-on))) ((#:phases phases) `(modify-phases ,phases @@ -530,6 +533,7 @@ inspecting signatures in Mach-O binaries.") libtool autoconf-2.71 automake + patchelf pkg-config ;; Scripting python-minimal ;; (3.10) diff --git a/contrib/devtools/security-check.py b/contrib/guix/security-check.py similarity index 78% rename from contrib/devtools/security-check.py rename to contrib/guix/security-check.py index 001e46ceeef7..e3f2c029932b 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/guix/security-check.py @@ -6,7 +6,12 @@ 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. + +Example usage: + + find ../path/to/guix/binaries -type f -executable | xargs python3 contrib/guix/security-check.py ''' +import re import sys from typing import List @@ -39,13 +44,13 @@ def check_ELF_RELRO(binary) -> bool: return have_gnu_relro and have_bindnow -def check_ELF_Canary(binary) -> bool: +def check_ELF_CANARY(binary) -> bool: ''' Check for use of stack canary ''' return binary.has_symbol('__stack_chk_fail') -def check_ELF_separate_code(binary): +def check_ELF_SEPARATE_CODE(binary): ''' Check that sections are appropriately separated in virtual memory, based on their permissions. This checks for missing -Wl,-z,separate-code @@ -106,7 +111,7 @@ def check_ELF_separate_code(binary): return False return True -def check_ELF_control_flow(binary) -> bool: +def check_ELF_CONTROL_FLOW(binary) -> bool: ''' Check for control flow instrumentation ''' @@ -117,6 +122,25 @@ def check_ELF_control_flow(binary) -> bool: return True return False +def check_ELF_FORTIFY(binary) -> bool: + + # bitcoin-util does not currently contain any fortified functions + if 'Bitcoin Core bitcoin-util utility version ' in binary.strings: + return True + + chk_funcs = set() + + for sym in binary.imported_symbols: + match = re.search(r'__[a-z]*_chk', sym.name) + if match: + chk_funcs.add(match.group(0)) + + # ignore stack-protector and bdb + chk_funcs.discard('__stack_chk') + chk_funcs.discard('__db_chk') + + return len(chk_funcs) >= 1 + def check_PE_DYNAMIC_BASE(binary) -> bool: '''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)''' return lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists @@ -131,7 +155,7 @@ def check_PE_RELOC_SECTION(binary) -> bool: '''Check for a reloc section. This is required for functional ASLR.''' return binary.has_relocations -def check_PE_control_flow(binary) -> bool: +def check_PE_CONTROL_FLOW(binary) -> bool: ''' Check for control flow instrumentation ''' @@ -146,7 +170,7 @@ def check_PE_control_flow(binary) -> bool: return True return False -def check_PE_Canary(binary) -> bool: +def check_PE_CANARY(binary) -> bool: ''' Check for use of stack canary ''' @@ -164,7 +188,7 @@ def check_MACHO_FIXUP_CHAINS(binary) -> bool: ''' return binary.has_dyld_chained_fixups -def check_MACHO_Canary(binary) -> bool: +def check_MACHO_CANARY(binary) -> bool: ''' Check for use of stack canary ''' @@ -183,7 +207,7 @@ def check_NX(binary) -> bool: ''' return binary.has_nx -def check_MACHO_control_flow(binary) -> bool: +def check_MACHO_CONTROL_FLOW(binary) -> bool: ''' Check for control flow instrumentation ''' @@ -193,7 +217,7 @@ def check_MACHO_control_flow(binary) -> bool: return True return False -def check_MACHO_branch_protection(binary) -> bool: +def check_MACHO_BRANCH_PROTECTION(binary) -> bool: ''' Check for branch protection instrumentation ''' @@ -207,8 +231,8 @@ def check_MACHO_branch_protection(binary) -> bool: ('PIE', check_PIE), ('NX', check_NX), ('RELRO', check_ELF_RELRO), - ('Canary', check_ELF_Canary), - ('separate_code', check_ELF_separate_code), + ('CANARY', check_ELF_CANARY), + ('SEPARATE_CODE', check_ELF_SEPARATE_CODE), ] BASE_PE = [ @@ -217,23 +241,23 @@ def check_MACHO_branch_protection(binary) -> bool: ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), ('NX', check_NX), ('RELOC_SECTION', check_PE_RELOC_SECTION), - ('CONTROL_FLOW', check_PE_control_flow), - ('Canary', check_PE_Canary), + ('CONTROL_FLOW', check_PE_CONTROL_FLOW), + ('CANARY', check_PE_CANARY), ] BASE_MACHO = [ ('NOUNDEFS', check_MACHO_NOUNDEFS), - ('Canary', check_MACHO_Canary), + ('CANARY', check_MACHO_CANARY), ('FIXUP_CHAINS', check_MACHO_FIXUP_CHAINS), ] CHECKS = { lief.EXE_FORMATS.ELF: { - lief.ARCHITECTURES.X86: BASE_ELF + [('CONTROL_FLOW', check_ELF_control_flow)], - lief.ARCHITECTURES.ARM: BASE_ELF, - lief.ARCHITECTURES.ARM64: BASE_ELF, - lief.ARCHITECTURES.PPC: BASE_ELF, - lief.ARCHITECTURES.RISCV: BASE_ELF, + lief.ARCHITECTURES.X86: BASE_ELF + [('CONTROL_FLOW', check_ELF_CONTROL_FLOW), ('FORTIFY', check_ELF_FORTIFY)], + lief.ARCHITECTURES.ARM: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)], + lief.ARCHITECTURES.ARM64: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)], + lief.ARCHITECTURES.PPC: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)], + lief.ARCHITECTURES.RISCV: BASE_ELF, # Skip FORTIFY. See https://github.com/lief-project/LIEF/issues/1082. }, lief.EXE_FORMATS.PE: { lief.ARCHITECTURES.X86: BASE_PE, @@ -241,39 +265,24 @@ def check_MACHO_branch_protection(binary) -> bool: lief.EXE_FORMATS.MACHO: { lief.ARCHITECTURES.X86: BASE_MACHO + [('PIE', check_PIE), ('NX', check_NX), - ('CONTROL_FLOW', check_MACHO_control_flow)], - lief.ARCHITECTURES.ARM64: BASE_MACHO + [('BRANCH_PROTECTION', check_MACHO_branch_protection)], + ('CONTROL_FLOW', check_MACHO_CONTROL_FLOW)], + lief.ARCHITECTURES.ARM64: BASE_MACHO + [('BRANCH_PROTECTION', check_MACHO_BRANCH_PROTECTION)], } } if __name__ == '__main__': retval: int = 0 for filename in sys.argv[1:]: - try: - binary = lief.parse(filename) - etype = binary.format - arch = binary.abstract.header.architecture - binary.concrete - - if etype == lief.EXE_FORMATS.UNKNOWN: - print(f'{filename}: unknown executable format') - retval = 1 - continue - - if arch == lief.ARCHITECTURES.NONE: - print(f'{filename}: unknown architecture') - retval = 1 - continue - - failed: List[str] = [] - for (name, func) in CHECKS[etype][arch]: - if not func(binary): - failed.append(name) - if failed: - print(f'{filename}: failed {" ".join(failed)}') - retval = 1 - except IOError: - print(f'{filename}: cannot open') + binary = lief.parse(filename) + etype = binary.format + arch = binary.abstract.header.architecture + binary.concrete + + failed: List[str] = [] + for (name, func) in CHECKS[etype][arch]: + if not func(binary): + failed.append(name) + if failed: + print(f'{filename}: failed {" ".join(failed)}') retval = 1 sys.exit(retval) - diff --git a/contrib/devtools/symbol-check.py b/contrib/guix/symbol-check.py similarity index 91% rename from contrib/devtools/symbol-check.py rename to contrib/guix/symbol-check.py index c296ad16fb9a..9f1e966e93e0 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/guix/symbol-check.py @@ -8,7 +8,7 @@ Example usage: - find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py + find ../path/to/guix/binaries -type f -executable | xargs python3 contrib/guix/symbol-check.py ''' import sys from typing import Dict, List @@ -33,7 +33,7 @@ # See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for more info. MAX_VERSIONS = { -'GCC': (4,3,0), +'GCC': (7,0,0), 'GLIBC': { lief.ELF.ARCH.x86_64: (2,31), lief.ELF.ARCH.ARM: (2,31), @@ -157,14 +157,16 @@ } PE_ALLOWED_LIBRARIES = { -'ADVAPI32.dll', # security & registry +'ADVAPI32.dll', # legacy security & registry +'bcrypt.dll', # newer security and identity API 'IPHLPAPI.DLL', # IP helper API 'KERNEL32.dll', # win32 base APIs 'msvcrt.dll', # C standard library for MSVC 'SHELL32.dll', # shell API 'WS2_32.dll', # sockets -'bcrypt.dll', # crypto API +'ntdll.dll', # NT kernel API 'dbghelp.dll', # debugging routines +'api-ms-win-core-synch-l1-2-0.dll', # sync primitives (API set) # bitcoin-qt only 'dwmapi.dll', # desktop window manager 'GDI32.dll', # graphics device interface @@ -243,12 +245,12 @@ def check_MACHO_libraries(binary) -> bool: return ok def check_MACHO_min_os(binary) -> bool: - if binary.build_version.minos == [11,0,0]: + if binary.build_version.minos == [14, 0, 0]: return True return False def check_MACHO_sdk(binary) -> bool: - if binary.build_version.sdk == [14, 0, 0]: + if binary.build_version.sdk == [15, 0, 0]: return True return False @@ -268,7 +270,7 @@ def check_PE_libraries(binary) -> bool: def check_PE_subsystem_version(binary) -> bool: major: int = binary.optional_header.major_subsystem_version minor: int = binary.optional_header.minor_subsystem_version - if major == 6 and minor == 1: + if major == 6 and minor == 2: return True return False @@ -308,22 +310,14 @@ def check_ELF_ABI(binary) -> bool: if __name__ == '__main__': retval: int = 0 for filename in sys.argv[1:]: - try: - binary = lief.parse(filename) - etype = binary.format - if etype == lief.EXE_FORMATS.UNKNOWN: - print(f'{filename}: unknown executable format') - retval = 1 - continue - - failed: List[str] = [] - for (name, func) in CHECKS[etype]: - if not func(binary): - failed.append(name) - if failed: - print(f'{filename}: failed {" ".join(failed)}') - retval = 1 - except IOError: - print(f'{filename}: cannot open') + binary = lief.parse(filename) + etype = binary.format + + failed: List[str] = [] + for (name, func) in CHECKS[etype]: + if not func(binary): + failed.append(name) + if failed: + print(f'{filename}: failed {" ".join(failed)}') retval = 1 sys.exit(retval) diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md index cf32a07602d3..86d122f6dfae 100644 --- a/contrib/macdeploy/README.md +++ b/contrib/macdeploy/README.md @@ -15,14 +15,14 @@ When complete, it will have produced `Dash-Core.zip`. A free Apple Developer Account is required to proceed. Our macOS SDK can be extracted from -[Xcode_15.xip](https://download.developer.apple.com/Developer_Tools/Xcode_15/Xcode_15.xip). +[Xcode_16.xip](https://download.developer.apple.com/Developer_Tools/Xcode_16/Xcode_16.xip). Alternatively, after logging in to your account go to 'Downloads', then 'More' -and search for [`Xcode 15`](https://developer.apple.com/download/all/?q=Xcode%2015). +and search for [`Xcode 16`](https://developer.apple.com/download/all/?q=Xcode%2016). An Apple ID and cookies enabled for the hostname are needed to download this. -The `sha256sum` of the downloaded XIP archive should be `4daaed2ef2253c9661779fa40bfff50655dc7ec45801aba5a39653e7bcdde48e`. +The `sha256sum` of the downloaded XIP archive should be `4a26c3d102a55c7222fb145e0ee1503249c9c26c6e02dc64d783c8810b37b1e3`. To extract the `.xip` on Linux: @@ -33,13 +33,13 @@ git clone https://github.com/bitcoin-core/apple-sdk-tools.git # Unpack the .xip and place the resulting Xcode.app in your current # working directory -python3 apple-sdk-tools/extract_xcode.py -f Xcode_15.xip | cpio -d -i +python3 apple-sdk-tools/extract_xcode.py -f Xcode_16.xip | cpio -d -i ``` On macOS: ```bash -xip -x Xcode_15.xip +xip -x Xcode_16.xip ``` ### Step 2: Generating the SDK tarball from `Xcode.app` @@ -51,8 +51,8 @@ path to `Xcode.app` (extracted in the previous stage) as the first argument. ./contrib/macdeploy/gen-sdk '/path/to/Xcode.app' ``` -The generated archive should be: `Xcode-15.0-15A240d-extracted-SDK-with-libcxx-headers.tar.gz`. -The `sha256sum` should be `c0c2e7bb92c1fee0c4e9f3a485e4530786732d6c6dd9e9f418c282aa6892f55d`. +The generated archive should be: `Xcode-16.0-16A242d-extracted-SDK-with-libcxx-headers.tar.gz`. +The `sha256sum` should be `bce59aa16560f182e44200a0b9539bd637c8b5c7089fbff13b0712730ce162ff`. ## Deterministic macOS App Notes diff --git a/depends/Makefile b/depends/Makefile index c8510f4cc010..ce65dece076e 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -60,6 +60,9 @@ DOWNLOAD_RETRIES:=3 HOST_ID_SALT ?= salt BUILD_ID_SALT ?= salt +CRATE_REGISTRY := vendored-sources +CRATE_ARCHIVE = $(SOURCES_PATH)/vendored-crates.tar.gz + ifneq ($(DEBUG),) release_type=debug else @@ -179,6 +182,7 @@ usdt_packages_$(NO_USDT) = $(usdt_$(host_os)_packages) packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(boost_packages_) $(libevent_packages_) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) $(natpmp_packages_) $(usdt_packages_) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) +native_packages += native_rust $(native_cargo_packages) ifneq ($(zmq_packages_),) packages += $(zmq_packages) @@ -202,9 +206,37 @@ $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) mkdir -p $(@D) echo copying packages: $^ echo to: $(@D) - cd $(@D); $(foreach package,$^, $(build_TAR) xf $($(package)_cached); ) + cd $(@D); $(foreach package,$^, $(build_TAR) -P --no-same-owner -xf $($(package)_cached); ) touch $@ +# Vendors Rust crate dependencies for offline builds +# Uses pre-built archive if available, otherwise runs 'cargo vendor' +$(host_prefix)/$(CRATE_REGISTRY): $(host_prefix)/.stamp_$(final_build_id) + @if test -f $(CRATE_ARCHIVE); \ + then echo Extracting pre-vendored crates from $(CRATE_ARCHIVE)...; \ + $(build_TAR) -P --no-same-owner -xf $(CRATE_ARCHIVE) -C $(@D); \ + else echo Vendoring crates...; \ + $(@D)/native/bin/cargo vendor --locked --manifest-path $(BASEDIR)/../Cargo.toml $@; \ + fi + @touch $@ + +# Vendors crates for cargo packages +vendor-dep-crates: $(foreach package,$(native_cargo_packages),vendor-$(package)-crates) + +# Vendors project-wide cargo packages +vendor-all-crates: $(native_rust_cached) + @rm -rf $(WORK_PATH)/vendor-main + @mkdir -p $(WORK_PATH)/vendor-main + @$(build_TAR) -P --no-same-owner -xf $(native_rust_cached) -C $(WORK_PATH)/vendor-main + @echo "Vendoring main project crates..." + @$(WORK_PATH)/vendor-main/native/bin/cargo vendor --locked --manifest-path $(BASEDIR)/../Cargo.toml $(WORK_PATH)/vendor-main/$(CRATE_REGISTRY) + @cd $(WORK_PATH)/vendor-main; find $(CRATE_REGISTRY) | sort | $(build_TAR) --no-recursion -czf $(CRATE_ARCHIVE) -T - + @rm -rf $(WORK_PATH)/vendor-main + @echo "Created $(CRATE_ARCHIVE)" + +# Vendors everything +vendor-crates: vendor-dep-crates vendor-all-crates + # $PATH is not preserved between ./configure and make by convention. Its # modification and overriding at ./configure time is (as I understand it) # supposed to be captured by the AC_{PROG_{,OBJ}CXX,PATH_{PROG,TOOL}} macros, @@ -232,13 +264,18 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ @mkdir -p $(@D) sed -e 's|@HOST@|$(host)|' \ -e 's|@CC@|$(host_CC)|' \ + -e 's|@NATIVE_CC@|$(build_CC)|' \ -e 's|@CXX@|$(host_CXX)|' \ + -e 's|@NATIVE_CXX@|$(build_CXX)|' \ -e 's|@AR@|$(host_AR)|' \ + -e 's|@NATIVE_AR@|$(build_AR)|' \ -e 's|@RANLIB@|$(host_RANLIB)|' \ -e 's|@NM@|$(host_NM)|' \ -e 's|@STRIP@|$(host_STRIP)|' \ -e 's|@OBJDUMP@|$(host_OBJDUMP)|' \ -e 's|@DSYMUTIL@|$(host_DSYMUTIL)|' \ + -e 's|@OSX_MIN_VERSION@|$(OSX_MIN_VERSION)|' \ + -e 's|@OSX_SDK@|$(OSX_SDK)|' \ -e 's|@WINDRES@|$(host_WINDRES)|' \ -e 's|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ @@ -293,7 +330,7 @@ clean-all: clean clean: @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) *.log -install: check-packages $(host_prefix)/share/config.site +install: check-packages $(host_prefix)/share/config.site $(host_prefix)/$(CRATE_REGISTRY) download-one: check-sources $(all_sources) @@ -304,10 +341,14 @@ download-linux: @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one download-win: @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one -download: download-osx download-linux download-win +download-rust-std: + @mkdir -p $(SOURCES_PATH) + @mkdir -p $(SOURCES_PATH)/download-stamps + @$(foreach target,$(rust_stdlib_targets),$(call download_rust_std_target,$(target)) && ) true +download: download-osx download-linux download-win download-rust-std $(foreach package,$(all_packages),$(eval $(call ext_add_stages,$(package)))) -.PHONY: install cached clean clean-all download-one download-osx download-linux download-win download check-packages check-sources +.PHONY: install cached clean clean-all download-one download-osx download-linux download-win download download-rust-std check-packages check-sources vendor-crates vendor-dep-crates vendor-all-crates .PHONY: FORCE $(V).SILENT: diff --git a/depends/config.site.in b/depends/config.site.in index 398a09b74c63..a1ccdbcbd7bf 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -95,14 +95,25 @@ LDFLAGS="-L${depends_prefix}/lib ${LDFLAGS}" if test -n "@CC@" -a -z "${CC}"; then CC="@CC@" fi +if test -n "@NATIVE_CC@" -a -z "${NATIVE_CC}"; then + NATIVE_CC="@NATIVE_CC@" +fi + if test -n "@CXX@" -a -z "${CXX}"; then CXX="@CXX@" fi +if test -n "@NATIVE_CXX@" -a -z "${NATIVE_CXX}"; then + NATIVE_CXX="@NATIVE_CXX@" +fi if test -n "@AR@"; then AR="@AR@" ac_cv_path_AR="${AR}" fi +if test -n "@NATIVE_AR@"; then + NATIVE_AR="@NATIVE_AR@" + ac_cv_path_NATIVE_AR="${NATIVE_AR}" +fi if test -n "@RANLIB@"; then RANLIB="@RANLIB@" @@ -129,6 +140,14 @@ if test "@host_os@" = darwin; then DSYMUTIL="@DSYMUTIL@" ac_cv_path_DSYMUTIL="${DSYMUTIL}" fi + + if test -n "@OSX_MIN_VERSION@"; then + OSX_MIN_VERSION="@OSX_MIN_VERSION@" + fi + + if test -n "@OSX_SDK@"; then + OSX_SDK="@OSX_SDK@" + fi fi if test "@host_os@" = mingw32; then @@ -154,3 +173,14 @@ fi if test -n "@LDFLAGS@"; then LDFLAGS="@LDFLAGS@ ${LDFLAGS}" fi + +if test -x "${depends_prefix}/native/bin/cargo"; then + CARGO="${depends_prefix}/native/bin/cargo" +fi +if test -x "${depends_prefix}/native/bin/rustc"; then + RUSTC="${depends_prefix}/native/bin/rustc" +fi +if test -x "${depends_prefix}/native/bin/cxxbridge"; then + CXXBRIDGE="${depends_prefix}/native/bin/cxxbridge" +fi +RUST_VENDORED_SOURCES="${depends_prefix}/vendored-sources" diff --git a/depends/funcs.mk b/depends/funcs.mk index 964be8ea61c5..7677234867a7 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -83,7 +83,7 @@ $(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 && $(build_TAR) --no-same-owner --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 && $(build_TAR) -P --no-same-owner --strip-components=1 -xf $$($(1)_source) $(1)_preprocess_cmds ?= true $(1)_build_cmds ?= true $(1)_config_cmds ?= true @@ -190,11 +190,23 @@ ifeq ($($(1)_type),build) $(1)_cmake += -DCMAKE_INSTALL_RPATH:PATH="$$($($(1)_type)_prefix)/lib" else ifneq ($(host),$(build)) -$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system) +$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system_name) $(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host) $(1)_cmake += -DCMAKE_CXX_COMPILER_TARGET=$(host) endif endif + +$(1)_cargo=env CC="$$($(1)_cc)" \ + CXX="$$($(1)_cxx)" \ + CFLAGS="$$($(1)_cppflags) $$($(1)_cflags)" \ + CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \ + LDFLAGS="$$($(1)_ldflags)" \ + RUSTFLAGS="-C linker=$$(firstword $($(1)_cc))" \ + LD_LIBRARY_PATH="$$($($(1)_type)_prefix)/lib" +ifeq ($(host_os),darwin) +$(1)_cargo += SDKROOT="$(OSX_SDK)" +endif +$(1)_cargo += cargo endef define int_add_cmds @@ -267,6 +279,36 @@ $(foreach stage,$(stages), .PHONY: $(1)_$(stage)) endef +# Template for vendoring a native package's Rust crate dependencies +# Packages opt-in by defining $(package)_vendored_file_name and $(package)_cargo_manifest +define int_vendor_crates +ifneq ($($(1)_vendored_file_name),) +$(1)_vendored_archive = $(SOURCES_PATH)/$($(1)_vendored_file_name) + +vendor-$(1)-crates: $(native_rust_cached) $(SOURCES_PATH)/$($(1)_file_name) + @rm -rf $(WORK_PATH)/vendor-$(1) + @mkdir -p $(WORK_PATH)/vendor-$(1) + @$(build_TAR) -P --no-same-owner -xf $(native_rust_cached) -C $(WORK_PATH)/vendor-$(1) + @echo "Vendoring $(1) crates..." + @mkdir -p $(WORK_PATH)/vendor-$(1)/src + @cd $(WORK_PATH)/vendor-$(1)/src && $(build_TAR) -P --no-same-owner --strip-components=1 -xf $(SOURCES_PATH)/$($(1)_file_name) + @cp $(PATCHES_PATH)/$(1)/Cargo.lock $(WORK_PATH)/vendor-$(1)/src/ + @$(WORK_PATH)/vendor-$(1)/native/bin/cargo vendor --locked --manifest-path $(WORK_PATH)/vendor-$(1)/src/$($(1)_cargo_manifest) $(WORK_PATH)/vendor-$(1)/src/vendored + @cd $(WORK_PATH)/vendor-$(1)/src; find vendored | sort | $(build_TAR) --no-recursion -czf $$($(1)_vendored_archive) -T - + @rm -rf $(WORK_PATH)/vendor-$(1) + @echo "Created $$($(1)_vendored_archive)" +.PHONY: vendor-$(1)-crates +endif +endef + +define download_rust_std_target +([ -f "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" ] && \ + echo "Already have rust-std-$(rust_stdlib_version)-$(1).tar.gz" || \ + (echo "Downloading rust-std-$(rust_stdlib_version)-$(1).tar.gz..." && \ + $(build_DOWNLOAD) "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" "$(rust_stdlib_download_path)/rust-std-$(rust_stdlib_version)-$(1).tar.gz")) && \ +echo "$(rust_stdlib_sha256_hash_$(1)) rust-std-$(rust_stdlib_version)-$(1).tar.gz" > "$(SOURCES_PATH)/download-stamps/.stamp_fetched-rust_stdlib-$(rust_stdlib_version)-$(rust_stdlib_sha256_hash_$(1)).hash" +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 @@ -284,6 +326,18 @@ $(foreach package,$(all_packages),$(eval $(call int_vars,$(package)))) $(foreach native_package,$(native_packages),$(eval include packages/$(native_package).mk)) $(foreach package,$(packages),$(eval include packages/$(package).mk)) +# Extend preprocess_cmds for cargo packages to extract vendored crates +define int_cargo_preprocess_ext +$(1)_preprocess_cmds += && \ + if test -f $(SOURCES_PATH)/$($(1)_vendored_file_name); then \ + echo "Extracting vendored crates for $(1)..." && \ + $(build_TAR) -P -xf $(SOURCES_PATH)/$($(1)_vendored_file_name) && \ + mkdir -p .cargo && \ + cp $(PATCHES_PATH)/$(1)/cargo-config.toml .cargo/config.toml; \ + fi +endef +$(foreach cargo_package,$(native_cargo_packages),$(eval $(call int_cargo_preprocess_ext,$(cargo_package)))) + #compute a hash of all files that comprise this package's build recipe $(foreach package,$(all_packages),$(eval $(call int_get_build_recipe_hash,$(package)))) @@ -295,3 +349,6 @@ $(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$ #create build targets $(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package)))) + +#create vendor targets for cargo packages +$(foreach cargo_package,$(native_cargo_packages),$(eval $(call int_vendor_crates,$(cargo_package)))) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 845ff03d6bae..eb5e3d15b3d7 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,7 +1,7 @@ -OSX_MIN_VERSION=11.0 -OSX_SDK_VERSION=14.0 -XCODE_VERSION=15.0 -XCODE_BUILD_ID=15A240d +OSX_MIN_VERSION=14.0 +OSX_SDK_VERSION=15.0 +XCODE_VERSION=16.0 +XCODE_BUILD_ID=16A242d LLD_VERSION=711 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers @@ -13,8 +13,10 @@ OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with- # distro releases. # # Source: https://lists.gnu.org/archive/html/bug-make/2017-11/msg00017.html -clang_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang") -clangxx_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") +clang_prog:=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang") +clangxx_prog:=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") + +clang_resource_dir:=$(shell $(SHELL) $(.SHELLFLAGS) "$(clang_prog) -print-resource-dir") darwin_AR=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-ar") darwin_DSYMUTIL=$(shell $(SHELL) $(.SHELLFLAGS) "command -v dsymutil") @@ -51,13 +53,15 @@ darwin_STRIP=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-strip") # Disable adhoc codesigning (for now) when using LLVM tooling, to avoid # non-determinism issues with the Identifier field. -darwin_CC=$(clang_prog) --target=$(host) \ - -isysroot$(OSX_SDK) -nostdlibinc \ +darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH $(clang_prog) --target=$(host) \ + -isysroot$(OSX_SDK) -nostdinc \ + -isystem$(clang_resource_dir)/include \ -iwithsysroot/usr/include -iframeworkwithsysroot/System/Library/Frameworks -darwin_CXX=$(clangxx_prog) --target=$(host) \ - -isysroot$(OSX_SDK) -nostdlibinc \ +darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH $(clangxx_prog) --target=$(host) \ + -isysroot$(OSX_SDK) -nostdinc -nostdinc++ \ -iwithsysroot/usr/include/c++/v1 \ + -isystem$(clang_resource_dir)/include \ -iwithsysroot/usr/include -iframeworkwithsysroot/System/Library/Frameworks darwin_CFLAGS=-pipe -std=$(C_STANDARD) -mmacos-version-min=$(OSX_MIN_VERSION) @@ -76,4 +80,7 @@ darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) darwin_debug_CFLAGS=-O1 -g darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) -darwin_cmake_system=Darwin +darwin_cmake_system_name=Darwin +# Darwin version, which corresponds to OSX_MIN_VERSION. +# See https://en.wikipedia.org/wiki/Darwin_(operating_system) +darwin_cmake_system_version=23.0 diff --git a/depends/hosts/freebsd.mk b/depends/hosts/freebsd.mk index 3b265f647dc7..009d215f82f8 100644 --- a/depends/hosts/freebsd.mk +++ b/depends/hosts/freebsd.mk @@ -28,4 +28,4 @@ x86_64_freebsd_CC=$(default_host_CC) -m64 x86_64_freebsd_CXX=$(default_host_CXX) -m64 endif -freebsd_cmake_system=FreeBSD +freebsd_cmake_system_name=FreeBSD diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index f5ce2bb0b855..e2f34265d153 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -39,4 +39,7 @@ 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 + +linux_cmake_system_name=Linux +# Refer to doc/dependencies.md for the minimum required kernel. +linux_cmake_system_version=3.17.0 diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index e324fd2fffe6..48db7fe863dd 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -21,4 +21,6 @@ mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS) mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -mingw32_cmake_system=Windows +mingw32_cmake_system_name=Windows +# Windows 10 +mingw32_cmake_system_version=10.0 diff --git a/depends/hosts/netbsd.mk b/depends/hosts/netbsd.mk index 842c015ca30a..d2b79f9d5bf3 100644 --- a/depends/hosts/netbsd.mk +++ b/depends/hosts/netbsd.mk @@ -34,4 +34,4 @@ x86_64_netbsd_CC=$(default_host_CC) -m64 x86_64_netbsd_CXX=$(default_host_CXX) -m64 endif -netbsd_cmake_system=NetBSD +netbsd_cmake_system_name=NetBSD diff --git a/depends/hosts/openbsd.mk b/depends/hosts/openbsd.mk index b6db8575ff7a..53595689b62e 100644 --- a/depends/hosts/openbsd.mk +++ b/depends/hosts/openbsd.mk @@ -28,4 +28,4 @@ x86_64_openbsd_CC=$(default_host_CC) -m64 x86_64_openbsd_CXX=$(default_host_CXX) -m64 endif -openbsd_cmake_system=OpenBSD +openbsd_cmake_system_name=OpenBSD diff --git a/depends/packages.md b/depends/packages.md index 0ffdc66d4884..4232bb1006bd 100644 --- a/depends/packages.md +++ b/depends/packages.md @@ -6,7 +6,7 @@ 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 bitcoin binaries/libraries (i.e. - those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't + those not in `ALLOWED_LIBRARIES` in `contrib/guix/symbol-check.py`) don't need to be shared and should be built statically whenever possible. See [below](#secondary-dependencies) for more details. @@ -168,7 +168,7 @@ the Autotools `--with-pic` flag, or `CMAKE_POSITION_INDEPENDENT_CODE` with CMake ## Secondary dependencies: Secondary dependency packages relative to the bitcoin binaries/libraries (i.e. -those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't +those not in `ALLOWED_LIBRARIES` in `contrib/guix/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: diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index bcc7cd067030..4997121f4fc8 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -10,7 +10,7 @@ $(package)_patches += winver_fixup.patch $(package)_build_subdir=build # 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 +# version as we do in releases. 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=-DCMAKE_BUILD_TYPE=None -DEVENT__DISABLE_BENCHMARK=ON -DEVENT__DISABLE_OPENSSL=ON @@ -18,7 +18,7 @@ define $(package)_set_vars $(package)_config_opts+=-DEVENT__DISABLE_TESTS=ON -DEVENT__LIBRARY_TYPE=STATIC $(package)_cflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr $(package)_cppflags += -D_GNU_SOURCE - $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 + $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0A00 ifeq ($(NO_HARDEN),) $(package)_cppflags += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index da32797ea60f..b3b3e999d3f0 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -9,7 +9,7 @@ $(package)_patches=dont_leak_info.patch respect_mingw_cflags.patch no_libtool.pa # See discussion in https://github.com/bitcoin/bitcoin/pull/25964. define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" -$(package)_build_opts_mingw32=-f Makefile.mingw CFLAGS="$($(package)_cflags) -D_WIN32_WINNT=0x0601" +$(package)_build_opts_mingw32=-f Makefile.mingw CFLAGS="$($(package)_cflags) -D_WIN32_WINNT=0x0A00" $(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)" endef diff --git a/depends/packages/native_cxxbridge.mk b/depends/packages/native_cxxbridge.mk new file mode 100644 index 000000000000..4f18d05fd8d6 --- /dev/null +++ b/depends/packages/native_cxxbridge.mk @@ -0,0 +1,34 @@ +# Copyright (c) 2022-2025 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# To update the package, change the version below and then run the script +# ./contrib/devtools/update-native-cxxbridge.py + +package:=native_cxxbridge +$(package)_version:=1.0.192 +$(package)_download_path:=https://github.com/dtolnay/cxx/archive/refs/tags +$(package)_file_name:=native_cxxbridge-$($(package)_version).tar.gz +$(package)_download_file:=$($(package)_version).tar.gz +$(package)_sha256_hash:=d242dbfb6deb362c5a95fcb69aeb5f25228de75af3cced94c9f6c8e11019d30e +$(package)_build_subdir:=gen/cmd +$(package)_dependencies:=native_rust +$(package)_patches:=Cargo.lock cargo-config.toml +$(package)_vendored_file_name:=native_cxxbridge-$($(package)_version)-vendored.tar.gz +$(package)_cargo_manifest:=gen/cmd/Cargo.toml + +define $(package)_preprocess_cmds + cp $($(package)_patch_dir)/Cargo.lock . +endef + +define $(package)_build_cmds + $($(package)_cargo) build --locked --release --package=cxxbridge-cmd --bin=cxxbridge +endef + +define $(package)_stage_cmds + $($(package)_cargo) install --locked --path=. --bin=cxxbridge --root=$($(package)_staging_prefix_dir) && \ + mkdir -p $($(package)_staging_prefix_dir)/lib && \ + bash $(BASEDIR)/patches/native_rust/fix-elf-interpreter.sh \ + $($(package)_staging_prefix_dir)/lib \ + $($(package)_staging_prefix_dir)/bin/cxxbridge +endef diff --git a/depends/packages/native_rust.mk b/depends/packages/native_rust.mk new file mode 100644 index 000000000000..961517b96ff1 --- /dev/null +++ b/depends/packages/native_rust.mk @@ -0,0 +1,58 @@ +# Copyright (c) 2016-2025 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# To update the Rust compiler, change the version below and then run the script +# ./contrib/devtools/update-rust-hashes.py + +package:=native_rust +$(package)_version:=1.85.1 +$(package)_download_path:=https://static.rust-lang.org/dist + +# FreeBSD (x86_64) +$(package)_file_name_x86_64_freebsd:=rust-$($(package)_version)-x86_64-unknown-freebsd.tar.gz +$(package)_sha256_hash_x86_64_freebsd:=f905730e22a9a8a2dfce1ab0c50d427b7978c5b235c33018b09552041b6f6329 + +# Linux (ARMv8) +$(package)_file_name_aarch64_linux:=rust-$($(package)_version)-aarch64-unknown-linux-gnu.tar.gz +$(package)_sha256_hash_aarch64_linux:=d2609d8cd965060f0b4a8c509131066369e8d3d31a92fedce177b42b32af6b4d + +# Linux (x86_64) +$(package)_file_name_x86_64_linux:=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz +$(package)_sha256_hash_x86_64_linux:=b7202563a52b47f575b284a5a4794fafd688e39bfe8fd855b5e80129e671cb7f + +# macOS (ARMv8) +$(package)_file_name_aarch64_darwin:=rust-$($(package)_version)-aarch64-apple-darwin.tar.gz +$(package)_sha256_hash_aarch64_darwin:=64b0341a47e684d648c9b7defd0b7ff9d5397a64718cf803c1e114544f94bbe9 + +# macOS (x86_64) +$(package)_file_name_x86_64_darwin:=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz +$(package)_sha256_hash_x86_64_darwin:=6e321957b7301d48e5ecf61bdeea6560400a5948b3e72830348367a8a9696ad7 + +$(package)_file_name=$($(package)_file_name_$(build_arch)_$(build_os)) +$(package)_sha256_hash=$($(package)_sha256_hash_$(build_arch)_$(build_os)) + +define $(package)_set_vars +$(package)_stage_opts=--disable-ldconfig +$(package)_stage_build_opts=--without=rust-docs-json-preview,rust-docs +endef + +define $(package)_fetch_cmds +$(call fetch_file,$(package),$($(package)_download_path),$($(package)_file_name),$($(package)_file_name),$($(package)_sha256_hash)) +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_dir)/$(host_prefix)/native/bin && \ + mkdir -p $($(package)_staging_dir)/$(host_prefix)/native/lib/rustlib && \ + cp cargo/bin/cargo $($(package)_staging_dir)/$(host_prefix)/native/bin/ && \ + cp rustc/bin/rustc $($(package)_staging_dir)/$(host_prefix)/native/bin/ && \ + cp rustc/bin/rustdoc $($(package)_staging_dir)/$(host_prefix)/native/bin/ && \ + cp -r rustc/lib/* $($(package)_staging_dir)/$(host_prefix)/native/lib/ && \ + cp -r rust-std-*/lib/rustlib/* $($(package)_staging_dir)/$(host_prefix)/native/lib/rustlib/ && \ + bash $(BASEDIR)/patches/native_rust/fix-elf-interpreter.sh \ + $($(package)_staging_dir)/$(host_prefix)/native/lib \ + $($(package)_staging_dir)/$(host_prefix)/native/bin/cargo \ + $($(package)_staging_dir)/$(host_prefix)/native/bin/rustc \ + $($(package)_staging_dir)/$(host_prefix)/native/bin/rustdoc +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 7e0bb2633219..66ffa913b07c 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,7 +1,9 @@ -packages:=gmp backtrace +packages:=gmp backtrace rustcxx rust_stdlib boost_packages = boost +native_cargo_packages = native_cxxbridge + libevent_packages = libevent qrencode_linux_packages = qrencode diff --git a/depends/packages/rust_stdlib.mk b/depends/packages/rust_stdlib.mk new file mode 100644 index 000000000000..16e47c439434 --- /dev/null +++ b/depends/packages/rust_stdlib.mk @@ -0,0 +1,77 @@ +# Copyright (c) 2016-2025 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# To update the Rust stdlib, change the version below and then run the script +# ./contrib/devtools/update-rust-hashes.py + +package:=rust_stdlib +$(package)_version:=1.85.1 +$(package)_download_path:=https://static.rust-lang.org/dist +$(package)_dependencies:=native_rust +$(package)_target=$(or \ + $($(package)_target_$(canonical_host)),\ + $($(package)_target_$(subst -pc-,-unknown-,$(canonical_host))),\ + $($(package)_target_$(subst -unknown-,-pc-,$(canonical_host))),\ + $($(package)_target_$(subst -linux-,-unknown-linux-,$(canonical_host)))) + +# FreeBSD (x86_64) +$(package)_targets += x86_64-unknown-freebsd +$(package)_target_x86_64-unknown-freebsd:=x86_64-unknown-freebsd +$(package)_sha256_hash_x86_64-unknown-freebsd:=08a691bcdb5bde37178368e9e49dbd822d9e39c68b9371191bd16ab7f8b321c4 + +# Linux (ARMv7) +$(package)_targets += armv7-unknown-linux-musleabihf +$(package)_target_arm-unknown-linux-gnueabihf:=armv7-unknown-linux-musleabihf +$(package)_target_armv7-unknown-linux-gnueabihf:=armv7-unknown-linux-musleabihf +$(package)_sha256_hash_armv7-unknown-linux-musleabihf:=fbdb48968dd7af3a862c29e4e3ff85bcf333d97d21d262f347106542cc08b96d + +# Linux (ARMv8) +$(package)_targets += aarch64-unknown-linux-musl +$(package)_target_aarch64-unknown-linux-gnu:=aarch64-unknown-linux-musl +$(package)_sha256_hash_aarch64-unknown-linux-musl:=991cc2f78d3db8fa1131ee2bb5807497e93e1efb9f447e2a7def0c4032ba4c54 + +# Linux (PowerPC 64-bit little-endian) +$(package)_targets += powerpc64le-unknown-linux-musl +$(package)_target_powerpc64le-unknown-linux-gnu:=powerpc64le-unknown-linux-musl +$(package)_sha256_hash_powerpc64le-unknown-linux-musl:=f6fad3f1c69acdd832ea2f487863f6428ba6e77b16c18e8db7fcd91b88e9e254 + +# Linux (RISCV64GC) +$(package)_targets += riscv64gc-unknown-linux-musl +$(package)_target_riscv64-unknown-linux-gnu:=riscv64gc-unknown-linux-musl +$(package)_target_riscv64gc-unknown-linux-gnu:=riscv64gc-unknown-linux-musl +$(package)_sha256_hash_riscv64gc-unknown-linux-musl:=4a85e0c909d6a3202919638c3b95a496acdfec7e1245be1c406b7c1d26c32fba + +# Linux (x86_64) +$(package)_targets += x86_64-unknown-linux-musl +$(package)_target_x86_64-unknown-linux-gnu:=x86_64-unknown-linux-musl +$(package)_sha256_hash_x86_64-unknown-linux-musl:=3035f0c3ea9ae10ba1c21871c7a53cdb54a398616febffd42825965627a77216 + +# macOS (ARMv8) +$(package)_targets += aarch64-apple-darwin +$(package)_target_aarch64-apple-darwin:=aarch64-apple-darwin +$(package)_target_arm64-apple-darwin:=aarch64-apple-darwin +$(package)_sha256_hash_aarch64-apple-darwin:=5d2fd6b5c3c482750074b6ab04443b1ec41ca824fddc814aab6a1fbcf5cfb53a + +# macOS (x86_64) +$(package)_targets += x86_64-apple-darwin +$(package)_target_x86_64-apple-darwin:=x86_64-apple-darwin +$(package)_sha256_hash_x86_64-apple-darwin:=b5111b105cfeb2772d92ca54e6f1c01d11def9c675c633f7d1ebdd09b83b0139 + +# Windows (x86_64) +$(package)_targets += x86_64-pc-windows-gnu +$(package)_target_x86_64-w64-mingw32:=x86_64-pc-windows-gnu +$(package)_sha256_hash_x86_64-pc-windows-gnu:=ae5c8942b3ccab5841c9ea65d1ac839c62553a763512799eb4c89de2ffad3d3e + +$(package)_file_name=rust-std-$($(package)_version)-$($(package)_target).tar.gz +$(package)_sha256_hash=$($(package)_sha256_hash_$($(package)_target)) + +define $(package)_fetch_cmds + $(call fetch_file,$(package),$($(package)_download_path),$($(package)_file_name),$($(package)_file_name),$($(package)_sha256_hash)) +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_dir)/$(host_prefix)/native/lib/rustlib && \ + cp -r rust-std-$($(package)_target)/lib/rustlib/$($(package)_target) $($(package)_staging_dir)/$(host_prefix)/native/lib/rustlib/ +endef diff --git a/depends/packages/rustcxx.mk b/depends/packages/rustcxx.mk new file mode 100644 index 000000000000..13125507f290 --- /dev/null +++ b/depends/packages/rustcxx.mk @@ -0,0 +1,17 @@ +# Copyright (c) 2022-2023 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +package:=rustcxx +$(package)_version:=$(native_cxxbridge_version) +$(package)_file_name:=$(native_cxxbridge_file_name) +$(package)_sha256_hash:=$(native_cxxbridge_sha256_hash) + +define $(package)_fetch_cmds + $(call native_cxxbridge_fetch_cmds,native_cxxbridge) +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/include/rust && \ + cp include/cxx.h $($(package)_staging_prefix_dir)/include/rust +endef diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 9cb0831d22cb..45da9259247e 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -20,7 +20,7 @@ define $(package)_set_vars $(package)_config_opts += -DBUILD_SHARED=OFF -DBUILD_TESTS=OFF -DZMQ_BUILD_TESTS=OFF $(package)_config_opts += -DENABLE_DRAFTS=OFF -DZMQ_BUILD_TESTS=OFF $(package)_cxxflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr - $(package)_config_opts_mingw32 += -DZMQ_WIN32_WINNT=0x0601 -DZMQ_HAVE_IPC=OFF + $(package)_config_opts_mingw32 += -DZMQ_WIN32_WINNT=0x0A00 -DZMQ_HAVE_IPC=OFF endef define $(package)_preprocess_cmds diff --git a/depends/patches/native_cxxbridge/Cargo.lock b/depends/patches/native_cxxbridge/Cargo.lock new file mode 100644 index 000000000000..4a9a074e7d3c --- /dev/null +++ b/depends/patches/native_cxxbridge/Cargo.lock @@ -0,0 +1,584 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "cc" +version = "1.2.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "clap" +version = "4.5.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +dependencies = [ + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "codespan-reporting" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + +[[package]] +name = "cxx" +version = "1.0.192" +dependencies = [ + "cc", + "cxx-build", + "cxx-gen", + "cxx-test-suite", + "cxxbridge-cmd", + "cxxbridge-flags", + "cxxbridge-macro", + "foldhash", + "indoc", + "link-cplusplus", + "proc-macro2", + "quote", + "rustversion", + "scratch", + "target-triple", + "tempfile", + "trybuild", +] + +[[package]] +name = "cxx-build" +version = "1.0.192" +dependencies = [ + "cc", + "codespan-reporting", + "cxx", + "cxx-gen", + "indexmap", + "pkg-config", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxx-gen" +version = "0.7.192" +dependencies = [ + "codespan-reporting", + "indexmap", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cxx-test-suite" +version = "0.0.0" +dependencies = [ + "cxx", + "cxx-build", + "cxxbridge-flags", + "serde", +] + +[[package]] +name = "cxxbridge-cmd" +version = "1.0.192" +dependencies = [ + "clap", + "codespan-reporting", + "indexmap", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.192" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.192" +dependencies = [ + "cxx", + "indexmap", + "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "demo" +version = "0.0.0" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "dissimilar" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indoc" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom", + "libc", +] + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "link-cplusplus" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" +dependencies = [ + "cc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "scratch" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-triple" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" + +[[package]] +name = "tempfile" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "toml" +version = "0.9.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" + +[[package]] +name = "trybuild" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17e807bff86d2a06b52bca4276746584a78375055b6e45843925ce2802b335" +dependencies = [ + "dissimilar", + "glob", + "serde", + "serde_derive", + "serde_json", + "target-triple", + "termcolor", + "toml", +] + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "zmij" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac93432f5b761b22864c774aac244fa5c0fd877678a4c37ebf6cf42208f9c9ec" diff --git a/depends/patches/native_cxxbridge/cargo-config.toml b/depends/patches/native_cxxbridge/cargo-config.toml new file mode 100644 index 000000000000..01ab67f3bd1f --- /dev/null +++ b/depends/patches/native_cxxbridge/cargo-config.toml @@ -0,0 +1,5 @@ +[source.crates-io] +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "vendored" diff --git a/depends/patches/native_rust/fix-elf-interpreter.sh b/depends/patches/native_rust/fix-elf-interpreter.sh new file mode 100644 index 000000000000..b25f30db3c52 --- /dev/null +++ b/depends/patches/native_rust/fix-elf-interpreter.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +LIBDIR="$1" +shift + +if ! command -v patchelf >/dev/null 2>&1; then + echo "patchelf not found, skipping ELF fix" + exit 0 +fi + +# Get the interpreter from a known working binary (ls) +LS_PATH=$(command -v ls) +GUIX_INTERP=$(patchelf --print-interpreter "$LS_PATH" 2>/dev/null) + +if [ -z "$GUIX_INTERP" ]; then + echo "Could not detect interpreter, skipping" + exit 0 +fi + +echo "Detected interpreter: $GUIX_INTERP" + +# Find and copy libgcc_s.so.1 into our lib directory +LIBGCC_SRC="" + +# Method 1: Use gcc to find it +if command -v gcc >/dev/null 2>&1; then + GCC_LIBDIR=$(dirname "$(gcc -print-libgcc-file-name)" 2>/dev/null) + if [ -f "$GCC_LIBDIR/libgcc_s.so.1" ]; then + LIBGCC_SRC="$GCC_LIBDIR/libgcc_s.so.1" + else + GCC_PATH=$(command -v gcc) + GCC_PREFIX=$(dirname "$(dirname "$GCC_PATH")") + if [ -f "$GCC_PREFIX/lib/libgcc_s.so.1" ]; then + LIBGCC_SRC="$GCC_PREFIX/lib/libgcc_s.so.1" + fi + fi +fi + +# Method 2: Search LIBRARY_PATH +if [ -z "$LIBGCC_SRC" ] && [ -n "$LIBRARY_PATH" ]; then + IFS=':' read -ra LIB_PATHS <<< "$LIBRARY_PATH" + for libpath in "${LIB_PATHS[@]}"; do + if [ -f "$libpath/libgcc_s.so.1" ]; then + LIBGCC_SRC="$libpath/libgcc_s.so.1" + break + fi + done +fi + +if [ -n "$LIBGCC_SRC" ]; then + # Resolve symlinks and copy the actual file + LIBGCC_REAL=$(readlink -f "$LIBGCC_SRC") + echo "Copying libgcc_s.so.1 from: $LIBGCC_REAL" + cp "$LIBGCC_REAL" "$LIBDIR/libgcc_s.so.1" +else + echo "WARNING: Could not find libgcc_s.so.1 to copy" +fi + +# RPATH just needs $ORIGIN/../lib - everything is self-contained +GUIX_RPATH="\$ORIGIN/../lib" +echo "Using RPATH: $GUIX_RPATH" + +for binary in "$@"; do + if [ -f "$binary" ]; then + echo "Patching: $binary" + patchelf --set-interpreter "$GUIX_INTERP" "$binary" + patchelf --set-rpath "$GUIX_RPATH" "$binary" + fi +done + +echo "Verifying first binary:" +patchelf --print-interpreter "$1" +patchelf --print-rpath "$1" diff --git a/doc/build-osx.md b/doc/build-osx.md index e6e9384356c3..bee24c39b404 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -1,15 +1,15 @@ # macOS Build Guide -**Updated for MacOS [11.2](https://www.apple.com/macos/big-sur/)** +**Updated for MacOS [14](https://www.apple.com/macos/macos-sequoia/)** -This guide describes how to build dashd, command-line utilities, and GUI on macOS +This guide describes how to build dashd, command-line utilities, and GUI on macOS. ## Preparation The commands in this guide should be executed in a Terminal application. macOS comes with a built-in Terminal located in: -``` +```bash /Applications/Utilities/Terminal.app ``` @@ -50,20 +50,6 @@ See [dependencies.md](dependencies.md) for a complete overview. brew install automake libtool boost gmp pkg-config libevent ``` -For macOS 11 (Big Sur) and 12 (Monterey) you need to install a more recent version of llvm. - -``` bash -brew install llvm -``` - -And append the following to the configure commands below: - -``` bash -CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ -``` - -Try `llvm@17` if compilation fails with the default version of llvm. - ### 4. Clone Dash repository `git` should already be installed by default on your system. diff --git a/doc/release-notes-empty-template.md b/doc/release-notes-empty-template.md index b129c6c599fc..f6b52ae6c7a6 100644 --- a/doc/release-notes-empty-template.md +++ b/doc/release-notes-empty-template.md @@ -29,6 +29,14 @@ installer (on Windows) or just copy over `/Applications/Dash-Qt` (on macOS) or Downgrading to a version older than *version* may not be supported, and will likely require a reindex. +# Compatibility + +Dash Core is supported and tested on operating systems using the +Linux Kernel 3.17+, macOS 14+, and Windows 10+. Dash Core +should also work on most other Unix-like systems but is not as +frequently tested on them. It is not recommended to use Dash Core on +unsupported systems. + # Release Notes Notable changes diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000000..00822fdf5828 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.85.1" diff --git a/rust/Makefile.am b/rust/Makefile.am new file mode 100644 index 000000000000..c01b61e07773 --- /dev/null +++ b/rust/Makefile.am @@ -0,0 +1,80 @@ +# Copyright (c) 2016-2025 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +CARGO_BUILD_OPTS = --locked --target $(RUST_TARGET) +CARGO_ENV = \ + MACOSX_DEPLOYMENT_TARGET="$(RUST_MACOS_DEPLOYMENT_TARGET)" \ + CARGO_INCREMENTAL="$(CARGO_INCREMENTAL)" \ + RUSTC="$(RUSTC)" \ + RUSTFLAGS="$(RUSTFLAGS)" \ + TERM="dumb" \ + ${RUST_OSX_SDK+SDKROOT="$(RUST_OSX_SDK)"} \ + ${RUSTUP_TOOLCHAIN+RUSTUP_TOOLCHAIN="$(RUSTUP_TOOLCHAIN)"} + +# 'cargo' needs uppercase +RUST_NATIVE_ENV_UPPER = $(shell echo '$(RUST_NATIVE)' | tr 'a-z-' 'A-Z_') +CARGO_ENV += \ + AR="$(NATIVE_AR)" \ + CC="$(NATIVE_CC)" \ + CXX="$(NATIVE_CXX)" \ + CARGO_TARGET_$(RUST_NATIVE_ENV_UPPER)_LINKER="$(NATIVE_CC)" + +# 'cc' needs preserved case +RUST_TARGET_ENV_LOWER = $(shell echo '$(RUST_TARGET)' | tr '-' '_') +# 'cargo' needs uppercase +RUST_TARGET_ENV_UPPER = $(shell echo '$(RUST_TARGET_ENV_LOWER)' | tr 'a-z' 'A-Z') +CARGO_ENV += \ + AR_$(RUST_TARGET_ENV_LOWER)="$(AR)" \ + CC_$(RUST_TARGET_ENV_LOWER)="$(CC)" \ + CFLAGS_$(RUST_TARGET_ENV_LOWER)="$(CFLAGS)" \ + CXX_$(RUST_TARGET_ENV_LOWER)="$(CXX)" \ + CXXFLAGS_$(RUST_TARGET_ENV_LOWER)="$(CXXFLAGS)" \ + CARGO_TARGET_$(RUST_TARGET_ENV_UPPER)_LINKER="$(CC)" + +if !ENABLE_DEBUG +CARGO_BUILD_OPTS += --release +endif # !ENABLE_DEBUG + +if !SILENT_RULES +CARGO_BUILD_OPTS += --verbose +endif # !SILENT_RULES + +if ENABLE_ONLINE_RUST +CARGO_CONFIGURED = $(top_srcdir)/.cargo/.configured-for-online + +$(CARGO_CONFIGURED): + $(AM_V_at)rm -f $(top_srcdir)/.cargo/.configured-for-offline + $(AM_V_at)rm -f $(top_srcdir)/.cargo/config.toml + $(AM_V_at)rm -f $(top_srcdir)/.cargo/config + $(AM_V_at)touch $@ +else +CARGO_BUILD_OPTS += --offline +CARGO_CONFIGURED = $(top_srcdir)/.cargo/.configured-for-offline + +$(CARGO_CONFIGURED): $(top_srcdir)/.cargo/config.toml.offline + $(AM_V_at)rm -f $(top_srcdir)/.cargo/.configured-for-online + $(AM_V_at)rm -f $(top_srcdir)/.cargo/config + $(AM_V_at)cp $< $(top_srcdir)/.cargo/config.toml + $(AM_V_at)echo "directory = \"$(RUST_VENDORED_SOURCES)\"" >> $(top_srcdir)/.cargo/config.toml + $(AM_V_at)touch $@ +endif # ENABLE_ONLINE_RUST + +include $(top_srcdir)/rust/Makefile.libs.include + +all-local: $(CARGO_CONFIGURED) cargo-build-chirp cxxbridge-chirp + +cargo-build: $(CARGO_CONFIGURED) cargo-build-chirp + +cargo-clean: cargo-clean-chirp + +cargo-clean-config: + $(AM_V_at)rm -f $(top_srcdir)/.cargo/.configured-for-online + $(AM_V_at)rm -f $(top_srcdir)/.cargo/.configured-for-offline + $(AM_V_at)rm -f $(top_srcdir)/.cargo/config.toml + $(AM_V_at)rm -f $(top_srcdir)/.cargo/config + +clean-local: cargo-clean-chirp cxxbridge-clean-chirp clean-librustdeps-la cargo-clean-config + +.PHONY: cargo-build cargo-clean cargo-clean-config diff --git a/rust/Makefile.chirp.include b/rust/Makefile.chirp.include new file mode 100644 index 000000000000..407f7549e631 --- /dev/null +++ b/rust/Makefile.chirp.include @@ -0,0 +1,49 @@ +# Copyright (c) 2016-2025 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +LIBRUST_CHIRP_TARGET_DIR = $(abs_top_builddir)/rust/chirp/target +LIBRUST_CHIRP = $(LIBRUST_CHIRP_TARGET_DIR)/$(RUST_TARGET)/$(CARGO_PROFILE)/libchirp.a + +LIBRUST_CHIRP_CARGO_ENV = $(CARGO_ENV) CARGO_TARGET_DIR="$(LIBRUST_CHIRP_TARGET_DIR)" +LIBRUST_CHIRP_CRATE_DIR = $(top_srcdir)/rust/chirp +LIBRUST_CHIRP_GEN_DIR = $(abs_top_builddir)/rust/chirp/gen +LIBRUST_CHIRP_MANIFEST = $(LIBRUST_CHIRP_CRATE_DIR)/Cargo.toml +LIBRUST_CHIRP_CARGO_BUILD_OPTS = $(CARGO_BUILD_OPTS) --manifest-path $(LIBRUST_CHIRP_MANIFEST) + +LIBRUST_CHIRP_SRCS = \ + $(LIBRUST_CHIRP_CRATE_DIR)/src/lib.rs + +LIBRUST_CHIRP_BUILD = \ + $(LIBRUST_CHIRP_CRATE_DIR)/build.rs + +LIBRUST_CHIRP_CPP = \ + $(LIBRUST_CHIRP_GEN_DIR)/src/lib.cpp + +LIBRUST_CHIRP_H = \ + $(LIBRUST_CHIRP_GEN_DIR)/include/rust/chirp/lib.h + +LIBRUST_CHIRP_INCLUDES = \ + -I$(LIBRUST_CHIRP_GEN_DIR)/include + +$(LIBRUST_CHIRP_SRCS): ; + +$(LIBRUST_CHIRP_H) $(LIBRUST_CHIRP_CPP): $(LIBRUST_CHIRP_SRCS) + $(AM_V_at)$(MKDIR_P) $(@D) + $(AM_V_GEN)$(CXXBRIDGE) $< $(if $(filter %.h,$@),--header) -o $@ + +$(LIBRUST_CHIRP): $(LIBRUST_CHIRP_SRCS) $(LIBRUST_CHIRP_BUILD) $(LIBRUST_CHIRP_MANIFEST) + $(AM_V_GEN)$(LIBRUST_CHIRP_CARGO_ENV) $(CARGO) build $(LIBRUST_CHIRP_CARGO_BUILD_OPTS) + +cargo-build-chirp: $(LIBRUST_CHIRP) + +cargo-clean-chirp: + $(AM_V_at)rm -rf $(LIBRUST_CHIRP_TARGET_DIR) + +cxxbridge-chirp: $(LIBRUST_CHIRP_CPP) $(LIBRUST_CHIRP_H) + +cxxbridge-clean-chirp: + $(AM_V_at)rm -rf $(LIBRUST_CHIRP_GEN_DIR) + +.PHONY: cargo-build-chirp cargo-clean-chirp cxxbridge-chirp cxxbridge-clean-chirp diff --git a/rust/Makefile.libs.include b/rust/Makefile.libs.include new file mode 100644 index 000000000000..a21cca9a3b84 --- /dev/null +++ b/rust/Makefile.libs.include @@ -0,0 +1,56 @@ +# Copyright (c) 2016-2025 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +if ENABLE_DEBUG +CARGO_PROFILE=debug +else +CARGO_PROFILE=release +endif + +include $(top_srcdir)/rust/Makefile.chirp.include + +LIBRUSTDEPS_A = \ + $(LIBRUST_CHIRP) + +LIBRUSTDEPS_INCLUDES = \ + $(LIBRUST_CHIRP_INCLUDES) + +LIBRUSTDEPS_CPP = \ + $(LIBRUST_CHIRP_CPP) + +LIBRUSTDEPS_H = \ + $(LIBRUST_CHIRP_H) + +# Libtool wrapper # +LIBRUSTDEPS = $(abs_top_builddir)/rust/librustdeps.la +LIBRUSTDEPS_LIBDIR = $(abs_top_builddir)/rust/.libs + +$(LIBRUSTDEPS): $(LIBRUSTDEPS_A) + $(AM_V_at)$(MKDIR_P) $(LIBRUSTDEPS_LIBDIR) + $(AM_V_at)rm -rf $(LIBRUSTDEPS_LIBDIR)/librustdeps.a $(LIBRUSTDEPS_LIBDIR)/objs + $(AM_V_at)$(MKDIR_P) $(LIBRUSTDEPS_LIBDIR)/objs + $(AM_V_at)for lib in $(LIBRUSTDEPS_A); do \ + cd $(LIBRUSTDEPS_LIBDIR)/objs && $(AR) -x $$lib; \ + done + $(AM_V_at)$(AR) crs $(LIBRUSTDEPS_LIBDIR)/librustdeps.a $(LIBRUSTDEPS_LIBDIR)/objs/*.o + $(AM_V_at)rm -rf $(LIBRUSTDEPS_LIBDIR)/objs + $(AM_V_at)$(RANLIB) $(LIBRUSTDEPS_LIBDIR)/librustdeps.a + $(AM_V_GEN)( \ + echo '# librustdeps.la - a libtool library file'; \ + echo '# Generated by Makefile.libs.include for libtool'; \ + echo "dlname=''"; \ + echo "library_names=''"; \ + echo "old_library='librustdeps.a'"; \ + echo "libdir='$(LIBRUSTDEPS_LIBDIR)'"; \ + echo "inherited_linker_flags=''"; \ + echo "installed=no"; \ + echo "shouldnotlink=no"; \ + ) > $@ + +clean-librustdeps-la: + rm -rf $(abs_top_builddir)/rust/.libs $(abs_top_builddir)/rust/librustdeps.la + +.PHONY: clean-librustdeps-la +# diff --git a/rust/chirp/Cargo.toml b/rust/chirp/Cargo.toml new file mode 100644 index 000000000000..fd9b62a4a9aa --- /dev/null +++ b/rust/chirp/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "chirp" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["staticlib"] + +[dependencies] +cxx = "1.0.192" + +[build-dependencies] +built = "0.8.0" diff --git a/rust/chirp/build.rs b/rust/chirp/build.rs new file mode 100644 index 000000000000..e57a97ad2171 --- /dev/null +++ b/rust/chirp/build.rs @@ -0,0 +1,3 @@ +fn main() { + built::write_built_file().expect("Failed to write build info"); +} diff --git a/rust/chirp/src/lib.rs b/rust/chirp/src/lib.rs new file mode 100644 index 000000000000..1d27c03613f3 --- /dev/null +++ b/rust/chirp/src/lib.rs @@ -0,0 +1,19 @@ +mod built_info { + include!(concat!(env!("OUT_DIR"), "/built.rs")); +} + +#[cxx::bridge(namespace = "chirp")] +mod ffi { + extern "Rust" { + fn chirp() -> String; + } +} + +fn chirp() -> String { + format!( + "{} {} built with {} reports \"cheep cheep\"", + built_info::PKG_NAME, + built_info::PKG_VERSION, + built_info::RUSTC_VERSION, + ) +} diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 81638b679803..2c0c7ba4a91e 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -3,7 +3,7 @@ LSMinimumSystemVersion - 11 + 14 LSArchitecturePriority diff --git a/src/Makefile.am b/src/Makefile.am index 1c5fd1936399..e4f669dbd11e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,6 @@ # Copyright (c) 2013-2016 The Bitcoin Core developers -# Copyright (c) 2014-2018 The Dash Core developers +# Copyright (c) 2016-2025 The Zcash developers +# Copyright (c) 2014-2026 The Dash Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +8,8 @@ print-%: FORCE @echo '$*'='$($*)' +include $(top_srcdir)/rust/Makefile.libs.include + DIST_SUBDIRS = secp256k1 AM_LDFLAGS = $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) $(CORE_LDFLAGS) $(BACKTRACE_LDFLAGS) @@ -17,6 +20,7 @@ AM_CPPFLAGS = $(DEBUG_CPPFLAGS) $(HARDENED_CPPFLAGS) $(CORE_CPPFLAGS) AM_LIBTOOLFLAGS = --preserve-dup-deps PTHREAD_FLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) EXTRA_LIBRARIES = +BUILT_SOURCES = $(LIBRUSTDEPS_H) lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS) noinst_LTLIBRARIES = @@ -44,6 +48,7 @@ endif # ENABLE_STACKTRACES BITCOIN_INCLUDES=-I$(builddir) -I$(srcdir)/$(MINISKETCH_INCLUDE_DIR_INT) -I$(srcdir)/secp256k1/include -I$(srcdir)/$(UNIVALUE_INCLUDE_DIR_INT) $(LEVELDB_CPPFLAGS) BITCOIN_INCLUDES+=-isystem$(srcdir)/dashbls/include -isystem$(srcdir)/dashbls/depends/relic/include -isystem$(srcdir)/dashbls/depends/minialloc/include BITCOIN_INCLUDES+=-isystem$(srcdir)/immer +BITCOIN_INCLUDES+=$(LIBRUSTDEPS_INCLUDES) LIBBITCOIN_NODE=libbitcoin_node.a LIBBITCOIN_COMMON=libbitcoin_common.a @@ -109,6 +114,8 @@ $(LIBDASHBLS): $(LIBSECP256K1): $(wildcard secp256k1/src/*.h) $(wildcard secp256k1/src/*.c) $(wildcard secp256k1/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) +LIBCXXBRIDGE=libcxxbridge.la + # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: EXTRA_LIBRARIES += \ @@ -122,6 +129,8 @@ EXTRA_LIBRARIES += \ $(LIBBITCOIN_WALLET_TOOL) \ $(LIBBITCOIN_ZMQ) +noinst_LTLIBRARIES += $(LIBCXXBRIDGE) + if BUILD_BITCOIND bin_PROGRAMS += dashd endif @@ -1053,9 +1062,11 @@ bitcoin_bin_ldadd = \ $(LIBDASHBLS) \ $(LIBLEVELDB) \ $(LIBMEMENV) \ - $(LIBSECP256K1) + $(LIBSECP256K1) \ + $(LIBCXXBRIDGE) \ + $(LIBRUSTDEPS) -bitcoin_bin_ldadd += $(BACKTRACE_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(GMP_LIBS) +bitcoin_bin_ldadd += $(BACKTRACE_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(GMP_LIBS) $(RUST_LIBS) dashd_SOURCES = $(bitcoin_daemon_sources) init/bitcoind.cpp dashd_CPPFLAGS = $(bitcoin_bin_cppflags) @@ -1083,8 +1094,10 @@ dash_cli_LDADD = \ $(LIBBITCOIN_CLI) \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) -dash_cli_LDADD += $(BACKTRACE_LIBS) $(EVENT_LIBS) $(GMP_LIBS) + $(LIBBITCOIN_CRYPTO) \ + $(LIBCXXBRIDGE) \ + $(LIBRUSTDEPS) +dash_cli_LDADD += $(BACKTRACE_LIBS) $(EVENT_LIBS) $(GMP_LIBS) $(RUST_LIBS) # # dash-tx binary # @@ -1104,9 +1117,11 @@ dash_tx_LDADD = \ $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBDASHBLS) \ - $(LIBSECP256K1) + $(LIBSECP256K1) \ + $(LIBCXXBRIDGE) \ + $(LIBRUSTDEPS) -dash_tx_LDADD += $(BACKTRACE_LIBS) $(GMP_LIBS) +dash_tx_LDADD += $(BACKTRACE_LIBS) $(GMP_LIBS) $(RUST_LIBS) # # dash-wallet binary # @@ -1125,11 +1140,14 @@ dash_wallet_LDADD = \ $(LIBBITCOIN_CRYPTO) \ $(LIBDASHBLS) \ $(LIBSECP256K1) \ + $(LIBCXXBRIDGE) \ + $(LIBRUSTDEPS) \ $(BACKTRACE_LIBS) \ $(BOOST_LIBS) \ $(BDB_LIBS) \ $(SQLITE_LIBS) \ - $(GMP_LIBS) + $(GMP_LIBS) \ + $(RUST_LIBS) if TARGET_WINDOWS dash_wallet_SOURCES += dash-wallet-res.rc @@ -1153,9 +1171,11 @@ dash_util_LDADD = \ $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBSECP256K1) \ + $(LIBCXXBRIDGE) \ + $(LIBRUSTDEPS) \ $(BACKTRACE_LIBS) -dash_util_LDADD += $(BOOST_LIBS) +dash_util_LDADD += $(BOOST_LIBS) $(RUST_LIBS) # # dashconsensus library # @@ -1164,7 +1184,7 @@ include_HEADERS = script/bitcoinconsensus.h libdashconsensus_la_SOURCES = support/cleanse.cpp $(crypto_libbitcoin_crypto_base_la_SOURCES) $(crypto_libbitcoin_crypto_sph_la_SOURCES) $(libbitcoin_consensus_a_SOURCES) libdashconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS) -libdashconsensus_la_LIBADD = $(LIBDASHBLS) $(LIBSECP256K1) $(GMP_LIBS) +libdashconsensus_la_LIBADD = $(LIBDASHBLS) $(LIBSECP256K1) $(LIBCXXBRIDGE) $(LIBRUSTDEPS) $(GMP_LIBS) $(RUST_LIBS) libdashconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL -DDISABLE_OPTIMIZED_SHA256 libdashconsensus_la_CPPFLAGS += -isystem$(srcdir)/dashbls/include -isystem$(srcdir)/dashbls/depends/relic/include -isystem$(srcdir)/dashbls/depends/minialloc/include libdashconsensus_la_CPPFLAGS += -isystem$(srcdir)/immer @@ -1173,6 +1193,15 @@ libdashconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) endif # +# CXX bridge library # +libcxxbridge_la_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(PIC_FLAGS) +libcxxbridge_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) $(PIC_FLAGS) -static +libcxxbridge_la_LDFLAGS = $(AM_LDFLAGS) -static +libcxxbridge_la_SOURCES = $(LIBRUSTDEPS_CPP) + +$(libcxxbridge_la_OBJECTS): $(LIBRUSTDEPS_H) +# + CTAES_DIST = crypto/ctaes/bench.c CTAES_DIST += crypto/ctaes/ctaes.c CTAES_DIST += crypto/ctaes/ctaes.h @@ -1232,12 +1261,12 @@ clean-local: check-symbols: $(bin_PROGRAMS) @echo "Running symbol and dynamic library checks..." - $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS) + $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/guix/symbol-check.py $(bin_PROGRAMS) check-security: $(bin_PROGRAMS) if HARDEN @echo "Checking binary security..." - $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS) + $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/guix/security-check.py $(bin_PROGRAMS) endif diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index be7bfe2d2dcc..2d74a9574315 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -75,12 +75,15 @@ bench_bench_dash_LDADD = \ $(LIBLEVELDB) \ $(LIBMEMENV) \ $(LIBSECP256K1) \ + $(LIBCXXBRIDGE) \ + $(LIBRUSTDEPS) \ $(LIBUNIVALUE) \ $(EVENT_PTHREADS_LIBS) \ $(EVENT_LIBS) \ $(MINIUPNPC_LIBS) \ $(NATPMP_LIBS) \ $(GMP_LIBS) \ + $(RUST_LIBS) \ $(BACKTRACE_LIBS) if ENABLE_ZMQ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 582f293ad853..86f173aa9b9e 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -419,8 +419,8 @@ if ENABLE_ZMQ bitcoin_qt_ldadd += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif bitcoin_qt_ldadd += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBDASHBLS) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ - $(BACKTRACE_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) $(LIBSECP256K1) \ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(GMP_LIBS) + $(BACKTRACE_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) $(LIBSECP256K1) $(LIBCXXBRIDGE) $(LIBRUSTDEPS) \ + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(GMP_LIBS) $(RUST_LIBS) bitcoin_qt_ldflags = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) bitcoin_qt_libtoolflags = $(AM_LIBTOOLFLAGS) --tag CXX diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 62071d40e5a5..535f466f26ec 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -60,8 +60,8 @@ qt_test_test_dash_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_test_test_dash_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBDASHBLS) $(LIBUNIVALUE) $(LIBLEVELDB) \ $(LIBMEMENV) $(BACKTRACE_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) \ - $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) $(LIBSECP256K1) \ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(GMP_LIBS) + $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) $(LIBSECP256K1) $(LIBCXXBRIDGE) $(LIBRUSTDEPS) \ + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(GMP_LIBS) $(RUST_LIBS) qt_test_test_dash_qt_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) qt_test_test_dash_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index dd6dda7178c3..8211363860d3 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -56,10 +56,13 @@ FUZZ_SUITE_LD_COMMON = \ $(LIBLEVELDB) \ $(LIBMEMENV) \ $(LIBSECP256K1) \ + $(LIBCXXBRIDGE) \ + $(LIBRUSTDEPS) \ $(MINISKETCH_LIBS) \ $(EVENT_LIBS) \ $(EVENT_PTHREADS_LIBS) \ $(GMP_LIBS) \ + $(RUST_LIBS) \ $(BACKTRACE_LIBS) if USE_UPNP @@ -257,10 +260,10 @@ test_test_dash_LDADD += $(LIBBITCOIN_WALLET) test_test_dash_CPPFLAGS += $(BDB_CPPFLAGS) endif test_test_dash_LDADD += $(LIBBITCOIN_NODE) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \ - $(LIBDASHBLS) $(LIBLEVELDB) $(LIBMEMENV) $(BACKTRACE_LIBS) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) $(MINISKETCH_LIBS) + $(LIBDASHBLS) $(LIBLEVELDB) $(LIBMEMENV) $(BACKTRACE_LIBS) $(LIBSECP256K1) $(LIBCXXBRIDGE) $(LIBRUSTDEPS) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) $(MINISKETCH_LIBS) test_test_dash_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_test_dash_LDADD += $(BDB_LIBS) $(MINIUPNPC_LIBS) $(SQLITE_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(GMP_LIBS) +test_test_dash_LDADD += $(BDB_LIBS) $(MINIUPNPC_LIBS) $(SQLITE_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(GMP_LIBS) $(RUST_LIBS) test_test_dash_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) -static if ENABLE_ZMQ diff --git a/src/init.cpp b/src/init.cpp index 312b38486423..60f030df0c06 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -112,6 +112,8 @@ #include #endif // ENABLE_WALLET +#include + #include #include #include @@ -1515,6 +1517,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) return false; } + LogPrintf("%s\n", std::string(chirp::chirp())); + LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD); // Warn about relative -datadir path. diff --git a/src/random.cpp b/src/random.cpp index 8f565000d9d6..3b5266ffc6ea 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -23,8 +23,7 @@ #include #ifdef WIN32 -#include -#include +#include #else #include #endif @@ -349,16 +348,15 @@ static void GetDevURandom(unsigned char *ent32) void GetOSRand(unsigned char *ent32) { #if defined(WIN32) - HCRYPTPROV hProvider; - int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - if (!ret) { - RandFailure(); - } - ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32); - if (!ret) { + constexpr uint32_t STATUS_SUCCESS{0x00000000}; + NTSTATUS status = BCryptGenRandom(/*hAlgorithm=*/NULL, + /*pbBuffer=*/ent32, + /*cbBuffer=*/NUM_OS_RANDOM_BYTES, + /*dwFlags=*/BCRYPT_USE_SYSTEM_PREFERRED_RNG); + + if (status != STATUS_SUCCESS) { RandFailure(); } - CryptReleaseContext(hProvider, 0); #elif defined(HAVE_SYS_GETRANDOM) /* Linux. From the getrandom(2) man page: * "If the urandom source has been initialized, reads of up to 256 bytes diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index fcbc405d2d9b..52976180f91d 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -40,23 +40,23 @@ CROSS = "x " CIRCLE = "o " -if os.name != 'nt' or sys.getwindowsversion() >= (10, 0, 14393): #type:ignore - if os.name == 'nt': - import ctypes - kernel32 = ctypes.windll.kernel32 # type: ignore - ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4 - STD_OUTPUT_HANDLE = -11 - STD_ERROR_HANDLE = -12 - # Enable ascii color control to stdout - stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE) - stdout_mode = ctypes.c_int32() - kernel32.GetConsoleMode(stdout, ctypes.byref(stdout_mode)) - kernel32.SetConsoleMode(stdout, stdout_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) - # Enable ascii color control to stderr - stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE) - stderr_mode = ctypes.c_int32() - kernel32.GetConsoleMode(stderr, ctypes.byref(stderr_mode)) - kernel32.SetConsoleMode(stderr, stderr_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) +if os.name == 'nt': #type:ignore + import ctypes + kernel32 = ctypes.windll.kernel32 # type: ignore + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4 + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + # Enable ascii color control to stdout + stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE) + stdout_mode = ctypes.c_int32() + kernel32.GetConsoleMode(stdout, ctypes.byref(stdout_mode)) + kernel32.SetConsoleMode(stdout, stdout_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) + # Enable ascii color control to stderr + stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE) + stderr_mode = ctypes.c_int32() + kernel32.GetConsoleMode(stderr, ctypes.byref(stderr_mode)) + kernel32.SetConsoleMode(stderr, stderr_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) +else: # primitive formatting on supported # terminal via ANSI escape sequences: DEFAULT = ('\033[0m', '\033[0m') diff --git a/test/get_previous_releases.py b/test/get_previous_releases.py index e900c5baeb29..a1f60346f03a 100755 --- a/test/get_previous_releases.py +++ b/test/get_previous_releases.py @@ -188,8 +188,8 @@ def download_binary(tag, args) -> int: Path(tarball).unlink() - if tag >= "v19" and platform == "arm64-apple-darwin": - # Starting with v23 there are arm64 binaries for ARM (e.g. M1, M2) macs, but they have to be signed to run + if tag >= "v19" and args.host == "arm64-apple-darwin": + # Starting with v19 there are arm64 binaries for ARM (e.g. M1, M2) macs, but they have to be signed to run binary_path = f'{os.getcwd()}/{tag}/bin/' for arm_binary in os.listdir(binary_path): @@ -311,7 +311,12 @@ def main(args) -> int: if __name__ == '__main__': parser = argparse.ArgumentParser( - formatter_class=argparse.ArgumentDefaultsHelpFormatter) + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + epilog=''' + HOST can be set to any of the `host-platform-triplet`s from + depends/README.md for which a release exists. + ''', + ) parser.add_argument('-r', '--remove-dir', action='store_true', help='remove existing directory.') parser.add_argument('-d', '--depends', action='store_true', diff --git a/test/lint/lint-files.py b/test/lint/lint-files.py index ee09cea93235..a53a060b550c 100755 --- a/test/lint/lint-files.py +++ b/test/lint/lint-files.py @@ -21,7 +21,7 @@ ALLOWED_FILENAME_REGEXP = "^[a-zA-Z0-9/_.@][a-zA-Z0-9/_.@-]*$" ALLOWED_SOURCE_FILENAME_REGEXP = "^[a-z0-9_./-]+$" ALLOWED_SOURCE_FILENAME_EXCEPTION_REGEXP = ( - "^src/(dashbls/|immer/|secp256k1/|minisketch/|test/fuzz/FuzzedDataProvider.h)" + "^rust/|src/(dashbls/|immer/|secp256k1/|minisketch/|test/fuzz/FuzzedDataProvider.h)" ) ALLOWED_PERMISSION_NON_EXECUTABLES = 0o644 ALLOWED_PERMISSION_EXECUTABLES = 0o755 diff --git a/test/lint/lint-format-strings.py b/test/lint/lint-format-strings.py index 6992343d6cf6..11c5ffd51ed7 100755 --- a/test/lint/lint-format-strings.py +++ b/test/lint/lint-format-strings.py @@ -82,7 +82,7 @@ def main(): matching_files_filtered = [] for matching_file in matching_files: - if not re.search('^src/(dashbls|leveldb|secp256k1|minisketch|tinyformat|test/fuzz/strprintf.cpp|clientversion.cpp)', matching_file): + if not re.search('^rust/|src/(dashbls|leveldb|secp256k1|minisketch|tinyformat|test/fuzz/strprintf.cpp|clientversion.cpp)', matching_file): matching_files_filtered.append(matching_file) matching_files_filtered.sort() diff --git a/test/lint/lint-include-guards.py b/test/lint/lint-include-guards.py index 6e59c83f7dbc..5e65e056831d 100755 --- a/test/lint/lint-include-guards.py +++ b/test/lint/lint-include-guards.py @@ -17,20 +17,21 @@ HEADER_ID_PREFIX = 'BITCOIN_' HEADER_ID_SUFFIX = '_H' -EXCLUDE_FILES_WITH_PREFIX = ['src/crypto/ctaes', - 'src/leveldb', - 'src/crc32c', - 'src/secp256k1', - 'src/minisketch', - 'src/tinyformat.h', +EXCLUDE_FILES_WITH_PREFIX = ['rust/', 'src/bench/nanobench.h', - 'src/test/fuzz/FuzzedDataProvider.h', 'src/bls', + 'src/crc32c', + 'src/crypto/ctaes', 'src/crypto/x11/sph', 'src/ctpl_stl.h', 'src/dashbls', 'src/gsl', - 'src/immer'] + 'src/immer', + 'src/leveldb', + 'src/minisketch', + 'src/secp256k1', + 'src/test/fuzz/FuzzedDataProvider.h', + 'src/tinyformat.h'] def _get_header_file_lst() -> List[str]: diff --git a/test/lint/lint-includes.py b/test/lint/lint-includes.py index 5169f5fc685f..927a7dae77e1 100755 --- a/test/lint/lint-includes.py +++ b/test/lint/lint-includes.py @@ -15,13 +15,14 @@ from subprocess import check_output, CalledProcessError -EXCLUDED_DIRS = ["src/leveldb/", +EXCLUDED_DIRS = ["rust/", "src/crc32c/", - "src/secp256k1/", - "src/minisketch/", + "src/crypto/x11/", "src/dashbls/", "src/immer/", - "src/crypto/x11/"] + "src/minisketch/", + "src/secp256k1/", + "src/leveldb/"] EXPECTED_BOOST_INCLUDES = ["boost/date_time/posix_time/posix_time.hpp", "boost/hana/for_each.hpp", diff --git a/test/lint/lint-locale-dependence.py b/test/lint/lint-locale-dependence.py index 2a8266d524dc..995f0afa63d0 100755 --- a/test/lint/lint-locale-dependence.py +++ b/test/lint/lint-locale-dependence.py @@ -57,13 +57,14 @@ ] REGEXP_EXTERNAL_DEPENDENCIES_EXCLUSIONS = [ + "rust/", "src/crypto/ctaes/", + "src/dashbls/", + "src/immer/", "src/leveldb/", - "src/secp256k1/", "src/minisketch/", + "src/secp256k1/", "src/tinyformat.h", - "src/dashbls/", - "src/immer/" ] LOCALE_DEPENDENT_FUNCTIONS = [ diff --git a/test/lint/lint-python-utf8-encoding.py b/test/lint/lint-python-utf8-encoding.py index 4f8b307c04ee..e6c03a22b5f9 100755 --- a/test/lint/lint-python-utf8-encoding.py +++ b/test/lint/lint-python-utf8-encoding.py @@ -12,7 +12,8 @@ from subprocess import check_output, CalledProcessError -EXCLUDED_DIRS = ["src/crc32c/", +EXCLUDED_DIRS = ["rust/", + "src/crc32c/", "src/secp256k1/"] diff --git a/test/lint/lint-python.py b/test/lint/lint-python.py index a81edfd2fc7f..8d6da0d0690a 100755 --- a/test/lint/lint-python.py +++ b/test/lint/lint-python.py @@ -18,7 +18,8 @@ DEPS = ['flake8', 'lief', 'mypy', 'pyzmq'] MYPY_CACHE_DIR = f"{os.getenv('BASE_ROOT_DIR', '')}/test/.mypy_cache" FILES_ARGS = ['git', 'ls-files', '--','test/functional/*.py', 'contrib/devtools/*.py', ':(exclude)contrib/devtools/github-merge.py'] -EXCLUDE_DIRS = ['src/dashbls/', +EXCLUDE_DIRS = ['rust/', + 'src/dashbls/', 'src/immer/'] ENABLED = ( diff --git a/test/lint/lint-shell-locale.py b/test/lint/lint-shell-locale.py index 77f6d79f3529..5b4ced04cf3a 100755 --- a/test/lint/lint-shell-locale.py +++ b/test/lint/lint-shell-locale.py @@ -41,7 +41,7 @@ def main(): exit_code = 0 shell_files = get_shell_files_list() for file_path in shell_files: - if re.search('src/(dashbls|secp256k1|minisketch)/', file_path): + if re.search('rust/|src/(dashbls|secp256k1|minisketch)/', file_path): continue with open(file_path, 'r', encoding='utf-8') as file_obj: diff --git a/test/lint/lint-shell.py b/test/lint/lint-shell.py index c1acd618c120..5a221dc6af02 100755 --- a/test/lint/lint-shell.py +++ b/test/lint/lint-shell.py @@ -68,7 +68,7 @@ def main(): ] files = get_files(files_cmd) # remove everything that doesn't match this regex - reg = re.compile(r'src/[dashbls,immer,leveldb,secp256k1,minisketch]') + reg = re.compile(r'rust|src/[dashbls,immer,leveldb,secp256k1,minisketch]') files[:] = [file for file in files if not reg.match(file)] # build the `shellcheck` command diff --git a/test/lint/lint-spelling.py b/test/lint/lint-spelling.py index 1acc5998d34a..73b2b14b2f7f 100755 --- a/test/lint/lint-spelling.py +++ b/test/lint/lint-spelling.py @@ -12,7 +12,27 @@ from subprocess import check_output, STDOUT, CalledProcessError IGNORE_WORDS_FILE = 'test/lint/spelling.ignore-words.txt' -FILES_ARGS = ['git', 'ls-files', '--', ":(exclude)build-aux/m4/", ":(exclude)contrib/seeds/*.txt", ":(exclude)depends/", ":(exclude)doc/release-notes/", ":(exclude)src/bip39_english.h", ":(exclude)src/dashbls/", ":(exclude)src/crc32c/", ":(exclude)src/crypto/", ":(exclude)src/ctpl_stl.h", ":(exclude)src/cxxtimer.hpp", ":(exclude)src/immer/", ":(exclude)src/leveldb/", ":(exclude)src/qt/locale/", ":(exclude)src/qt/*.qrc", ":(exclude)src/secp256k1/", ":(exclude)src/minisketch/", ":(exclude)contrib/builder-keys/", ":(exclude)contrib/guix/patches", ":(exclude)src/util/subprocess.hpp"] +FILES_ARGS = ['git', 'ls-files', '--', + ":(exclude)build-aux/m4/", + ":(exclude)contrib/builder-keys/", + ":(exclude)contrib/guix/patches", + ":(exclude)contrib/seeds/*.txt", + ":(exclude)depends/", + ":(exclude)doc/release-notes/", + ":(exclude)rust/", + ":(exclude)src/bip39_english.h", + ":(exclude)src/crc32c/", + ":(exclude)src/crypto/", + ":(exclude)src/ctpl_stl.h", + ":(exclude)src/cxxtimer.hpp", + ":(exclude)src/dashbls/", + ":(exclude)src/immer/", + ":(exclude)src/leveldb/", + ":(exclude)src/minisketch/", + ":(exclude)src/qt/*.qrc", + ":(exclude)src/qt/locale/", + ":(exclude)src/secp256k1/", + ":(exclude)src/util/subprocess.hpp"] def check_codespell_install(): diff --git a/test/lint/lint-whitespace.py b/test/lint/lint-whitespace.py index 15d009b29c15..62c734c07fd0 100755 --- a/test/lint/lint-whitespace.py +++ b/test/lint/lint-whitespace.py @@ -16,17 +16,18 @@ from subprocess import check_output -EXCLUDED_DIRS = ["depends/patches/", - "contrib/guix/patches/", - "src/crypto/x11/", - "src/leveldb/", +EXCLUDED_DIRS = ["contrib/guix/patches/", + "depends/patches/", + "doc/release-notes/", + "rust/", "src/crc32c/", - "src/secp256k1/", - "src/minisketch/", + "src/crypto/x11/", "src/dashbls/", "src/immer/", - "doc/release-notes/", - "src/qt/locale"] + "src/leveldb/", + "src/minisketch/", + "src/qt/locale/", + "src/secp256k1/"] def parse_args(): """Parse command line arguments."""