curl/.github/workflows/macos.yml
Viktor Szakats 62d77b12fc
spacecheck: check long lines and repeat spaces, fix fallouts
Verify if lines are not longer than 192 characters. Also verify if lines
have less than 79 repeat spaces (and fix one fallout).

To improve readability by avoiding long lines and to prevent adding
overly long lines with text that may go unnoticed in an editor or diff
viewer.

In addition to pre-existing line length limits: 79 for C, 132 for CMake
sources.

Also:
- spacecheck: fix/harden allowlist regexes.
- spacecheck: tidy-up quotes and simplify escaping.
- spacecheck: allow folding strings with repeat spaces.
- GHA: fix a suppressed shellcheck warning.
- GHA/macos: simplify by dropping brew bundle.
- test1119.pl: precompile a regex.
- FAQ.md: delete very long link to a Windows 7/2008 support article
  that's lost it relevance.

Closes #21087
2026-03-25 11:02:08 +01:00

770 lines
34 KiB
YAML

# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
name: 'macOS'
'on':
push:
branches:
- master
- '*/ci'
paths-ignore:
- '**/*.md'
- '.circleci/**'
- 'appveyor.*'
- 'Dockerfile'
- 'projects/**'
pull_request:
branches:
- master
paths-ignore:
- '**/*.md'
- '.circleci/**'
- 'appveyor.*'
- 'Dockerfile'
- 'projects/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
permissions: {}
# Apple APIs and the macos-version-min value required to avoid deprecation
# warnings with llvm/clang, and/or the feature getting enabled at build-time
# or runtime:
#
# - 10.7 Lion (2011) - GSS (build-time, deprecated MIT Kerberos shim)
# - 10.9 Mavericks (2013) - LDAP (build-time, deprecated), OCSP (runtime)
# - 10.11 El Capitan (2015) - connectx() (runtime)
# - 10.12 Sierra (2016) - clock_gettime() (build-time, runtime)
# - 10.14 Mojave (2018) - SecTrustEvaluateWithError() (runtime)
env:
CURL_CI: github
CURL_TEST_MIN: 1700
MAKEFLAGS: -j 4
LDFLAGS: -w # suppress 'object file was built for newer macOS version than being linked' warnings
jobs:
ios:
name: "iOS, ${{ (matrix.build.generator && format('CM-{0}', matrix.build.generator)) || (matrix.build.generate && 'CM' || 'AM' )}} ${{ matrix.build.name }} arm64"
runs-on: macos-latest
timeout-minutes: 10
env:
DEVELOPER_DIR: "/Applications/Xcode${{ matrix.build.xcode && format('_{0}', matrix.build.xcode) || '' }}.app/Contents/Developer"
CC: 'clang'
LDFLAGS: ''
MATRIX_BUILD: ${{ matrix.build.generate && 'cmake' || 'autotools' }}
MATRIX_OPTIONS: ${{ matrix.build.options }}
# renovate: datasource=github-tags depName=libressl/portable versioning=semver registryUrl=https://github.com
LIBRESSL_VERSION: 4.2.1
strategy:
fail-fast: false
matrix:
build:
- name: 'libressl'
install_steps: libressl
configure: --with-openssl=/Users/runner/libressl --without-libpsl
- name: 'libressl'
install_steps: libressl
# FIXME: Could not make OPENSSL_ROOT_DIR work. CMake seems to prepend sysroot to it.
generator: Xcode
xcode: '' # default Xcode. Set it once to silence actionlint.
options: --config Debug
generate: >-
-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=OFF
-DMACOSX_BUNDLE_GUI_IDENTIFIER=se.curl
-DOPENSSL_INCLUDE_DIR=/Users/runner/libressl/include
-DOPENSSL_SSL_LIBRARY=/Users/runner/libressl/lib/libssl.a
-DOPENSSL_CRYPTO_LIBRARY=/Users/runner/libressl/lib/libcrypto.a
-DCURL_USE_LIBPSL=OFF -DCURL_ENABLE_NTLM=ON
steps:
- name: 'brew install'
if: ${{ matrix.build.configure }}
timeout-minutes: 5
run: |
# shellcheck disable=SC2181
while [[ $? == 0 ]]; do
for i in 1 2 3; do
if brew update && brew install automake libtool; then
break 2
else
echo "Error: wait to try again: $i"
sleep 10
fi
done
false Too many retries
done
- name: 'toolchain versions'
run: |
command -v "${CC}"; "${CC}" --version || true
xcodebuild -version || true
xcodebuild -sdk -version | grep '^Path:' || true
xcrun --sdk iphoneos --show-sdk-path 2>/dev/null || true
xcrun --sdk iphoneos --show-sdk-version || true
echo '::group::compiler defaults'; echo 'int main(void) {}' | "${CC}" -v -x c -; echo '::endgroup::'
echo '::group::macros predefined'; "${CC}" -dM -E - < /dev/null | sort || true; echo '::endgroup::'
echo '::group::brew packages installed'; ls -l "$(brew --prefix)"/opt; echo '::endgroup::'
- name: 'cache libressl'
if: ${{ contains(matrix.build.install_steps, 'libressl') }}
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
id: cache-libressl
env:
cache-name: cache-libressl
with:
path: ~/libressl
key: iOS-${{ env.cache-name }}-${{ env.LIBRESSL_VERSION }}
- name: 'build libressl'
if: ${{ contains(matrix.build.install_steps, 'libressl') && steps.cache-libressl.outputs.cache-hit != 'true' }}
run: |
curl --disable --fail --silent --show-error --connect-timeout 15 --max-time 60 --retry 3 --retry-connrefused \
--location "https://github.com/libressl/portable/releases/download/v${LIBRESSL_VERSION}/libressl-${LIBRESSL_VERSION}.tar.gz" --output pkg.bin
sha256sum pkg.bin && tar -xzf pkg.bin && rm -f pkg.bin
cd "libressl-${LIBRESSL_VERSION}"
cmake -B . -G Ninja \
-DCMAKE_INSTALL_PREFIX=/Users/runner/libressl \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
-DBUILD_SHARED_LIBS=OFF \
-DLIBRESSL_APPS=OFF \
-DLIBRESSL_TESTS=OFF
cmake --build .
cmake --install . --verbose
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: 'autoreconf'
if: ${{ matrix.build.configure }}
run: autoreconf -fi
- name: 'configure'
env:
MATRIX_CONFIGURE: '${{ matrix.build.configure }}'
MATRIX_GENERATE: '${{ matrix.build.generate }}'
MATRIX_GENERATOR: '${{ matrix.build.generator }}'
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
# https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-ios-tvos-visionos-or-watchos
[ -n "${MATRIX_GENERATOR}" ] && options="-G ${MATRIX_GENERATOR}"
cmake -B bld -G Ninja -D_CURL_PREFILL=ON \
-DCMAKE_UNITY_BUILD=ON -DCURL_DROP_UNUSED=ON -DCURL_WERROR=ON \
-DCMAKE_SYSTEM_NAME=iOS \
-DUSE_APPLE_IDN=ON \
${MATRIX_GENERATE} ${options}
else
mkdir bld && cd bld && ../configure --enable-unity --enable-warnings --enable-werror \
--disable-dependency-tracking --enable-option-checking=fatal \
CFLAGS="-isysroot $(xcrun --sdk iphoneos --show-sdk-path 2>/dev/null)" \
--host=aarch64-apple-darwin \
--with-apple-idn \
${MATRIX_CONFIGURE}
fi
- name: 'configure log'
if: ${{ !cancelled() }}
run: cat bld/config.log bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
- name: 'curl_config.h'
run: |
echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::'
grep -F '#define' bld/lib/curl_config.h | sort || true
- name: 'build'
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld ${MATRIX_OPTIONS} --parallel 4 --verbose
else
make -C bld V=1
fi
- name: 'curl info'
run: |
find . -type f \( -name curl -o -name '*.dylib' -o -name '*.a' \) -print0 | xargs -0 file --
find . -type f \( -name curl -o -name '*.dylib' -o -name '*.a' \) -print0 | xargs -0 stat -f '%10z bytes: %N' --
- name: 'build tests'
if: ${{ matrix.build.generate }} # skip for autotools to save time
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld ${MATRIX_OPTIONS} --parallel 4 --target testdeps --verbose
else
make -C bld V=1 -C tests
fi
- name: 'build examples'
if: ${{ matrix.build.generate }} # skip for autotools to save time
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld ${MATRIX_OPTIONS} --parallel 4 --target curl-examples-build --verbose
else
make -C bld examples V=1
fi
macos:
name: "${{ matrix.build.generate && 'CM' || 'AM' }} ${{ matrix.build.compiler }} ${{ matrix.build.name }}"
runs-on: ${{ matrix.build.image || 'macos-15' }}
timeout-minutes: 15
env:
DEVELOPER_DIR: "/Applications/Xcode${{ matrix.build.xcode && format('_{0}', matrix.build.xcode) || '' }}.app/Contents/Developer"
CC: '${{ matrix.build.compiler }}'
MATRIX_BUILD: ${{ matrix.build.generate && 'cmake' || 'autotools' }}
MATRIX_COMPILER: '${{ matrix.build.compiler }}'
MATRIX_INSTALL: '${{ matrix.build.install }}'
MATRIX_INSTALL_STEPS: '${{ matrix.build.install_steps }}'
MATRIX_MACOS_VERSION_MIN: '${{ matrix.build.macos-version-min }}'
strategy:
fail-fast: false
matrix:
build:
- name: '!ssl !debug brotli zstd'
compiler: gcc-13
configure: --without-ssl --with-brotli --with-zstd --with-apple-idn
tflags: '--min=1450'
xcode: '' # default Xcode. Set it once to silence actionlint.
- name: '!ssl libssh2 AppleIDN'
compiler: clang
generate: -DENABLE_DEBUG=ON -DCURL_USE_LIBSSH2=ON -DUSE_APPLE_IDN=ON -DCURL_ENABLE_SSL=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF
tflags: '--min=1550'
- name: 'OpenSSL libssh c-ares'
compiler: clang
install: libssh
configure: --enable-debug --with-libssh --with-openssl=/opt/homebrew/opt/openssl --enable-ares --with-fish-functions-dir --with-zsh-functions-dir
- name: 'OpenSSL libssh'
compiler: llvm@18
install: libssh libnghttp3
generate: -DENABLE_DEBUG=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF
- name: '!ssl HTTP-only c-ares'
macos-version-min: '10.15' # Catalina (2019)
compiler: clang
tflags: '--min=930'
generate: >-
-DENABLE_DEBUG=ON -DENABLE_ARES=ON
-DCURL_ENABLE_SSL=OFF -DHTTP_ONLY=ON
-DCURL_DISABLE_ALTSVC=ON -DENABLE_UNIX_SOCKETS=OFF
-DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=OFF -DUSE_NGHTTP2=OFF
-DCURL_USE_GSSAPI=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF
-DCURL_BROTLI=OFF -DCURL_ZLIB=OFF -DCURL_ZSTD=OFF
-DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF
- name: 'LibreSSL !ldap +examples'
compiler: clang
install: libressl
install_steps: pytest
generate: >-
-DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/libressl -DCURL_DISABLE_LDAP=ON -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF
-DCURL_USE_LIBSSH2=OFF -DCURL_ENABLE_NTLM=ON
- name: 'OpenSSL 10.15 C89'
macos-version-min: '10.15'
compiler: clang
install: libnghttp3 libngtcp2
install_steps: pytest
generate: >-
-DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DUSE_NGTCP2=ON -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_USE_LIBSSH2=OFF
-DCMAKE_C_STANDARD=90 -DCURL_ENABLE_NTLM=ON
- name: 'OpenSSL SecTrust'
compiler: clang
install: libnghttp3 libngtcp2
install_steps: pytest
configure: --enable-debug --with-openssl=/opt/homebrew/opt/openssl --with-ngtcp2 --with-apple-sectrust --enable-ntlm
- name: 'OpenSSL event-based'
compiler: clang
generate: -DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_USE_LIBSSH2=OFF -DCURL_ENABLE_NTLM=ON
tflags: '--test-event --min=1300'
- name: 'OpenSSL gsasl AppleIDN SecTrust +examples'
compiler: clang
install: libnghttp3 libngtcp2 gsasl
generate: >-
-DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCURL_USE_GSASL=ON -DUSE_APPLE_IDN=ON -DUSE_NGTCP2=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON
-DUSE_APPLE_SECTRUST=ON -DCURL_ENABLE_NTLM=ON
- name: 'MultiSSL AppleIDN clang-tidy +examples'
image: macos-26
compiler: clang
install: llvm gnutls nettle libressl krb5 mbedtls gsasl rustls-ffi libssh fish
install_steps: skiprun
chkprefill: _chkprefill
generate: >-
-DCURL_USE_OPENSSL=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/libressl -DCURL_DEFAULT_SSL_BACKEND=openssl
-DCURL_USE_GNUTLS=ON -DCURL_USE_MBEDTLS=ON -DCURL_USE_RUSTLS=ON -DENABLE_ARES=ON -DCURL_USE_GSASL=ON
-DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON -DUSE_APPLE_IDN=ON -DUSE_SSLS_EXPORT=ON
-DCURL_USE_GSSAPI=ON -DGSS_ROOT_DIR=/opt/homebrew/opt/krb5
-DCURL_BROTLI=ON -DCURL_ZSTD=ON
-DCURL_CLANG_TIDY=ON -DCLANG_TIDY=/opt/homebrew/opt/llvm/bin/clang-tidy
-DCURL_COMPLETION_FISH=ON -DCURL_COMPLETION_ZSH=ON
-DCURL_ENABLE_NTLM=ON
- name: 'HTTP/3 clang-tidy'
image: macos-26
compiler: clang
install: llvm libnghttp3 libngtcp2 openldap krb5
install_steps: skipall
generate: >-
-DCURL_USE_OPENSSL=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DUSE_NGTCP2=ON
-DLDAP_INCLUDE_DIR=/opt/homebrew/opt/openldap/include
-DLDAP_LIBRARY=/opt/homebrew/opt/openldap/lib/libldap.dylib
-DLDAP_LBER_LIBRARY=/opt/homebrew/opt/openldap/lib/liblber.dylib
-DCURL_USE_GSSAPI=ON -DGSS_ROOT_DIR=/opt/homebrew/opt/krb5
-DCURL_BROTLI=ON -DCURL_ZSTD=ON
-DCURL_CLANG_TIDY=ON -DCLANG_TIDY=/opt/homebrew/opt/llvm/bin/clang-tidy
-DCURL_ENABLE_NTLM=ON
- name: 'LibreSSL openldap krb5 c-ares +examples'
compiler: clang
install: libressl krb5 openldap
generate: >-
-DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/libressl -DENABLE_ARES=ON -DCURL_USE_GSSAPI=ON
-DGSS_ROOT_DIR=/opt/homebrew/opt/krb5
-DLDAP_INCLUDE_DIR=/opt/homebrew/opt/openldap/include
-DLDAP_LIBRARY=/opt/homebrew/opt/openldap/lib/libldap.dylib
-DLDAP_LBER_LIBRARY=/opt/homebrew/opt/openldap/lib/liblber.dylib
- name: 'wolfSSL !ldap brotli zstd'
compiler: clang
install: brotli wolfssl zstd
install_steps: pytest
generate: -DCURL_USE_WOLFSSL=ON -DCURL_DISABLE_LDAP=ON -DUSE_ECH=ON -DCURL_ENABLE_NTLM=ON
- name: 'mbedTLS !ldap brotli zstd MultiSSL AppleIDN'
compiler: llvm@18
install: brotli mbedtls zstd
install_steps: codeset-test
generate: -DCURL_USE_MBEDTLS=ON -DCURL_DISABLE_LDAP=ON -DCURL_DEFAULT_SSL_BACKEND=mbedtls -DCURL_USE_OPENSSL=ON -DUSE_APPLE_IDN=ON -DCURL_ENABLE_NTLM=ON
- name: 'GnuTLS !ldap krb5 +examples'
compiler: clang
install: gnutls nettle krb5
generate: >-
-DENABLE_DEBUG=ON -DCURL_USE_GNUTLS=ON -DCURL_USE_OPENSSL=OFF
-DCURL_USE_GSSAPI=ON -DGSS_ROOT_DIR=/opt/homebrew/opt/krb5
-DCURL_DISABLE_LDAP=ON -DUSE_SSLS_EXPORT=ON -DCURL_ENABLE_NTLM=ON
- name: 'aws-lc +analyzer'
compiler: gcc-15
install: aws-lc
generate: >-
-DENABLE_DEBUG=ON -DCURL_USE_OPENSSL=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/aws-lc -DUSE_ECH=ON
-DCURL_DISABLE_LDAP=ON -DUSE_SSLS_EXPORT=ON -DCURL_GCC_ANALYZER=ON
- name: 'Rustls'
compiler: clang
install: rustls-ffi
generate: -DENABLE_DEBUG=ON -DCURL_USE_RUSTLS=ON -DUSE_ECH=ON -DCURL_DISABLE_LDAP=ON -DCURL_ENABLE_NTLM=ON
tflags: '--min=1650'
- name: 'OpenSSL torture 1'
compiler: clang
install: libnghttp3
install_steps: torture
generate: -DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DENABLE_THREADED_RESOLVER=OFF -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCURL_ENABLE_NTLM=ON
tflags: '-t --shallow=25 --min=480 1 to 500'
- name: 'OpenSSL torture 2'
compiler: clang
install: libnghttp3
install_steps: torture
generate: -DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DENABLE_THREADED_RESOLVER=OFF -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCURL_ENABLE_NTLM=ON
tflags: '-t --shallow=25 --min=730 501 to 1250'
- name: 'OpenSSL torture 3'
compiler: clang
install: libnghttp3
install_steps: torture
generate: -DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DENABLE_THREADED_RESOLVER=OFF -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCURL_ENABLE_NTLM=ON
tflags: '-t --shallow=25 --min=628 1251 to 9999'
steps:
- name: 'brew install'
timeout-minutes: 5
# Run this command with retries because of spurious failures seen
# while running the tests, for example
# https://github.com/curl/curl/runs/4095721123?check_suite_focus=true
env:
INSTALL_PACKAGES: >-
${{ matrix.build.generate && 'ninja' || 'automake libtool' }}
${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') && 'nghttp2 stunnel' || '' }}
${{ contains(matrix.build.install_steps, 'pytest') && 'caddy httpd vsftpd' || '' }}
run: |
# shellcheck disable=SC2181
while [[ $? == 0 ]]; do
for i in 1 2 3; do
if brew update && brew install pkgconf libpsl libssh2 ${INSTALL_PACKAGES} ${MATRIX_INSTALL}; then
break 2
else
echo "Error: wait to try again: $i"
sleep 10
fi
done
false Too many retries
done
- name: 'brew unlink openssl'
if: ${{ contains(matrix.build.install, 'aws-lc') || contains(matrix.build.install, 'libressl') }}
run: |
if [ -d "$(brew --prefix)"/include/openssl ]; then
brew unlink openssl
fi
- name: 'toolchain versions'
run: |
[[ "${MATRIX_COMPILER}" = 'llvm'* ]] && CC="$(brew --prefix "${MATRIX_COMPILER}")/bin/clang"
[[ "${MATRIX_COMPILER}" = 'gcc'* ]] && "${CC}" --print-sysroot
command -v "${CC}"; "${CC}" --version || true
xcodebuild -version || true
xcrun --sdk macosx --show-sdk-path 2>/dev/null || true
xcrun --sdk macosx --show-sdk-version || true
ls -l /Library/Developer/CommandLineTools/SDKs || true
echo '::group::macros predefined'; "${CC}" -dM -E - < /dev/null | sort || true; echo '::endgroup::'
echo '::group::brew packages installed'; ls -l "$(brew --prefix)"/opt; echo '::endgroup::'
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: 'autoreconf'
if: ${{ matrix.build.configure }}
run: autoreconf -fi
- name: 'configure'
env:
MATRIX_CHKPREFILL: '${{ matrix.build.chkprefill }}'
MATRIX_CONFIGURE: '${{ matrix.build.configure }}'
MATRIX_GENERATE: '${{ matrix.build.generate }}'
run: |
if [[ "${MATRIX_COMPILER}" = 'gcc'* ]]; then
sysroot="$("${CC}" --print-sysroot)" # Must match the SDK gcc was built for
else
sysroot="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)"
fi
if [[ "${MATRIX_COMPILER}" = 'llvm'* ]]; then
CC="$(brew --prefix "${MATRIX_COMPILER}")/bin/clang"
CC+=" --sysroot=${sysroot}"
CC+=" --target=$(uname -m)-apple-darwin"
fi
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
for _chkprefill in '' ${MATRIX_CHKPREFILL}; do
options=''
[ -n "${MATRIX_MACOS_VERSION_MIN}" ] && options+=" -DCMAKE_OSX_DEPLOYMENT_TARGET=${MATRIX_MACOS_VERSION_MIN}"
[[ "${MATRIX_INSTALL_STEPS}" = *'pytest'* ]] && options+=' -DVSFTPD=NO' # Skip ~20 tests that stretch run time by 7x on macOS
[ "${_chkprefill}" = '_chkprefill' ] && options+=' -D_CURL_PREFILL=OFF'
cmake -B "bld${_chkprefill}" -G Ninja -D_CURL_PREFILL=ON \
-DCMAKE_INSTALL_PREFIX="$HOME"/curl-install \
-DCMAKE_UNITY_BUILD=ON -DCURL_DROP_UNUSED=ON -DCURL_WERROR=ON \
-DCMAKE_OSX_SYSROOT="${sysroot}" \
-DCMAKE_C_COMPILER_TARGET="$(uname -m | sed 's/arm64/aarch64e/')-apple-darwin$(uname -r)" \
${MATRIX_GENERATE} ${options}
done
if [ -d bld_chkprefill ] && ! diff -u bld/lib/curl_config.h bld_chkprefill/lib/curl_config.h; then
echo '::group::reference configure log'; cat bld_chkprefill/CMakeFiles/CMake*.yaml 2>/dev/null || true; echo '::endgroup::'
false
fi
else
export CFLAGS
if [[ "${MATRIX_COMPILER}" = 'llvm'* ]]; then
options+=" --target=$(uname -m)-apple-darwin"
fi
if [ "${MATRIX_COMPILER}" != 'clang' ]; then
options+=" --with-sysroot=${sysroot}"
CFLAGS+=" --sysroot=${sysroot}"
fi
[ -n "${MATRIX_MACOS_VERSION_MIN}" ] && CFLAGS+=" -mmacosx-version-min=${MATRIX_MACOS_VERSION_MIN}"
[[ "${MATRIX_INSTALL_STEPS}" = *'pytest'* ]] && options+=' --with-test-vsftpd=no' # Skip ~20 tests that stretch run time by 7x on macOS
mkdir bld && cd bld && ../configure --prefix="$PWD"/curl-install --enable-unity --enable-warnings --enable-werror --disable-static \
--disable-dependency-tracking --enable-option-checking=fatal \
--with-libpsl="$(brew --prefix libpsl)" \
${MATRIX_CONFIGURE} ${options}
fi
- name: 'configure log'
if: ${{ !cancelled() }}
run: cat bld/config.log bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
- name: 'curl_config.h'
run: |
echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::'
grep -F '#define' bld/lib/curl_config.h | sort || true
- name: 'test configs'
run: grep -H -v '^#' bld/tests/config bld/tests/http/config.ini || true
- name: 'build'
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld --verbose
else
make -C bld V=1
fi
- name: 'curl -V'
run: |
find . -type f \( -name curl -o -name '*.dylib' -o -name '*.a' \) -print0 | xargs -0 file --
find . -type f \( -name curl -o -name '*.dylib' -o -name '*.a' \) -print0 | xargs -0 stat -f '%10z bytes: %N' --
bld/src/curl --disable --version
- name: 'curl install'
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --install bld --strip
else
make -C bld V=1 install
fi
- name: 'build tests'
if: ${{ !contains(matrix.build.install_steps, 'skipall') }}
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld --verbose --target testdeps
else
make -C bld V=1 -C tests
fi
- name: 'install test prereqs'
if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') }}
run: |
python3 -m venv ~/venv
if bld/src/curl --disable -V 2>/dev/null | grep smb; then
~/venv/bin/pip --disable-pip-version-check --no-input --no-cache-dir install --progress-bar off --prefer-binary -r tests/requirements.txt
fi
- name: 'run tests'
if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') }}
timeout-minutes: ${{ contains(matrix.build.install_steps, 'torture') && 20 || 10 }}
env:
TEST_TARGET: ${{ contains(matrix.build.install_steps, 'torture') && 'test-torture' || 'test-ci' }}
TFLAGS: '${{ matrix.build.tflags }}'
run: |
TFLAGS="-j20 ${TFLAGS}"
if [ "${TEST_TARGET}" != 'test-ci' ]; then
TFLAGS+=' --buildinfo' # only test-ci sets this by default, set it manually for test-torture
fi
source ~/venv/bin/activate
if [[ "${MATRIX_INSTALL_STEPS}" = *'codeset-test'* ]]; then
locale || true
export LC_ALL=C
export LC_CTYPE=C
export LC_NUMERIC=fr_FR.UTF-8
fi
rm -f ~/.curlrc
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld --verbose --target "${TEST_TARGET}"
else
make -C bld V=1 "${TEST_TARGET}"
fi
- name: 'install pytest prereqs'
if: ${{ contains(matrix.build.install_steps, 'pytest') }}
run: |
[ -d ~/venv ] || python3 -m venv ~/venv
~/venv/bin/pip --disable-pip-version-check --no-input --no-cache-dir install --progress-bar off --prefer-binary -r tests/http/requirements.txt
- name: 'run pytest'
if: ${{ contains(matrix.build.install_steps, 'pytest') }}
env:
PYTEST_ADDOPTS: '--color=yes'
PYTEST_XDIST_AUTO_NUM_WORKERS: 4
run: |
source ~/venv/bin/activate
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld --verbose --target curl-pytest-ci
else
make -C bld V=1 pytest-ci
fi
- name: 'build examples'
if: ${{ contains(matrix.build.name, '+examples') }}
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld --verbose --target curl-examples-build
else
make -C bld examples V=1
fi
combinations: # Test buildability with host OS, Xcode / SDK, compiler, target-OS, built tool, combinations
name: "${{ matrix.build == 'cmake' && 'CM' || 'AM' }} ${{ matrix.compiler }} ${{ matrix.image }} ${{ matrix.xcode }}"
runs-on: ${{ matrix.image }}
timeout-minutes: 10
env:
DEVELOPER_DIR: "/Applications/Xcode${{ matrix.xcode && format('_{0}', matrix.xcode) || '' }}.app/Contents/Developer"
CC: '${{ matrix.compiler }}'
MATRIX_BUILD: '${{ matrix.build }}'
MATRIX_COMPILER: '${{ matrix.compiler }}'
MATRIX_IMAGE: '${{ matrix.image }}'
MATRIX_MACOS_VERSION_MIN: '${{ matrix.macos-version-min }}'
strategy:
fail-fast: false
matrix:
# Sources:
# https://github.com/actions/runner-images/blob/main/images/macos/macos-14-arm64-Readme.md
# https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md
# https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
compiler: [gcc-13, gcc-14, gcc-15, llvm@15, llvm@18, llvm@20, clang]
# Xcode support matrix as of 2025-10, with default macOS SDK versions and OS names, years:
# * = default Xcode on the runner.
# macos-14: 15.0.1, 15.1, 15.2, 15.3,*15.4
# macos-15: 16.0, 16.1, 16.2, 16.3,*16.4, 26.0
# macos-26: 16.4 *26.0
# macOSSDK: 14.0, 14.2, 14.2, 14.4, 14.5, 15.0, 15.1, 15.2, 15.4, 15.5, 26.0
# Sonoma (2023) Sequoia (2024) Tahoe (2025)
# https://github.com/actions/runner-images/tree/main/images/macos
# https://en.wikipedia.org/wiki/MacOS_version_history
image: [macos-14, macos-15, macos-26]
xcode: [''] # default Xcodes
macos-version-min: ['']
build: [autotools, cmake]
exclude:
# Combinations not covered by runner images:
- { image: macos-14, compiler: 'llvm@18' }
- { image: macos-14, compiler: 'llvm@20' }
- { image: macos-15, compiler: 'llvm@15' }
- { image: macos-15, compiler: 'llvm@20' }
- { image: macos-26, compiler: 'llvm@15' }
- { image: macos-26, compiler: 'llvm@18' }
# Covered by the main workflow
- { image: macos-15, compiler: 'gcc-13' }
- { image: macos-15, compiler: 'llvm@18' }
- { image: macos-15, compiler: 'clang' }
# Reduce build combinations, by dropping less interesting ones
- { image: macos-26, compiler: 'gcc-13' }
- { compiler: 'gcc-14' , build: cmake }
# Reduce autotools to just one job that is also build with cmake
- { compiler: 'gcc-13' , build: autotools }
- { compiler: 'gcc-14' , build: autotools }
- { compiler: 'gcc-15' , build: autotools }
- { compiler: 'llvm@15', build: autotools }
- { compiler: 'llvm@18', build: autotools }
- { compiler: 'llvm@20', build: autotools }
- { image: macos-14, build: autotools }
- { image: macos-15, build: autotools }
steps:
- name: 'install autotools'
if: ${{ matrix.build == 'autotools' }}
run: |
# shellcheck disable=SC2181
while [[ $? == 0 ]]; do
for i in 1 2 3; do
if brew update && brew install automake libtool; then
break 2
else
echo "Error: wait to try again: $i"
sleep 10
fi
done
false Too many retries
done
- name: 'toolchain versions'
run: |
[[ "${MATRIX_COMPILER}" = 'llvm'* ]] && CC="$(brew --prefix "${MATRIX_COMPILER}")/bin/clang"
[[ "${MATRIX_COMPILER}" = 'gcc'* ]] && "${CC}" --print-sysroot
command -v "${CC}"; "${CC}" --version || true
xcodebuild -version || true
xcrun --sdk macosx --show-sdk-path 2>/dev/null || true
xcrun --sdk macosx --show-sdk-version || true
ls -l /Library/Developer/CommandLineTools/SDKs || true
echo '::group::compiler defaults'; echo 'int main(void) {}' | "${CC}" -v -x c -; echo '::endgroup::'
echo '::group::macros predefined'; "${CC}" -dM -E - < /dev/null | sort || true; echo '::endgroup::'
echo '::group::brew packages preinstalled'; ls -l "$(brew --prefix)"/opt; echo '::endgroup::'
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: 'autoreconf'
if: ${{ matrix.build == 'autotools' }}
run: autoreconf -fi
- name: 'configure / ${{ matrix.build }}'
run: |
if [ "${MATRIX_COMPILER}" = 'gcc-13' ] && [ "${MATRIX_IMAGE}" = 'macos-15' ]; then
# Ref: https://github.com/Homebrew/homebrew-core/issues/194778#issuecomment-2793243409
"$(brew --prefix gcc@13)"/libexec/gcc/aarch64-apple-darwin24/13/install-tools/mkheaders
fi
if [[ "${MATRIX_COMPILER}" = 'gcc'* ]]; then
sysroot="$("${CC}" --print-sysroot)" # Must match the SDK gcc was built for
else
sysroot="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)"
fi
if [[ "${MATRIX_COMPILER}" = 'llvm'* ]]; then
CC="$(brew --prefix "${MATRIX_COMPILER}")/bin/clang"
CC+=" --sysroot=${sysroot}"
CC+=" --target=$(uname -m)-apple-darwin"
fi
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
[ -n "${MATRIX_MACOS_VERSION_MIN}" ] && options+=" -DCMAKE_OSX_DEPLOYMENT_TARGET=${MATRIX_MACOS_VERSION_MIN}"
# would pick up nghttp2, libidn2, and libssh2
cmake -B bld -G Ninja -D_CURL_PREFILL=ON \
-DCMAKE_UNITY_BUILD=ON -DCURL_DROP_UNUSED=ON -DCURL_WERROR=ON \
-DCMAKE_OSX_SYSROOT="${sysroot}" \
-DCMAKE_C_COMPILER_TARGET="$(uname -m | sed 's/arm64/aarch64e/')-apple-darwin$(uname -r)" \
-DCMAKE_IGNORE_PREFIX_PATH="$(brew --prefix)" \
-DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF \
-DCURL_USE_OPENSSL=ON \
-DUSE_NGHTTP2=OFF -DUSE_LIBIDN2=OFF \
-DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF \
-DUSE_APPLE_IDN=ON -DUSE_APPLE_SECTRUST=ON \
${options}
else
export CFLAGS
if [[ "${MATRIX_COMPILER}" = 'llvm'* ]]; then
options+=" --target=$(uname -m)-apple-darwin"
fi
if [ "${MATRIX_COMPILER}" != 'clang' ]; then
options+=" --with-sysroot=${sysroot}"
CFLAGS+=" --sysroot=${sysroot}"
fi
[ -n "${MATRIX_MACOS_VERSION_MIN}" ] && CFLAGS+=" -mmacosx-version-min=${MATRIX_MACOS_VERSION_MIN}"
# would pick up nghttp2, libidn2, but libssh2 is disabled by default
mkdir bld && cd bld && ../configure --enable-unity --enable-warnings --enable-werror --disable-static \
--disable-dependency-tracking --enable-option-checking=fatal \
--disable-docs --disable-manual \
--with-openssl="$(brew --prefix openssl)" \
--without-nghttp2 --without-libidn2 \
--without-libpsl \
--with-apple-idn --with-apple-sectrust \
${options}
fi
- name: 'configure log'
if: ${{ !cancelled() }}
run: cat bld/config.log bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
- name: 'curl_config.h'
run: |
echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::'
grep -F '#define' bld/lib/curl_config.h | sort || true
- name: 'build / ${{ matrix.build }}'
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld --verbose
else
make -C bld V=1
fi
- name: 'curl -V'
run: |
find . -type f \( -name curl -o -name '*.dylib' -o -name '*.a' \) -print0 | xargs -0 file --
find . -type f \( -name curl -o -name '*.dylib' -o -name '*.a' \) -print0 | xargs -0 stat -f '%10z bytes: %N' --
bld/src/curl --disable --version