diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh index dbbf55c1478..7489188900a 100755 --- a/ci/test/00_setup_env_win64.sh +++ b/ci/test/00_setup_env_win64.sh @@ -7,9 +7,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_win64 -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-ucrt64 can cross-compile +export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export HOST=x86_64-w64-mingw32ucrt -export PACKAGES="g++-mingw-w64-ucrt64 nsis" +export PACKAGES="nix-bin nix-setup-systemd" export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/00_setup_env_win64_msvcrt.sh b/ci/test/00_setup_env_win64_msvcrt.sh index 6c948aeb351..d1c1aa8ac62 100755 --- a/ci/test/00_setup_env_win64_msvcrt.sh +++ b/ci/test/00_setup_env_win64_msvcrt.sh @@ -7,9 +7,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_win64_msvcrt -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-x86-64-posix (version 14.x, similar to guix) can cross-compile +export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export HOST=x86_64-w64-mingw32 -export PACKAGES="g++-mingw-w64-x86-64-posix nsis" +export PACKAGES="nix-bin nix-setup-systemd" export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index 29121476c37..7cd3a07cb3d 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -50,6 +50,11 @@ elif [ "$CI_OS_NAME" != "macos" ]; then ${CI_RETRY_EXE} apt-get install --no-install-recommends --no-upgrade -y $PACKAGES $CI_BASE_PACKAGES fi +if [[ ${HOST:-} == x86_64-w64-mingw32* ]]; then + # Install Nix packages. + NIX_BUILD_SHELL=bash nix-shell "${BASE_ROOT_DIR}/contrib/devtools/shell-win64-cross.nix" --run true +fi + if [ -n "${APT_LLVM_V}" ]; then update-alternatives --install /usr/bin/clang++ clang++ "/usr/bin/clang++-${APT_LLVM_V}" 100 update-alternatives --install /usr/bin/clang clang "/usr/bin/clang-${APT_LLVM_V}" 100 diff --git a/ci/test/02_run_container.py b/ci/test/02_run_container.py index 05887000a2b..d726b36a449 100755 --- a/ci/test/02_run_container.py +++ b/ci/test/02_run_container.py @@ -183,7 +183,18 @@ def main(): f"{os.environ['BASE_ROOT_DIR']}", ]) ci_exec([f"{os.environ['BASE_ROOT_DIR']}/ci/test/01_base_install.sh"]) - ci_exec([f"{os.environ['BASE_ROOT_DIR']}/ci/test/03_test_script.sh"]) + test_script = f"{os.environ['BASE_ROOT_DIR']}/ci/test/03_test_script.sh" + if os.environ.get("HOST", "").startswith("x86_64-w64-mingw32"): + ci_exec([ + "env", + "NIX_BUILD_SHELL=bash", + "nix-shell", + f"{os.environ['BASE_ROOT_DIR']}/contrib/devtools/shell-win64-cross.nix", + "--run", + f"exec bash {shlex.quote(test_script)}", + ]) + else: + ci_exec([test_script]) if not os.getenv("DANGER_RUN_CI_ON_HOST"): print("Stop and remove CI container by ID") diff --git a/ci/test_imagefile b/ci/test_imagefile index c696f075922..7cb88ddbf4e 100644 --- a/ci/test_imagefile +++ b/ci/test_imagefile @@ -17,6 +17,7 @@ ENV BASE_ROOT_DIR=${BASE_ROOT_DIR} # Make retry available in PATH, needed for CI_RETRY_EXE COPY ./ci/retry/retry /usr/bin/retry COPY ./ci/test/00_setup_env.sh ./${FILE_ENV} ./ci/test/01_base_install.sh ${BASE_ROOT_DIR}/ci/test/ +COPY ./contrib/devtools/shell-win64-cross.nix ${BASE_ROOT_DIR}/contrib/devtools/ COPY ./ci/test/*.patch ${BASE_ROOT_DIR}/ci/test/ # Bash is required, so install it when missing diff --git a/contrib/devtools/shell-win64-cross.nix b/contrib/devtools/shell-win64-cross.nix new file mode 100644 index 00000000000..4fd83b0da7a --- /dev/null +++ b/contrib/devtools/shell-win64-cross.nix @@ -0,0 +1,45 @@ +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +{ pkgs ? import (builtins.fetchTarball { + # Pin, to keep the versions of the toolchain aligned with the versions used by Guix. + url = "https://github.com/NixOS/nixpkgs/archive/531670d871c0e29724a02f3cbcac170adc65b58c.tar.gz"; + }) {} }: + +let + host = builtins.getEnv "HOST"; + crossPkgs = if host == "x86_64-w64-mingw32ucrt" + then pkgs.pkgsCross.ucrt64 + else if host == "x86_64-w64-mingw32" + then pkgs.pkgsCross.mingwW64 + else throw "Unsupported HOST: ${host}"; + toolchain = crossPkgs.stdenv.cc.targetPrefix; + pthreads = crossPkgs.windows.pthreads; +in + +pkgs.mkShellNoCC { + packages = [ + crossPkgs.gcc14 + pkgs.nsis + ]; + + shellHook = '' + export NIX_CFLAGS_COMPILE="-isystem ${pthreads}/include $NIX_CFLAGS_COMPILE" + export NIX_LDFLAGS="-L${pthreads}/lib $NIX_LDFLAGS" + export CC=$(command -v ${toolchain}gcc) + export CXX=$(command -v ${toolchain}g++) + export LD=$(command -v ${toolchain}ld) + export AR=$(command -v ${toolchain}ar) + export AS=$(command -v ${toolchain}as) + export RANLIB=$(command -v ${toolchain}ranlib) + export NM=$(command -v ${toolchain}nm) + export STRIP=$(command -v ${toolchain}strip) + export OBJCOPY=$(command -v ${toolchain}objcopy) + export OBJDUMP=$(command -v ${toolchain}objdump) + export READELF=$(command -v ${toolchain}readelf) + export SIZE=$(command -v ${toolchain}size) + export WINDRES=$(command -v ${toolchain}windres) + export RC=$(command -v ${toolchain}windres) + ''; +} diff --git a/depends/README.md b/depends/README.md index 99ae78324ab..9018fc12f1e 100644 --- a/depends/README.md +++ b/depends/README.md @@ -160,14 +160,23 @@ proceeding with a cross-compile. Under the depends directory, create a subdirectory named `SDKs`. Then, place the extracted SDK under this new directory. For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-extraction). -#### For Windows cross compilation using MSVCRT +#### For Windows cross compilation + +Using MSVCRT: apt install g++-mingw-w64-x86-64-posix -#### For Windows cross compilation using UCRT +Using UCRT: apt install g++-mingw-w64-ucrt64 +Some Ubuntu or Debian versions may not offer a working package. In this case, +you may install `nix-bin` and use the Nix shell from the repository root: + + apt install nix-bin + NIX_BUILD_SHELL=bash HOST=x86_64-w64-mingw32 nix-shell contrib/devtools/shell-win64-cross.nix # MSVCRT + NIX_BUILD_SHELL=bash HOST=x86_64-w64-mingw32ucrt nix-shell contrib/devtools/shell-win64-cross.nix # UCRT + #### For Linux cross compilation Please note that package availability might depend on the arch+OS you are building on.