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    generate-cmake
168
169    # Reject patches that forgot to re-run the generator scripts.
170    echo "+++ Making sure the generator scripts were run"
171    ${NINJA} -vC "${BUILD_DIR}" libcxx-generate-files
172    git diff | tee ${BUILD_DIR}/generated_output.patch
173    git ls-files -o --exclude-standard | tee ${BUILD_DIR}/generated_output.status
174    ! grep -q '^--- a' ${BUILD_DIR}/generated_output.patch || false
175    if [ -s ${BUILD_DIR}/generated_output.status ]; then
176        echo "It looks like not all the generator scripts were run,"
177        echo "did you forget to build the libcxx-generate-files target?"
178        echo "Did you add all new files it generated?"
179        false
180    fi
181
182    # Reject patches that introduce non-ASCII characters or hard tabs.
183    # Depends on LC_COLLATE set at the top of this script.
184    ! grep -rn '[^ -~]' libcxx/include/ || false
185
186    # Reject patches that introduce dependency cycles in the headers.
187    python3 libcxx/utils/graph_header_deps.py >/dev/null
188;;
189generic-cxx03)
190    clean
191    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx03.cmake" \
192                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
193    check-cxx-cxxabi
194    check-abi-list
195;;
196generic-cxx11)
197    clean
198    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx11.cmake" \
199                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
200    check-cxx-cxxabi
201    check-abi-list
202;;
203generic-cxx14)
204    clean
205    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx14.cmake" \
206                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
207    check-cxx-cxxabi
208    check-abi-list
209;;
210generic-cxx17)
211    clean
212    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx17.cmake" \
213                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
214    check-cxx-cxxabi
215    check-abi-list
216;;
217generic-cxx20)
218    clean
219    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx20.cmake" \
220                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
221    check-cxx-cxxabi
222    check-abi-list
223;;
224generic-cxx2b)
225    clean
226    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx2b.cmake" \
227                   -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/libcxx-trunk-shared.cfg.in"
228    check-cxx-cxxabi
229    check-abi-list
230;;
231generic-assertions)
232    clean
233    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-assertions.cmake"
234    check-cxx-cxxabi
235    check-abi-list
236;;
237generic-debug-iterators)
238    clean
239    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-debug-iterators.cmake"
240    check-cxx-cxxabi
241    check-abi-list
242;;
243generic-noexceptions)
244    clean
245    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-noexceptions.cmake"
246    check-cxx-cxxabi
247;;
248generic-modules)
249    clean
250    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-modules.cmake"
251    check-cxx-cxxabi
252;;
253generic-static)
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    clean
261    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-32bits.cmake"
262    check-cxx-cxxabi
263;;
264generic-clang-11)
265    export CC=clang-11
266    export CXX=clang++-11
267    clean
268    generate-cmake
269    check-cxx-cxxabi
270;;
271generic-clang-12)
272    export CC=clang-12
273    export CXX=clang++-12
274    clean
275    generate-cmake
276    check-cxx-cxxabi
277;;
278generic-gcc)
279    export CC=gcc-11
280    export CXX=g++-11
281    clean
282    generate-cmake
283    check-cxx-cxxabi
284;;
285generic-gcc-cxx11)
286    export CC=gcc-11
287    export CXX=g++-11
288    clean
289    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx11.cmake"
290    check-cxx-cxxabi
291;;
292generic-asan)
293    clean
294    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-asan.cmake"
295    check-cxx-cxxabi
296;;
297generic-msan)
298    clean
299    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-msan.cmake"
300    check-cxx-cxxabi
301;;
302generic-tsan)
303    clean
304    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-tsan.cmake"
305    check-cxx-cxxabi
306;;
307generic-ubsan)
308    clean
309    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-ubsan.cmake"
310    check-cxx-cxxabi
311;;
312generic-with_llvm_unwinder)
313    clean
314    generate-cmake -DLIBCXXABI_USE_LLVM_UNWINDER=ON
315    check-cxx-cxxabi
316;;
317generic-singlethreaded)
318    clean
319    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-singlethreaded.cmake"
320    check-cxx-cxxabi
321;;
322generic-no-debug)
323    clean
324    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-debug.cmake"
325    check-cxx-cxxabi
326;;
327generic-no-filesystem)
328    clean
329    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-filesystem.cmake"
330    check-cxx-cxxabi
331;;
332generic-no-random_device)
333    clean
334    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-random_device.cmake"
335    check-cxx-cxxabi
336;;
337generic-no-localization)
338    clean
339    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake"
340    check-cxx-cxxabi
341;;
342x86_64-apple-system)
343    clean
344    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake"
345    check-cxx-cxxabi
346;;
347x86_64-apple-system-noexceptions)
348    clean
349    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
350                   -DLIBCXX_ENABLE_EXCEPTIONS=OFF \
351                   -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
352    check-cxx-cxxabi
353;;
354x86_64-apple-system-backdeployment-*)
355    clean
356
357    if [[ "${OSX_ROOTS}" == "" ]]; then
358        echo "--- Downloading previous macOS dylibs"
359        PREVIOUS_DYLIBS_URL="https://dl.dropboxusercontent.com/s/liu4fmc53qzlfly/libcxx-roots.tar.gz"
360        OSX_ROOTS="${BUILD_DIR}/macos-roots"
361        mkdir -p "${OSX_ROOTS}"
362        curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${OSX_ROOTS}"
363    fi
364
365    DEPLOYMENT_TARGET="${BUILDER#x86_64-apple-system-backdeployment-}"
366
367    # TODO: On Apple platforms, we never produce libc++abi.1.dylib, always libc++abi.dylib.
368    #       Fix that in the build so that the tests stop searching for @rpath/libc++abi.1.dylib.
369    cp "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.dylib" \
370       "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.1.dylib"
371
372    PARAMS="target_triple=x86_64-apple-macosx${DEPLOYMENT_TARGET}"
373    PARAMS+=";cxx_runtime_root=${OSX_ROOTS}/macOS/libc++/${DEPLOYMENT_TARGET}"
374    PARAMS+=";abi_runtime_root=${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}"
375    PARAMS+=";use_system_cxx_lib=True"
376
377    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
378                   -DLIBCXX_TEST_PARAMS="${PARAMS}" \
379                   -DLIBCXXABI_TEST_PARAMS="${PARAMS}"
380
381    check-cxx-cxxabi
382;;
383benchmarks)
384    clean
385    generate-cmake
386    check-cxx-benchmarks
387;;
388documentation)
389    clean
390    generate-cmake -DLLVM_ENABLE_SPHINX=ON
391
392    echo "+++ Generating documentation"
393    ${NINJA} -vC "${BUILD_DIR}" docs-libcxx-html
394;;
395unified-standalone)
396
397    clean
398
399    echo "--- Generating CMake"
400    ${CMAKE} \
401          -S "${MONOREPO_ROOT}/libcxx/utils/ci/runtimes" \
402          -B "${BUILD_DIR}" \
403          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
404          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
405          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
406          -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;libunwind"
407
408    check-cxx-cxxabi
409;;
410runtimes-build)
411    clean
412
413    echo "--- Generating CMake"
414    # TODO: We currently enable modules and assertions in the runtimes build
415    #       because that provides coverage for some specific Clang failures
416    #       we've been seeing recently, however it would be better to instead
417    #       run all CI configurations against a Clang that has assertions enabled.
418    ${CMAKE} \
419          -S "${MONOREPO_ROOT}/llvm" \
420          -B "${BUILD_DIR}" \
421          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
422          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
423          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
424          -DLLVM_ENABLE_PROJECTS="clang" \
425          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
426          -DLLVM_RUNTIME_TARGETS="x86_64-unknown-linux-gnu" \
427          -DLLVM_ENABLE_ASSERTIONS=ON \
428          -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-modules.cmake"
429
430    echo "+++ Running the libc++ and libc++abi tests"
431    ${NINJA} -C "${BUILD_DIR}" check-runtimes
432
433    echo "--- Installing libc++ and libc++abi to a fake location"
434    ${NINJA} -C "${BUILD_DIR}" install-runtimes
435;;
436legacy-test-config)
437    clean
438    generate-cmake -DLIBCXX_TEST_CONFIG="${MONOREPO_ROOT}/libcxx/test/configs/legacy.cfg.in"
439    check-cxx-cxxabi
440;;
441legacy-standalone)
442    clean
443
444    echo "--- Generating CMake"
445    ${CMAKE} \
446          -S "${MONOREPO_ROOT}/libcxx" \
447          -B "${BUILD_DIR}/libcxx" \
448          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
449          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
450          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
451          -DLLVM_PATH="${MONOREPO_ROOT}/llvm" \
452          -DLIBCXX_CXX_ABI=libcxxabi \
453          -DLIBCXX_CXX_ABI_INCLUDE_PATHS="${MONOREPO_ROOT}/libcxxabi/include" \
454          -DLIBCXX_CXX_ABI_LIBRARY_PATH="${BUILD_DIR}/libcxxabi/lib"
455
456    ${CMAKE} \
457          -S "${MONOREPO_ROOT}/libcxxabi" \
458          -B "${BUILD_DIR}/libcxxabi" \
459          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
460          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
461          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
462          -DLLVM_PATH="${MONOREPO_ROOT}/llvm" \
463          -DLIBCXXABI_LIBCXX_PATH="${MONOREPO_ROOT}/libcxx" \
464          -DLIBCXXABI_LIBCXX_INCLUDES="${BUILD_DIR}/libcxx/include/c++/v1" \
465          -DLIBCXXABI_LIBCXX_LIBRARY_PATH="${BUILD_DIR}/libcxx/lib"
466
467    echo "+++ Generating libc++ headers"
468    ${NINJA} -vC "${BUILD_DIR}/libcxx" generate-cxx-headers
469
470    echo "+++ Building libc++abi"
471    ${NINJA} -vC "${BUILD_DIR}/libcxxabi" cxxabi
472
473    echo "+++ Building libc++"
474    ${NINJA} -vC "${BUILD_DIR}/libcxx" cxx
475
476    echo "+++ Running the libc++ tests"
477    ${NINJA} -vC "${BUILD_DIR}/libcxx" check-cxx
478
479    echo "+++ Running the libc++abi tests"
480    ${NINJA} -vC "${BUILD_DIR}/libcxxabi" check-cxxabi
481;;
482aarch64)
483    export CC=/usr/local/bin/cc
484    export CXX=/usr/local/bin/c++
485    clean
486    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AArch64.cmake"
487    check-cxx-cxxabi
488;;
489aarch64-noexceptions)
490    export CC=/usr/local/bin/cc
491    export CXX=/usr/local/bin/c++
492    clean
493    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AArch64.cmake" \
494                   -DLIBCXX_ENABLE_EXCEPTIONS=OFF \
495                   -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
496    check-cxx-cxxabi
497;;
498# Aka Armv8 32 bit
499armv8)
500    export CC=/usr/local/bin/cc
501    export CXX=/usr/local/bin/c++
502    clean
503    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv8Arm.cmake"
504    check-cxx-cxxabi
505;;
506armv8-noexceptions)
507    export CC=/usr/local/bin/cc
508    export CXX=/usr/local/bin/c++
509    clean
510    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv8Thumb-noexceptions.cmake"
511    check-cxx-cxxabi
512;;
513# Armv7 32 bit. One building Arm only one Thumb only code.
514armv7)
515    export CC=/usr/local/bin/cc
516    export CXX=/usr/local/bin/c++
517    clean
518    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7Arm.cmake"
519    check-cxx-cxxabi
520;;
521armv7-noexceptions)
522    export CC=/usr/local/bin/cc
523    export CXX=/usr/local/bin/c++
524    clean
525    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7Thumb-noexceptions.cmake"
526    check-cxx-cxxabi
527;;
528windows-dll)
529    clean
530    # TODO: Currently, building with the experimental library breaks running
531    # tests (the test linking look for the c++experimental library with the
532    # wrong name, and the statically linked c++experimental can't be linked
533    # correctly when libc++ visibility attributes indicate dllimport linkage
534    # anyway), thus just disable the experimental library. Remove this
535    # setting when cmake and the test driver does the right thing automatically.
536    generate-cmake-libcxx-win -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF
537    echo "+++ Running the libc++ tests"
538    ${NINJA} -vC "${BUILD_DIR}" check-cxx
539;;
540windows-static)
541    clean
542    generate-cmake-libcxx-win -DLIBCXX_ENABLE_SHARED=OFF
543    echo "+++ Running the libc++ tests"
544    ${NINJA} -vC "${BUILD_DIR}" check-cxx
545;;
546#################################################################
547# Insert vendor-specific internal configurations below.
548#
549# This allows vendors to extend this file with their own internal
550# configurations without running into merge conflicts with upstream.
551#################################################################
552
553#################################################################
554*)
555    echo "${BUILDER} is not a known configuration"
556    exit 1
557;;
558esac
559