Merge bitcoin/bitcoin#35877: build: ci/doc win64-cross build via nix

fa8762da62 build: ci/doc win64-cross build via nix (MarcoFalke)
fafe7205cc doc: Clarify that cygwin/msys2 are not tested/supported (MarcoFalke)

Pull request description:

  Release cross-builds to win64 are done in guix. There are also docs to use Debian/Ubuntu for those cross-builds and this approach is used in CI. However, there are many problems:

  * The CI is intended to mirror the guix build, but often it is not possible to find the major versions used for mingw and GCC in the guix build in the `apt` packages for an LTS distro.
  * Users on older distro releases may lack released bugfixes, such as 8e06daa36d in mingw 13  (e.g. Debian Trixie with mingw 12, https://packages.debian.org/trixie/mingw-w64-x86-64-dev).
  * When using the UCRT variant of the build, this uncovers bugs such as https://bugs.launchpad.net/ubuntu/+source/mingw-w64/+bug/2106420 or https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1121403.

  So add a way to use nix to do the cross build. This allows to closer mimic the guix build.

  Also, clarify that cygwin/msys2 are not tested/supported.

ACKs for top commit:
  willcl-ark:
    reACK fa8762da62
  hebasto:
    re-ACK fa8762da62.

Tree-SHA512: de94f8bc4bb6ed9a75352cd909aa227c5954e336bf9b14969d7412b5cedfbe6cd6b2d8b476d5b1b0bcfc93bdb32fc229015855082350c8c507189e34b9b3ef3f
This commit is contained in:
merge-script
2026-08-20 15:26:53 +01:00
8 changed files with 79 additions and 8 deletions

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -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")

View File

@@ -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

View File

@@ -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)
'';
}

View File

@@ -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.

View File

@@ -9,7 +9,7 @@ The options known to work for building Bitcoin Core on Windows are:
* On Windows, using [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/about) and Mingw-w64.
* On Windows, using [Microsoft Visual Studio](https://visualstudio.microsoft.com). See [`build-windows-msvc.md`](./build-windows-msvc.md).
Other options which may work, but which have not been extensively tested are (please contribute instructions):
Other options may work, but are not officially tested:
* On Windows, using a POSIX compatibility layer application such as [cygwin](https://www.cygwin.com/) or [msys2](https://www.msys2.org/).