crossgcc: Upgrade binutils from 2.42 to 2.43.1
[coreboot.git] / util / crossgcc / buildgcc
blob4440fe87eb099deb6f5e2b416baa1693ae87542b
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.
15 # SPDX-License-Identifier: GPL-2.0-only
17 cd "$(dirname "$0")" || exit 1
19 if [ -z "$CROSSGCC_VERSION" ]; then
20 CROSSGCC_VERSION="$(git log -n 1 --pretty=%cd --date=short .)_$(git log -n 1 --pretty=%h .)"
23 # default settings
24 PACKAGE=GCC
25 TARGETDIR=$(pwd)/xgcc
26 TARGETARCH=i386-elf
27 DEFAULT_LANGUAGES=c
28 LANGUAGES=
29 DESTDIR=
30 SAVETEMPS=0
31 BOOTSTRAP=0
32 THREADS=1
33 FETCH_ONLY=0
34 USE_COREBOOT_MIRROR=0
35 COREBOOT_MIRROR_URL="https://www.coreboot.org/releases/crossgcc-sources"
37 # GCC toolchain version numbers
38 GMP_VERSION=6.3.0
39 MPFR_VERSION=4.2.1
40 MPC_VERSION=1.3.1
41 GCC_VERSION=14.1.0
42 BINUTILS_VERSION=2.43.1
43 IASL_VERSION="20230628"
44 # CLANG version number
45 CLANG_VERSION=18.1.6
46 CMAKE_VERSION=3.29.3
47 NASM_VERSION=2.16.03
49 # Filename for each package
50 GMP_ARCHIVE="gmp-${GMP_VERSION}.tar.xz"
51 MPFR_ARCHIVE="mpfr-${MPFR_VERSION}.tar.xz"
52 MPC_ARCHIVE="mpc-${MPC_VERSION}.tar.gz"
53 GCC_ARCHIVE="gcc-${GCC_VERSION}.tar.xz"
54 BINUTILS_ARCHIVE="binutils-${BINUTILS_VERSION}.tar.xz"
55 IASL_ARCHIVE="acpica-unix-${IASL_VERSION}.tar.gz"
56 # CLANG toolchain FILE locations
57 LLD_ARCHIVE="lld-${CLANG_VERSION}.src.tar.xz"
58 LLVM_ARCHIVE="llvm-${CLANG_VERSION}.src.tar.xz"
59 CLANG_ARCHIVE="clang-${CLANG_VERSION}.src.tar.xz"
60 CRT_ARCHIVE="compiler-rt-${CLANG_VERSION}.src.tar.xz"
61 CTE_ARCHIVE="clang-tools-extra-${CLANG_VERSION}.src.tar.xz"
62 LLVMCMAKE_ARCHIVE="cmake-${CLANG_VERSION}.src.tar.xz"
63 LIBUNWIND_ARCHIVE="libunwind-${CLANG_VERSION}.src.tar.xz"
64 CMAKE_ARCHIVE="cmake-${CMAKE_VERSION}.tar.gz"
65 NASM_ARCHIVE="nasm-${NASM_VERSION}.tar.bz2"
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.
71 # GCC toolchain archive locations
72 GMP_BASE_URL="https://ftpmirror.gnu.org/gmp"
73 MPFR_BASE_URL="https://ftpmirror.gnu.org/mpfr"
74 MPC_BASE_URL="https://ftpmirror.gnu.org/mpc"
75 GCC_BASE_URL="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}"
76 BINUTILS_BASE_URL="https://ftpmirror.gnu.org/binutils"
77 IASL_BASE_URL="https://downloadmirror.intel.com/783534"
78 # CLANG toolchain archive locations
79 LLVM_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
80 CLANG_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
81 CRT_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
82 CTE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
83 LLVMCMAKE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
84 LLD_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
85 LIBUNWIND_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
86 CMAKE_BASE_URL="https://cmake.org/files/v${CMAKE_VERSION%.*}"
87 NASM_BASE_URL="https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}"
89 ALL_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"
95 # GCC toolchain directories
96 GMP_DIR="gmp-${GMP_VERSION}"
97 MPFR_DIR="mpfr-${MPFR_VERSION}"
98 MPC_DIR="mpc-${MPC_VERSION}"
99 # shellcheck disable=SC2034
100 GCC_DIR="gcc-${GCC_VERSION}"
101 # shellcheck disable=SC2034
102 BINUTILS_DIR="binutils-${BINUTILS_VERSION}"
103 IASL_DIR="acpica-unix-${IASL_VERSION}"
104 # CLANG toolchain directories
105 LLD_DIR="lld-${CLANG_VERSION}.src"
106 LLVM_DIR="llvm-${CLANG_VERSION}.src"
107 CLANG_DIR="clang-${CLANG_VERSION}.src"
108 CRT_DIR="compiler-rt-${CLANG_VERSION}.src"
109 CTE_DIR="clang-tools-extra-${CLANG_VERSION}.src"
110 LLVMCMAKE_DIR="cmake-${CLANG_VERSION}.src"
111 LIBUNWIND_DIR="libunwind-${CLANG_VERSION}.src"
112 CMAKE_DIR="cmake-${CMAKE_VERSION}"
113 NASM_DIR="nasm-${NASM_VERSION}"
115 unset MAKELEVEL MAKEFLAGS
117 red='\033[0;31m'
118 RED='\033[1;31m'
119 green='\033[0;32m'
120 GREEN='\033[1;32m'
121 blue='\033[0;34m'
122 CYAN='\033[1;36m'
123 NC='\033[0m' # No Color
125 UNAME=$(if uname | grep -iq cygwin; then echo Cygwin; else uname; fi)
126 HALT_FOR_TOOLS=0
128 hostcc()
130 # $1 "host" or "target"
131 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then
132 echo "$DESTDIR$TARGETDIR/bin/gcc"
133 else
134 echo "$CC"
138 hostcxx()
140 # $1 "host" or "target"
141 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then
142 echo "$DESTDIR$TARGETDIR/bin/g++"
143 else
144 echo "$CXX"
148 normalize_dirs()
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"
155 perl -pi -e "s,/lib32,/lib," "$DESTDIR$TARGETDIR"/lib/*.la
156 perl -pi -e "s,/lib64,/lib," "$DESTDIR$TARGETDIR"/lib/*.la
159 countdown()
161 tout=${1:-10}
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"
172 timeout()
174 tout=${1:-10}
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
181 (countdown "$tout"; kill -USR1 $$)&
182 counter=$!
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
193 kill $counter > /dev/null 2>&1
194 trap - USR1 EXIT
197 please_install()
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}
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
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
218 searchtool()
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"
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
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
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
272 [ -z "$3" ] && please_install "$1" "$4"
273 false
276 # Run a compile check of the specified library option to see if it's installed
277 check_for_library() {
278 LIBRARY_FLAGS="$1"
279 LIBRARY_PACKAGES="$2"
280 LIBTEST_FILE=.libtest
282 echo "int main(int argc, char **argv) { (void) argc; (void) argv; return 0; }" > "${LIBTEST_FILE}.c"
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}"
290 buildcc_major() {
291 echo "${GCC_VERSION}" | cut -d. -f1
294 buildcc_minor() {
295 echo "${GCC_VERSION}" | cut -d. -f2
298 buildcc_version() {
299 echo "${GCC_VERSION}" | cut -d. -f1-2
302 hostcc_major() {
303 (echo __GNUC__ | ${CC} -E - 2>/dev/null || echo 0) | tail -1
306 hostcc_minor() {
307 (echo __GNUC_MINOR__ | ${CC} -E - 2>/dev/null || echo 0) | tail -1
310 hostcc_version() {
311 printf "%d.%d" "$(hostcc_major)" "$(hostcc_minor)"
314 hostcc_has_gnat1() {
315 [ -x "$(${CC} -print-prog-name=gnat1)" ]
318 have_gnat() {
319 hostcc_has_gnat1 && \
320 searchtool gnatbind "Free Software Foundation" nofail > /dev/null
323 ada_requested() {
324 echo "${LANGUAGES}" | grep -q '\<ada\>'
327 download() {
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}"
336 file="$(eval echo \$$package"_ARCHIVE")"
337 printf " * ${file} "
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 ..
349 if [ ! -f "tarballs/${file}" ]; then
350 printf "${RED}Failed to download ${file}.${NC}\n"
351 exit 1
355 # Compute the hash of the package given in $1, and print it raw (just the
356 # hexadecimal hash).
357 compute_hash() {
358 package=$1
359 # shellcheck disable=SC2086
360 file="$(eval echo \$$package"_ARCHIVE")"
362 if test -z "$CHECKSUM"; then
363 echo "${RED}\$CHECKSUM program missing. This is bad.${NC}" 1>&2
364 exit 1
367 $CHECKSUM "tarballs/$file" 2>/dev/null | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@'
370 error_hash_missing() {
371 package="$1"
372 # shellcheck disable=SC2086
373 file="$(eval echo \$$package"_ARCHIVE")"
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
382 exit 1
385 # Read the known hash file of the package given in $1, and print it raw.
386 get_known_hash() {
387 package=$1
388 # shellcheck disable=SC2086
389 file="$(eval echo \$$package"_ARCHIVE")"
390 hashfile="sum/$file.cksum"
392 if [ ! -f "$hashfile" ]; then
393 calc_hash="$(compute_hash "$package")" || exit 1
394 echo "$calc_hash tarballs/$file" > "${hashfile}.calc"
396 error_hash_missing "$package"
397 exit 1
400 sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' < "$hashfile"
403 error_hash_mismatch() {
404 package=$1
405 known_hash="$2"
406 computed_hash="$3"
407 # shellcheck disable=SC2086
408 file="$(eval echo \$$package"_ARCHIVE")"
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"
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"
420 exit 1
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.
425 verify_hash() {
426 package=$1
428 known_hash="$(get_known_hash "$package")" || exit "$?"
429 computed_hash="$(compute_hash "$package")" || exit "$?"
431 if [ "$known_hash" != "$computed_hash" ]; then
432 error_hash_mismatch "$package" "$known_hash" "$computed_hash"
433 exit 1
436 printf "${GREEN}hash verified (${known_hash})${NC}\n"
439 unpack_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"
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
465 done
466 touch "${dir}/.unpack_success"
470 fn_exists()
472 # shellcheck disable=SC2039
473 type "$1" >/dev/null 2>&1
476 is_package_enabled()
478 echo "$PACKAGES" |grep -q "\<$1\>"
481 package_uses_targetarch()
483 if [ "$1" = "GCC" ] || [ "$1" = "BINUTILS" ]; then
484 true
485 else
486 false
490 generic_build()
492 package=$1
493 host_target=$2
494 builddir=$3
495 success=$4
496 version=$5
498 fn_exists "build_$package" || return
500 mkdir -p "$builddir"
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
517 printf "${green}ok${NC}\n"
521 build_for_host()
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"
529 build_for_target()
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"
537 build()
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
543 build_for_target "$1"
544 else
545 build_for_host "$1"
549 exit_handler()
551 printf "${NC}Stop\n"
552 exit 1
555 cleanup()
557 if [ $SAVETEMPS -ne 0 ]; then
558 printf "Leaving temporary files around... ${green}ok${NC}\n"
559 return
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"
571 myhelp()
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"
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"
607 printversion() {
608 printf "${blue}Welcome to the ${red}coreboot${blue} cross toolchain builder v$CROSSGCC_VERSION ${NC}\n\n"
611 myversion()
613 printversion
615 cat << EOF
616 Copyright (C) 2008-2010 by coresystems GmbH
617 Copyright (C) 2011 by Sage Electronic Engineering
619 This program is free software; you can redistribute it and/or modify
620 it under the terms of the GNU General Public License as published by
621 the Free Software Foundation; version 2 of the License.
623 This program is distributed in the hope that it will be useful,
624 but WITHOUT ANY WARRANTY; without even the implied warranty of
625 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
626 GNU General Public License for more details.
631 have_hostcflags_from_gmp() {
632 grep -q __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" >/dev/null 2>&1
635 set_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
643 build_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"
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
662 normalize_dirs
664 set_hostcflags_from_gmp
667 build_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
680 normalize_dirs
682 # work around build problem of libgmp.la
683 if [ "$DESTDIR" != "" ]; then
684 perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libgmp.la"
688 build_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
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"
703 # shellcheck disable=SC2086
704 $MAKE $JOBS || touch .failed
705 $MAKE install DESTDIR=$DESTDIR || touch .failed
707 # work around build problem of libmpfr.la
708 if [ "$DESTDIR" != "" ]; then
709 perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libmpfr.la"
712 normalize_dirs
715 build_BINUTILS() {
716 if [ $TARGETARCH = "x86_64-elf" ]; then
717 ADDITIONALTARGET=",i386-elf"
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
740 bootstrap_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
777 build_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"
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"
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
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
849 build_GCC() {
850 if [ "$1" = host ]; then
851 bootstrap_GCC "$1"
852 else
853 build_cross_GCC "$1"
857 build_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"
874 build_LLVM() {
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
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
898 rm -f ../llvm ../clang ../clang-tools-extra ../compiler-rt ../cmake ../lld ../libunwind
900 cp -a ../$CLANG_DIR/tools/scan-build/* "$DESTDIR$TARGETDIR/bin"
901 cp -a ../$CLANG_DIR/tools/scan-view/* "$DESTDIR$TARGETDIR/bin"
904 build_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
914 build_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
922 normalize_dirs
925 print_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
939 trap exit_handler 1 2 3 15
941 # Look if we have getopt. If not, build it.
942 export PATH=$PATH:.
943 getopt - > /dev/null 2>/dev/null || gcc -o getopt getopt.c
945 # parse parameters.. try to find out whether we're running GNU getopt
946 getoptbrand="$(getopt -V 2>/dev/null | sed -e '1!d' -e 's,^\(......\).*,\1,')"
947 if [ "${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"
952 else
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
960 if [ $getopt_ret != 0 ]; then
961 myhelp
962 exit 1
965 while 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
990 done
992 if [ $# -gt 0 ]; then
993 printf "Excessive arguments: $*\n"
994 myhelp
995 exit 1
998 if [ -n "$PRINTSUPPORTED" ]; then
999 print_supported
1000 exit 0
1003 #print toolchain builder version string as the header
1004 printversion
1006 printf "Building toolchain using %d thread(s).\n\n" "$THREADS"
1008 case "$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"; ;;
1022 esac
1024 # Figure out which packages to build
1026 case "$PACKAGE" in
1027 GCC|gcc)
1028 echo "Target architecture is $TARGETARCH"
1029 NAME="${TARGETARCH} cross GCC"
1030 PACKAGES="GMP MPFR MPC BINUTILS GCC"
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
1038 IASL|iasl)
1039 NAME="IASL ACPI compiler"
1040 PACKAGES=IASL
1042 CMAKE|cmake)
1043 NAME="CMake"
1044 PACKAGES=CMAKE
1046 NASM|nasm)
1047 NAME="NASM"
1048 PACKAGES=NASM
1051 printf "${red}ERROR: Unsupported package $PACKAGE. (Supported packages are GCC, CLANG, IASL, and NASM)${NC}\n\n";
1052 exit 1
1054 esac
1056 # Find all the required tools:
1058 TAR=$(searchtool tar) || exit $?
1059 PATCH=$(searchtool patch) || exit $?
1060 MAKE=$(searchtool make) || exit $?
1061 SHA1SUM=$(searchtool sha1sum)
1062 #SHA512SUM=$(searchtool sha512sum)
1063 #MD5SUM=$(searchtool md5sum)
1064 CHECKSUM=$SHA1SUM
1065 LBZIP2=$(searchtool lbzip2 "" nofail)
1066 PIGZ=$(searchtool pigz "" nofail)
1068 searchtool m4 > /dev/null
1069 searchtool bison > /dev/null
1070 searchtool flex flex > /dev/null
1071 searchtool bzip2 "bzip2," > /dev/null
1072 searchtool xz "XZ Utils" "" "xz-utils" > /dev/null
1074 if 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}... "
1083 elif searchtool curl "^curl " > /dev/null; then
1084 download_showing_percentage() {
1085 url=$1
1086 echo
1087 curl -O --progress-bar --location --retry 3 "$url"
1091 # Allow $CC override from the environment.
1092 if [ -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
1097 else
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
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
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()).
1122 if [ -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
1127 else
1128 searchtool g++ "Free Software Foundation" nofail > /dev/null || \
1129 searchtool clang "clang version" nofail > /dev/null || \
1130 searchtool clang "LLVM" "" "g++" > /dev/null
1133 check_for_library "-lz" "zlib (zlib1g-dev or zlib-devel)"
1135 if [ "$HALT_FOR_TOOLS" -ne 0 ]; then
1136 exit 1
1139 # This initial cleanup is useful when updating the toolchain script.
1141 if [ "$clean" = "1" ]; then
1142 cleanup
1145 # Set up host compiler and flags needed for various OSes
1147 if 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
1150 OPTIONS="ABI="
1151 if [ "$UNAME" = "Darwin" ]; then
1152 #GCC_OPTIONS="$GCC_OPTIONS --enable-threads=posix"
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"
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
1173 elif [ "$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"
1179 elif [ "$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"
1185 if [ -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"
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"
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"
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}"
1211 if [ "$BOOTSTRAP" != 1 ] && \
1212 { [ "$(hostcc_major)" -lt 4 ] || \
1213 { [ "$(hostcc_major)" -eq 4 ] && \
1214 [ "$(hostcc_minor)" -lt 9 ] ; } ; }
1215 then
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
1225 if ada_requested; then
1226 if ! have_gnat; then
1227 please_install gnat gcc-ada
1228 exit 1
1231 fi # GCC
1233 export HOSTCFLAGS="-Os"
1234 if have_hostcflags_from_gmp; then
1235 set_hostcflags_from_gmp
1238 if [ "$USECCACHE" = 1 ]; then
1239 CC="ccache $CC"
1242 # Prepare target directory for building GCC
1243 # (dependencies must be in the PATH)
1244 mkdir -p "$DESTDIR$TARGETDIR/bin"
1245 mkdir -p "$DESTDIR$TARGETDIR/share"
1246 export PATH=$DESTDIR$TARGETDIR/bin:$PATH
1248 # Download, unpack, patch and build all packages
1250 printf "Downloading and verifying tarballs ...\n"
1251 mkdir -p tarballs
1252 for P in $PACKAGES; do
1253 download "$P" || exit "$?"
1254 verify_hash "$P" || exit "$?"
1255 done
1256 printf "Downloaded tarballs ... ${green}ok${NC}\n"
1258 if [ ${FETCH_ONLY} -eq 1 ]; then
1259 exit 0
1262 printf "Unpacking and patching ...\n"
1263 for P in $PACKAGES; do
1264 unpack_and_patch $P || exit 1
1265 done
1266 printf "Unpacked and patched ... ${green}ok${NC}\n"
1268 if [ -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
1276 printf "Building packages ...\n"
1277 for package in $PACKAGES; do
1278 build $package
1279 done
1280 printf "Packages built ... ${green}ok${NC}\n"
1282 # Adding git information of current tree to target directory
1283 # for reproducibility
1284 PROGNAME=$(basename "$0")
1285 rm -f "$DESTDIR$TARGETDIR/share/$PROGNAME-*"
1286 cp "$PROGNAME" "$DESTDIR$TARGETDIR/share/$PROGNAME-$CROSSGCC_VERSION"
1288 # Adding edk2 tools template
1289 mkdir -p "$DESTDIR$TARGETDIR/share/edk2config"
1290 sed -e "s,@@PREFIX@@,$TARGETDIR,g" edk2tools.txt > "$DESTDIR$TARGETDIR/share/edk2config/tools_def.txt"
1291 printf "Copied EDK2 tools template ... ${green}ok${NC}\n"
1293 cleanup
1295 printf "\n${green}You can now run $NAME from $TARGETDIR.${NC}\n"