diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c92762fa4..398305ef0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: run: make -C ./depends download-linux - name: build dependencies - run: make -C ./depends + run: make -C ./depends -j - run: ./autogen.sh @@ -57,6 +57,45 @@ jobs: src/zsided src/zside-cli + build-windows: + name: Build Windows binaries + runs-on: ubuntu-latest + steps: + # https://zcash.readthedocs.io/en/master/rtd_pages/Debian-Ubuntu-build.html + - uses: actions/checkout@v3 + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ./depends + key: Windows-${{ hashFiles('depends/packages/**') }} + + - name: Run build in Docker + uses: addnab/docker-run-action@v3 + with: + image: electriccoinco/zcashd-build-ubuntu-jammy + options: -v ${{ github.workspace }}:/zside --workdir=/zside + shell: bash + run: | + set -e + make -C ./depends download-win + HOST=x86_64-w64-mingw32 make -C ./depends + export CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site + ./autogen.sh + ./configure --disable-tests --disable-bench --disable-hardening --enable-online-rust + make -C src cargo-build-lib + BRIDGE_LOCATION=$(dirname $(./contrib/devtools/find-libcxxbridge.sh)) + export LDFLAGS="-L$BRIDGE_LOCATION -lcxxbridge1" + ./configure --disable-tests --disable-bench --disable-hardening --enable-online-rust + make -j + + - uses: actions/upload-artifact@v4 + with: + name: binaries-Windows + if-no-files-found: error + path: | + src/zsided.exe + src/zside-cli.exe build-macos: name: Build macOS binaries @@ -83,7 +122,7 @@ jobs: run: make -C ./depends download-osx - name: build dependencies - run: make -C ./depends + run: make -C ./depends -j - run: ./autogen.sh diff --git a/README.md b/README.md index 633ac5457..f1121f705 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,31 @@ system instead, without success. If someone more skilled at the build system than the previous author strolls along, please take a look. +### Cross-compiling from Linux to Windows + +Building binaries for Windows must happen through cross-compiling +from a Linux machine. This requires a rather specific set of +packages on the host machine, so the easiest way is to do this +through a Docker container. We use the `electriccoinco/zcashd-build-ubuntu-jammy` +image, provided by the upstream Zcash devs. + +```bash +# from the root of this repo +$ docker run -ti -v $PWD:/zside --workdir /zside electriccoinco/zcashd-build-ubuntu-jammy bash + +$ HOST=x86_64-w64-mingw32 make -C depends V=1 -j8 +$ export CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site +$ ./autogen.sh +$ ./configure --disable-tests --disable-bench --disable-hardening --enable-online-rust +$ make -C src cargo-build-lib +$ BRIDGE_LOCATION=$(dirname $(./contrib/devtools/find-libcxxbridge.sh)) +$ export LDFLAGS="-L$BRIDGE_LOCATION -lcxxbridge1" +$ ./configure --disable-tests --disable-bench --disable-hardening --enable-online-rust +$ make -j8 + +# final result is in ./src/zsided.exe +``` + ### Nix - currently not working To install all dependencies and build zcash-sidechain on ubuntu (22.04) run: @@ -119,6 +144,13 @@ nix-shell # this will install all build tools and dependencies make -j8 # or number of cores you want to use ``` +### General build notes + +* **Binary sizes**. The `zsided` and `zside-cli` binaries are large. Linux binaries + are around 150MB, and Windows binaries are over 200MB! They can be reduced by + setting `CFLAGS` and `CXXFLAGS` to `-g0`. This disables debug information, and + more than halves binary sizes. + ### Regtest Demo Script A script for: activating this sidechain (on [drivechain](https://github.com/drivechain-project/mainchain/)), mining blocks, depositing and withdrawing coins, generating t/z addresses and using them, is [available here](zside-tour-2022.sh). diff --git a/configure.ac b/configure.ac index 8b4b24fd5..f5d6af392 100644 --- a/configure.ac +++ b/configure.ac @@ -405,6 +405,9 @@ case $host in CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN" LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" + + dnl Windows seems to require libssp even if hardening is disabled. + LDFLAGS="$LDFLAGS -lssp" dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against. dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override diff --git a/contrib/devtools/update-clang-hashes.sh b/contrib/devtools/update-clang-hashes.sh new file mode 100755 index 000000000..df464707e --- /dev/null +++ b/contrib/devtools/update-clang-hashes.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +export LC_ALL=C +set -o pipefail + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CLANG_PACKAGE="$SCRIPT_DIR/../../depends/packages/native_clang.mk" +LIBCXX_PACKAGE="$SCRIPT_DIR/../../depends/packages/libcxx.mk" + +CLANG_MAJOR_VERSION=$( cat $CLANG_PACKAGE | grep -oP "_major_version=\K.*" ) +CLANG_VERSION=$( cat $CLANG_PACKAGE | grep -v _major_version | grep -oP "_version=\K.*" ) +LIBCXX_MSYS2_VERSION=$( cat $LIBCXX_PACKAGE | grep -oP "_msys2_version=\K.*" ) + +update_clang_hash() { + url="https://github.com/llvm/llvm-project/releases/download/llvmorg-$CLANG_VERSION/clang+llvm-$CLANG_VERSION-$1.tar.xz" + echo "Fetching $url" + hash=$( curl -fL $url | sha256sum | awk '{print $1}' ) + retVal=$? + if [ $retVal -ne 0 ]; then + if [ $retVal -eq 22 ]; then + echo + echo "The LLVM project has not published a $CLANG_VERSION build for $1." + echo "You will need to manually fix the Makefile to use a different version." + echo + fi + else + sed -i "/\$(package)_sha256_hash_$2=/c\\\$(package)_sha256_hash_$2=$hash" $CLANG_PACKAGE + sed -i "/\$(package)_sha256_hash_$2=/c\\\$(package)_sha256_hash_$2=$hash" $LIBCXX_PACKAGE + fi +} + +update_libcxx_msys2_hash() { + url="https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-$1-$LIBCXX_MSYS2_VERSION-any.pkg.tar.zst" + echo "Fetching $url" + hash=$( curl -fL $url | sha256sum | awk '{print $1}' ) + sed -i "/\$(package)_$2=/c\\\$(package)_$2=$hash" $LIBCXX_PACKAGE +} + +# For native targets +# update_clang_hash CLANG_COMPILED_TARGET MAKEFILE_PACKAGE_IDENTIFIER +update_clang_hash aarch64-linux-gnu aarch64_linux +update_clang_hash x86_64-apple-darwin darwin +update_clang_hash x86_64-linux-gnu-ubuntu-18.04 linux +update_clang_hash amd64-unknown-freebsd12 freebsd + +# For Windows cross-compilation +# update_libcxx_msys2_hash LIBCXX_LIBRARY MAKEFILE_HASH_SUFFIX +update_libcxx_msys2_hash libc++ sha256_hash diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index e48546cce..dea80371b 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -3,6 +3,9 @@ mingw32_CXXFLAGS=$(mingw32_CFLAGS) -isystem $(host_prefix)/include/c++/v1 mingw32_LDFLAGS?=-fuse-ld=lld +# Port from upstream https://github.com/zcash/zcash/commit/c3693a5f857b27224707538179840eea223c1b41 +mingw32_LDFLAGS+=-L/usr/lib/gcc/x86_64-w64-mingw32/$(shell x86_64-w64-mingw32-g++-posix -dumpversion) + mingw32_release_CFLAGS=-O3 mingw32_release_CXXFLAGS=$(mingw32_release_CFLAGS) diff --git a/depends/packages/libcxx.mk b/depends/packages/libcxx.mk index bbadd228e..fcda4be5c 100644 --- a/depends/packages/libcxx.mk +++ b/depends/packages/libcxx.mk @@ -1,5 +1,6 @@ package=libcxx $(package)_version=$(native_clang_version) +$(package)_msys2_version=15.0.7-3 ifneq ($(canonical_host),$(build)) ifneq ($(host_os),mingw32) @@ -8,51 +9,34 @@ ifneq ($(host_os),mingw32) $(package)_download_path=$(native_clang_download_path) $(package)_download_file_aarch64_linux=clang+llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz $(package)_file_name_aarch64_linux=clang-llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz -$(package)_sha256_hash_aarch64_linux=15ff2db12683e69e552b6668f7ca49edaa01ce32cb1cbc8f8ed2e887ab291069 +$(package)_sha256_hash_aarch64_linux=8ca4d68cf103da8331ca3f35fe23d940c1b78fb7f0d4763c1c059e352f5d1bec $(package)_download_file_linux=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz $(package)_file_name_linux=clang-llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz -$(package)_sha256_hash_linux=84a54c69781ad90615d1b0276a83ff87daaeded99fbc64457c350679df7b4ff0 +$(package)_sha256_hash_linux=38bc7f5563642e73e69ac5626724e206d6d539fbef653541b34cae0ba9c3f036 +# Starting from LLVM 14.0.0, some Clang binary tarballs store libc++ in a +# target-specific subdirectory. define $(package)_stage_cmds mkdir -p $($(package)_staging_prefix_dir)/lib && \ - cp lib/libc++.a $($(package)_staging_prefix_dir)/lib && \ - cp lib/libc++abi.a $($(package)_staging_prefix_dir)/lib + (test ! -f lib/*/libc++.a || cp lib/*/libc++.a $($(package)_staging_prefix_dir)/lib) && \ + (test ! -f lib/*/libc++abi.a || cp lib/*/libc++abi.a $($(package)_staging_prefix_dir)/lib) && \ + (test ! -f lib/libc++.a || cp lib/libc++.a $($(package)_staging_prefix_dir)/lib) && \ + (test ! -f lib/libc++abi.a || cp lib/libc++abi.a $($(package)_staging_prefix_dir)/lib) endef else # For Windows cross-compilation, use the MSYS2 binaries. -# Using 13.0.0-3 because 13.0.1-1 has missing `new` and `delete` symbols. +# Starting from LLVM 15.0.0, libc++abi is provided by libc++. $(package)_download_path=https://repo.msys2.org/mingw/x86_64 -$(package)_download_file=mingw-w64-x86_64-libc++-13.0.0-3-any.pkg.tar.zst -$(package)_file_name=mingw-w64-x86_64-libcxx-13.0.0-3-any.pkg.tar.zst -$(package)_sha256_hash=0f8819e88273579f7c9262456c6b8f4d73e1693095c2364d1192c61c5f6a1a4f - -$(package)_libcxxabi_download_file=mingw-w64-x86_64-libc++abi-13.0.0-3-any.pkg.tar.zst -$(package)_libcxxabi_file_name=mingw-w64-x86_64-libcxxabi-13.0.0-3-any.pkg.tar.zst -$(package)_libcxxabi_sha256_hash=7224a7252a566938afe91ea8f130682abd29b10e13c9a3c2347af523ca0d7c42 - -$(package)_extra_sources += $($(package)_libcxxabi_file_name) - -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_libcxxabi_download_file),$($(package)_libcxxabi_file_name),$($(package)_libcxxabi_sha256_hash)) -endef - -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_libcxxabi_sha256_hash) $($(package)_source_dir)/$($(package)_libcxxabi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p libcxxabi && \ - tar --no-same-owner --strip-components=1 -C libcxxabi -xf $($(package)_source_dir)/$($(package)_libcxxabi_file_name) && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -endef +$(package)_download_file=mingw-w64-x86_64-libc++-$($(package)_msys2_version)-any.pkg.tar.zst +$(package)_file_name=mingw-w64-x86_64-libcxx-$($(package)_msys2_version)-any.pkg.tar.zst +$(package)_sha256_hash=8c14da21fa9622cc7450b22467452c6c933a03cee526cf8744faea3d4674035b define $(package)_stage_cmds mkdir -p $($(package)_staging_prefix_dir)/lib && \ mv include/ $($(package)_staging_prefix_dir) && \ cp lib/libc++.a $($(package)_staging_prefix_dir)/lib && \ - cp libcxxabi/lib/libc++abi.a $($(package)_staging_prefix_dir)/lib + cp lib/libc++abi.a $($(package)_staging_prefix_dir)/lib endef endif @@ -68,8 +52,10 @@ endef define $(package)_stage_cmds mkdir -p $($(package)_staging_prefix_dir)/lib && \ - cp $(build_prefix)/lib/libc++.a $($(package)_staging_prefix_dir)/lib && \ - if [ -f "$(build_prefix)/lib/libc++abi.a" ]; then cp $(build_prefix)/lib/libc++abi.a $($(package)_staging_prefix_dir)/lib; fi + (test ! -f $(build_prefix)/lib/*/libc++.a || cp $(build_prefix)/lib/*/libc++.a $($(package)_staging_prefix_dir)/lib) && \ + (test ! -f $(build_prefix)/lib/*/libc++abi.a || cp $(build_prefix)/lib/*/libc++abi.a $($(package)_staging_prefix_dir)/lib) && \ + (test ! -f $(build_prefix)/lib/libc++.a || cp $(build_prefix)/lib/libc++.a $($(package)_staging_prefix_dir)/lib) && \ + (test ! -f $(build_prefix)/lib/libc++abi.a || cp $(build_prefix)/lib/libc++abi.a $($(package)_staging_prefix_dir)/lib) endef endif diff --git a/depends/packages/native_clang.mk b/depends/packages/native_clang.mk index 662e088eb..be2a48a70 100644 --- a/depends/packages/native_clang.mk +++ b/depends/packages/native_clang.mk @@ -1,22 +1,30 @@ package=native_clang -$(package)_major_version=13 -$(package)_version=13.0.1 -$(package)_download_path=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) +# To update the Clang compiler: +# - Change the versions below, and the MSYS2 version in libcxx.mk +# - Run the script ./contrib/devtools/update-clang-hashes.sh +# - Manually fix the versions for packages that don't exist (the LLVM project +# doesn't uniformly cut binaries across releases). +# The Clang compiler should use the same LLVM version as the Rust compiler. +$(package)_major_version=15 +$(package)_version=15.0.6 $(package)_download_path_linux=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) $(package)_download_file_linux=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz $(package)_file_name_linux=clang-llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz -$(package)_sha256_hash_linux=84a54c69781ad90615d1b0276a83ff87daaeded99fbc64457c350679df7b4ff0 -$(package)_download_path_darwin=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) -$(package)_download_file_darwin=clang+llvm-$($(package)_version)-x86_64-apple-darwin.tar.xz -$(package)_file_name_darwin=clang-llvm-$($(package)_version)-x86_64-apple-darwin.tar.xz -$(package)_sha256_hash_darwin=dec02d17698514d0fc7ace8869c38937851c542b02adf102c4e898f027145a4d -$(package)_download_path_freebsd=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) -$(package)_download_file_freebsd=clang+llvm-$($(package)_version)-amd64-unknown-freebsd12.tar.xz -$(package)_file_name_freebsd=clang-llvm-$($(package)_version)-amd64-unknown-freebsd12.tar.xz -$(package)_sha256_hash_freebsd=8101c8d3a920bf930b33987ada5373f43537c5de8c194be0ea10530fd0ad5617 +$(package)_sha256_hash_linux=38bc7f5563642e73e69ac5626724e206d6d539fbef653541b34cae0ba9c3f036 +$(package)_download_path_darwin=https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.4 +$(package)_download_file_darwin=clang+llvm-15.0.4-x86_64-apple-darwin.tar.xz +$(package)_file_name_darwin=clang-llvm-15.0.4-x86_64-apple-darwin.tar.xz +$(package)_sha256_hash_darwin=4c98d891c07c8f6661b233bf6652981f28432cfdbd6f07181114195c3536544b +# 2023-02-16: No FreeBSD packages are available for Clang 15, so we use Clang 14 +# here. This means FreeBSD builds will use two different versions of LLVM, but +# FreeBSD is only a Tier 3 platform, so that is acceptable. +$(package)_download_path_freebsd=https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.6 +$(package)_download_file_freebsd=clang+llvm-14.0.6-amd64-unknown-freebsd12.tar.xz +$(package)_file_name_freebsd=clang-llvm-14.0.6-amd64-unknown-freebsd12.tar.xz +$(package)_sha256_hash_freebsd=b0a7b86dacb12afb8dd2ca99ea1b894d9cce84aab7711cb1964b3005dfb09af3 $(package)_download_file_aarch64_linux=clang+llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz $(package)_file_name_aarch64_linux=clang-llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz -$(package)_sha256_hash_aarch64_linux=15ff2db12683e69e552b6668f7ca49edaa01ce32cb1cbc8f8ed2e887ab291069 +$(package)_sha256_hash_aarch64_linux=8ca4d68cf103da8331ca3f35fe23d940c1b78fb7f0d4763c1c059e352f5d1bec ifneq (,$(wildcard /etc/arch-release)) $(package)_dependencies=native_libtinfo @@ -45,6 +53,8 @@ define $(package)_stage_cmds cp -P bin/lld-link $($(package)_staging_prefix_dir)/bin && \ cp -P bin/llvm-ranlib $($(package)_staging_prefix_dir)/bin && \ cp -P bin/llvm-strip $($(package)_staging_prefix_dir)/bin && \ + (test ! -f include/x86_64-unknown-linux-gnu/c++/v1/__config_site || \ + cp include/x86_64-unknown-linux-gnu/c++/v1/__config_site include/c++/v1/__config_site) && \ mv include/ $($(package)_staging_prefix_dir) && \ mv lib/ $($(package)_staging_prefix_dir) && \ mv libexec/ $($(package)_staging_prefix_dir) diff --git a/qa/zcash/postponed-updates.txt b/qa/zcash/postponed-updates.txt index 423e1c2f7..a224f184e 100644 --- a/qa/zcash/postponed-updates.txt +++ b/qa/zcash/postponed-updates.txt @@ -17,16 +17,9 @@ native_ccache 4.5 2022-06-01 native_ccache 4.5.1 2022-06-01 native_ccache 4.6 2022-06-01 -# Clang and Rust are currently pinned to LLVM 13 -native_clang 14.0.0 2022-06-01 -native_clang 14.0.1 2022-06-01 -native_clang 14.0.2 2022-06-01 -native_clang 14.0.3 2022-06-01 -libcxx 14.0.0 2022-06-01 -libcxx 14.0.1 2022-06-01 -libcxx 14.0.2 2022-06-01 -libcxx 14.0.3 2022-06-01 -native_rust 1.60.0 2022-06-01 +# Clang and Rust are currently pinned to LLVM 15 +libcxx 15.0.7 2022-04-30 +native_clang 15.0.7 2022-04-30 # We're never updating to this version bdb 18.1.40 2024-02-01 diff --git a/src/Makefile.am b/src/Makefile.am index cf484929f..a362b7b1f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,10 +53,10 @@ endif # requires https://github.com/rust-bitcoin/rust-secp256k1/issues/380 to be addressed. # FIXME: fix linking errors and add RUSTFLAGS="--cfg=rust_secp_no_symbol_renaming" back # -# It's important that we pass on the CXX parameters to Rust. This ensures that the generated +# It's important that we pass on the CXX and CXXFLAGS parameters to Rust. This ensures that the generated # C++ code is compiled with the same configuration as the non-generated C++ code, which again # ensures ABI compatability at link time. -RUST_ENV_VARS = CXX="$(CXX)" RUSTC="$(RUSTC)" TERM=dumb +RUST_ENV_VARS = CXXFLAGS="$(CXXFLAGS)" CXX="$(CXX)" RUSTC="$(RUSTC)" TERM=dumb RUST_BUILD_OPTS = --release --target $(RUST_TARGET) --manifest-path $(top_srcdir)/Cargo.toml rust_verbose = $(rust_verbose_@AM_V@)