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