]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
GHA/windows: make MSVC jobs use MSYS2 libraries: psl, OpenSSL, H2, libssh2
authorViktor Szakats <commit@vsz.me>
Mon, 9 Jun 2025 14:07:05 +0000 (16:07 +0200)
committerViktor Szakats <commit@vsz.me>
Tue, 10 Jun 2025 22:51:04 +0000 (00:51 +0200)
Extend MSVC jobs with the option to use MSYS2 binary package as DLL
dependencies. Allow to use them alone (without vcpkg) or combined with
vcpkg packages. This saves the trouble of building these packages from
source and cache them manually.

This solution requires two tricks:
- workaround for zlib which installs a target-specific `zconf.h` that's
  not portable between platforms and C compilers.
- manual dependency configuration in CMake to ensure linking against
  the MSYS2 DLLs (and not it static libs). Static libs aren't portable
  to MSVC due to missing symbols `__chkstk_ms`, `_stack_chk_fail`,
  `_memcpy_chk`, `_stack_chk_guard`, and potentially other issues. CMake
  in MSVC mode, `linker.exe` and `pkg-config` pick the static libs by
  default. To pick `.dll.a` in favour of `.a`, these tools would have
  to be taught about this convention. An alternative is deleting static
  libs and see if `.dll.a` are picked-up automatically.

Using MSYS2 packages adds an install step taking 15-45 seconds per job.

It allowed to:
- re-enable libpsl for all MSVC jobs.
- convert the Intel 64-bit job to use MSYS2 without vcpkg, enabling
  brotli, zstd, OpenSSL 3.5.0, libssh2 (with OpenSSL cryprography) and
  nghttp2.

Using the same technique it's possible to re-enable more features
in MSVC builds, e.g. GnuTLS (also with H3), LibreSSL, mbedTLS, nghttp3,
ngtcp2, libssh, c-ares, gsasl, and replace vcpkg zlib, for faster runs.
What's missing compared to vcpkg is BoringSSL and wolfSSL
(the MSYS2-supplied build doesn't fit curl's requirements IIRC). These
could be built and cached manually.

Also:
- add workaround for zlib (classic) which uses a generated `zconf.h`,
  rendering the MSYS2 zlib header incompatible with MSVC.
- set the correct `msystem` for arm64.
- allow using MSVC without vcpkg.

Follow-up to cd0ec4784c1c0f873939f33ec1a73c8739f276b9 #17089

Closes #17561

.github/workflows/windows.yml

index ed6303db91a7449c705a2aff2f085732b547d7a5..871501ad2349ec365eded6ba857bd2c01ba19389 100644 (file)
@@ -807,7 +807,8 @@ jobs:
     env:
       MATRIX_ARCH: '${{ matrix.arch }}'
       MATRIX_IMAGE: '${{ matrix.image }}'
-      MATRIX_INSTALL: '${{ matrix.install }}'
+      MATRIX_INSTALL_MSYS2: '${{ matrix.install-msys2 }}'
+      MATRIX_INSTALL_VCPKG: '${{ matrix.install-vcpkg }}'
       MATRIX_OPENSSH: '${{ matrix.openssh }}'
       MATRIX_PLAT: '${{ matrix.plat }}'
       MATRIX_TYPE: '${{ matrix.type }}'
@@ -817,8 +818,9 @@ jobs:
       matrix:
         include:
           - name: '!ssl +examples'
-            install: 'zlib libssh2[core,zlib]'
+            install-vcpkg: 'zlib libssh2[core,zlib]'
             arch: 'x64'
+            env: 'ucrt-x86_64'
             plat: 'uwp'
             type: 'Debug'
             image: 'windows-2025'
@@ -827,23 +829,46 @@ jobs:
               -DENABLE_DEBUG=ON
               -DCURL_ENABLE_SSL=OFF
               -DUSE_WIN32_IDN=ON
-              -DCURL_USE_LIBPSL=OFF
 
