macos.yml 32 KB

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