# Copyright (C) Daniel Stenberg, , 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 steps: - name: 'brew install' if: ${{ matrix.build.configure }} timeout-minutes: 5 run: | # shellcheck disable=SC2181,SC2034 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; 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' compiler: clang tflags: '--min=930' generate: >- -DENABLE_DEBUG=ON -DENABLE_ARES=ON -DCURL_ENABLE_SSL=OFF -DHTTP_ONLY=ON -DCURL_DISABLE_NTLM=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 -DUSE_LIBRTMP=OFF -DCURL_BROTLI=OFF -DCURL_ZLIB=OFF -DCURL_ZSTD=OFF -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF macos-version-min: '10.15' # Catalina (2019) - 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 - name: 'OpenSSL 10.15 C89' 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 macos-version-min: '10.15' - 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 - 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 tflags: '--test-event --min=1300' - name: 'OpenSSL gsasl rtmp AppleIDN SecTrust +examples' compiler: clang install: libnghttp3 libngtcp2 gsasl rtmpdump generate: -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCURL_USE_GSASL=ON -DUSE_LIBRTMP=ON -DUSE_APPLE_IDN=ON -DUSE_NGTCP2=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DUSE_APPLE_SECTRUST=ON - name: 'MultiSSL AppleIDN clang-tidy +examples' image: macos-26 compiler: clang install: llvm gnutls nettle libressl krb5 mbedtls gsasl rustls-ffi rtmpdump 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 -DUSE_LIBRTMP=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 - 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 - 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 - 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 - 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 - 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 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 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 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 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: | echo pkgconf libpsl libssh2 ${INSTALL_PACKAGES} ${MATRIX_INSTALL} | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile # shellcheck disable=SC2181,SC2034 while [[ $? == 0 ]]; do for i in 1 2 3; do if brew update && brew bundle install --file /tmp/Brewfile; then break 2; else echo Error: wait to try again; 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,SC2034 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; 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