-          - name: 'schannel +examples'
-            install: 'zlib libssh2[core,zlib]'
+          - name: 'openssl +examples'
+            install-msys2: >-
+              mingw-w64-ucrt-x86_64-brotli
+              mingw-w64-ucrt-x86_64-zlib
+              mingw-w64-ucrt-x86_64-zstd
+              mingw-w64-ucrt-x86_64-openssl
+              mingw-w64-ucrt-x86_64-libssh2
+              mingw-w64-ucrt-x86_64-nghttp2
+
             arch: 'x64'
+            env: 'ucrt-x86_64'
             plat: 'windows'
             type: 'Debug'
             chkprefill: '_chkprefill'
             config: >-
               -DENABLE_DEBUG=ON
-              -DCURL_USE_SCHANNEL=ON
+              -DCURL_USE_OPENSSL=ON
+              -DOPENSSL_INCLUDE_DIR=/ucrt64/include
+              -DSSL_EAY_DEBUG=/ucrt64/lib/libssl.dll.a
+              -DSSL_EAY_RELEASE=/ucrt64/lib/libssl.dll.a
+              -DLIB_EAY_DEBUG=/ucrt64/lib/libcrypto.dll.a
+              -DLIB_EAY_RELEASE=/ucrt64/lib/libcrypto.dll.a
               -DUSE_WIN32_IDN=ON -DUSE_SSLS_EXPORT=ON
-              -DCURL_USE_LIBPSL=OFF
+              -DBROTLI_INCLUDE_DIR=/ucrt64/include
+              -DBROTLICOMMON_LIBRARY=/ucrt64/lib/libbrotlicommon.dll.a
+              -DBROTLIDEC_LIBRARY=/ucrt64/lib/libbrotlidec.dll.a
+              -DZSTD_INCLUDE_DIR=/ucrt64/include
+              -DZSTD_LIBRARY=/ucrt64/lib/libzstd.dll.a
+              -DZLIB_INCLUDE_DIR=/ucrt64/include
+              -DZLIB_LIBRARY=/ucrt64/lib/libz.dll.a
+              -DLIBSSH2_INCLUDE_DIR=/ucrt64/include
+              -DLIBSSH2_LIBRARY=/ucrt64/lib/libssh2.dll.a
+              -DNGHTTP2_INCLUDE_DIR=/ucrt64/include
+              -DNGHTTP2_LIBRARY=/ucrt64/lib/libnghttp2.dll.a
 
           - name: 'schannel U'
-            install: 'zlib libssh2[core,zlib]'
+            install-vcpkg: 'zlib libssh2[core,zlib]'
             arch: 'arm64'
+            env: 'clang-aarch64'
             plat: 'windows'
             type: 'Debug'
             image: 'windows-11-arm'
@@ -852,26 +877,30 @@ jobs:
               -DENABLE_DEBUG=ON
               -DCURL_USE_SCHANNEL=ON
               -DUSE_WIN32_IDN=ON -DENABLE_UNICODE=ON -DUSE_SSLS_EXPORT=ON
-              -DCURL_USE_LIBPSL=OFF
 
       fail-fast: false
     steps:
       - uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # v2
         with:
-          msystem: ucrt64
+          msystem: ${{ matrix.arch == 'arm64' && 'clangarm64' || 'ucrt64' }}
           release: ${{ contains(matrix.image, 'arm') }}
           cache: ${{ contains(matrix.image, 'arm') }}
           path-type: inherit
+          install: >-
+            mingw-w64-${{ matrix.env }}-libpsl
+            ${{ matrix.install-msys2 }}
 
       - name: 'vcpkg versions'
+        if: ${{ matrix.install-vcpkg  }}
         timeout-minutes: 1
         run: |
           git -C "$VCPKG_INSTALLATION_ROOT" show --no-patch --format='%H %ai'
           vcpkg version
 
       - name: 'vcpkg build'
+        if: ${{ matrix.install-vcpkg  }}
         timeout-minutes: 45
-        run: vcpkg x-set-installed ${MATRIX_INSTALL} --triplet="${MATRIX_ARCH}-${MATRIX_PLAT}"
+        run: vcpkg x-set-installed ${MATRIX_INSTALL_VCPKG} --triplet="${MATRIX_ARCH}-${MATRIX_PLAT}"
 
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
         with:
@@ -883,6 +912,7 @@ jobs:
           MATRIX_CHKPREFILL: '${{ matrix.chkprefill }}'
           MATRIX_CONFIG: '${{ matrix.config }}'
         run: |
