1#!/usr/bin/env sh 2# shellcheck disable=SC2030,SC2031,SC2059 3# The above line must be directly after the shebang line. 4# Disables these warnings: 5# 2030 - Modification of var is local (to subshell caused by pipeline). 6# shell check 0.4.6 gets confused by the read -t 1 command and interprets 7# the '1' as $1 getting modified. 8# 2031 - var was modified in a subshell. That change might be lost. 9# caused by shell check bug with SC2030? This causes any $1 from that 10# point on to be flagged. 11# 2059 - Don't use variables in the printf format string. Use printf "..%s.." "$foo". 12# This is used for all of our color printing. 13 14# 15# SPDX-License-Identifier: GPL-2.0-only 16 17cd "$(dirname "$0")" || exit 1 18 19if [ -z "$CROSSGCC_VERSION" ]; then 20 CROSSGCC_VERSION="$(git log -n 1 --pretty=%cd --date=short .)_$(git log -n 1 --pretty=%h .)" 21fi 22 23# default settings 24PACKAGE=GCC 25TARGETDIR=$(pwd)/xgcc 26TARGETARCH=i386-elf 27DEFAULT_LANGUAGES=c 28LANGUAGES= 29DESTDIR= 30SAVETEMPS=0 31BOOTSTRAP=0 32THREADS=1 33FETCH_ONLY=0 34USE_COREBOOT_MIRROR=0 35COREBOOT_MIRROR_URL="https://www.coreboot.org/releases/crossgcc-sources" 36 37# GCC toolchain version numbers 38GMP_VERSION=6.3.0 39MPFR_VERSION=4.2.1 40MPC_VERSION=1.3.1 41GCC_VERSION=14.1.0 42BINUTILS_VERSION=2.42 43IASL_VERSION="20230628" 44# CLANG version number 45CLANG_VERSION=18.1.6 46CMAKE_VERSION=3.29.3 47NASM_VERSION=2.16.03 48 49# Filename for each package 50GMP_ARCHIVE="gmp-${GMP_VERSION}.tar.xz" 51MPFR_ARCHIVE="mpfr-${MPFR_VERSION}.tar.xz" 52MPC_ARCHIVE="mpc-${MPC_VERSION}.tar.gz" 53GCC_ARCHIVE="gcc-${GCC_VERSION}.tar.xz" 54BINUTILS_ARCHIVE="binutils-${BINUTILS_VERSION}.tar.xz" 55IASL_ARCHIVE="acpica-unix-${IASL_VERSION}.tar.gz" 56# CLANG toolchain FILE locations 57LLD_ARCHIVE="lld-${CLANG_VERSION}.src.tar.xz" 58LLVM_ARCHIVE="llvm-${CLANG_VERSION}.src.tar.xz" 59CLANG_ARCHIVE="clang-${CLANG_VERSION}.src.tar.xz" 60CRT_ARCHIVE="compiler-rt-${CLANG_VERSION}.src.tar.xz" 61CTE_ARCHIVE="clang-tools-extra-${CLANG_VERSION}.src.tar.xz" 62LLVMCMAKE_ARCHIVE="cmake-${CLANG_VERSION}.src.tar.xz" 63LIBUNWIND_ARCHIVE="libunwind-${CLANG_VERSION}.src.tar.xz" 64CMAKE_ARCHIVE="cmake-${CMAKE_VERSION}.tar.gz" 65NASM_ARCHIVE="nasm-${NASM_VERSION}.tar.bz2" 66 67# These URLs are sanitized by the jenkins toolchain test builder, so if 68# a completely new URL is added here, it probably needs to be added 69# to the jenkins build as well, or the builder won't download it. 70 71# GCC toolchain archive locations 72GMP_BASE_URL="https://ftpmirror.gnu.org/gmp" 73MPFR_BASE_URL="https://ftpmirror.gnu.org/mpfr" 74MPC_BASE_URL="https://ftpmirror.gnu.org/mpc" 75GCC_BASE_URL="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}" 76BINUTILS_BASE_URL="https://ftpmirror.gnu.org/binutils" 77IASL_BASE_URL="https://downloadmirror.intel.com/783534" 78# CLANG toolchain archive locations 79LLVM_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" 80CLANG_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" 81CRT_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" 82CTE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" 83LLVMCMAKE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" 84LLD_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" 85LIBUNWIND_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" 86CMAKE_BASE_URL="https://cmake.org/files/v${CMAKE_VERSION%.*}" 87NASM_BASE_URL="https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}" 88 89ALL_ARCHIVES="$GMP_BASE_URL/$GMP_ARCHIVE $MPFR_BASE_URL/$MPFR_ARCHIVE $MPC_BASE_URL/$MPC_ARCHIVE \ 90 $GCC_BASE_URL/$GCC_ARCHIVE $BINUTILS_BASE_URL/$BINUTILS_ARCHIVE $IASL_BASE_URL/$IASL_ARCHIVE \ 91 $LLD_BASE_URL/$LLD_ARCHIVE $LLVM_BASE_URL/$LLVM_ARCHIVE $CLANG_BASE_URL/$CLANG_ARCHIVE \ 92 $LLVMCMAKE_BASE_URL/$LLVMCMAKE_ARCHIVE $CRT_BASE_URL/$CRT_ARCHIVE $CTE_BASE_URL/$CTE_ARCHIVE \ 93 $LIBUNWIND_BASE_URL/$LIBUNWIND_ARCHIVE $CMAKE_BASE_URL/$CMAKE_ARCHIVE $NASM_BASE_URL/$NASM_ARCHIVE" 94 95# GCC toolchain directories 96GMP_DIR="gmp-${GMP_VERSION}" 97MPFR_DIR="mpfr-${MPFR_VERSION}" 98MPC_DIR="mpc-${MPC_VERSION}" 99# shellcheck disable=SC2034 100GCC_DIR="gcc-${GCC_VERSION}" 101# shellcheck disable=SC2034 102BINUTILS_DIR="binutils-${BINUTILS_VERSION}" 103IASL_DIR="acpica-unix-${IASL_VERSION}" 104# CLANG toolchain directories 105LLD_DIR="lld-${CLANG_VERSION}.src" 106LLVM_DIR="llvm-${CLANG_VERSION}.src" 107CLANG_DIR="clang-${CLANG_VERSION}.src" 108CRT_DIR="compiler-rt-${CLANG_VERSION}.src" 109CTE_DIR="clang-tools-extra-${CLANG_VERSION}.src" 110LLVMCMAKE_DIR="cmake-${CLANG_VERSION}.src" 111LIBUNWIND_DIR="libunwind-${CLANG_VERSION}.src" 112CMAKE_DIR="cmake-${CMAKE_VERSION}" 113NASM_DIR="nasm-${NASM_VERSION}" 114 115unset MAKELEVEL MAKEFLAGS 116 117red='\033[0;31m' 118RED='\033[1;31m' 119green='\033[0;32m' 120GREEN='\033[1;32m' 121blue='\033[0;34m' 122CYAN='\033[1;36m' 123NC='\033[0m' # No Color 124 125UNAME=$(if uname | grep -iq cygwin; then echo Cygwin; else uname; fi) 126HALT_FOR_TOOLS=0 127 128hostcc() 129{ 130 # $1 "host" or "target" 131 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then 132 echo "$DESTDIR$TARGETDIR/bin/gcc" 133 else 134 echo "$CC" 135 fi 136} 137 138hostcxx() 139{ 140 # $1 "host" or "target" 141 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then 142 echo "$DESTDIR$TARGETDIR/bin/g++" 143 else 144 echo "$CXX" 145 fi 146} 147 148normalize_dirs() 149{ 150 mkdir -p "$DESTDIR$TARGETDIR/lib" 151 test -d "$DESTDIR$TARGETDIR/lib32" && mv "$DESTDIR$TARGETDIR"/lib32/* "$DESTDIR$TARGETDIR/lib" 152 test -d "$DESTDIR$TARGETDIR/lib64" && mv "$DESTDIR$TARGETDIR"/lib64/* "$DESTDIR$TARGETDIR/lib" 153 rm -rf "$DESTDIR$TARGETDIR/lib32" "$DESTDIR$TARGETDIR/lib64" 154 155 perl -pi -e "s,/lib32,/lib," "$DESTDIR$TARGETDIR"/lib/*.la 156 perl -pi -e "s,/lib64,/lib," "$DESTDIR$TARGETDIR"/lib/*.la 157} 158 159countdown() 160{ 161 tout=${1:-10} 162 163 printf "\nPress Ctrl-C to abort, Enter to continue... %2ds" "$tout" 164 while [ "$tout" -gt 0 ]; do 165 sleep 1 166 tout=$((tout - 1)) 167 printf "\b\b\b%2ds" $tout 168 done 169 printf "\n" 170} 171 172timeout() 173{ 174 tout=${1:-10} 175 176 # Ignore SIGUSR1, should interrupt `read` though. 177 trap false USR1 178 # Clean up in case the user aborts. 179 trap 'kill $counter > /dev/null 2>&1' EXIT 180 181 (countdown "$tout"; kill -USR1 $$)& 182 counter=$! 183 184 # Some shells with sh compatibility mode (e.g. zsh, mksh) only 185 # let us interrupt `read` if a non-standard -t parameter is given. 186 # shellcheck disable=SC2034,SC2039,SC2162 187 if echo | read -t 1 foo 2>/dev/null; then 188 read -t $((tout + 1)) foo 189 else 190 read foo 191 fi 192 193 kill $counter > /dev/null 2>&1 194 trap - USR1 EXIT 195} 196 197please_install() 198{ 199 HALT_FOR_TOOLS=1 200 # shellcheck disable=SC1091 201 test -r /etc/os-release && . /etc/os-release 202 # vanilla debian doesn't define `ID_LIKE`, just `ID` 203 if [ -z "${ID_LIKE}" ] && [ -n "${ID}" ]; then 204 ID_LIKE=${ID} 205 fi 206 case "$ID_LIKE" in 207 debian) solution="sudo apt-get install $1" ;; 208 suse) solution="sudo zypper install $1" ;; 209 *) solution="using your OS packaging system" ;; 210 esac 211 212 printf "${RED}ERROR:${red} Missing tool: Please install '$1'. (eg $solution)${NC}\n" >&2 213 if [ -n "$2" ]; then 214 printf "${RED}ERROR:${red} or install '$2'.${NC}\n" >&2 215 fi 216} 217 218searchtool() 219{ 220 # $1 short name 221 # $2 search string 222 # $3 soft fail if set 223 # $4 alternative package to install on failure 224 # result: file name of that tool on stdout 225 # or no output if nothing suitable was found 226 search=GNU 227 if [ -n "$2" ]; then 228 search="$2" 229 fi 230 for i in "$1" "g$1" "gnu$1"; do 231 if [ -x "$(command -v "$i" 2>/dev/null)" ]; then 232 if [ "$(cat /dev/null | $i --version 2>&1 | grep -c "$search")" \ 233 -gt 0 ]; then 234 echo "$i" 235 return 236 fi 237 fi 238 done 239 # A workaround for OSX 10.9 and some BSDs, whose nongnu 240 # patch and tar also work. 241 if [ "$UNAME" = "Darwin" ] || [ "$UNAME" = "FreeBSD" ] || [ "$UNAME" = "NetBSD" ] || [ "$UNAME" = "OpenBSD" ]; then 242 if [ "$1" = "patch" ] || [ "$1" = "tar" ]; then 243 if [ -x "$(command -v "$1" 2>/dev/null)" ]; then 244 echo "$1" 245 return 246 fi 247 fi 248 fi 249 if echo "$1" | grep -q "sum" ; then 250 algor=$(echo "$1" | sed -e 's,sum,,') 251 if [ -x "$(command -v "$1" 2>/dev/null)" ]; then 252 #xxxsum [file] 253 echo "$1" 254 return 255 elif [ -x "$(command -v "$algor" 2>/dev/null)" ]; then 256 #xxx [file] 257 echo "$algor" 258 return 259 elif [ -x "$(command -v openssl 2>/dev/null)" ]; then 260 #openssl xxx [file] 261 echo openssl "$algor" 262 return 263 elif [ -x "$(command -v cksum 2>/dev/null)" ]; then 264 #cksum -a xxx [file] 265 #cksum has special options in NetBSD. Actually, NetBSD will use the second case above. 266 echo "buildgcc" | cksum -a "$algor" > /dev/null 2>/dev/null && \ 267 echo cksum -a "$algor" 268 return 269 fi 270 fi 271 272 [ -z "$3" ] && please_install "$1" "$4" 273 false 274} 275 276# Run a compile check of the specified library option to see if it's installed 277check_for_library() { 278 LIBRARY_FLAGS="$1" 279 LIBRARY_PACKAGES="$2" 280 LIBTEST_FILE=.libtest 281 282 echo "int main(int argc, char **argv) { (void) argc; (void) argv; return 0; }" > "${LIBTEST_FILE}.c" 283 284 # shellcheck disable=SC2086 285 "$CC" $CFLAGS $LIBRARY_FLAGS "${LIBTEST_FILE}.c" -o "${LIBTEST_FILE}" >/dev/null 2>&1 || \ 286 please_install "$LIBRARY_PACKAGES" 287 rm -rf "${LIBTEST_FILE}.c" "${LIBTEST_FILE}" 288} 289 290buildcc_major() { 291 echo "${GCC_VERSION}" | cut -d. -f1 292} 293 294buildcc_minor() { 295 echo "${GCC_VERSION}" | cut -d. -f2 296} 297 298buildcc_version() { 299 echo "${GCC_VERSION}" | cut -d. -f1-2 300} 301 302hostcc_major() { 303 (echo __GNUC__ | ${CC} -E - 2>/dev/null || echo 0) | tail -1 304} 305 306hostcc_minor() { 307 (echo __GNUC_MINOR__ | ${CC} -E - 2>/dev/null || echo 0) | tail -1 308} 309 310hostcc_version() { 311 printf "%d.%d" "$(hostcc_major)" "$(hostcc_minor)" 312} 313 314hostcc_has_gnat1() { 315 [ -x "$(${CC} -print-prog-name=gnat1)" ] 316} 317 318have_gnat() { 319 hostcc_has_gnat1 && \ 320 searchtool gnatbind "Free Software Foundation" nofail > /dev/null 321} 322 323ada_requested() { 324 echo "${LANGUAGES}" | grep -q '\<ada\>' 325} 326 327download() { 328 package=$1 329 # shellcheck disable=SC2086 330 if [ "${USE_COREBOOT_MIRROR}" -eq 0 ]; then 331 url="$(eval echo \$$package"_BASE_URL")" 332 else 333 url="${COREBOOT_MIRROR_URL}" 334 fi 335 336 file="$(eval echo \$$package"_ARCHIVE")" 337 printf " * ${file} " 338 339 if test -f "tarballs/${file}"; then 340 printf "(cached)... " 341 else 342 printf "(downloading from ${url}/${file})" 343 rm -f "tarballs/${file}" 344 cd tarballs || exit 1 345 download_showing_percentage "${url}/${file}" 346 cd .. 347 fi 348 349 if [ ! -f "tarballs/${file}" ]; then 350 printf "${RED}Failed to download ${file}.${NC}\n" 351 exit 1 352 fi 353} 354 355# Compute the hash of the package given in $1, and print it raw (just the 356# hexadecimal hash). 357compute_hash() { 358 package=$1 359 # shellcheck disable=SC2086 360 file="$(eval echo \$$package"_ARCHIVE")" 361 362 if test -z "$CHECKSUM"; then 363 echo "${RED}\$CHECKSUM program missing. This is bad.${NC}" 1>&2 364 exit 1 365 fi 366 367 $CHECKSUM "tarballs/$file" 2>/dev/null | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' 368} 369 370error_hash_missing() { 371 package="$1" 372 # shellcheck disable=SC2086 373 file="$(eval echo \$$package"_ARCHIVE")" 374 375 fullhashfile="util/crossgcc/sum/$file.cksum" 376 printf "${RED}hash file missing:${NC}\n\n" 1>&2 377 printf "Please verify util/crossgcc/tarball/$file carefully\n" 1>&2 378 printf "(using PGP if possible), and then rename\n" 1>&2 379 printf " ${CYAN}${fullhashfile}.calc${NC}\n" 1>&2 380 printf " to ${CYAN}${fullhashfile}${NC}\n\n" 1>&2 381 382 exit 1 383} 384 385# Read the known hash file of the package given in $1, and print it raw. 386get_known_hash() { 387 package=$1 388 # shellcheck disable=SC2086 389 file="$(eval echo \$$package"_ARCHIVE")" 390 hashfile="sum/$file.cksum" 391 392 if [ ! -f "$hashfile" ]; then 393 calc_hash="$(compute_hash "$package")" || exit 1 394 echo "$calc_hash tarballs/$file" > "${hashfile}.calc" 395 396 error_hash_missing "$package" 397 exit 1 398 fi 399 400 sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' < "$hashfile" 401} 402 403error_hash_mismatch() { 404 package=$1 405 known_hash="$2" 406 computed_hash="$3" 407 # shellcheck disable=SC2086 408 file="$(eval echo \$$package"_ARCHIVE")" 409 410 printf "${RED}hash mismatch:${NC}\n\n" 411 printf " expected (known) hash: $known_hash\n" 412 printf "calculated hash of downloaded file: $computed_hash\n\n" 413 414 printf "If you think this is due to a network error, please delete\n" 415 printf " ${CYAN}util/crossgcc/tarballs/$file${NC}\n" 416 printf "and try again. If the problem persists, it may be due to an\n" 417 printf "administration error on the file server, or you might be\n" 418 printf "subject to a Man-in-the-Middle attack\n\n" 419 420 exit 1 421} 422 423# verify_hash - Check that the hash of the file given in $1 matches the known 424# hash; Bail out on mismatch or missing hash file. 425verify_hash() { 426 package=$1 427 428 known_hash="$(get_known_hash "$package")" || exit "$?" 429 computed_hash="$(compute_hash "$package")" || exit "$?" 430 431 if [ "$known_hash" != "$computed_hash" ]; then 432 error_hash_mismatch "$package" "$known_hash" "$computed_hash" 433 exit 1 434 fi 435 436 printf "${GREEN}hash verified (${known_hash})${NC}\n" 437} 438 439unpack_and_patch() { 440 package="$1" 441 # shellcheck disable=SC2086 442 archive="$(eval echo \$$package"_ARCHIVE")" 443 # shellcheck disable=SC2086 444 dir="$(eval echo \$$package"_DIR")" 445 test -d "${dir}" && test -f "${dir}/.unpack_success" || ( 446 printf " * "$archive"\n" 447 FLAGS=zxf 448 suffix=$(echo "$archive" | sed 's,.*\.,,') 449 if [ "$suffix" = "gz" ] && [ -n "$PIGZ" ]; then FLAGS="-I pigz -xf" 450 elif [ "$suffix" = "gz" ]; then FLAGS=zxf 451 elif [ "$suffix" = "bz2" ] && [ -n "$LBZIP2" ]; then FLAGS="-I lbzip2 -xf" 452 elif [ "$suffix" = "bz2" ]; then FLAGS=jxf 453 elif [ "$suffix" = "xz" ]; then FLAGS="--xz -xf" 454 elif [ "$suffix" = "lzma" ]; then FLAGS="--lzma -xf" 455 fi 456 # shellcheck disable=SC2086 457 $TAR $FLAGS "tarballs/$archive" 458 for patch in patches/${dir}_*.patch; do 459 test -r "$patch" || continue 460 printf " o $(basename "$patch")\n" 461 (cd "${dir}" || exit 1; $PATCH -s -N -p1 <"../${patch}") || { 462 printf "\n${RED}Failed $patch.${NC}\n" 463 exit 1 464 } 465 done 466 touch "${dir}/.unpack_success" 467 ) 468} 469 470fn_exists() 471{ 472 # shellcheck disable=SC2039 473 type "$1" >/dev/null 2>&1 474} 475 476is_package_enabled() 477{ 478 echo "$PACKAGES" |grep -q "\<$1\>" 479} 480 481package_uses_targetarch() 482{ 483 if [ "$1" = "GCC" ] || [ "$1" = "BINUTILS" ]; then 484 true 485 else 486 false 487 fi 488} 489 490generic_build() 491{ 492 package=$1 493 host_target=$2 494 builddir=$3 495 success=$4 496 version=$5 497 498 fn_exists "build_$package" || return 499 500 mkdir -p "$builddir" 501 502 if [ -f "$success" ]; then 503 printf "Skipping $package v$version for $host_target as it is already built\n" 504 else 505 printf "Building $package v$version for $host_target ... " 506 DIR="$PWD" 507 cd "$builddir" || exit 1 508 rm -f .failed 509 "build_${package}" "$host_target" > build.log 2>&1 510 cd "$DIR" || exit 1 511 if [ ! -f "$builddir/.failed" ]; then 512 touch "$success"; 513 else 514 printf "${RED}failed${NC}. Check '$builddir/build.log'.\n" 515 exit 1 516 fi 517 printf "${green}ok${NC}\n" 518 fi 519} 520 521build_for_host() 522{ 523 package="$1" 524 # shellcheck disable=SC2086 525 version="$(eval echo \$$package"_VERSION")" 526 generic_build "$package" host "build-$package" "${DESTDIR}${TARGETDIR}/.${package}.${version}.success" "$version" 527} 528 529build_for_target() 530{ 531 package="$1" 532 # shellcheck disable=SC2086 533 version="$(eval echo \$$package"_VERSION")" 534 generic_build "$package" target "build-${TARGETARCH}-$package" "${DESTDIR}${TARGETDIR}/.${TARGETARCH}-${package}.${version}.success" "$version" 535} 536 537build() 538{ 539 if package_uses_targetarch "$1"; then 540 if [ $BOOTSTRAP -eq 1 ] && [ ! -f "${DESTDIR}${TARGETDIR}/.GCC.${GCC_VERSION}.success" ]; then 541 build_for_host GCC 542 fi 543 build_for_target "$1" 544 else 545 build_for_host "$1" 546 fi 547} 548 549exit_handler() 550{ 551 printf "${NC}Stop\n" 552 exit 1 553} 554 555cleanup() 556{ 557 if [ $SAVETEMPS -ne 0 ]; then 558 printf "Leaving temporary files around... ${green}ok${NC}\n" 559 return 560 fi 561 562 printf "Cleaning up temporary files... " 563 for package in $PACKAGES; do 564 # shellcheck disable=SC2086 565 rm -rf "build-${TARGETARCH}-$package" "build-$package" "$(eval echo \$$package"_DIR")" 566 done 567 rm -f getopt 568 printf "${green}ok${NC}\n" 569} 570 571myhelp() 572{ 573 printf "Usage: $0 [-V] [-c] [-p <platform>] [-d <target directory>] [-D <dest dir>] [-C] [-G] [-S]\n" 574 printf " $0 [-V|--version]\n" 575 printf " $0 [-h|--help]\n\n" 576 577 printf "Options:\n" 578 printf " [-W|--print-version Print machine readable version\n" 579 printf " [-V|--version] print version number and exit\n" 580 printf " [-h|--help] print this help and exit\n" 581 printf " [-c|--clean] remove temporary files before build\n" 582 printf " [-t|--savetemps] don't remove temporary files after build\n" 583 printf " [-y|--ccache] Use ccache when building cross compiler\n" 584 printf " [-n|--nocolor] don't print color codes in output\n" 585 printf " [-u|--urls] print the urls for all packages\n" 586 printf " [-j|--jobs <num>] run <num> jobs in parallel in make\n" 587 printf " [-s]--supported <tool> print supported version of a tool\n" 588 printf " [-d|--directory <target dir>] target directory to install cross compiler to\n" 589 printf " (defaults to $TARGETDIR)\n\n" 590 printf " [-D|--destdir <dest dir>] destination directory to install cross compiler to\n" 591 printf " (for RPM builds, default unset)\n" 592 printf " [-f|--fetch] Download tarballs, but don't build anything\n" 593 printf " [-P|--package <package>] Build a specific package: GCC, CLANG, IASL\n" 594 printf " (defaults to $PACKAGE)\n" 595 printf "GCC specific options:\n" 596 printf " [-b|--bootstrap] bootstrap the host compiler before building\n" 597 printf " the cross compiler\n" 598 printf " [-p|--platform <platform>] target platform to build cross compiler for\n" 599 printf " (defaults to $TARGETARCH)\n" 600 printf " [-l|--languages <languages>] comma separated list of target languages\n" 601 printf " (defaults to $DEFAULT_LANGUAGES)\n" 602 printf "Platforms for GCC:\n" 603 printf " x86_64 i386-elf i386-mingw32 riscv-elf arm aarch64\n" 604 printf " powerpc64le-linux-gnu nds32le-elf\n\n" 605} 606 607printversion() { 608 printf "${blue}Welcome to the ${red}coreboot${blue} cross toolchain builder v$CROSSGCC_VERSION ${NC}\n\n" 609} 610 611myversion() 612{ 613 printversion 614 615 cat << EOF 616Copyright (C) 2008-2010 by coresystems GmbH 617Copyright (C) 2011 by Sage Electronic Engineering 618 619This program is free software; you can redistribute it and/or modify 620it under the terms of the GNU General Public License as published by 621the Free Software Foundation; version 2 of the License. 622 623This program is distributed in the hope that it will be useful, 624but WITHOUT ANY WARRANTY; without even the implied warranty of 625MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 626GNU General Public License for more details. 627 628EOF 629} 630 631have_hostcflags_from_gmp() { 632 grep -q __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" >/dev/null 2>&1 633} 634 635set_hostcflags_from_gmp() { 636 # Now set CFLAGS to match GMP CFLAGS but strip out -pedantic 637 # as GCC 4.6.x fails if it's there. 638 HOSTCFLAGS="$(grep __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" |cut -d\" -f2 |\ 639 sed s,-pedantic,,)" 640 export HOSTCFLAGS 641} 642 643build_GMP() { 644 # Check if GCC enables `-pie` by default (possible since GCC 6). 645 # We need PIC in all static libraries then. 646 if $CC -dumpspecs 2>/dev/null | grep -q '[{;][[:space:]]*:-pie\>' 647 then 648 OPTIONS="$OPTIONS --with-pic" 649 fi 650 651 # shellcheck disable=SC2086 652 CC="$(hostcc host)" CXX="$(hostcxx host)" \ 653 ../${GMP_DIR}/configure \ 654 --disable-shared \ 655 --enable-fat \ 656 --prefix="$TARGETDIR" \ 657 $OPTIONS || touch .failed 658 # shellcheck disable=SC2086 659 $MAKE $JOBS || touch .failed 660 $MAKE install DESTDIR=$DESTDIR || touch .failed 661 662 normalize_dirs 663 664 set_hostcflags_from_gmp 665} 666 667build_MPFR() { 668 test "$UNAME" = "Darwin" && CFLAGS="$CFLAGS -force_cpusubtype_ALL" 669 CC="$(hostcc host)" CXX="$(hostcxx host)" \ 670 ../${MPFR_DIR}/configure \ 671 --disable-shared \ 672 --prefix="$TARGETDIR" \ 673 --infodir="$TARGETDIR/info" \ 674 --with-gmp="$DESTDIR$TARGETDIR" \ 675 CFLAGS="$HOSTCFLAGS" || touch .failed 676 # shellcheck disable=SC2086 677 $MAKE $JOBS || touch .failed 678 $MAKE install DESTDIR=$DESTDIR || touch .failed 679 680 normalize_dirs 681 682 # work around build problem of libgmp.la 683 if [ "$DESTDIR" != "" ]; then 684 perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libgmp.la" 685 fi 686} 687 688build_MPC() { 689 CC="$(hostcc host)" CXX="$(hostcxx host)" \ 690 ../${MPC_DIR}/configure \ 691 --disable-shared \ 692 --prefix="$TARGETDIR" \ 693 --infodir="$TARGETDIR/info" \ 694 --with-mpfr="$DESTDIR$TARGETDIR" \ 695 --with-gmp="$DESTDIR$TARGETDIR" \ 696 CFLAGS="$HOSTCFLAGS" || touch .failed 697 698 # work around build problem of libmpfr.la 699 if [ "$DESTDIR" != "" ]; then 700 perl -pi -e "s,$TARGETDIR/lib/libgmp.la,$DESTDIR\$&," "$DESTDIR$TARGETDIR/lib/libmpfr.la" 701 fi 702 703 # shellcheck disable=SC2086 704 $MAKE $JOBS || touch .failed 705 $MAKE install DESTDIR=$DESTDIR || touch .failed 706 707 # work around build problem of libmpfr.la 708 if [ "$DESTDIR" != "" ]; then 709 perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libmpfr.la" 710 fi 711 712 normalize_dirs 713} 714 715build_BINUTILS() { 716 if [ $TARGETARCH = "x86_64-elf" ]; then 717 ADDITIONALTARGET=",i386-elf" 718 fi 719 # shellcheck disable=SC2086 720 CC="$(hostcc target)" CXX="$(hostcxx target)" \ 721 ../binutils-${BINUTILS_VERSION}/configure \ 722 --prefix="$TARGETDIR" \ 723 --target=${TARGETARCH} \ 724 --enable-targets=${TARGETARCH}${ADDITIONALTARGET} \ 725 --disable-werror \ 726 --disable-nls \ 727 --enable-lto \ 728 --enable-gold \ 729 --enable-multilib \ 730 --disable-docs \ 731 --disable-texinfo \ 732 ${TARGET_BINUTILS_OPTIONS} \ 733 CFLAGS="$HOSTCFLAGS" \ 734 CXXFLAGS="$HOSTCFLAGS" || touch .failed 735 # shellcheck disable=SC2086 736 $MAKE $JOBS || touch .failed 737 $MAKE install DESTDIR=$DESTDIR || touch .failed 738} 739 740bootstrap_GCC() { 741 # shellcheck disable=SC2086 742 CC="$(hostcc host)" CXX="$(hostcxx host)" \ 743 CFLAGS="$HOSTCFLAGS" \ 744 CFLAGS_FOR_BUILD="$HOSTCFLAGS" \ 745 CFLAGS_FOR_TARGET="$HOSTCFLAGS -fPIC" \ 746 CXXFLAGS="$HOSTCFLAGS" \ 747 CXXFLAGS_FOR_BUILD="$HOSTCFLAGS" \ 748 CXXFLAGS_FOR_TARGET="$HOSTCFLAGS -fPIC" \ 749 ../gcc-${GCC_VERSION}/configure \ 750 --prefix="$TARGETDIR" \ 751 --libexecdir="$TARGETDIR/lib" \ 752 --enable-bootstrap \ 753 --disable-werror \ 754 --disable-nls \ 755 --disable-shared \ 756 --disable-multilib \ 757 --disable-libssp \ 758 --disable-libquadmath \ 759 --disable-libcc1 \ 760 --disable-libsanitizer \ 761 ${GCC_OPTIONS} \ 762 --enable-languages="${LANGUAGES}" \ 763 --with-gmp="$DESTDIR$TARGETDIR" \ 764 --with-mpfr="$DESTDIR$TARGETDIR" \ 765 --with-mpc="$DESTDIR$TARGETDIR" \ 766 --with-pkgversion="coreboot bootstrap v$CROSSGCC_VERSION" \ 767 && \ 768 # shellcheck disable=SC2086 769 $MAKE $JOBS BOOT_CFLAGS="$HOSTCFLAGS" BUILD_CONFIG="" bootstrap && \ 770 $MAKE install-gcc \ 771 install-target-libgcc \ 772 maybe-install-target-libada \ 773 maybe-install-target-libstdc++-v3 \ 774 DESTDIR=$DESTDIR || touch .failed 775} 776 777build_cross_GCC() { 778 # Work around crazy code generator in GCC that confuses CLANG. 779 $CC --version | grep clang >/dev/null 2>&1 && \ 780 CLANGFLAGS="-fbracket-depth=1024" 781 [ -n "$CXX" ] && $CXX --version | grep clang >/dev/null 2>&1 && \ 782 CLANGCXXFLAGS="-fbracket-depth=1024" 783 784 # standard code model is medlow but all mainboards are compiled with medany code model 785 if [ "${TARGETARCH}" = "riscv64-elf" ]; then 786 CFLAGS_FOR_TARGET_EXTRA="-mcmodel=medany" 787 fi 788 789 # GCC does not honor HOSTCFLAGS at all. CFLAGS are used for 790 # both target and host object files. 791 # There's a work-around called CFLAGS_FOR_BUILD and CFLAGS_FOR_TARGET 792 # but it does not seem to work properly. At least the host library 793 # libiberty is not compiled with CFLAGS_FOR_BUILD. 794 # Also set the CXX version of the flags because GCC is now compiled 795 # using C++. 796 # shellcheck disable=SC2086 797 CC="$(hostcc target)" CXX="$(hostcxx target)" \ 798 CFLAGS_FOR_TARGET="${CFLAGS_FOR_TARGET_EXTRA} -O2 -Dinhibit_libc" \ 799 CFLAGS="$HOSTCFLAGS $CLANGFLAGS" \ 800 CFLAGS_FOR_BUILD="$HOSTCFLAGS $CLANGFLAGS" \ 801 CXXFLAGS="$HOSTCFLAGS $CLANGCXXFLAGS" \ 802 CXXFLAGS_FOR_BUILD="$HOSTCFLAGS $CLANGCXXFLAGS" \ 803 ../gcc-${GCC_VERSION}/configure \ 804 --prefix="$TARGETDIR" \ 805 --libexecdir="$TARGETDIR/lib" \ 806 --target=${TARGETARCH} \ 807 --disable-werror \ 808 --disable-shared \ 809 --enable-lto \ 810 --enable-plugins \ 811 --enable-gold \ 812 --enable-ld=default \ 813 --disable-libssp \ 814 --disable-bootstrap \ 815 --disable-nls \ 816 --disable-libquadmath \ 817 --without-headers \ 818 --disable-threads \ 819 --enable-interwork \ 820 --enable-multilib \ 821 --enable-targets=all \ 822 --disable-libatomic \ 823 --disable-libcc1 \ 824 --disable-decimal-float \ 825 ${GCC_OPTIONS} \ 826 ${TARGET_GCC_OPTIONS} \ 827 --enable-languages="${LANGUAGES}" \ 828 --with-system-zlib \ 829 --with-gmp="$DESTDIR$TARGETDIR" \ 830 --with-mpfr="$DESTDIR$TARGETDIR" \ 831 --with-mpc="$DESTDIR$TARGETDIR" \ 832 --with-gnu-as \ 833 --with-gnu-ld \ 834 --with-pkgversion="coreboot toolchain v$CROSSGCC_VERSION" \ 835 && \ 836 mkdir -p gcc/$TARGETARCH && \ 837 rm -f "gcc/$TARGETARCH/$GCC_VERSION" && \ 838 ln -s "$DESTDIR$TARGETDIR/$TARGETARCH/bin" "gcc/$TARGETARCH/$GCC_VERSION" && \ 839 $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-gcc && \ 840 $MAKE install-gcc DESTDIR="$DESTDIR" || touch .failed 841 842 if [ ! -f .failed ] && [ "$(echo $TARGETARCH | grep -c -- -mingw32)" -eq 0 ]; then 843 # shellcheck disable=SC2086 844 $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-target-libgcc && \ 845 $MAKE install-target-libgcc DESTDIR=$DESTDIR || touch .failed 846 fi 847} 848 849build_GCC() { 850 if [ "$1" = host ]; then 851 bootstrap_GCC "$1" 852 else 853 build_cross_GCC "$1" 854 fi 855} 856 857build_IASL() { 858 RDIR=$PWD 859 cd ../$IASL_DIR/generate/unix || exit 1 860 CFLAGS="$HOSTCFLAGS" 861 HOST="_LINUX" 862 test "$UNAME" = "Darwin" && HOST="_APPLE" && OPT_LDFLAGS="-Wl,-no_fixup_chains" 863 test "$UNAME" = "FreeBSD" && HOST="_FreeBSD" 864 test "$UNAME" = "Cygwin" && HOST="_CYGWIN" 865 HOST="$HOST" CFLAGS="$CFLAGS" \ 866 OPT_LDFLAGS="$OPT_LDFLAGS" \ 867 OPT_CFLAGS="-O -D_FORTIFY_SOURCE=2 -D COREBOOT_TOOLCHAIN_VERSION='\"coreboot toolchain v$CROSSGCC_VERSION\"' " \ 868 $MAKE $JOBS CC="$(hostcc host)" iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract 869 mkdir -p "$DESTDIR$TARGETDIR/bin/" 870 (cd "$DESTDIR$TARGETDIR/bin" && rm -f iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract) || touch "$RDIR/.failed" 871 (cd bin && cp iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract "$DESTDIR$TARGETDIR/bin") || touch "$RDIR/.failed" 872} 873 874build_LLVM() { 875 876 ln -nsf "$LLD_DIR" ../lld 877 ln -nsf "$LLVM_DIR" ../llvm 878 ln -nsf "$CLANG_DIR" ../clang 879 ln -nsf "$CTE_DIR" ../clang-tools-extra 880 ln -nsf "$CRT_DIR" ../compiler-rt 881 ln -nsf "$LLVMCMAKE_DIR" ../cmake 882 ln -nsf "$LIBUNWIND_DIR" ../libunwind 883 884 $CMAKE -G "Unix Makefiles" \ 885 -DCMAKE_INSTALL_PREFIX="$DESTDIR$TARGETDIR" \ 886 -DCLANG_VENDOR="coreboot toolchain v$CROSSGCC_VERSION - " \ 887 -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;compiler-rt;lld" \ 888 -DLLVM_INCLUDE_BENCHMARKS="OFF" \ 889 -DLLVM_INCLUDE_TESTS="OFF" \ 890 -DLLVM_INCLUDE_EXAMPLES="OFF" \ 891 -DCMAKE_BUILD_TYPE=Release \ 892 -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;PowerPC;RISCV;X86" \ 893 ../llvm || touch .failed 894 # shellcheck disable=SC2086 895 $MAKE $JOBS || touch .failed 896 $MAKE install || touch .failed 897 898 rm -f ../llvm ../clang ../clang-tools-extra ../compiler-rt ../cmake ../lld ../libunwind 899 900 cp -a ../$CLANG_DIR/tools/scan-build/* "$DESTDIR$TARGETDIR/bin" 901 cp -a ../$CLANG_DIR/tools/scan-view/* "$DESTDIR$TARGETDIR/bin" 902} 903 904build_CMAKE() { 905 CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" \ 906 ../${CMAKE_DIR}/configure \ 907 --parallel=${THREADS} \ 908 --prefix="$TARGETDIR" || touch .failed 909 # shellcheck disable=SC2086 910 $MAKE $JOBS || touch .failed 911 $MAKE install DESTDIR=$DESTDIR || touch .failed 912} 913 914build_NASM() { 915 CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" \ 916 ../${NASM_DIR}/configure \ 917 --prefix="$TARGETDIR" || touch .failed 918 # shellcheck disable=SC2086 919 $MAKE $JOBS || touch .failed 920 $MAKE install DESTDIR=$DESTDIR || touch .failed 921 922 normalize_dirs 923} 924 925print_supported() { 926 case "$PRINTSUPPORTED" in 927 BINUTILS|binutils) printf "%s\n" "$BINUTILS_VERSION";; 928 CLANG|clang) printf "%s\n" "$CLANG_VERSION";; 929 GCC|gcc) printf "%s\n" "$GCC_VERSION";; 930 GMP|gmp) printf "%s\n" "$GMP_VERSION";; 931 IASL|iasl) printf "%s\n" "$IASL_VERSION";; 932 MPC|mpc) printf "%s\n" "$MPC_VERSION";; 933 MPFR|mpfr) printf "%s\n" "$MPFR_VERSION";; 934 NASM|nasm) printf "%s\n" "${NASM_VERSION}";; 935 *) printf "Unknown tool %s\n" "$PRINTSUPPORTED";; 936 esac 937} 938 939trap exit_handler 1 2 3 15 940 941# Look if we have getopt. If not, build it. 942export PATH=$PATH:. 943getopt - > /dev/null 2>/dev/null || gcc -o getopt getopt.c 944 945# parse parameters.. try to find out whether we're running GNU getopt 946getoptbrand="$(getopt -V 2>/dev/null | sed -e '1!d' -e 's,^\(......\).*,\1,')" 947if [ "${getoptbrand}" = "getopt" ]; then 948 # Detected GNU getopt that supports long options. 949 args=$(getopt -l print-version,version,help,clean,directory:,bootstrap,bootstrap-only,platform:,languages:,package:,jobs:,destdir:,savetemps,scripting,ccache,supported:,urls,nocolor,mirror,fetch -o WVhcd:bBp:l:P:j:D:tSys:unmf -- "$@") 950 getopt_ret=$? 951 eval set -- "$args" 952else 953 # Detected non-GNU getopt 954 args=$(getopt WVhcd:bBp:l:P:j:D:tSys:unm $*) 955 getopt_ret=$? 956 # shellcheck disable=SC2086 957 set -- $args 958fi 959 960if [ $getopt_ret != 0 ]; then 961 myhelp 962 exit 1 963fi 964 965while true ; do 966 case "$1" in 967 -W|--print-version) shift; echo $CROSSGCC_VERSION; exit 0;; 968 -V|--version) shift; myversion; exit 0;; 969 -h|--help) shift; myhelp; exit 0;; 970 -c|--clean) shift; clean=1;; 971 -t|--savetemps) shift; SAVETEMPS=1;; 972 -d|--directory) shift; TARGETDIR="$1"; shift;; 973 -b|--bootstrap) shift; BOOTSTRAP=1;; 974 -B|--bootstrap-only) shift; BOOTSTRAPONLY=1; BOOTSTRAP=1;; 975 -p|--platform) shift; TARGETARCH="$1"; shift;; 976 -l|--languages) shift; LANGUAGES="$1"; shift;; 977 -m|--mirror) shift; USE_COREBOOT_MIRROR=1;; 978 -D|--destdir) shift; DESTDIR="$1"; shift;; 979 -f|--fetch) shift; FETCH_ONLY=1;; 980 -j|--jobs) shift; THREADS="$1"; JOBS="-j $1"; shift;; 981 -P|--package) shift; PACKAGE="$1"; shift;; 982 -y|--ccache) shift; USECCACHE=1;; 983 -s|--supported) shift; PRINTSUPPORTED="$1"; shift;; 984 -u|--urls) shift; printf "%s\n" "$ALL_ARCHIVES"; exit 0;; 985 -n|--nocolor) shift; \ 986 unset red RED green GREEN blue BLUE cyan CYAN NC;; 987 --) shift; break;; 988 *) break;; 989 esac 990done 991 992if [ $# -gt 0 ]; then 993 printf "Excessive arguments: $*\n" 994 myhelp 995 exit 1 996fi 997 998if [ -n "$PRINTSUPPORTED" ]; then 999 print_supported 1000 exit 0 1001fi 1002 1003#print toolchain builder version string as the header 1004printversion 1005 1006printf "Building toolchain using %d thread(s).\n\n" "$THREADS" 1007 1008case "$TARGETARCH" in 1009 x86_64-elf) ;; 1010 x86_64*) TARGETARCH=x86_64-elf;; 1011 i386-elf) ;; 1012 i386-mingw32) ;; 1013 riscv-elf) TARGETARCH=riscv64-elf 1014 TARGET_GCC_OPTIONS="$TARGET_GCC_OPTIONS --with-isa-spec=20191213" 1015 TARGET_BINUTILS_OPTIONS="$TARGET_BINUTILS_OPTIONS --with-isa-spec=20191213";; 1016 powerpc64*-linux*) ;; 1017 i386*) TARGETARCH=i386-elf;; 1018 arm*) TARGETARCH=arm-eabi;; 1019 aarch64*) TARGETARCH=aarch64-elf;; 1020 nds32le-elf) ;; 1021 *) printf "${red}WARNING: Unsupported architecture $TARGETARCH.${NC}\n\n"; ;; 1022esac 1023 1024# Figure out which packages to build 1025 1026case "$PACKAGE" in 1027 GCC|gcc) 1028 echo "Target architecture is $TARGETARCH" 1029 NAME="${TARGETARCH} cross GCC" 1030 PACKAGES="GMP MPFR MPC BINUTILS GCC" 1031 ;; 1032 CLANG|clang) 1033 NAME="LLVM clang" 1034 LLVM_VERSION=${CLANG_VERSION} 1035 PACKAGES="CMAKE LLVM CLANG CRT CTE LLVMCMAKE LLD LIBUNWIND" 1036 CMAKE=${DESTDIR}${TARGETDIR}/bin/cmake 1037 ;; 1038 IASL|iasl) 1039 NAME="IASL ACPI compiler" 1040 PACKAGES=IASL 1041 ;; 1042 CMAKE|cmake) 1043 NAME="CMake" 1044 PACKAGES=CMAKE 1045 ;; 1046 NASM|nasm) 1047 NAME="NASM" 1048 PACKAGES=NASM 1049 ;; 1050 *) 1051 printf "${red}ERROR: Unsupported package $PACKAGE. (Supported packages are GCC, CLANG, IASL, and NASM)${NC}\n\n"; 1052 exit 1 1053 ;; 1054esac 1055 1056# Find all the required tools: 1057 1058TAR=$(searchtool tar) || exit $? 1059PATCH=$(searchtool patch) || exit $? 1060MAKE=$(searchtool make) || exit $? 1061SHA1SUM=$(searchtool sha1sum) 1062#SHA512SUM=$(searchtool sha512sum) 1063#MD5SUM=$(searchtool md5sum) 1064CHECKSUM=$SHA1SUM 1065LBZIP2=$(searchtool lbzip2 "" nofail) 1066PIGZ=$(searchtool pigz "" nofail) 1067 1068searchtool m4 > /dev/null 1069searchtool bison > /dev/null 1070searchtool flex flex > /dev/null 1071searchtool bzip2 "bzip2," > /dev/null 1072searchtool xz "XZ Utils" "" "xz-utils" > /dev/null 1073 1074if searchtool wget "GNU" nofail > /dev/null; then 1075 download_showing_percentage() { 1076 url=$1 1077 printf "... ${red} 0%%" 1078 wget --tries=3 "$url" 2>&1 | while read -r line; do 1079 echo "$line" | grep -o "\<[0-9]\{1,3\}%" | awk '{printf("\b\b\b\b%4s", $1)}' 1080 done 1081 printf "${NC}... " 1082 } 1083elif searchtool curl "^curl " > /dev/null; then 1084 download_showing_percentage() { 1085 url=$1 1086 echo 1087 curl -O --progress-bar --location --retry 3 "$url" 1088 } 1089fi 1090 1091# Allow $CC override from the environment. 1092if [ -n "$CC" ]; then 1093 if [ ! -x "$(command -v "$CC" 2>/dev/null)" ]; then 1094 printf "${RED}ERROR:${red} CC is set to '%s' but wasn't found.${NC}\n" "$CC" 1095 HALT_FOR_TOOLS=1 1096 fi 1097else 1098 if searchtool gnatgcc "Free Software Foundation" nofail > /dev/null; then 1099 # gnatgcc is deprecated and in recent GCC releases its purpose is 1100 # fulfilled by the gcc binary. In case of a deprecated gnatgcc 1101 # version is installed, it doesn't provide the expected output and 1102 # hostcc_has_gnat1() fails. In this case, just set the value of CC 1103 # to gcc. 1104 # TODO: Remove this whole branch when time is appropriate as the 1105 # second branch fulfills our needs. 1106 CC=gnatgcc 1107 if ! hostcc_has_gnat1; then 1108 CC=gcc 1109 fi 1110 elif searchtool gcc "Free Software Foundation" nofail > /dev/null; then 1111 CC=gcc 1112 else 1113 searchtool cc '^' nofail > /dev/null || please_install gcc 1114 CC=cc 1115 fi 1116fi 1117 1118# We can leave $CXX empty if it's not set since *buildgcc* never 1119# calls it directly. This way configure scripts can search for 1120# themselves and we still override it when a bootstrapped g++ is 1121# to be used (cf. hostcxx()). 1122if [ -n "$CXX" ]; then 1123 if [ ! -x "$(command -v "$CXX" 2>/dev/null)" ]; then 1124 printf "${RED}ERROR:${red} CXX is set to '%s' but wasn't found.${NC}\n" "$CXX" 1125 HALT_FOR_TOOLS=1 1126 fi 1127else 1128 searchtool g++ "Free Software Foundation" nofail > /dev/null || \ 1129 searchtool clang "clang version" nofail > /dev/null || \ 1130 searchtool clang "LLVM" "" "g++" > /dev/null 1131fi 1132 1133check_for_library "-lz" "zlib (zlib1g-dev or zlib-devel)" 1134 1135if [ "$HALT_FOR_TOOLS" -ne 0 ]; then 1136 exit 1 1137fi 1138 1139# This initial cleanup is useful when updating the toolchain script. 1140 1141if [ "$clean" = "1" ]; then 1142 cleanup 1143fi 1144 1145# Set up host compiler and flags needed for various OSes 1146 1147if is_package_enabled "GCC"; then 1148# sane preset: let the configure script figure out things by itself 1149# more importantly, avoid any values that might already linger in the variable 1150OPTIONS="ABI=" 1151if [ "$UNAME" = "Darwin" ]; then 1152 #GCC_OPTIONS="$GCC_OPTIONS --enable-threads=posix" 1153 1154 # generally the OS X compiler can create x64 binaries. 1155 # Per default it generated i386 binaries in 10.5 and x64 1156 # binaries in 10.6 (even if the kernel is 32bit) 1157 # For some weird reason, 10.5 autodetects an ABI=64 though 1158 # so we're setting the ABI explicitly here. 1159 if [ "$(sysctl -n hw.optional.x86_64 2>/dev/null)" -eq 1 ] 2>/dev/null; then 1160 OPTIONS="ABI=64" 1161 elif [ "$(sysctl -n hw.optional.arm64 2>/dev/null)" -eq 1 ] 2>/dev/null; then 1162 OPTIONS="ABI=64" 1163 else 1164 OPTIONS="ABI=32" 1165 fi 1166 1167 # In Xcode 4.5.2 the default compiler is clang. 1168 # However, this compiler fails to compile gcc 4.7.x. As a 1169 # workaround it's possible to compile gcc with llvm-gcc. 1170 if $CC -v 2>&1 | grep -q LLVM; then 1171 CC=llvm-gcc 1172 fi 1173elif [ "$UNAME" = "Linux" ] || [ "$UNAME" = "Cygwin" ]; then 1174 # gmp is overeager with detecting 64bit CPUs even if they run 1175 # a 32bit kernel and userland. 1176 if [ "$(uname -m 2>/dev/null)" = "i686" ]; then 1177 OPTIONS="ABI=32" 1178 fi 1179elif [ "$UNAME" = "NetBSD" ]; then 1180 # same for NetBSD but this one reports an i386 1181 if [ "$(uname -m 2>/dev/null)" = "i386" ]; then 1182 OPTIONS="ABI=32" 1183 fi 1184fi 1185if [ -z "${LANGUAGES}" ]; then 1186 if have_gnat; then 1187 printf "\nFound compatible Ada compiler, enabling Ada support by default.\n\n" 1188 LANGUAGES="ada,${DEFAULT_LANGUAGES}" 1189 else 1190 printf "\n${red}WARNING${NC}\n" 1191 printf "No compatible Ada compiler (GNAT) found. You can continue without\n" 1192 printf "Ada support, but this will limit the features of ${blue}coreboot${NC} (e.g.\n" 1193 printf "native graphics initialization won't be available on most Intel\n" 1194 printf "boards).\n\n" 1195 1196 printf "Usually, you can install GNAT with your package management system\n" 1197 printf "(the package is called \`gnat\` or \`gcc-ada\`). It has to match the\n" 1198 printf "\`gcc\` package in version. If there are multiple versions of GCC in-\n" 1199 printf "stalled, you can point this script to the matching version through\n" 1200 printf "the \`CC\` and \`CXX\` environment variables.\n\n" 1201 1202 printf "e.g. on Ubuntu 14.04, if \`gcc\` is \`gcc-4.8\`:\n" 1203 printf " apt-get install gnat-4.8 && make crossgcc\n\n" 1204 1205 printf "on Ubuntu 16.04, if \`gcc\` is \`gcc-5\`:\n" 1206 printf " apt-get install gnat-5 && make crossgcc\n" 1207 timeout 30 1208 LANGUAGES="${DEFAULT_LANGUAGES}" 1209 fi 1210fi 1211if [ "$BOOTSTRAP" != 1 ] && \ 1212 { [ "$(hostcc_major)" -lt 4 ] || \ 1213 { [ "$(hostcc_major)" -eq 4 ] && \ 1214 [ "$(hostcc_minor)" -lt 9 ] ; } ; } 1215then 1216 printf "\n${red}WARNING${NC}\n" 1217 printf "Building coreboot requires a host compiler newer than 4.9.x while\n" 1218 printf "yours is $(hostcc_version).\n" 1219 printf "Enabling bootstrapping to provide a sufficiently new compiler:\n" 1220 printf "This will take significantly longer than a usual build.\n" 1221 printf "Alternatively you can abort now and update your host compiler.\n" 1222 timeout 15 1223 BOOTSTRAP=1 1224fi 1225if ada_requested; then 1226 if ! have_gnat; then 1227 please_install gnat gcc-ada 1228 exit 1 1229 fi 1230fi 1231fi # GCC 1232 1233export HOSTCFLAGS="-Os" 1234if have_hostcflags_from_gmp; then 1235 set_hostcflags_from_gmp 1236fi 1237 1238if [ "$USECCACHE" = 1 ]; then 1239 CC="ccache $CC" 1240fi 1241 1242# Prepare target directory for building GCC 1243# (dependencies must be in the PATH) 1244mkdir -p "$DESTDIR$TARGETDIR/bin" 1245mkdir -p "$DESTDIR$TARGETDIR/share" 1246export PATH=$DESTDIR$TARGETDIR/bin:$PATH 1247 1248# Download, unpack, patch and build all packages 1249 1250printf "Downloading and verifying tarballs ...\n" 1251mkdir -p tarballs 1252for P in $PACKAGES; do 1253 download "$P" || exit "$?" 1254 verify_hash "$P" || exit "$?" 1255done 1256printf "Downloaded tarballs ... ${green}ok${NC}\n" 1257 1258if [ ${FETCH_ONLY} -eq 1 ]; then 1259 exit 0 1260fi 1261 1262printf "Unpacking and patching ...\n" 1263for P in $PACKAGES; do 1264 unpack_and_patch $P || exit 1 1265done 1266printf "Unpacked and patched ... ${green}ok${NC}\n" 1267 1268if [ -n "$BOOTSTRAPONLY" ]; then 1269 printf "Building bootstrap compiler only ...\n" 1270 for pkg in GMP MPFR MPC GCC; do 1271 build_for_host $pkg 1272 done 1273 exit 0 1274fi 1275 1276printf "Building packages ...\n" 1277for package in $PACKAGES; do 1278 build $package 1279done 1280printf "Packages built ... ${green}ok${NC}\n" 1281 1282# Adding git information of current tree to target directory 1283# for reproducibility 1284PROGNAME=$(basename "$0") 1285rm -f "$DESTDIR$TARGETDIR/share/$PROGNAME-*" 1286cp "$PROGNAME" "$DESTDIR$TARGETDIR/share/$PROGNAME-$CROSSGCC_VERSION" 1287 1288# Adding edk2 tools template 1289mkdir -p "$DESTDIR$TARGETDIR/share/edk2config" 1290sed -e "s,@@PREFIX@@,$TARGETDIR,g" edk2tools.txt > "$DESTDIR$TARGETDIR/share/edk2config/tools_def.txt" 1291printf "Copied EDK2 tools template ... ${green}ok${NC}\n" 1292 1293cleanup 1294 1295printf "\n${green}You can now run $NAME from $TARGETDIR.${NC}\n" 1296