From fc0ae5438152cf5e557115ab47a97f5bccc1f5dd Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Thu, 10 Mar 2022 20:09:41 +0100 Subject: [PATCH] ci: Add MSVC builds This adds MSVC builds built on Linux using wine. This requires some settings of tools and flags because the autotools support for MSVC is naturally somewhat limited. The advantage of this approach is that it is compatible with the our existing CI scripts, so there's no need to write a Windows CI script (in PowerShell or similar). A limitation of this approach is that it still relies on autotools and some less important parts of the MinGW-w64 toolchain, e.g., ar and nm. As such, the approach is most likely good enough to spot real miscompilations but it does not replicate native MSVC builds entirely. If we want to test building and running on Windows native (e.g., as supported by Cirrus CI) we could still do this in the future. Another feature of this approach is that contributors can simply use the docker image if they need a MSVC installation in a non-Windows environment. This commit also raises the TEST_ITERS for wine tasks to the default. The overhead of wine is negligible, so we can certainly afford the same number of iterations as for native Linux tests. --- .cirrus.yml | 85 +++++++++++++++++++++++++++++++++++++- ci/cirrus.sh | 1 + ci/linux-debian.Dockerfile | 31 +++++++++----- 3 files changed, 105 insertions(+), 12 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 271cbe5f54..273c378c8e 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -249,8 +249,24 @@ task: name: "x86_64 (mingw32-w64): Windows (Debian stable, Wine)" << : *LINUX_CONTAINER env: - WRAPPER_CMD: wine64-stable - SECP256K1_TEST_ITERS: 16 + WRAPPER_CMD: wine + HOST: x86_64-w64-mingw32 + WITH_VALGRIND: no + ECDH: yes + RECOVERY: yes + EXPERIMENTAL: yes + SCHNORRSIG: yes + CTIMETEST: no + << : *MERGE_BASE + test_script: + - ./ci/cirrus.sh + << : *CAT_LOGS + +task: + name: "i686 (mingw32-w64): Windows (Debian stable, Wine)" + << : *LINUX_CONTAINER + env: + WRAPPER_CMD: wine HOST: x86_64-w64-mingw32 WITH_VALGRIND: no ECDH: yes @@ -263,6 +279,71 @@ task: - ./ci/cirrus.sh << : *CAT_LOGS +task: + name: "x86_64 (mingw32-w64): Windows (Debian stable, Wine)" + << : *LINUX_CONTAINER + env: + WRAPPER_CMD: wine + HOST: x86_64-w64-mingw32 + WITH_VALGRIND: no + ECDH: yes + RECOVERY: yes + EXPERIMENTAL: yes + SCHNORRSIG: yes + CTIMETEST: no + << : *MERGE_BASE + test_script: + - ./ci/cirrus.sh + << : *CAT_LOGS + +task: + name: "x86_64 (MSVC/mingw32-w64): Windows (Debian stable, Wine)" + << : *LINUX_CONTAINER + env: + # MSVC compiler and linker plus some auxiliary MinGW-w64 tools (e.g., ar and nm) + HOST: x86_64-w64-mingw32 + CC: "/opt/msvc/bin/x64/cl" + # Set non-essential options that affect the CLI messages here. + # (They depend on the user's taste, so we don't want to set them automatically in configure.ac.) + CFLAGS: "/nologo /diagnostics:caret" + LDFLAGS: "-XCClinker /nologo -XCClinker /diagnostics:caret" + WERROR_CFLAGS: "/WX" + WRAPPER_CMD: wine + WITH_VALGRIND: no + ECDH: yes + RECOVERY: yes + EXPERIMENTAL: yes + SCHNORRSIG: yes + CTIMETEST: no + << : *MERGE_BASE + test_script: + - ./ci/cirrus.sh + << : *CAT_LOGS + +task: + name: "i686 (MSVC/mingw32-w64): Windows (Debian stable, Wine)" + << : *LINUX_CONTAINER + env: + # MSVC compiler and linker plus some auxiliary MinGW-w64 tools (e.g., ar and nm) + HOST: i686-w64-mingw32 + CC: "/opt/msvc/bin/x86/cl" + # Set non-essential options that affect the CLI messages here. + # (They depend on the user's taste, so we don't want to set them automatically in configure.ac.) + CFLAGS: "/nologo /diagnostics:caret" + LDFLAGS: "-XCClinker /nologo -XCClinker /diagnostics:caret" + WERROR_CFLAGS: "/WX" + WRAPPER_CMD: wine + WITH_VALGRIND: no + ECDH: yes + RECOVERY: yes + EXPERIMENTAL: yes + SCHNORRSIG: yes + CTIMETEST: no + << : *MERGE_BASE + test_script: + - ./ci/cirrus.sh + << : *CAT_LOGS + # Sanitizers task: << : *LINUX_CONTAINER diff --git a/ci/cirrus.sh b/ci/cirrus.sh index b85f012d3f..929c16d511 100755 --- a/ci/cirrus.sh +++ b/ci/cirrus.sh @@ -9,6 +9,7 @@ env >> test_env.log $CC -v || true valgrind --version || true +$WRAPPER_CMD --version || true ./autogen.sh diff --git a/ci/linux-debian.Dockerfile b/ci/linux-debian.Dockerfile index 5cccbb5565..a83a4e36db 100644 --- a/ci/linux-debian.Dockerfile +++ b/ci/linux-debian.Dockerfile @@ -1,15 +1,14 @@ FROM debian:stable -RUN dpkg --add-architecture i386 -RUN dpkg --add-architecture s390x -RUN dpkg --add-architecture armhf -RUN dpkg --add-architecture arm64 -RUN dpkg --add-architecture ppc64el -RUN apt-get update +RUN dpkg --add-architecture i386 && \ + dpkg --add-architecture s390x && \ + dpkg --add-architecture armhf && \ + dpkg --add-architecture arm64 && \ + dpkg --add-architecture ppc64el # dkpg-dev: to make pkg-config work in cross-builds # llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces -RUN apt-get install --no-install-recommends --no-upgrade -y \ +RUN apt-get update && apt-get install --no-install-recommends -y \ git ca-certificates \ make automake libtool pkg-config dpkg-dev valgrind qemu-user \ gcc clang llvm libc6-dbg \ @@ -19,8 +18,20 @@ RUN apt-get install --no-install-recommends --no-upgrade -y \ gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \ gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 \ gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \ - wine gcc-mingw-w64-x86-64 \ + gcc-mingw-w64-x86-64-win32 wine64 wine \ + gcc-mingw-w64-i686-win32 wine32 \ sagemath -# Run a dummy command in wine to make it set up configuration -RUN wine64-stable xcopy || true +WORKDIR /root +# The "wine" package provides a convience wrapper that we need +RUN apt-get update && apt-get install --no-install-recommends -y \ + git ca-certificates wine64 wine python3-simplejson python3-six msitools winbind procps && \ + git clone https://github.com/mstorsjo/msvc-wine && \ + mkdir /opt/msvc && \ + python3 msvc-wine/vsdownload.py --accept-license --dest /opt/msvc Microsoft.VisualStudio.Workload.VCTools && \ + msvc-wine/install.sh /opt/msvc + +# Initialize the wine environment. Wait until the wineserver process has +# exited before closing the session, to avoid corrupting the wine prefix. +RUN wine64 wineboot --init && \ + while (ps -A | grep wineserver) > /dev/null; do sleep 1; done