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 -ex
11
12PROGNAME="$(basename "${0}")"
13
14function usage() {
15cat <<EOF
16Usage:
17${PROGNAME} [options] <BUILDER>
18
19[-h|--help]         Display this help and exit.
20
21--llvm-root <DIR>   Path to the root of the LLVM monorepo. By default, we try
22                    to figure it out based on the current working directory.
23
24--build-dir <DIR>   The directory to use for building the library. By default,
25                    this is '<llvm-root>/build/<builder>'.
26
27--osx-roots <DIR>   Path to pre-downloaded macOS dylibs. By default, we download
28                    them from Green Dragon. This is only relevant at all when
29                    running back-deployment testing if one wants to override
30                    the old dylibs we use to run the tests with different ones.
31EOF
32}
33
34while [[ $# -gt 0 ]]; do
35    case ${1} in
36        -h|--help)
37            usage
38            exit 0
39            ;;
40        --llvm-root)
41            MONOREPO_ROOT="${2}"
42            shift; shift
43            ;;
44        --build-dir)
45            BUILD_DIR="${2}"
46            shift; shift
47            ;;
48        --osx-roots)
49            OSX_ROOTS="${2}"
50            shift; shift
51            ;;
52        *)
53            BUILDER="${1}"
54            shift
55            ;;
56    esac
57done
58
59MONOREPO_ROOT="${MONOREPO_ROOT:="$(git rev-parse --show-toplevel)"}"
60BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build/${BUILDER}}"
61INSTALL_DIR="${BUILD_DIR}/install}"
62
63function clean() {
64    rm -rf "${BUILD_DIR}"
65}
66
67function generate-cmake() {
68    echo "--- Generating CMake"
69    cmake -S "${MONOREPO_ROOT}/llvm" \
70          -B "${BUILD_DIR}" \
71          -GNinja \
72          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
73          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
74          -DLLVM_ENABLE_PROJECTS="libcxx;libunwind;libcxxabi" \
75          -DLLVM_LIT_ARGS="-sv --show-unsupported --xunit-xml-output test-results.xml" \
76          -DLIBCXX_CXX_ABI=libcxxabi \
77          "${@}"
78}
79
80function check-cxx-cxxabi() {
81    echo "+++ Running the libc++ tests"
82    ninja -C "${BUILD_DIR}" check-cxx
83
84    echo "+++ Running the libc++abi tests"
85    ninja -C "${BUILD_DIR}" check-cxxabi
86
87    echo "--- Installing libc++ and libc++abi to a fake location"
88    ninja -C "${BUILD_DIR}" install-cxx install-cxxabi
89}
90
91# TODO: The goal is to test this against all configurations. We should also move
92#       this to the Lit test suite instead of being a separate CMake target.
93function check-abi-list() {
94    echo "+++ Running the libc++ ABI list test"
95    ninja -C "${BUILD_DIR}" check-cxx-abilist || (
96        echo "+++ Generating the libc++ ABI list after failed check"
97        ninja -C "${BUILD_DIR}" generate-cxx-abilist
98        false
99    )
100}
101
102function check-cxx-benchmarks() {
103    echo "--- Running the benchmarks"
104    ninja -C "${BUILD_DIR}" check-cxx-benchmarks
105}
106
107case "${BUILDER}" in
108generic-cxx03)
109    export CC=clang
110    export CXX=clang++
111    clean
112    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx03.cmake"
113    check-cxx-cxxabi
114    check-abi-list
115;;
116generic-cxx11)
117    export CC=clang
118    export CXX=clang++
119    clean
120    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx11.cmake"
121    check-cxx-cxxabi
122    check-abi-list
123;;
124generic-cxx14)
125    export CC=clang
126    export CXX=clang++
127    clean
128    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx14.cmake"
129    check-cxx-cxxabi
130    check-abi-list
131;;
132generic-cxx17)
133    export CC=clang
134    export CXX=clang++
135    clean
136    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx17.cmake"
137    check-cxx-cxxabi
138    check-abi-list
139;;
140generic-cxx2a)
141    export CC=clang
142    export CXX=clang++
143    clean
144    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx2a.cmake"
145    check-cxx-cxxabi
146    check-abi-list
147;;
148generic-noexceptions)
149    export CC=clang
150    export CXX=clang++
151    clean
152    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-noexceptions.cmake"
153    check-cxx-cxxabi
154;;
155generic-32bit)
156    export CC=clang
157    export CXX=clang++
158    clean
159    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-32bits.cmake"
160    check-cxx-cxxabi
161;;
162generic-gcc)
163    export CC=gcc
164    export CXX=g++
165    clean
166    # FIXME: Re-enable experimental testing on GCC. GCC cares about the order
167    #        in which we link -lc++experimental, which causes issues.
168    generate-cmake -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF
169    check-cxx-cxxabi
170;;
171generic-asan)
172    export CC=clang
173    export CXX=clang++
174    clean
175    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-asan.cmake"
176    check-cxx-cxxabi
177;;
178generic-msan)
179    export CC=clang
180    export CXX=clang++
181    clean
182    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-msan.cmake"
183    check-cxx-cxxabi
184;;
185generic-tsan)
186    export CC=clang
187    export CXX=clang++
188    clean
189    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-tsan.cmake"
190    check-cxx-cxxabi
191;;
192generic-ubsan)
193    export CC=clang
194    export CXX=clang++
195    clean
196    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-ubsan.cmake"
197    check-cxx-cxxabi
198;;
199generic-with_llvm_unwinder)
200    export CC=clang
201    export CXX=clang++
202    clean
203    generate-cmake -DLIBCXXABI_USE_LLVM_UNWINDER=ON
204    check-cxx-cxxabi
205;;
206generic-singlethreaded)
207    export CC=clang
208    export CXX=clang++
209    clean
210    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-singlethreaded.cmake"
211    check-cxx-cxxabi
212;;
213generic-nodebug)
214    export CC=clang
215    export CXX=clang++
216    clean
217    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-nodebug.cmake"
218    check-cxx-cxxabi
219;;
220generic-no-random_device)
221    export CC=clang
222    export CXX=clang++
223    clean
224    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-random_device.cmake"
225    check-cxx-cxxabi
226;;
227generic-no-localization)
228    export CC=clang
229    export CXX=clang++
230    clean
231    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake"
232    check-cxx-cxxabi
233;;
234x86_64-apple-system)
235    export CC=clang
236    export CXX=clang++
237    clean
238    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake"
239    check-cxx-cxxabi
240;;
241x86_64-apple-system-noexceptions)
242    export CC=clang
243    export CXX=clang++
244    clean
245    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
246                   -DLIBCXX_ENABLE_EXCEPTIONS=OFF \
247                   -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
248    check-cxx-cxxabi
249;;
250x86_64-apple-system-backdeployment-*)
251    clean
252
253    if [[ "${OSX_ROOTS}" == "" ]]; then
254        echo "--- Downloading previous macOS dylibs"
255        PREVIOUS_DYLIBS_URL="http://lab.llvm.org:8080/roots/libcxx-roots.tar.gz"
256        OSX_ROOTS="${BUILD_DIR}/macos-roots"
257        mkdir -p "${OSX_ROOTS}"
258        curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${OSX_ROOTS}"
259    fi
260
261    DEPLOYMENT_TARGET="${BUILDER#x86_64-apple-system-backdeployment-}"
262    PARAMS="target_triple=x86_64-apple-macosx${DEPLOYMENT_TARGET}"
263    PARAMS+=";cxx_runtime_root=${OSX_ROOTS}/macOS/libc++/${DEPLOYMENT_TARGET}"
264    PARAMS+=";abi_library_path=${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}"
265    PARAMS+=";use_system_cxx_lib=True"
266    # Filesystem is supported on Apple platforms starting with macosx10.15.
267    if [[ ${DEPLOYMENT_TARGET} =~ ^10.9|10.10|10.11|10.12|10.13|10.14$ ]]; then
268        PARAMS+=";enable_filesystem=False"
269    fi
270
271    export CC=clang
272    export CXX=clang++
273    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
274                   -DLIBCXX_TEST_PARAMS="${PARAMS}" \
275                   -DLIBCXXABI_TEST_PARAMS="${PARAMS}"
276
277    # TODO: Also run the libc++abi tests
278    echo "+++ Running the libc++ tests"
279    ninja -C "${BUILD_DIR}" check-cxx
280;;
281benchmarks)
282    export CC=clang
283    export CXX=clang++
284    clean
285    generate-cmake
286    check-cxx-benchmarks
287;;
288documentation)
289    export CC=clang
290    export CXX=clang++
291    clean
292    generate-cmake -DLLVM_ENABLE_SPHINX=ON
293
294    echo "+++ Generating documentation"
295    ninja -C "${BUILD_DIR}" docs-libcxx-html
296;;
297unified-standalone)
298    export CC=clang
299    export CXX=clang++
300
301    clean
302
303    echo "--- Generating CMake"
304    cmake -S "${MONOREPO_ROOT}/libcxx/utils/ci/runtimes" \
305          -B "${BUILD_DIR}" \
306          -GNinja \
307          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
308          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
309          -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;libunwind"
310
311    check-cxx-cxxabi
312;;
313legacy-standalone)
314    export CC=clang
315    export CXX=clang++
316
317    clean
318
319    echo "--- Generating CMake"
320    cmake -S "${MONOREPO_ROOT}/libcxx" \
321          -B "${BUILD_DIR}/libcxx" \
322          -GNinja \
323          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
324          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
325          -DLLVM_PATH="${MONOREPO_ROOT}/llvm" \
326          -DLIBCXX_CXX_ABI=libcxxabi \
327          -DLIBCXX_CXX_ABI_INCLUDE_PATHS="${MONOREPO_ROOT}/libcxxabi/include" \
328          -DLIBCXX_CXX_ABI_LIBRARY_PATH="${BUILD_DIR}/libcxxabi/lib"
329
330    cmake -S "${MONOREPO_ROOT}/libcxxabi" \
331          -B "${BUILD_DIR}/libcxxabi" \
332          -GNinja \
333          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
334          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
335          -DLLVM_PATH="${MONOREPO_ROOT}/llvm" \
336          -DLIBCXXABI_LIBCXX_PATH="${MONOREPO_ROOT}/libcxx" \
337          -DLIBCXXABI_LIBCXX_INCLUDES="${MONOREPO_ROOT}/libcxx/include" \
338          -DLIBCXXABI_LIBCXX_LIBRARY_PATH="${BUILD_DIR}/libcxx/lib"
339
340    echo "+++ Building libc++abi"
341    ninja -C "${BUILD_DIR}/libcxxabi" cxxabi
342
343    echo "+++ Building libc++"
344    ninja -C "${BUILD_DIR}/libcxx" cxx
345
346    echo "+++ Running the libc++ tests"
347    ninja -C "${BUILD_DIR}/libcxx" check-cxx
348
349    echo "+++ Running the libc++abi tests"
350    ninja -C "${BUILD_DIR}/libcxxabi" check-cxxabi
351;;
352*)
353    echo "${BUILDER} is not a known configuration"
354    exit 1
355;;
356esac
357