+          [ -f "${MINGW_PREFIX}/include/zconf.h" ] && sed -i -E 's|(# +define +Z_HAVE_UNISTD_H)|/*\1*/|g' "${MINGW_PREFIX}/include/zconf.h"  # Patch MSYS2 zconf.h for MSVC
           for _chkprefill in '' ${MATRIX_CHKPREFILL}; do
             options=''
             if [ "${MATRIX_PLAT}" = 'uwp' ]; then
@@ -895,17 +925,21 @@ jobs:
             [ "${MATRIX_ARCH}" = 'x64' ] && options+=' -A x64'
             [ "${MATRIX_ARCH}" = 'x86' ] && options+=' -A Win32'
             [ "${_chkprefill}" = '_chkprefill' ] && options+=' -D_CURL_PREFILL=OFF'
+            if [ -n "${MATRIX_INSTALL_VCPKG}" ]; then
+              options+=" -DCMAKE_TOOLCHAIN_FILE=$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"
+              options+=" -DVCPKG_INSTALLED_DIR=$VCPKG_INSTALLATION_ROOT/installed"
+              options+=" -DVCPKG_TARGET_TRIPLET=${MATRIX_ARCH}-${MATRIX_PLAT}"
+              options+=" -DCMAKE_C_COMPILER_TARGET=${MATRIX_ARCH}-${MATRIX_PLAT}"
+            fi
             cmake -B "bld${_chkprefill}" ${options} \
-              -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" \
-              -DVCPKG_INSTALLED_DIR="$VCPKG_INSTALLATION_ROOT/installed" \
-              -DVCPKG_TARGET_TRIPLET="${MATRIX_ARCH}-${MATRIX_PLAT}" \
-              -DCMAKE_C_COMPILER_TARGET="${MATRIX_ARCH}-${MATRIX_PLAT}" \
               -DCMAKE_C_FLAGS="${cflags}" \
               -DCMAKE_EXE_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \
               -DCMAKE_SHARED_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \
               -DCMAKE_VS_GLOBALS="TrackFileAccess=false${vsglobals}" \
               -DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON \
               -DCURL_WERROR=ON \
+              -DLIBPSL_INCLUDE_DIR="${MINGW_PREFIX}/include" \
+              -DLIBPSL_LIBRARY="${MINGW_PREFIX}/lib/libpsl.dll.a" \
               -DBUILD_SHARED_LIBS=OFF \
               ${MATRIX_CONFIG}
           done
@@ -984,12 +1018,14 @@ jobs:
           export CURL_DIRSUFFIX="${MATRIX_TYPE}"
           TFLAGS="-j8 ${TFLAGS}"
           TFLAGS+=' !498'  # 'Reject too large HTTP response headers on endless redirects' HTTP, HTTP GET (runtests detecting result code 2009 instead of 56 returned by curl)
-          if [[ "${MATRIX_INSTALL}" = *'libssh2[core,zlib]'* ]]; then
+          if [[ "${MATRIX_INSTALL_MSYS2}" = *'libssh2-wincng'* || \
+                "${MATRIX_INSTALL_VCPKG}" = *'libssh2[core,zlib]'* ]]; then
             TFLAGS+=' ~SCP ~SFTP'  # Flaky: `-8, Unable to exchange encryption keys`. https://github.com/libssh2/libssh2/issues/804
           fi
           if [ -n "${MATRIX_OPENSSH}" ]; then  # OpenSSH-Windows
             TFLAGS+=' ~601 ~603 ~617 ~619 ~621 ~641 ~665 ~2004'  # SCP
-            if [[ "${MATRIX_INSTALL}" = *'libssh '* ]]; then
+            if [[ "${MATRIX_INSTALL_MSYS2} " = *'libssh '* || \
+                  "${MATRIX_INSTALL_VCPKG} " = *'libssh '* ]]; then
               TFLAGS+=' ~614'  # 'SFTP pre-quote chmod' SFTP, pre-quote, directory
             else
               TFLAGS+=' ~3022'  # 'SCP correct sha256 host key' SCP, server sha256 key check