• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env bash
2# ===----------------------------------------------------------------------===##
3#
4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5# See https://llvm.org/LICENSE.txt for license information.
6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7#
8# ===----------------------------------------------------------------------===##
9
10set -e
11set -o pipefail
12unset LANG
13unset LC_ALL
14unset LC_COLLATE
15
16PROGNAME="$(basename "${0}")"
17
18function usage() {
19cat <<EOF
20Usage:
21${PROGNAME} [options] <BUILDER>
22
23[-h|--help]         Display this help and exit.
24
25--llvm-root <DIR>   Path to the root of the LLVM monorepo. By default, we try
26                    to figure it out based on the current working directory.
27
28--build-dir <DIR>   The directory to use for building the library. By default,
29                    this is '<llvm-root>/build/<builder>'.
30
31Environment variables
32CC                  The C compiler to use, this value is used by CMake. This
33                    variable is optional.
34
35CXX                 The C++ compiler to use, this value is used by CMake. This
36                    variable is optional.
37
38CMAKE               The CMake binary to use. This variable is optional.
39
40CLANG_FORMAT        The clang-format binary to use when generating the format
41                    ignore list.
42
43EOF
44}
45
46if [[ $# == 0 ]]; then
47   usage
48   exit 0
49fi
50
51while [[ $# -gt 0 ]]; do
52    case ${1} in
53        -h|--help)
54            usage
55            exit 0
56            ;;
57        --llvm-root)
58            MONOREPO_ROOT="${2}"
59            shift; shift
60            ;;
61        --build-dir)
62            BUILD_DIR="${2}"
63            shift; shift
64            ;;
65        *)
66            BUILDER="${1}"
67            shift
68            ;;
69    esac
70done
71
72MONOREPO_ROOT="${MONOREPO_ROOT:="$(git rev-parse --show-toplevel)"}"
73BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build/${BUILDER}}"
74INSTALL_DIR="${BUILD_DIR}/install"
75
76# If we can find Ninja/CMake provided by Xcode, use those since we know their
77# version will generally work with the Clang shipped in Xcode (e.g. if Clang
78# knows about -std=c++20, the CMake bundled in Xcode will probably know about
79# that flag too).
80if xcrun --find ninja &>/dev/null; then
81    NINJA="$(xcrun --find ninja)"
82elif which ninja &>/dev/null; then
83    # The current implementation of modules needs the absolute path to the ninja
84    # binary.
85    # TODO MODULES Is this still needed when CMake has libc++ module support?
86    NINJA="$(which ninja)"
87else
88    NINJA="ninja"
89fi
90
91if [ -z "${CMAKE}" ]; then
92    if xcrun --find cmake &>/dev/null; then
93        CMAKE="$(xcrun --find cmake)"
94    else
95        CMAKE="cmake"
96    fi
97fi
98
99function step() {
100  endstep
101  set +x
102  if [[ ! -z ${GITHUB_ACTIONS+x} ]]; then
103    echo "::group::$1"
104    export IN_GROUP=1
105  else
106    echo "--- $1"
107  fi
108  set -x
109}
110
111function endstep() {
112  set +x
113  if [[ ! -z ${GITHUB_ACTIONS+x} ]] && [[ ! -z ${IN_GROUP+x} ]]; then
114    echo "::endgroup::"
115    unset IN_GROUP
116  fi
117  set -x
118}
119
120function error() {
121    echo "::error::$1"
122}
123
124function clean() {
125    rm -rf "${BUILD_DIR}"
126}
127
128function generate-cmake-base() {
129    step "Generating CMake"
130    ${CMAKE} \
131          -S "${MONOREPO_ROOT}/runtimes" \
132          -B "${BUILD_DIR}" \
133          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
134          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
135          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
136          -DLIBCXX_ENABLE_WERROR=YES \
137          -DLIBCXXABI_ENABLE_WERROR=YES \
138          -DLIBUNWIND_ENABLE_WERROR=YES \
139          -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
140          "${@}"
141}
142
143function generate-cmake() {
144    generate-cmake-base \
145          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
146          -DLIBCXX_CXX_ABI=libcxxabi \
147          "${@}"
148}
149
150function generate-cmake-libcxx-win() {
151    generate-cmake-base \
152          -DLLVM_ENABLE_RUNTIMES="libcxx" \
153          -DCMAKE_C_COMPILER=clang-cl \
154          -DCMAKE_CXX_COMPILER=clang-cl \
155          "${@}"
156}
157
158function generate-cmake-android() {
159    generate-cmake-base \
160          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
161          -DLIBCXX_CXX_ABI=libcxxabi \
162          "${@}"
163}
164
165function check-runtimes() {
166    step "Building libc++ test dependencies"
167    ${NINJA} -vC "${BUILD_DIR}" cxx-test-depends
168
169    step "Running the libc++ tests"
170    ${NINJA} -vC "${BUILD_DIR}" check-cxx
171
172    step "Running the libc++abi tests"
173    ${NINJA} -vC "${BUILD_DIR}" check-cxxabi
174
175    step "Running the libunwind tests"
176    ${NINJA} -vC "${BUILD_DIR}" check-unwind
177}
178
179# TODO: The goal is to test this against all configurations. We should also move
180#       this to the Lit test suite instead of being a separate CMake target.
181function check-abi-list() {
182    step "Running the libc++ ABI list test"
183    ${NINJA} -vC "${BUILD_DIR}" check-cxx-abilist || (
184        error "Generating the libc++ ABI list after failed check"
185        ${NINJA} -vC "${BUILD_DIR}" generate-cxx-abilist
186        false
187    )
188}
189
190function test-armv7m-picolibc() {
191    clean
192
193    # To make it easier to get this builder up and running, build picolibc
194    # from scratch. Anecdotally, the build-picolibc script takes about 16 seconds.
195    # This could be optimised by building picolibc into the Docker container.
196    step "Building picolibc from source"
197    ${MONOREPO_ROOT}/libcxx/utils/ci/build-picolibc.sh \
198        --build-dir "${BUILD_DIR}" \
199        --install-dir "${INSTALL_DIR}" \
200        --target armv7m-none-eabi
201
202    step "Generating CMake for compiler-rt"
203    flags="--sysroot=${INSTALL_DIR}"
204    ${CMAKE} \
205        -S "${MONOREPO_ROOT}/compiler-rt" \
206        -B "${BUILD_DIR}/compiler-rt" \
207        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
208        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
209        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
210        -DCMAKE_C_FLAGS="${flags}" \
211        -DCMAKE_CXX_FLAGS="${flags}" \
212        -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \
213        "${@}"
214
215    step "Generating CMake for libc++"
216    generate-cmake \
217        -DLIBCXX_TEST_CONFIG="armv7m-picolibc-libc++.cfg.in" \
218        -DLIBCXXABI_TEST_CONFIG="armv7m-picolibc-libc++abi.cfg.in" \
219        -DLIBUNWIND_TEST_CONFIG="armv7m-picolibc-libunwind.cfg.in" \
220        -DCMAKE_C_FLAGS="${flags}" \
221        -DCMAKE_CXX_FLAGS="${flags}" \
222        "${@}"
223
224    step "Installing compiler-rt"
225    ${NINJA} -vC "${BUILD_DIR}/compiler-rt" install
226
227    # Prior to clang 19, armv7m-none-eabi normalised to armv7m-none-unknown-eabi.
228    # clang 19 changed this to armv7m-unknown-none-eabi. So for as long as 18.x
229    # is supported, we have to ask clang what the triple will be.
230    NORMALISED_TARGET_TRIPLE=$(${CC-cc} --target=armv7m-none-eabi -print-target-triple)
231    # Without this step linking fails later in the build.
232    mv "${BUILD_DIR}/install/lib/${NORMALISED_TARGET_TRIPLE}"/* "${BUILD_DIR}/install/lib"
233
234    check-runtimes
235}
236
237# Print the version of a few tools to aid diagnostics in some cases
238step "Diagnose tools in use"
239${CMAKE} --version
240${NINJA} --version
241if [ ! -z "${CXX}" ]; then ${CXX} --version; fi
242
243case "${BUILDER}" in
244check-generated-output)
245    # `! foo` doesn't work properly with `set -e`, use `! foo || false` instead.
246    # https://stackoverflow.com/questions/57681955/set-e-does-not-respect-logical-not
247    clean
248    generate-cmake
249
250    # Reject patches that forgot to re-run the generator scripts.
251    step "Making sure the generator scripts were run"
252    set +x # Printing all the commands below just creates extremely confusing output
253    ${NINJA} -vC "${BUILD_DIR}" libcxx-generate-files
254    git diff | tee ${BUILD_DIR}/generated_output.patch
255    git ls-files -o --exclude-standard | tee ${BUILD_DIR}/generated_output.status
256    ! grep -q '^--- a' ${BUILD_DIR}/generated_output.patch || false
257    if [ -s ${BUILD_DIR}/generated_output.status ]; then
258        echo "It looks like not all the generator scripts were run,"
259        echo "did you forget to build the libcxx-generate-files target?"
260        echo "Did you add all new files it generated?"
261        false
262    fi
263
264    # This depends on LC_COLLATE set at the top of this script.
265    step "Reject patches that introduce non-ASCII characters or hard tabs."
266    ! grep -rn '[^ -~]' libcxx/include libcxx/src libcxx/test \
267           --exclude '*.dat' \
268           --exclude '*unicode*.cpp' \
269           --exclude '*print*.sh.cpp' \
270           --exclude 'escaped_output.*.pass.cpp' \
271           --exclude 'format_tests.h' \
272           --exclude 'format.functions.tests.h' \
273           --exclude 'formatter.*.pass.cpp' \
274           --exclude 'grep.pass.cpp' \
275           --exclude 'locale-specific_form.pass.cpp' \
276           --exclude 'ostream.pass.cpp' \
277           --exclude 'transcoding.pass.cpp' \
278           --exclude 'underflow.pass.cpp' \
279           || false
280;;
281#
282# Various Standard modes
283#
284generic-cxx03)
285    clean
286    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx03.cmake"
287    check-runtimes
288    check-abi-list
289;;
290generic-cxx11)
291    clean
292    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx11.cmake"
293    check-runtimes
294    check-abi-list
295;;
296generic-cxx14)
297    clean
298    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx14.cmake"
299    check-runtimes
300    check-abi-list
301;;
302generic-cxx17)
303    clean
304    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx17.cmake"
305    check-runtimes
306    check-abi-list
307;;
308generic-cxx20)
309    clean
310    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx20.cmake"
311    check-runtimes
312    check-abi-list
313;;
314generic-cxx23)
315    clean
316    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx23.cmake"
317    check-runtimes
318    check-abi-list
319;;
320generic-cxx26)
321    clean
322    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx26.cmake"
323    check-runtimes
324    check-abi-list
325;;
326#
327# Other compiler support
328#
329generic-gcc)
330    clean
331    generate-cmake -DLIBCXX_ENABLE_WERROR=NO \
332                   -DLIBCXXABI_ENABLE_WERROR=NO \
333                   -DLIBUNWIND_ENABLE_WERROR=NO
334    check-runtimes
335;;
336generic-gcc-cxx11)
337    clean
338    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx11.cmake" \
339                   -DLIBCXX_ENABLE_WERROR=NO \
340                   -DLIBCXXABI_ENABLE_WERROR=NO \
341                   -DLIBUNWIND_ENABLE_WERROR=NO
342    check-runtimes
343;;
344#
345# Sanitizers
346#
347generic-asan)
348    clean
349    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-asan.cmake"
350    check-runtimes
351;;
352generic-msan)
353    clean
354    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-msan.cmake"
355    check-runtimes
356;;
357generic-tsan)
358    clean
359    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-tsan.cmake"
360    check-runtimes
361;;
362generic-ubsan)
363    clean
364    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-ubsan.cmake"
365    check-runtimes
366;;
367#
368# Various build configurations
369#
370bootstrapping-build)
371    clean
372
373    step "Generating CMake"
374    ${CMAKE} \
375          -S "${MONOREPO_ROOT}/llvm" \
376          -B "${BUILD_DIR}" \
377          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
378          -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \
379          -DCMAKE_BUILD_TYPE=Release \
380          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
381          -DLLVM_ENABLE_PROJECTS="clang;lldb" \
382          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
383          -DLLVM_RUNTIME_TARGETS="$(${CXX} --print-target-triple)" \
384          -DLLVM_HOST_TRIPLE="$(${CXX} --print-target-triple)" \
385          -DLLVM_TARGETS_TO_BUILD="host" \
386          -DRUNTIMES_BUILD_ALLOW_DARWIN=ON \
387          -DLLVM_ENABLE_ASSERTIONS=ON \
388          -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests"
389
390    step "Running the LLDB libc++ data formatter tests"
391    ${NINJA} -vC "${BUILD_DIR}" lldb-api-test-deps
392    ${BUILD_DIR}/bin/llvm-lit -sv --param dotest-args='--category libc++' "${MONOREPO_ROOT}/lldb/test/API"
393
394    step "Running the libc++ and libc++abi tests"
395    ${NINJA} -vC "${BUILD_DIR}" check-runtimes
396
397    step "Installing libc++ and libc++abi to a fake location"
398    ${NINJA} -vC "${BUILD_DIR}" install-runtimes
399
400    ccache -s
401;;
402generic-static)
403    clean
404    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-static.cmake"
405    check-runtimes
406;;
407generic-merged)
408    clean
409    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-merged.cmake" \
410                   -DLIBCXX_TEST_CONFIG="llvm-libc++-shared.cfg.in" \
411                   -DLIBCXXABI_TEST_CONFIG="llvm-libc++abi-merged.cfg.in" \
412                   -DLIBUNWIND_TEST_CONFIG="llvm-libunwind-merged.cfg.in"
413    check-runtimes
414;;
415generic-hardening-mode-fast)
416    clean
417    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-hardening-mode-fast.cmake"
418    check-runtimes
419    check-abi-list
420;;
421generic-hardening-mode-fast-with-abi-breaks)
422    clean
423    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake"
424    check-runtimes
425    # Not checking ABI list since we purposefully enable ABI breaking changes
426;;
427generic-hardening-mode-extensive)
428    clean
429    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-hardening-mode-extensive.cmake"
430    check-runtimes
431    check-abi-list
432;;
433generic-hardening-mode-debug)
434    clean
435    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-hardening-mode-debug.cmake"
436    check-runtimes
437    check-abi-list
438;;
439#
440# Module builds
441#
442generic-modules)
443    clean
444    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-modules.cmake"
445    check-runtimes
446    check-abi-list
447;;
448generic-modules-lsv)
449    clean
450    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-modules-lsv.cmake"
451    check-runtimes
452    check-abi-list
453;;
454#
455# Parts removed
456#
457generic-no-threads)
458    clean
459    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-threads.cmake"
460    check-runtimes
461;;
462generic-no-filesystem)
463    clean
464    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-filesystem.cmake"
465    check-runtimes
466;;
467generic-no-random_device)
468    clean
469    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-random_device.cmake"
470    check-runtimes
471;;
472generic-no-localization)
473    clean
474    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake"
475    check-runtimes
476;;
477generic-no-terminal)
478    clean
479    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-terminal.cmake"
480    check-runtimes
481;;
482generic-no-unicode)
483    clean
484    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-unicode.cmake"
485    check-runtimes
486;;
487generic-no-wide-characters)
488    clean
489    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-wide-characters.cmake"
490    check-runtimes
491;;
492generic-no-tzdb)
493    clean
494    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-tzdb.cmake"
495    check-runtimes
496;;
497generic-no-experimental)
498    clean
499    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-experimental.cmake"
500    check-runtimes
501    check-abi-list
502;;
503generic-no-exceptions)
504    clean
505    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-exceptions.cmake"
506    check-runtimes
507    check-abi-list
508;;
509generic-no-rtti)
510    clean
511    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-rtti.cmake"
512    check-runtimes
513;;
514#
515# Other miscellaneous jobs
516#
517generic-abi-unstable)
518    clean
519    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-abi-unstable.cmake"
520    check-runtimes
521;;
522generic-optimized-speed)
523    clean
524    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-optimized-speed.cmake"
525    check-runtimes
526;;
527apple-configuration)
528    clean
529
530    step "Installing libc++ with the Apple system configuration"
531    arch="$(uname -m)"
532    xcrun --sdk macosx                                              \
533        ${MONOREPO_ROOT}/libcxx/utils/ci/apple-install-libcxx.sh    \
534            --llvm-root ${MONOREPO_ROOT}                            \
535            --build-dir ${BUILD_DIR}                                \
536            --install-dir ${INSTALL_DIR}                            \
537            --symbols-dir "${BUILD_DIR}/symbols"                    \
538            --architectures "${arch}"                               \
539            --version "999.99"
540
541    step "Running tests against Apple-configured libc++"
542    # TODO: It would be better to run the tests against the fake-installed version of libc++ instead
543    xcrun --sdk macosx ninja -vC "${BUILD_DIR}/${arch}" check-cxx check-cxxabi check-cxx-abilist
544;;
545apple-system-hardened)
546    clean
547
548    arch="$(uname -m)"
549    version="$(sw_vers --productVersion)"
550    params="target_triple=${arch}-apple-macosx${version}"
551    params+=";hardening_mode=fast"
552
553    # In the Apple system configuration, we build libc++ and libunwind separately.
554    step "Installing libc++ and libc++abi in Apple-system configuration"
555    ${CMAKE} \
556        -S "${MONOREPO_ROOT}/runtimes" \
557        -B "${BUILD_DIR}/cxx" \
558        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
559        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
560        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/cxx" \
561        -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
562        -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
563        -DLIBCXX_CXX_ABI=libcxxabi \
564        -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
565        -DLIBCXX_TEST_CONFIG="apple-libc++-system.cfg.in" \
566        -DLIBCXXABI_TEST_CONFIG="apple-libc++abi-system.cfg.in" \
567        -DLIBCXX_TEST_PARAMS="${params}" \
568        -DLIBCXXABI_TEST_PARAMS="${params}"
569
570    step "Installing libunwind in Apple-system configuration"
571    ${CMAKE} \
572        -S "${MONOREPO_ROOT}/runtimes" \
573        -B "${BUILD_DIR}/unwind" \
574        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
575        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
576        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/unwind" \
577        -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
578        -DLLVM_ENABLE_RUNTIMES="libunwind" \
579        -DLIBUNWIND_TEST_CONFIG="apple-libunwind-system.cfg.in" \
580        -DLIBUNWIND_TEST_PARAMS="${params}" \
581        -DCMAKE_INSTALL_NAME_DIR="/usr/lib/system"
582
583    step "Running the libc++ tests"
584    ${NINJA} -vC "${BUILD_DIR}/cxx" check-cxx
585
586    step "Running the libc++abi tests"
587    ${NINJA} -vC "${BUILD_DIR}/cxx" check-cxxabi
588
589    step "Running the libunwind tests"
590    ${NINJA} -vC "${BUILD_DIR}/unwind" check-unwind
591;;
592apple-system)
593    clean
594
595    arch="$(uname -m)"
596    version="$(sw_vers --productVersion)"
597    params="target_triple=${arch}-apple-macosx${version}"
598
599    # In the Apple system configuration, we build libc++ and libunwind separately.
600    step "Installing libc++ and libc++abi in Apple-system configuration"
601    ${CMAKE} \
602        -S "${MONOREPO_ROOT}/runtimes" \
603        -B "${BUILD_DIR}/cxx" \
604        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
605        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
606        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/cxx" \
607        -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
608        -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
609        -DLIBCXX_CXX_ABI=libcxxabi \
610        -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
611        -DLIBCXX_TEST_CONFIG="apple-libc++-system.cfg.in" \
612        -DLIBCXXABI_TEST_CONFIG="apple-libc++abi-system.cfg.in" \
613        -DLIBCXX_TEST_PARAMS="${params}" \
614        -DLIBCXXABI_TEST_PARAMS="${params}"
615
616    step "Installing libunwind in Apple-system configuration"
617    ${CMAKE} \
618        -S "${MONOREPO_ROOT}/runtimes" \
619        -B "${BUILD_DIR}/unwind" \
620        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
621        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
622        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/unwind" \
623        -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
624        -DLLVM_ENABLE_RUNTIMES="libunwind" \
625        -DLIBUNWIND_TEST_CONFIG="apple-libunwind-system.cfg.in" \
626        -DLIBUNWIND_TEST_PARAMS="${params}" \
627        -DCMAKE_INSTALL_NAME_DIR="/usr/lib/system"
628
629    step "Running the libc++ tests"
630    ${NINJA} -vC "${BUILD_DIR}/cxx" check-cxx
631
632    step "Running the libc++abi tests"
633    ${NINJA} -vC "${BUILD_DIR}/cxx" check-cxxabi
634
635    step "Running the libunwind tests"
636    ${NINJA} -vC "${BUILD_DIR}/unwind" check-unwind
637;;
638aarch64)
639    clean
640    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AArch64.cmake"
641    check-runtimes
642;;
643aarch64-no-exceptions)
644    clean
645    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AArch64.cmake" \
646                   -DLIBCXX_ENABLE_EXCEPTIONS=OFF \
647                   -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
648    check-runtimes
649;;
650# Aka Armv8 32 bit
651armv8)
652    clean
653    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv8Arm.cmake"
654    check-runtimes
655;;
656armv8-no-exceptions)
657    clean
658    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv8Thumb-no-exceptions.cmake"
659    check-runtimes
660;;
661# Armv7 32 bit. One building Arm only one Thumb only code.
662armv7)
663    clean
664    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7Arm.cmake"
665    check-runtimes
666;;
667armv7-no-exceptions)
668    clean
669    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7Thumb-no-exceptions.cmake"
670    check-runtimes
671;;
672armv7m-picolibc)
673    test-armv7m-picolibc \
674        -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7M-picolibc.cmake"
675;;
676armv7m-picolibc-no-exceptions)
677    test-armv7m-picolibc \
678        -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7M-picolibc.cmake" \
679        -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF \
680        -DLIBCXXABI_ENABLE_STATIC_UNWINDER=OFF \
681        -DLIBCXX_ENABLE_EXCEPTIONS=OFF \
682        -DLIBCXX_ENABLE_RTTI=OFF
683;;
684clang-cl-dll)
685    clean
686    # TODO: Currently, building with the experimental library breaks running
687    # tests (the test linking look for the c++experimental library with the
688    # wrong name, and the statically linked c++experimental can't be linked
689    # correctly when libc++ visibility attributes indicate dllimport linkage
690    # anyway), thus just disable the experimental library. Remove this
691    # setting when cmake and the test driver does the right thing automatically.
692    generate-cmake-libcxx-win -DLIBCXX_TEST_PARAMS="enable_experimental=False"
693    step "Running the libc++ tests"
694    ${NINJA} -vC "${BUILD_DIR}" check-cxx
695;;
696clang-cl-static)
697    clean
698    generate-cmake-libcxx-win -DLIBCXX_ENABLE_SHARED=OFF
699    step "Running the libc++ tests"
700    ${NINJA} -vC "${BUILD_DIR}" check-cxx
701;;
702clang-cl-no-vcruntime)
703    clean
704    # Building libc++ in the same way as in clang-cl-dll above, but running
705    # tests with -D_HAS_EXCEPTIONS=0, which users might set in certain
706    # translation units while using libc++, even if libc++ is built with
707    # exceptions enabled.
708    generate-cmake-libcxx-win -DLIBCXX_TEST_PARAMS="enable_experimental=False" \
709                              -DLIBCXX_TEST_CONFIG="llvm-libc++-shared-no-vcruntime-clangcl.cfg.in"
710    step "Running the libc++ tests"
711    ${NINJA} -vC "${BUILD_DIR}" check-cxx
712;;
713clang-cl-debug)
714    clean
715    generate-cmake-libcxx-win -DLIBCXX_TEST_PARAMS="enable_experimental=False" \
716                              -DCMAKE_BUILD_TYPE=Debug
717    step "Running the libc++ tests"
718    ${NINJA} -vC "${BUILD_DIR}" check-cxx
719;;
720clang-cl-static-crt)
721    clean
722    # Test linking a static libc++ with the static CRT ("MultiThreaded" denotes
723    # the static CRT, as opposed to "MultiThreadedDLL" which is the default).
724    generate-cmake-libcxx-win -DLIBCXX_ENABLE_SHARED=OFF \
725                              -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
726    step "Running the libc++ tests"
727    ${NINJA} -vC "${BUILD_DIR}" check-cxx
728;;
729mingw-dll)
730    clean
731    generate-cmake \
732          -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake"
733    check-runtimes
734;;
735mingw-static)
736    clean
737    generate-cmake \
738          -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake" \
739          -DLIBCXX_ENABLE_SHARED=OFF \
740          -DLIBUNWIND_ENABLE_SHARED=OFF
741    check-runtimes
742;;
743mingw-dll-i686)
744    clean
745    generate-cmake \
746          -DCMAKE_C_COMPILER=i686-w64-mingw32-clang \
747          -DCMAKE_CXX_COMPILER=i686-w64-mingw32-clang++ \
748          -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake"
749    check-runtimes
750;;
751mingw-incomplete-sysroot)
752    # When bringing up a new cross compiler from scratch, we build
753    # libunwind/libcxx in a setup where the toolchain is incomplete and
754    # unable to perform the normal linker checks; this requires a few
755    # special cases in the CMake files.
756    #
757    # Building in an incomplete setup requires setting CMAKE_*_COMPILER_WORKS,
758    # as CMake fails to probe the compiler. This case also requires
759    # setting CMAKE_CXX_COMPILER_TARGET, as LLVM's heuristics for setting
760    # the triple fails when CMake hasn't been able to probe the environment.
761    # (This is what one has to do when building the initial libunwind/libcxx
762    # for a new toolchain.)
763    clean
764    generate-cmake \
765          -DCMAKE_C_COMPILER_WORKS=TRUE \
766          -DCMAKE_CXX_COMPILER_WORKS=TRUE \
767          -DCMAKE_C_COMPILER_TARGET=x86_64-w64-windows-gnu \
768          -DCMAKE_CXX_COMPILER_TARGET=x86_64-w64-windows-gnu \
769          -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake"
770    # Only test that building succeeds; there's not much extra value in running
771    # the tests here, as it would be equivalent to the mingw-dll config above.
772    step "Building the runtimes"
773    ${NINJA} -vC "${BUILD_DIR}"
774;;
775aix)
776    clean
777    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AIX.cmake" \
778                   -DLIBCXX_TEST_CONFIG="ibm-libc++-shared.cfg.in" \
779                   -DLIBCXXABI_TEST_CONFIG="ibm-libc++abi-shared.cfg.in" \
780                   -DLIBUNWIND_TEST_CONFIG="ibm-libunwind-shared.cfg.in"
781    check-abi-list
782    check-runtimes
783;;
784android-ndk-*)
785    clean
786
787    ANDROID_EMU_IMG="${BUILDER#android-ndk-}"
788    . "${MONOREPO_ROOT}/libcxx/utils/ci/vendor/android/emulator-functions.sh"
789    if ! validate_emu_img "${ANDROID_EMU_IMG}"; then
790        error "android-ndk suffix must be a valid emulator image (${ANDROID_EMU_IMG})" >&2
791        exit 1
792    fi
793    ARCH=$(arch_of_emu_img ${ANDROID_EMU_IMG})
794
795    # Use the Android compiler by default.
796    export CC=${CC:-/opt/android/clang/clang-current/bin/clang}
797    export CXX=${CXX:-/opt/android/clang/clang-current/bin/clang++}
798
799    # The NDK libc++_shared.so is always built against the oldest supported API
800    # level. When tests are run against a device with a newer API level, test
801    # programs can be built for any supported API level, but building for the
802    # newest API (i.e. the system image's API) is probably the most interesting.
803    PARAMS="executor=${MONOREPO_ROOT}/libcxx/utils/adb_run.py;target_triple=$(triple_of_arch ${ARCH})$(api_of_emu_img ${ANDROID_EMU_IMG})"
804    generate-cmake-android -C "${MONOREPO_ROOT}/runtimes/cmake/android/Arch-${ARCH}.cmake" \
805                           -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AndroidNDK.cmake" \
806                           -DCMAKE_SYSROOT=/opt/android/ndk/sysroot \
807                           -DLIBCXX_TEST_PARAMS="${PARAMS}" \
808                           -DLIBCXXABI_TEST_PARAMS="${PARAMS}"
809    check-abi-list
810    ${NINJA} -vC "${BUILD_DIR}" install-cxx install-cxxabi
811
812    # Start the emulator and make sure we can connect to the adb server running
813    # inside of it.
814    "${MONOREPO_ROOT}/libcxx/utils/ci/vendor/android/start-emulator.sh" ${ANDROID_EMU_IMG}
815    trap "${MONOREPO_ROOT}/libcxx/utils/ci/vendor/android/stop-emulator.sh" EXIT
816    . "${MONOREPO_ROOT}/libcxx/utils/ci/vendor/android/setup-env-for-emulator.sh"
817
818    # Create adb_run early to avoid concurrent `mkdir -p` of common parent
819    # directories.
820    adb shell mkdir -p /data/local/tmp/adb_run
821    adb push "${BUILD_DIR}/lib/libc++_shared.so" /data/local/tmp/libc++/libc++_shared.so
822    step "Running the libc++ tests"
823    ${NINJA} -vC "${BUILD_DIR}" check-cxx
824    step "Running the libc++abi tests"
825    ${NINJA} -vC "${BUILD_DIR}" check-cxxabi
826;;
827#################################################################
828# Insert vendor-specific internal configurations below.
829#
830# This allows vendors to extend this file with their own internal
831# configurations without running into merge conflicts with upstream.
832#################################################################
833
834#################################################################
835*)
836    echo "${BUILDER} is not a known configuration"
837    exit 1
838;;
839esac
840
841endstep # Make sure we close any still-open output group
842