xref: /netbsd-src/external/apache2/llvm/dist/libcxx/utils/ci/run-buildbot (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
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
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
31--osx-roots <DIR>   Path to pre-downloaded macOS dylibs. By default, we download
32                    them from Green Dragon. This is only relevant at all when
33                    running back-deployment testing if one wants to override
34                    the old dylibs we use to run the tests with different ones.
35EOF
36}
37
38while [[ $# -gt 0 ]]; do
39    case ${1} in
40        -h|--help)
41            usage
42            exit 0
43            ;;
44        --llvm-root)
45            MONOREPO_ROOT="${2}"
46            shift; shift
47            ;;
48        --build-dir)
49            BUILD_DIR="${2}"
50            shift; shift
51            ;;
52        --osx-roots)
53            OSX_ROOTS="${2}"
54            shift; shift
55            ;;
56        *)
57            BUILDER="${1}"
58            shift
59            ;;
60    esac
61done
62
63MONOREPO_ROOT="${MONOREPO_ROOT:="$(git rev-parse --show-toplevel)"}"
64BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build/${BUILDER}}"
65INSTALL_DIR="${BUILD_DIR}/install"
66
67# If we can find Ninja/CMake provided by Xcode, use those since we know their
68# version will generally work with the Clang shipped in Xcode (e.g. if Clang
69# knows about -std=c++20, the CMake bundled in Xcode will probably know about
70# that flag too).
71if xcrun --find ninja &>/dev/null; then NINJA="$(xcrun --find ninja)"; else NINJA="ninja"; fi
72if xcrun --find cmake &>/dev/null; then CMAKE="$(xcrun --find cmake)"; else CMAKE="cmake"; fi
73
74function clean() {
75    rm -rf "${BUILD_DIR}"
76}
77
78function generate-cmake-base() {
79    echo "--- Generating CMake"
80    ${CMAKE} \
81          -B "${BUILD_DIR}" \
82          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
83          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
84          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
85          -DLLVM_LIT_ARGS="-sv --show-unsupported --xunit-xml-output test-results.xml" \
86          "${@}"
87}
88
89function generate-cmake() {
90    generate-cmake-base \
91          -S "${MONOREPO_ROOT}/llvm" \
92          -DLLVM_ENABLE_PROJECTS="libcxx;libunwind;libcxxabi" \
93          -DLIBCXX_CXX_ABI=libcxxabi \
94          "${@}"
95}
96
97function generate-cmake-libcxx-win() {
98    # TODO: Clang-cl in MSVC configurations don't have access to compiler_rt
99    # builtins helpers for int128 division. See
100    # https://reviews.llvm.org/D91139#2429595 for a comment about longterm
101    # intent for handling the issue. In the meantime, define
102    # -D_LIBCPP_HAS_NO_INT128 (both when building the library itself and
103    # when building tests) to allow enabling filesystem for running tests,
104    # even if it uses a non-permanent ABI.
105
106    generate-cmake-base \
107          -S "${MONOREPO_ROOT}/libcxx" \
108          -DCMAKE_C_COMPILER=clang-cl \
109          -DCMAKE_CXX_COMPILER=clang-cl \
110          -DLIBCXX_ENABLE_FILESYSTEM=YES \
111          -DCMAKE_CXX_FLAGS="-D_LIBCPP_HAS_NO_INT128" \
112          -DLIBCXX_TEST_COMPILER_FLAGS="-D_LIBCPP_HAS_NO_INT128" \
113          "${@}"
114}
115
116function check-cxx-cxxabi() {
117    echo "--- Installing libc++ and libc++abi to a fake location"
118    ${NINJA} -vC "${BUILD_DIR}" install-cxx install-cxxabi
119
120    echo "+++ Running the libc++ tests"
121    ${NINJA} -vC "${BUILD_DIR}" check-cxx
122
123    echo "+++ Running the libc++abi tests"
124    ${NINJA} -vC "${BUILD_DIR}" check-cxxabi
125}
126
127# TODO: The goal is to test this against all configurations. We should also move
128#       this to the Lit test suite instead of being a separate CMake target.
129function check-abi-list() {
130    echo "+++ Running the libc++ ABI list test"
131    ${NINJA} -vC "${BUILD_DIR}" check-cxx-abilist || (
132        echo "+++ Generating the libc++ ABI list after failed check"
133        ${NINJA} -vC "${BUILD_DIR}" generate-cxx-abilist
134        false
135    )
136}
137
138function check-cxx-benchmarks() {
139    echo "--- Running the benchmarks"
140    ${NINJA} -vC "${BUILD_DIR}" check-cxx-benchmarks
141}
142
143# Print the version of a few tools to aid diagnostics in some cases
144${CMAKE} --version
145${NINJA} --version
146
147case "${BUILDER}" in
148check-format)
149    clean
150    echo "+++ Checking formatting"
151    # We need to set --extensions so that clang-format checks extensionless files.
152    mkdir -p ${BUILD_DIR}
153    git-clang-format \
154        --binary /usr/bin/clang-format --diff \
155        --extensions ',h,hh,hpp,hxx,c,cc,cxx,cpp' HEAD~1 \
156        -- \
157            libcxx/{benchmarks,include,src,test} \
158            libcxxabi/{fuzz,include,src,test} \
159        | tee ${BUILD_DIR}/clang-format.patch
160    # Check if the diff is empty, fail otherwise.
161    ! grep -q '^--- a' ${BUILD_DIR}/clang-format.patch
162;;
163check-generated-output)
164    # `! foo` doesn't work properly with `set -e`, use `! foo || false` instead.
165    # https://stackoverflow.com/questions/57681955/set-e-does-not-respect-logical-not
166    clean
167    echo "+++ Checking the output of the generator scripts"
168    mkdir -p ${BUILD_DIR}
169    # Reject patches that don't update the generated output correctly.
170    python3 libcxx/utils/generate_feature_test_macro_components.py
171    python3 libcxx/utils/generate_header_inclusion_tests.py
172    python3 libcxx/utils/generate_header_tests.py
173    git diff | tee ${BUILD_DIR}/generated_output.patch
174    # Check if the diffs are empty, fail otherwise.
175    ! grep -q '^--- a' ${BUILD_DIR}/generated_output.patch || false
176    # Reject patches that introduce non-ASCII characters or hard tabs.
177    # Depends on LC_COLLATE set at the top of this script.
178    ! grep -rn '[^ -~]' libcxx/include/ || false
179    # Check that no dependency cycles have been introduced.
180    python3 libcxx/utils/graph_header_deps.py >/dev/null
181;;
182generic-cxx03)
183    export CC=clang
184    export CXX=clang++
185    clean
186    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx03.cmake" \
187                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
188    check-cxx-cxxabi
189    check-abi-list
190;;
191generic-cxx11)
192    export CC=clang
193    export CXX=clang++
194    clean
195    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx11.cmake" \
196                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
197    check-cxx-cxxabi
198    check-abi-list
199;;
200generic-cxx14)
201    export CC=clang
202    export CXX=clang++
203    clean
204    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx14.cmake" \
205                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
206    check-cxx-cxxabi
207    check-abi-list
208;;
209generic-cxx17)
210    export CC=clang
211    export CXX=clang++
212    clean
213    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx17.cmake" \
214                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
215    check-cxx-cxxabi
216    check-abi-list
217;;
218generic-cxx20)
219    export CC=clang
220    export CXX=clang++
221    clean
222    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx20.cmake" \
223                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
224    check-cxx-cxxabi
225    check-abi-list
226;;
227generic-cxx2b)
228    export CC=clang-tot
229    export CXX=clang++-tot
230    clean
231    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx2b.cmake" \
232                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
233    check-cxx-cxxabi
234    check-abi-list
235;;
236generic-debug-iterators)
237    export CC=clang-tot
238    export CXX=clang++-tot
239    clean
240    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-debug-iterators.cmake"
241    check-cxx-cxxabi
242    check-abi-list
243;;
244generic-noexceptions)
245    export CC=clang
246    export CXX=clang++
247    clean
248    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-noexceptions.cmake"
249    check-cxx-cxxabi
250;;
251generic-static)
252    export CC=clang
253    export CXX=clang++
254    clean
255    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-static.cmake" \
256                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-static.cfg.in"
257    check-cxx-cxxabi
258;;
259generic-32bit)
260    export CC=clang
261    export CXX=clang++
262    clean
263    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-32bits.cmake"
264    check-cxx-cxxabi
265;;
266generic-gcc)
267    export CC=gcc
268    export CXX=g++
269    clean
270    generate-cmake
271    check-cxx-cxxabi
272;;
273generic-asan)
274    export CC=clang
275    export CXX=clang++
276    clean
277    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-asan.cmake"
278    check-cxx-cxxabi
279;;
280generic-msan)
281    export CC=clang
282    export CXX=clang++
283    clean
284    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-msan.cmake"
285    check-cxx-cxxabi
286;;
287generic-tsan)
288    export CC=clang
289    export CXX=clang++
290    clean
291    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-tsan.cmake"
292    check-cxx-cxxabi
293;;
294generic-ubsan)
295    export CC=clang
296    export CXX=clang++
297    clean
298    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-ubsan.cmake"
299    check-cxx-cxxabi
300;;
301generic-with_llvm_unwinder)
302    export CC=clang
303    export CXX=clang++
304    clean
305    generate-cmake -DLIBCXXABI_USE_LLVM_UNWINDER=ON
306    check-cxx-cxxabi
307;;
308generic-singlethreaded)
309    export CC=clang
310    export CXX=clang++
311    clean
312    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-singlethreaded.cmake"
313    check-cxx-cxxabi
314;;
315generic-no-debug)
316    export CC=clang
317    export CXX=clang++
318    clean
319    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-debug.cmake"
320    check-cxx-cxxabi
321;;
322generic-no-filesystem)
323    export CC=clang
324    export CXX=clang++
325    clean
326    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-filesystem.cmake"
327    check-cxx-cxxabi
328;;
329generic-no-random_device)
330    export CC=clang
331    export CXX=clang++
332    clean
333    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-random_device.cmake"
334    check-cxx-cxxabi
335;;
336generic-no-localization)
337    export CC=clang
338    export CXX=clang++
339    clean
340    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake"
341    check-cxx-cxxabi
342;;
343x86_64-apple-system)
344    export CC=clang
345    export CXX=clang++
346    clean
347    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake"
348    check-cxx-cxxabi
349;;
350x86_64-apple-system-noexceptions)
351    export CC=clang
352    export CXX=clang++
353    clean
354    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
355                   -DLIBCXX_ENABLE_EXCEPTIONS=OFF \
356                   -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
357    check-cxx-cxxabi
358;;
359x86_64-apple-system-backdeployment-*)
360    clean
361
362    if [[ "${OSX_ROOTS}" == "" ]]; then
363        echo "--- Downloading previous macOS dylibs"
364        PREVIOUS_DYLIBS_URL="https://dl.dropboxusercontent.com/s/liu4fmc53qzlfly/libcxx-roots.tar.gz"
365        OSX_ROOTS="${BUILD_DIR}/macos-roots"
366        mkdir -p "${OSX_ROOTS}"
367        curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${OSX_ROOTS}"
368    fi
369
370    DEPLOYMENT_TARGET="${BUILDER#x86_64-apple-system-backdeployment-}"
371
372    # TODO: On Apple platforms, we never produce libc++abi.1.dylib, always libc++abi.dylib.
373    #       Fix that in the build so that the tests stop searching for @rpath/libc++abi.1.dylib.
374    cp "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.dylib" \
375       "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.1.dylib"
376
377    PARAMS="target_triple=x86_64-apple-macosx${DEPLOYMENT_TARGET}"
378    PARAMS+=";cxx_runtime_root=${OSX_ROOTS}/macOS/libc++/${DEPLOYMENT_TARGET}"
379    PARAMS+=";abi_runtime_root=${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}"
380    PARAMS+=";use_system_cxx_lib=True"
381
382    export CC=clang
383    export CXX=clang++
384    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
385                   -DLIBCXX_TEST_PARAMS="${PARAMS}" \
386                   -DLIBCXXABI_TEST_PARAMS="${PARAMS}"
387
388    check-cxx-cxxabi
389;;
390benchmarks)
391    export CC=clang
392    export CXX=clang++
393    clean
394    generate-cmake
395    check-cxx-benchmarks
396;;
397documentation)
398    export CC=clang
399    export CXX=clang++
400    clean
401    generate-cmake -DLLVM_ENABLE_SPHINX=ON
402
403    echo "+++ Generating documentation"
404    ${NINJA} -vC "${BUILD_DIR}" docs-libcxx-html
405;;
406unified-standalone)
407    export CC=clang
408    export CXX=clang++
409
410    clean
411
412    echo "--- Generating CMake"
413    ${CMAKE} \
414          -S "${MONOREPO_ROOT}/libcxx/utils/ci/runtimes" \
415          -B "${BUILD_DIR}" \
416          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
417          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
418          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
419          -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;libunwind"
420
421    check-cxx-cxxabi
422;;
423runtimes-build)
424    export CC=clang
425    export CXX=clang++
426
427    clean
428
429    echo "--- Generating CMake"
430    ${CMAKE} \
431          -S "${MONOREPO_ROOT}/llvm" \
432          -B "${BUILD_DIR}" \
433          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
434          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
435          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
436          -DLLVM_ENABLE_PROJECTS="clang" \
437          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
438          -DLLVM_RUNTIME_TARGETS="x86_64-unknown-linux-gnu"
439
440    echo "+++ Running the libc++ and libc++abi tests"
441    ${NINJA} -C "${BUILD_DIR}" check-runtimes
442
443    echo "--- Installing libc++ and libc++abi to a fake location"
444    ${NINJA} -C "${BUILD_DIR}" install-cxx install-cxxabi
445;;
446legacy-test-config)
447    export CC=clang
448    export CXX=clang++
449    clean
450    generate-cmake -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/legacy.cfg.in"
451    check-cxx-cxxabi
452;;
453legacy-standalone)
454    export CC=clang
455    export CXX=clang++
456
457    clean
458
459    echo "--- Generating CMake"
460    ${CMAKE} \
461          -S "${MONOREPO_ROOT}/libcxx" \
462          -B "${BUILD_DIR}/libcxx" \
463          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
464          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
465          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
466          -DLLVM_PATH="${MONOREPO_ROOT}/llvm" \
467          -DLIBCXX_CXX_ABI=libcxxabi \
468          -DLIBCXX_CXX_ABI_INCLUDE_PATHS="${MONOREPO_ROOT}/libcxxabi/include" \
469          -DLIBCXX_CXX_ABI_LIBRARY_PATH="${BUILD_DIR}/libcxxabi/lib"
470
471    ${CMAKE} \
472          -S "${MONOREPO_ROOT}/libcxxabi" \
473          -B "${BUILD_DIR}/libcxxabi" \
474          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
475          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
476          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
477          -DLLVM_PATH="${MONOREPO_ROOT}/llvm" \
478          -DLIBCXXABI_LIBCXX_PATH="${MONOREPO_ROOT}/libcxx" \
479          -DLIBCXXABI_LIBCXX_INCLUDES="${BUILD_DIR}/libcxx/include/c++/v1" \
480          -DLIBCXXABI_LIBCXX_LIBRARY_PATH="${BUILD_DIR}/libcxx/lib"
481
482    echo "+++ Generating libc++ headers"
483    ${NINJA} -vC "${BUILD_DIR}/libcxx" generate-cxx-headers
484
485    echo "+++ Building libc++abi"
486    ${NINJA} -vC "${BUILD_DIR}/libcxxabi" cxxabi
487
488    echo "+++ Building libc++"
489    ${NINJA} -vC "${BUILD_DIR}/libcxx" cxx
490
491    echo "+++ Running the libc++ tests"
492    ${NINJA} -vC "${BUILD_DIR}/libcxx" check-cxx
493
494    echo "+++ Running the libc++abi tests"
495    ${NINJA} -vC "${BUILD_DIR}/libcxxabi" check-cxxabi
496;;
497aarch64)
498    clean
499    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AArch64.cmake"
500    check-cxx-cxxabi
501;;
502aarch64-noexceptions)
503    clean
504    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AArch64.cmake" \
505    -DLIBCXX_ENABLE_EXCEPTIONS=OFF \
506    -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
507    check-cxx-cxxabi
508;;
509# Aka Armv8 32 bit
510armv8)
511    clean
512    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv8Arm.cmake"
513    check-cxx-cxxabi
514;;
515armv8-noexceptions)
516    clean
517    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv8Thumb-noexceptions.cmake"
518    check-cxx-cxxabi
519;;
520# Armv7 32 bit. One building Arm only one Thumb only code.
521armv7)
522    clean
523    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7Arm.cmake"
524    check-cxx-cxxabi
525;;
526armv7-noexceptions)
527    clean
528    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7Thumb-noexceptions.cmake"
529    check-cxx-cxxabi
530;;
531windows-dll)
532    clean
533    # TODO: Currently, building with the experimental library breaks running
534    # tests (the test linking look for the c++experimental library with the
535    # wrong name, and the statically linked c++experimental can't be linked
536    # correctly when libc++ visibility attributes indicate dllimport linkage
537    # anyway), thus just disable the experimental library. Remove this
538    # setting when cmake and the test driver does the right thing automatically.
539    generate-cmake-libcxx-win -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF
540    echo "+++ Running the libc++ tests"
541    ${NINJA} -vC "${BUILD_DIR}" check-cxx
542;;
543windows-static)
544    clean
545    generate-cmake-libcxx-win -DLIBCXX_ENABLE_SHARED=OFF
546    echo "+++ Running the libc++ tests"
547    ${NINJA} -vC "${BUILD_DIR}" check-cxx
548;;
549*)
550    echo "${BUILDER} is not a known configuration"
551    exit 1
552;;
553esac
554