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