1# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 2# 3# SPDX-License-Identifier: curl 4 5name: macOS 6 7'on': 8 push: 9 branches: 10 - master 11 - '*/ci' 12 paths-ignore: 13 - '**/*.md' 14 - '.circleci/**' 15 - 'appveyor.*' 16 - 'packages/**' 17 - 'plan9/**' 18 - 'projects/**' 19 - 'winbuild/**' 20 pull_request: 21 branches: 22 - master 23 paths-ignore: 24 - '**/*.md' 25 - '.circleci/**' 26 - 'appveyor.*' 27 - 'packages/**' 28 - 'plan9/**' 29 - 'projects/**' 30 - 'winbuild/**' 31 32concurrency: 33 group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} 34 cancel-in-progress: true 35 36permissions: {} 37 38# Deprecated Apple APIs and the macos-version-min value required to avoid 39# deprecation warnings with llvm/clang: 40# 41# - 10.7 Lion (2011) - GSS 42# - 10.8 Mountain Lion (2012) - CFURLCreateDataAndPropertiesFromResource (used by curl Secure Transport code) 43# - 10.9 Maverick (2013) - LDAP 44# - 10.14 Mojave (2018) - Secure Transport 45# 46# For Secure Transport, curl implements features that require a target 47# newer than the 10.8 required by `CFURLCreateDataAndPropertiesFromResource`. 48# In this case `-Wno-deprecated-declarations` still comes handy to pacify 49# deprecation warnings, though the real solution would be to avoid calling 50# that function. 51 52env: 53 LDFLAGS: -w # suppress 'object file was built for newer macOS version than being linked' warnings 54 MAKEFLAGS: -j 4 55 56jobs: 57 autotools: 58 name: 'AM ${{ matrix.compiler }} ${{ matrix.name }}' 59 runs-on: 'macos-latest' 60 timeout-minutes: 60 61 env: 62 DEVELOPER_DIR: "/Applications/Xcode${{ matrix.xcode && format('_{0}', matrix.xcode) || '' }}.app/Contents/Developer" 63 CC: ${{ matrix.compiler }} 64 CFLAGS: '-mmacosx-version-min=${{ matrix.macos-version-min }}' 65 strategy: 66 fail-fast: false 67 matrix: 68 include: 69 - name: '!ssl !debug brotli zstd' 70 compiler: clang 71 install: brotli zstd 72 configure: --without-ssl --enable-websockets --with-brotli --with-zstd 73 macos-version-min: '10.9' 74 - name: '!ssl !debug' 75 compiler: gcc-12 76 configure: --without-ssl --enable-websockets 77 macos-version-min: '10.9' 78 - name: '!ssl' 79 compiler: clang 80 configure: --enable-debug --without-ssl --enable-websockets 81 macos-version-min: '10.9' 82 - name: '!ssl libssh2 AppleIDN' 83 compiler: clang 84 configure: --enable-debug --with-libssh2=$(brew --prefix libssh2) --without-ssl --with-apple-idn --enable-websockets 85 macos-version-min: '10.9' 86 - name: 'OpenSSL libssh c-ares' 87 compiler: clang 88 install: libssh 89 configure: --enable-debug --with-libssh --with-openssl=$(brew --prefix openssl) --enable-ares --enable-websockets 90 macos-version-min: '10.9' 91 - name: 'OpenSSL libssh' 92 compiler: llvm@15 93 install: libssh 94 configure: --enable-debug --with-libssh --with-openssl=$(brew --prefix openssl) --enable-websockets 95 macos-version-min: '10.9' 96 - name: '!ssl c-ares' 97 compiler: clang 98 configure: --enable-debug --enable-ares --without-ssl --enable-websockets 99 macos-version-min: '10.9' 100 - name: '!ssl HTTP-only' 101 compiler: clang 102 configure: | 103 --enable-debug \ 104 --disable-alt-svc --disable-dict --disable-file --disable-ftp --disable-gopher --disable-imap \ 105 --disable-ldap --disable-pop3 --disable-rtmp --disable-rtsp --disable-scp --disable-sftp \ 106 --disable-shared --disable-smb --disable-smtp --disable-telnet --disable-tftp --disable-unix-sockets \ 107 --without-brotli --without-gssapi --without-libidn2 --without-libpsl --without-librtmp --without-libssh2 \ 108 --without-nghttp2 --without-ntlm-auth --without-ssl --without-zlib --without-zstd 109 110 macos-version-min: '10.15' # Catalina (2019) 111 - name: 'SecureTransport libssh2' 112 compiler: clang 113 configure: --enable-debug --with-secure-transport --enable-websockets --with-libssh2=$(brew --prefix libssh2) 114 macos-version-min: '10.8' 115 - name: 'SecureTransport libssh2 10.12' 116 compiler: clang 117 configure: --enable-debug --with-secure-transport --enable-websockets --with-libssh2=$(brew --prefix libssh2) 118 macos-version-min: '10.12' # for monotonic timers 119 cflags: '-Wno-deprecated-declarations' 120 - name: 'SecureTransport libssh2' 121 compiler: gcc-12 122 configure: --enable-debug --with-secure-transport --enable-websockets --with-libssh2=$(brew --prefix libssh2) 123 macos-version-min: '10.8' 124 - name: 'LibreSSL +examples' 125 compiler: clang 126 install: libressl 127 configure: --enable-debug --with-openssl=$(brew --prefix libressl) --enable-websockets 128 macos-version-min: '10.9' 129 - name: 'OpenSSL' 130 compiler: clang 131 configure: --enable-debug --with-openssl=$(brew --prefix openssl) --enable-websockets 132 macos-version-min: '10.9' 133 - name: 'OpenSSL event-based' 134 compiler: clang 135 configure: --enable-debug --with-openssl=$(brew --prefix openssl) --enable-websockets 136 macos-version-min: '10.9' 137 tflags: -e 138 - name: 'OpenSSL libssh2 !ldap 10.15' 139 compiler: clang 140 configure: --enable-debug --disable-ldap --with-openssl=$(brew --prefix openssl) --enable-websockets 141 macos-version-min: '10.15' 142 steps: 143 - name: 'brew install' 144 # Run this command with retries because of spurious failures seen 145 # while running the tests, for example 146 # https://github.com/curl/curl/runs/4095721123?check_suite_focus=true 147 run: | 148 echo automake libtool pkg-config libpsl libssh2 nghttp2 stunnel ${{ matrix.install }} | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile 149 while [[ $? == 0 ]]; do for i in 1 2 3; do brew update && brew bundle install --no-lock --file /tmp/Brewfile && break 2 || { echo Error: wait to try again; sleep 10; } done; false Too many retries; done 150 151 - name: 'brew unlink openssl' 152 run: | 153 if test -d $(brew --prefix)/include/openssl; then 154 brew unlink openssl 155 fi 156 157 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 158 159 - name: 'toolchain versions' 160 run: | 161 [[ '${{ matrix.compiler }}' = 'llvm'* ]] && CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" 162 [[ '${{ matrix.compiler }}' = 'gcc'* ]] && \ 163 grep -h -r -E -o '.+[0-9.]+\.sdk/' "$(dirname "$("${CC}" -print-libgcc-file-name)")/include-fixed" | sed -E 's/^\t+//g' | tr -d '"' | sort -u || true 164 which "${CC}"; "${CC}" --version || true 165 xcodebuild -version || true 166 xcrun --sdk macosx --show-sdk-path 2>/dev/null || true 167 xcrun --sdk macosx --show-sdk-version || true 168 echo '::group::macros predefined'; "${CC}" -dM -E - < /dev/null | sort || true; echo '::endgroup::' 169 echo '::group::brew packages installed'; ls -l "$(brew --prefix)/opt"; echo '::endgroup::' 170 171 - name: 'autoreconf' 172 run: autoreconf -fi 173 174 - name: 'configure' 175 run: | 176 [[ '${{ matrix.compiler }}' = 'llvm'* ]] && CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" 177 CFLAGS+=' ${{ matrix.cflags }}' 178 if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then 179 libgccdir="$(dirname "$("${CC}" -print-libgcc-file-name)")" 180 echo '::group::gcc include-fixed details'; find "${libgccdir}/include-fixed" | sort; echo '::endgroup::' 181 for f in dispatch os AvailabilityInternal.h stdio.h; do 182 if [ -r "${libgccdir}/include-fixed/${f}" ]; then 183 echo "Zap gcc hack: '${libgccdir}/include-fixed/${f}'" 184 mv "${libgccdir}/include-fixed/${f}" "${libgccdir}/include-fixed/${f}-BAK" 185 fi 186 done 187 fi 188 if [[ '${{ matrix.compiler }}' = 'llvm'* ]]; then 189 options+=" --target=$(uname -m)-apple-darwin" 190 CC+=" --target=$(uname -m)-apple-darwin" 191 fi 192 if [ '${{ matrix.compiler }}' != 'clang' ]; then 193 options+=" --with-sysroot=$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" 194 CFLAGS+=" --sysroot=$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" 195 fi 196 mkdir bld && cd bld && ../configure --enable-unity --enable-test-bundles --enable-warnings --enable-werror \ 197 --disable-dependency-tracking \ 198 --with-libpsl=$(brew --prefix libpsl) \ 199 ${{ matrix.configure }} ${options} 200 201 - name: 'configure log' 202 if: ${{ !cancelled() }} 203 run: cat bld/config.log || true 204 205 - name: 'curl_config.h' 206 run: | 207 echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::' 208 cat bld/lib/curl_config.h | grep -F '#define' | sort || true 209 210 - name: 'build-cert' 211 if: contains(matrix.configure, '--with-secure-transport') 212 run: | 213 make -C bld/tests/certs clean-certs 214 make -C bld/tests/certs build-certs -j1 215 216 - name: 'make' 217 run: make -C bld V=1 218 219 - name: 'curl version' 220 run: bld/src/curl --disable --version 221 222 - name: 'make tests' 223 run: make -C bld V=1 -C tests 224 225 - name: 'pip3 install' 226 run: | 227 python3 -m venv $HOME/venv 228 source $HOME/venv/bin/activate 229 python3 -m pip install impacket 230 231 - name: 'run tests' 232 timeout-minutes: 20 233 run: | 234 export TFLAGS='-j10 ${{ matrix.tflags }}' 235 TFLAGS+=' ~2037 ~2041' # flaky 236 if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then 237 TFLAGS+=' ~RTSP' # 567 568 569 570 571 572 577 689 3100 238 TFLAGS+=' ~1156 ~1539' # HTTP Content-Range, Content-Length 239 if [[ '${{ matrix.configure }}' = *'--with-secure-transport'* ]]; then 240 TFLAGS+=' ~2100' # 2100:'HTTP GET using DoH' https://github.com/curl/curl/actions/runs/9942146678/job/27462937524#step:15:5059 241 TFLAGS+=' ~HTTP/2' # 2400 2401 2402 2403 2404 2406, Secure Transport + nghttp2 242 else 243 TFLAGS+=' ~2402 ~2404' # non-Secure Transport + nghttp2 244 fi 245 fi 246 if [[ '${{ matrix.configure }}' = *'--with-secure-transport'* ]]; then 247 TFLAGS+=' ~313' # Secure Transport does not support crl file 248 TFLAGS+=' ~1631 ~1632' # Secure Transport is not able to shutdown ftp over https gracefully yet 249 fi 250 source $HOME/venv/bin/activate 251 rm -f $HOME/.curlrc 252 make -C bld V=1 test-ci 253 254 - name: 'make examples' 255 if: ${{ contains(matrix.build.name, '+examples') }} 256 run: make -C bld V=1 examples 257 258 cmake: 259 name: 'CM ${{ matrix.compiler }} ${{ matrix.build.name }}' 260 runs-on: 'macos-latest' 261 timeout-minutes: 30 262 env: 263 DEVELOPER_DIR: "/Applications/Xcode${{ matrix.xcode && format('_{0}', matrix.xcode) || '' }}.app/Contents/Developer" 264 CC: ${{ matrix.compiler }} 265 strategy: 266 fail-fast: false 267 matrix: 268 compiler: [clang, llvm@15, gcc-12] 269 build: 270 - name: 'OpenSSL ws gsasl AppleIDN' 271 install: gsasl 272 generate: -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) -DCURL_USE_GSASL=ON -DUSE_APPLE_IDN=ON -DENABLE_WEBSOCKETS=ON 273 macos-version-min: '10.9' 274 - name: 'OpenSSL +static libssh' 275 install: libssh 276 generate: -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) -DBUILD_STATIC_LIBS=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON 277 macos-version-min: '10.9' 278 - name: 'SecureTransport ws debug' 279 generate: -DCURL_USE_SECTRANSP=ON -DENABLE_WEBSOCKETS=ON -DENABLE_DEBUG=ON 280 macos-version-min: '10.8' 281 - name: 'LibreSSL !ldap heimdal c-ares +examples' 282 install: libressl heimdal 283 generate: -DOPENSSL_ROOT_DIR=$(brew --prefix libressl) -DENABLE_ARES=ON -DCURL_USE_GSSAPI=ON -DGSS_ROOT_DIR=$(brew --prefix heimdal) -DCURL_DISABLE_LDAP=ON 284 macos-version-min: '10.15' 285 - name: 'wolfSSL !ldap brotli zstd' 286 install: brotli wolfssl zstd 287 generate: -DCURL_USE_WOLFSSL=ON -DCURL_BROTLI=ON -DCURL_ZSTD=ON -DCURL_DISABLE_LDAP=ON 288 macos-version-min: '10.15' 289 - name: 'GnuTLS !ldap krb5' 290 install: gnutls nettle krb5 291 generate: -DCURL_USE_GNUTLS=ON -DCURL_USE_OPENSSL=OFF -DCURL_USE_GSSAPI=ON -DGSS_ROOT_DIR=$(brew --prefix krb5) -DCURL_DISABLE_LDAP=ON 292 macos-version-min: '10.15' 293 - name: 'OpenSSL torture !FTP' 294 generate: -DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DENABLE_THREADED_RESOLVER=OFF -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) -DCURL_BROTLI=ON -DCURL_ZSTD=ON -DENABLE_WEBSOCKETS=ON 295 tflags: -t --shallow=25 !FTP 296 macos-version-min: '10.9' 297 torture: true 298 - name: 'OpenSSL torture FTP' 299 generate: -DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DENABLE_THREADED_RESOLVER=OFF -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) -DCURL_BROTLI=ON -DCURL_ZSTD=ON 300 tflags: -t --shallow=20 FTP 301 macos-version-min: '10.9' 302 torture: true 303 exclude: 304 - { compiler: llvm@15, build: { macos-version-min: '10.15' } } 305 - { compiler: llvm@15, build: { macos-version-min: '10.9' } } 306 - { compiler: gcc-12, build: { torture: true } } 307 steps: 308 - name: 'brew install' 309 run: | 310 echo ninja pkg-config libpsl libssh2 nghttp2 stunnel ${{ matrix.build.install }} | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile 311 while [[ $? == 0 ]]; do for i in 1 2 3; do brew update && brew bundle install --no-lock --file /tmp/Brewfile && break 2 || { echo Error: wait to try again; sleep 10; } done; false Too many retries; done 312 313 - name: 'brew unlink openssl' 314 run: | 315 if test -d $(brew --prefix)/include/openssl; then 316 brew unlink openssl 317 fi 318 319 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 320 321 - name: 'toolchain versions' 322 run: | 323 [[ '${{ matrix.compiler }}' = 'llvm'* ]] && CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" 324 [[ '${{ matrix.compiler }}' = 'gcc'* ]] && \ 325 grep -h -r -E -o '.+[0-9.]+\.sdk/' "$(dirname "$("${CC}" -print-libgcc-file-name)")/include-fixed" | sed -E 's/^\t+//g' | tr -d '"' | sort -u || true 326 which "${CC}"; "${CC}" --version || true 327 xcodebuild -version || true 328 xcrun --sdk macosx --show-sdk-path 2>/dev/null || true 329 xcrun --sdk macosx --show-sdk-version || true 330 echo '::group::macros predefined'; "${CC}" -dM -E - < /dev/null | sort || true; echo '::endgroup::' 331 echo '::group::brew packages installed'; ls -l "$(brew --prefix)/opt"; echo '::endgroup::' 332 333 - name: 'cmake configure' 334 run: | 335 [[ '${{ matrix.compiler }}' = 'llvm'* ]] && CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" 336 if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then 337 libgccdir="$(dirname "$("${CC}" -print-libgcc-file-name)")" 338 echo '::group::gcc include-fixed details'; find "${libgccdir}/include-fixed" | sort; echo '::endgroup::' 339 for f in dispatch os AvailabilityInternal.h stdio.h; do 340 if [ -r "${libgccdir}/include-fixed/${f}" ]; then 341 echo "Zap gcc hack: '${libgccdir}/include-fixed/${f}'" 342 mv "${libgccdir}/include-fixed/${f}" "${libgccdir}/include-fixed/${f}-BAK" 343 fi 344 done 345 fi 346 cmake -B bld -G Ninja -DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON -DCURL_WERROR=ON \ 347 -DCMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.build.macos-version-min }} \ 348 "-DCMAKE_C_COMPILER_TARGET=$(uname -m | sed 's/arm64/aarch64/')-apple-darwin$(uname -r)" \ 349 ${{ matrix.build.generate }} 350 351 - name: 'configure log' 352 if: ${{ !cancelled() }} 353 run: cat bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true 354 355 - name: 'curl_config.h' 356 run: | 357 echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::' 358 cat bld/lib/curl_config.h | grep -F '#define' | sort || true 359 360 - name: 'build-cert' 361 if: contains(matrix.build.generate, '-DCURL_USE_SECTRANSP=ON') 362 run: | 363 ninja -C bld clean-certs 364 ninja -C bld build-certs -j 1 365 366 - name: 'cmake build' 367 run: ninja -C bld --verbose 368 369 - name: 'curl version' 370 run: bld/src/curl --disable --version 371 372 - name: 'cmake build tests' 373 run: ninja -C bld testdeps 374 375 - name: 'pip3 install' 376 run: | 377 python3 -m venv $HOME/venv 378 source $HOME/venv/bin/activate 379 python3 -m pip install impacket 380 381 - name: 'cmake run tests' 382 timeout-minutes: ${{ matrix.build.torture && 20 || 10 }} 383 run: | 384 export TFLAGS='-j10 ${{ matrix.build.tflags }}' 385 if [ -z '${{ matrix.build.torture }}' ]; then 386 TFLAGS+=' ~2037 ~2041' # flaky 387 if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then 388 TFLAGS+=' ~RTSP' # 567 568 569 570 571 572 577 689 3100 389 TFLAGS+=' ~1156 ~1539' # HTTP Content-Range, Content-Length 390 if [[ '${{ matrix.build.generate }}' = *'-DCURL_USE_SECTRANSP=ON'* ]]; then 391 TFLAGS+=' ~2100' # 2100:'HTTP GET using DoH' https://github.com/curl/curl/actions/runs/9942146678/job/27462937524#step:15:5059 392 TFLAGS+=' ~HTTP/2' # 2400 2401 2402 2403 2404 2406, Secure Transport + nghttp2 393 else 394 TFLAGS+=' ~2402 ~2404' # non-Secure Transport + nghttp2 395 fi 396 fi 397 if [[ '${{ matrix.build.generate }}' = *'-DCURL_USE_SECTRANSP=ON'* ]]; then 398 TFLAGS+=' ~313' # Secure Transport does not support crl file 399 TFLAGS+=' ~1631 ~1632' # Secure Transport is not able to shutdown ftp over https gracefully yet 400 fi 401 fi 402 source $HOME/venv/bin/activate 403 rm -f $HOME/.curlrc 404 ninja -C bld test-ci 405 406 - name: 'cmake build examples' 407 if: ${{ contains(matrix.name, '+examples') }} 408 run: make -C bld VERBOSE=1 409 410 combinations: # Test buildability with host OS, Xcode / SDK, compiler, target-OS, Secure Transport/not, built tool, combinations 411 if: true # Set to `true` to enable this test matrix. It runs quickly. 412 name: "${{ matrix.build == 'cmake' && 'CM' || 'AM' }} ${{ matrix.compiler }} ${{ matrix.image }} ${{ matrix.xcode }} ${{ matrix.config }}" 413 runs-on: ${{ matrix.image }} 414 timeout-minutes: 10 415 env: 416 DEVELOPER_DIR: "/Applications/Xcode${{ matrix.xcode && format('_{0}', matrix.xcode) || '' }}.app/Contents/Developer" 417 CC: ${{ matrix.compiler }} 418 strategy: 419 fail-fast: false 420 matrix: 421 config: [SecureTransport] # also: OpenSSL 422 compiler: [gcc-12, gcc-13, gcc-14, llvm@15, clang] 423 # Xcode support matrix as of 2024-07, with default macOS SDK versions and OS names, years: 424 # * = default Xcode on the runner. 425 # macos-12: 13.1, 13.2.1, 13.3.1, 13.4.1, 14.0.1, 14.1,*14.2 426 # macos-13: 14.1, 14.2, 14.3.1,*15.0.1, 15.1, 15.2 427 # macos-14: 14.3.1, 15.0.1, 15.1, 15.2, 15.3,*15.4, 16.0 428 # macOSSDK: 12.0, 12.1, 12.3, 12.3, 12.3, 13.0, 13.1, 13.3, 14.0, 14.2, 14.2, 14.4, 14.5, 15.0 429 # Monterey (2021) Ventura (2022) Sonoma (2023) Sequoia (2024) 430 # https://github.com/actions/runner-images/tree/main/images/macos 431 # https://en.wikipedia.org/wiki/MacOS_version_history 432 image: [macos-12, macos-13, macos-14] 433 # Can skip these to reduce jobs: 434 # 13.1, 13.2.1 are fairly old. 435 # 13.3.1, 14.0.1 have the same default macOS SDK as 13.4.1 and identical test results. 436 # 15.1 has the same default macOS SDK as 15.2 and identical test result. 437 # 14.1, 15.4 not revealing new fallouts. 438 #xcode: ['13.1', '13.2.1', '13.3.1', '13.4.1', '14.0.1', '14.1', '14.2', '14.3.1', '15.0.1', '15.1', '15.2', '15.3', '15.4', '16.0'] # all Xcode 439 #xcode: ['13.1', '13.2.1', '13.4.1', '14.1', '14.2', '14.3.1', '15.0.1', '15.2', '15.3', '15.4', '16.0'] # all SDK 440 #xcode: ['13.4.1', '14.2', '14.3.1', '15.0.1', '15.2', '15.3', '16.0'] # coverage 441 xcode: [''] # default Xcodes 442 macos-version-min: ['10.8'] 443 build: [autotools, cmake] 444 exclude: 445 # Combinations uncovered by runner images: 446 - { image: macos-12, xcode: '14.3.1' } 447 - { image: macos-12, xcode: '15.0.1' } 448 - { image: macos-12, xcode: '15.1' } 449 - { image: macos-12, xcode: '15.2' } 450 - { image: macos-12, xcode: '15.3' } 451 - { image: macos-12, xcode: '15.4' } 452 - { image: macos-12, xcode: '16.0' } 453 - { image: macos-13, xcode: '13.1' } 454 - { image: macos-13, xcode: '13.2.1' } 455 - { image: macos-13, xcode: '13.3.1' } 456 - { image: macos-13, xcode: '13.4.1' } 457 - { image: macos-13, xcode: '14.0.1' } 458 - { image: macos-13, xcode: '15.3' } 459 - { image: macos-13, xcode: '15.4' } 460 - { image: macos-13, xcode: '16.0' } 461 - { image: macos-14, xcode: '13.1' } 462 - { image: macos-14, xcode: '13.2.1' } 463 - { image: macos-14, xcode: '13.3.1' } 464 - { image: macos-14, xcode: '13.4.1' } 465 - { image: macos-14, xcode: '14.0.1' } 466 - { image: macos-14, xcode: '14.1' } 467 - { image: macos-14, xcode: '14.2' } 468 # Reduce build combinations, by dropping less interesting ones 469 - { compiler: gcc-12, config: SecureTransport } 470 - { compiler: gcc-13, build: cmake } 471 - { compiler: gcc-13, image: macos-13 } 472 - { compiler: gcc-14, config: SecureTransport } 473 steps: 474 - name: 'install autotools' 475 if: ${{ matrix.build == 'autotools' }} 476 run: | 477 echo automake libtool | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile 478 while [[ $? == 0 ]]; do for i in 1 2 3; do brew update && brew bundle install --no-lock --file /tmp/Brewfile && break 2 || { echo Error: wait to try again; sleep 10; } done; false Too many retries; done 479 480 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 481 482 - name: 'toolchain versions' 483 run: | 484 [[ '${{ matrix.compiler }}' = 'llvm'* ]] && CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" 485 [[ '${{ matrix.compiler }}' = 'gcc'* ]] && \ 486 grep -h -r -E -o '.+[0-9.]+\.sdk/' "$(dirname "$("${CC}" -print-libgcc-file-name)")/include-fixed" | sed -E 's/^\t+//g' | tr -d '"' | sort -u || true 487 which "${CC}"; "${CC}" --version || true 488 xcodebuild -version || true 489 xcrun --sdk macosx --show-sdk-path 2>/dev/null || true 490 xcrun --sdk macosx --show-sdk-version || true 491 echo '::group::macros predefined'; "${CC}" -dM -E - < /dev/null | sort || true; echo '::endgroup::' 492 echo '::group::brew packages preinstalled'; ls -l "$(brew --prefix)/opt"; echo '::endgroup::' 493 494 - name: 'autoreconf' 495 if: ${{ matrix.build == 'autotools' }} 496 run: autoreconf -fi 497 498 - name: 'configure / ${{ matrix.build }}' 499 run: | 500 [[ '${{ matrix.compiler }}' = 'llvm'* ]] && CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" 501 502 # gcc ships with an `include-fixed` header set, which overrides SDK 503 # headers with the intent of making them compatible with gcc. The 504 # source for these headers is: 505 # https://github.com/gcc-mirror/gcc/tree/master/fixincludes 506 # with extra Apple-specific patches applied from here for Homebrew: 507 # https://github.com/iains/gcc-12-branch 508 # 509 # They pass through a generator phase at build-time which seems to 510 # pick the SDK installed on the build machine (maintained by the 511 # Homebrew project in our case) and patches it according to a set 512 # of rules in `inclhack.def`. 513 # 514 # Homebrew builds and ships different binaries for different macOS 515 # versions and CPUs, built on machines using the same OS version as 516 # the target one. Each of these machines have a particular version 517 # of Apple CommandLineTools with a default SDK version installed with 518 # them. 519 # 520 # Then this binary gets installed onto the end-user machine, 521 # matching the OS version at the time of installation. 522 # 523 # The problem with this approach is that the SDK version picked up 524 # at gcc build-time has a high chance of being or becoming out of 525 # sync with actual SDK installed on the end-user machine. This 526 # can happen after upgrading the OS, Xcode, selecting an SDK version 527 # manually, or other reasons. 528 # 529 # When the SDK versions do not match, the gcc hacks, instead of 530 # improving compatibility the SDK, are actively _breaking_ 531 # compatibility, in an unexpected, hard to diagnose way. 532 # 533 # The SDK version used for gcc-hacks is not advertised. We can 534 # extract the major SDK version from the generated gcc-hack header 535 # files, assuming someone knows what to look for and where. 536 # 537 # Basically it also means that the same `gcc-N` Homebrew package 538 # behaves differently depending on the OS it was built on. Causing 539 # an explosion of build combination. It may also mean that a minor 540 # gcc version bump is built against a different SDK version, and due 541 # to the extra patch for the hack applied by Homebrew, there may 542 # be extra changes as well. 543 # 544 # For GHA runners, it means that the default Xcode + OS combo is 545 # broken in 8 out of 12 combinations (66%) have an SDK mismatch, 546 # and 9 fail to build (75%). These are the 3 lucky default 547 # combinations that worked to build curl: 548 # macos-14 + Xcode 15.0.1 + gcc-12, gcc-14 549 # 550 # Of all possible valid GHA runner, gcc, manually selected Xcode 551 # combinations, 40% are broken. 552 # 553 # Compared to mainline llvm: llvm ships the same binaries regardless 554 # of build-OS or environent, it contains no SDK-version-specific 555 # hacks, and has no 3rd party patches. This still leaves some 556 # occasional issues, but works much closer to expectations. 557 # 558 # Some of these hacks are helpful, in particular for fixing this 559 # issue via math.h: 560 # /Applications/Xcode_14.3.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/math.h:53:5: error: #error "Unsupported value of 561 # 53 | # error "Unsupported value of __FLT_EVAL_METHOD__." 562 # 563 # Errors seen in available CI combinations: 564 # error: two or more data types in declaration specifiers # fatal error: AvailabilityInternalLegacy.h: No such file or directory 565 # gcc-13 + macos-14 + Xcode 14.3.1 566 # error: two or more data types in declaration specifiers 567 # gcc-13 + macos-12 + Xcode 14.1, 14.2 568 # gcc-13 + Xcode 15.0.1, 15.1, 5.2 569 # error: expected ';' before 'extern' 570 # gcc-12, gcc-14 + macos-12 + Xcode 14.1, 14.2 571 # error: unknown type name 'dispatch_queue_t' 572 # gcc-12 + macos-13 + Xcode 15.0.1, 15.1, 15.2 573 # error: type defaults to 'int' in declaration of 'DISPATCH_DECL_FACTORY_CLASS_SWIFT' [-Wimplicit-int] 574 # gcc-14 macos-13 Xcode 15.0.1, 15.1, 15.2 575 # error: unknown type name 'FILE' 576 # Xcode 16.0 577 # 578 # Unbreak Homebrew gcc builds by moving problematic SDK header overlay 579 # directories/files out of the way: 580 if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then 581 # E.g.: 582 # $(brew --prefix)/Cellar/gcc@11/11.4.0/lib/gcc/11/gcc/aarch64-apple-darwin23/11/include-fixed 583 # $(brew --prefix)/Cellar/gcc@11/11.4.0/lib/gcc/11/gcc/x86_64-apple-darwin21/11/include-fixed 584 # $(brew --prefix)/Cellar/gcc/14.1.0_1/lib/gcc/14/gcc/x86_64-apple-darwin21/14/include-fixed 585 libgccdir="$(dirname "$("${CC}" -print-libgcc-file-name)")" 586 echo '::group::gcc include-fixed details'; find "${libgccdir}/include-fixed" | sort; echo '::endgroup::' 587 patch_out='dispatch os AvailabilityInternal.h' 588 patch_out+=' stdio.h' # for Xcode 16 error: unknown type name 'FILE' 589 for f in ${patch_out}; do 590 if [ -r "${libgccdir}/include-fixed/${f}" ]; then 591 echo "Zap gcc hack: '${libgccdir}/include-fixed/${f}'" 592 mv "${libgccdir}/include-fixed/${f}" "${libgccdir}/include-fixed/${f}-BAK" 593 fi 594 done 595 fi 596 597 if [ '${{ matrix.build }}' = 'autotools' ]; then 598 export CFLAGS 599 if [[ '${{ matrix.compiler }}' = 'llvm'* ]]; then 600 options+=" --target=$(uname -m)-apple-darwin" 601 CC+=" --target=$(uname -m)-apple-darwin" 602 fi 603 if [ '${{ matrix.compiler }}' != 'clang' ]; then 604 options+=" --with-sysroot=$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" 605 CFLAGS+=" --sysroot=$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" 606 fi 607 [ '${{ matrix.config }}' = 'OpenSSL' ] && options+=" --with-openssl=$(brew --prefix openssl)" 608 [ '${{ matrix.config }}' = 'SecureTransport' ] && options+=' --with-secure-transport' 609 CFLAGS+=' -mmacosx-version-min=${{ matrix.macos-version-min }}' 610 # would pick up nghttp2, libidn2, but libssh2 is disabled by default 611 mkdir bld && cd bld && ../configure --enable-unity --enable-test-bundles --enable-warnings --enable-werror \ 612 --disable-dependency-tracking \ 613 --disable-docs --disable-manual \ 614 --without-nghttp2 --without-libidn2 \ 615 --without-libpsl \ 616 ${options} 617 else 618 [ '${{ matrix.config }}' = 'OpenSSL' ] && options+=' -DCURL_USE_OPENSSL=ON' 619 [ '${{ matrix.config }}' = 'SecureTransport' ] && options+=' -DCURL_USE_SECTRANSP=ON' 620 # would pick up nghttp2, libidn2, and libssh2 621 cmake -B bld -DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON -DCURL_WERROR=ON \ 622 -DCMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.macos-version-min }} \ 623 "-DCMAKE_IGNORE_PREFIX_PATH=$(brew --prefix)" \ 624 "-DCMAKE_C_COMPILER_TARGET=$(uname -m | sed 's/arm64/aarch64/')-apple-darwin$(uname -r)" \ 625 -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF \ 626 -DUSE_NGHTTP2=OFF -DUSE_LIBIDN2=OFF \ 627 -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF \ 628 ${options} 629 fi 630 631 - name: 'configure log' 632 if: ${{ !cancelled() }} 633 run: cat bld/config.log bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true 634 635 - name: 'curl_config.h' 636 run: | 637 echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::' 638 cat bld/lib/curl_config.h | grep -F '#define' | sort || true 639 640 - name: 'build / ${{ matrix.build }}' 641 run: make -C bld V=1 VERBOSE=1 642 643 - name: 'curl version' 644 run: bld/src/curl --disable --version 645