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 .)"
34 COREBOOT_MIRROR_URL
="https://www.coreboot.org/releases/crossgcc-sources"
36 # GCC toolchain version numbers
42 IASL_VERSION
="R10_20_22"
43 # CLANG version number
48 # Filename for each package
49 GMP_ARCHIVE
="gmp-${GMP_VERSION}.tar.xz"
50 MPFR_ARCHIVE
="mpfr-${MPFR_VERSION}.tar.xz"
51 MPC_ARCHIVE
="mpc-${MPC_VERSION}.tar.gz"
52 GCC_ARCHIVE
="gcc-${GCC_VERSION}.tar.xz"
53 BINUTILS_ARCHIVE
="binutils-${BINUTILS_VERSION}.tar.xz"
54 IASL_ARCHIVE
="${IASL_VERSION}.tar.gz"
55 # CLANG toolchain FILE locations
56 LLVM_ARCHIVE
="llvm-${CLANG_VERSION}.src.tar.xz"
57 CLANG_ARCHIVE
="clang-${CLANG_VERSION}.src.tar.xz"
58 CRT_ARCHIVE
="compiler-rt-${CLANG_VERSION}.src.tar.xz"
59 CTE_ARCHIVE
="clang-tools-extra-${CLANG_VERSION}.src.tar.xz"
60 LLVMCMAKE_ARCHIVE
="cmake-${CLANG_VERSION}.src.tar.xz"
61 CMAKE_ARCHIVE
="cmake-${CMAKE_VERSION}.tar.gz"
62 NASM_ARCHIVE
="nasm-${NASM_VERSION}.tar.bz2"
64 # These URLs are sanitized by the jenkins toolchain test builder, so if
65 # a completely new URL is added here, it probably needs to be added
66 # to the jenkins build as well, or the builder won't download it.
68 # GCC toolchain archive locations
69 GMP_BASE_URL
="https://ftpmirror.gnu.org/gmp"
70 MPFR_BASE_URL
="https://ftpmirror.gnu.org/mpfr"
71 MPC_BASE_URL
="https://ftpmirror.gnu.org/mpc"
72 GCC_BASE_URL
="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}"
73 BINUTILS_BASE_URL
="https://ftpmirror.gnu.org/binutils"
74 IASL_BASE_URL
="https://github.com/acpica/acpica/archive/refs/tags"
75 # CLANG toolchain archive locations
76 LLVM_BASE_URL
="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
77 CLANG_BASE_URL
="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
78 CRT_BASE_URL
="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
79 CTE_BASE_URL
="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
80 LLVMCMAKE_BASE_URL
="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
81 CMAKE_BASE_URL
="https://cmake.org/files/v${CMAKE_VERSION%.*}"
82 NASM_BASE_URL
="https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}"
84 ALL_ARCHIVES
="$GMP_BASE_URL/$GMP_ARCHIVE $MPFR_BASE_URL/$MPFR_ARCHIVE $MPC_BASE_URL/$MPC_ARCHIVE \
85 $GCC_BASE_URL/$GCC_ARCHIVE $BINUTILS_BASE_URL/$BINUTILS_ARCHIVE $IASL_BASE_URL/$IASL_ARCHIVE \
86 $LLVM_BASE_URL/$LLVM_ARCHIVE $CLANG_BASE_URL/$CLANG_ARCHIVE $LLVMCMAKE_BASE_URL/$LLVMCMAKE_ARCHIVE \
87 $CRT_BASE_URL/$CRT_ARCHIVE $CTE_BASE_URL/$CTE_ARCHIVE $CMAKE_BASE_URL/$CMAKE_ARCHIVE $NASM_BASE_URL/$NASM_ARCHIVE"
89 # GCC toolchain directories
90 GMP_DIR
="gmp-${GMP_VERSION}"
91 MPFR_DIR
="mpfr-${MPFR_VERSION}"
92 MPC_DIR
="mpc-${MPC_VERSION}"
93 # shellcheck disable=SC2034
94 GCC_DIR
="gcc-${GCC_VERSION}"
95 # shellcheck disable=SC2034
96 BINUTILS_DIR
="binutils-${BINUTILS_VERSION}"
97 IASL_DIR
="acpica-${IASL_VERSION}"
98 # CLANG toolchain directories
99 LLVM_DIR
="llvm-${CLANG_VERSION}.src"
100 CLANG_DIR
="clang-${CLANG_VERSION}.src"
101 CRT_DIR
="compiler-rt-${CLANG_VERSION}.src"
102 CTE_DIR
="clang-tools-extra-${CLANG_VERSION}.src"
103 LLVMCMAKE_DIR
="cmake-${CLANG_VERSION}.src"
104 CMAKE_DIR
="cmake-${CMAKE_VERSION}"
105 NASM_DIR
="nasm-${NASM_VERSION}"
107 unset MAKELEVEL MAKEFLAGS
115 NC
='\033[0m' # No Color
117 UNAME
=$
(if uname |
grep -iq cygwin
; then echo Cygwin
; else uname
; fi)
122 # $1 "host" or "target"
123 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target
]; then
124 echo "$DESTDIR$TARGETDIR/bin/gcc"
132 # $1 "host" or "target"
133 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target
]; then
134 echo "$DESTDIR$TARGETDIR/bin/g++"
142 mkdir
-p "$DESTDIR$TARGETDIR/lib"
143 test -d "$DESTDIR$TARGETDIR/lib32" && mv "$DESTDIR$TARGETDIR"/lib32
/* "$DESTDIR$TARGETDIR/lib"
144 test -d "$DESTDIR$TARGETDIR/lib64" && mv "$DESTDIR$TARGETDIR"/lib64
/* "$DESTDIR$TARGETDIR/lib"
145 rm -rf "$DESTDIR$TARGETDIR/lib32" "$DESTDIR$TARGETDIR/lib64"
147 perl
-pi -e "s,/lib32,/lib," "$DESTDIR$TARGETDIR"/lib
/*.la
148 perl
-pi -e "s,/lib64,/lib," "$DESTDIR$TARGETDIR"/lib
/*.la
155 printf "\nPress Ctrl-C to abort, Enter to continue... %2ds" "$tout"
156 while [ "$tout" -gt 0 ]; do
159 printf "\b\b\b%2ds" $tout
168 # Ignore SIGUSR1, should interrupt `read` though.
170 # Clean up in case the user aborts.
171 trap 'kill $counter > /dev/null 2>&1' EXIT
173 (countdown
"$tout"; kill -USR1 $$
)&
176 # Some shells with sh compatibility mode (e.g. zsh, mksh) only
177 # let us interrupt `read` if a non-standard -t parameter is given.
178 # shellcheck disable=SC2034,SC2039,SC2162
179 if echo |
read -t 1 foo
2>/dev
/null
; then
180 read -t $
((tout
+ 1)) foo
185 kill $counter > /dev
/null
2>&1
192 # shellcheck disable=SC1091
193 test -r /etc
/os-release
&& .
/etc
/os-release
194 # vanilla debian doesn't define `ID_LIKE`, just `ID`
195 if [ -z "${ID_LIKE}" ] && [ -n "${ID}" ]; then
199 debian
) solution
="sudo apt-get install $1" ;;
200 suse
) solution
="sudo zypper install $1" ;;
201 *) solution
="using your OS packaging system" ;;
204 printf "${RED}ERROR:${red} Missing tool: Please install '$1'. (eg $solution)${NC}\n" >&2
206 printf "${RED}ERROR:${red} or install '$2'.${NC}\n" >&2
214 # $3 soft fail if set
215 # $4 alternative package to install on failure
216 # result: file name of that tool on stdout
217 # or no output if nothing suitable was found
222 for i
in "$1" "g$1" "gnu$1"; do
223 if [ -x "$(command -v "$i" 2>/dev/null)" ]; then
224 if [ "$(cat /dev/null | $i --version 2>&1 | grep -c "$search")" \
231 # A workaround for OSX 10.9 and some BSDs, whose nongnu
232 # patch and tar also work.
233 if [ "$UNAME" = "Darwin" ] ||
[ "$UNAME" = "FreeBSD" ] ||
[ "$UNAME" = "NetBSD" ] ||
[ "$UNAME" = "OpenBSD" ]; then
234 if [ "$1" = "patch" ] ||
[ "$1" = "tar" ]; then
235 if [ -x "$(command -v "$1" 2>/dev/null)" ]; then
241 if echo "$1" |
grep -q "sum" ; then
242 algor
=$
(echo "$1" |
sed -e 's,sum,,')
243 if [ -x "$(command -v "$1" 2>/dev/null)" ]; then
247 elif [ -x "$(command -v "$algor" 2>/dev/null)" ]; then
251 elif [ -x "$(command -v openssl 2>/dev/null)" ]; then
253 echo openssl
"$algor"
255 elif [ -x "$(command -v cksum 2>/dev/null)" ]; then
257 #cksum has special options in NetBSD. Actually, NetBSD will use the second case above.
258 echo "buildgcc" |
cksum -a "$algor" > /dev
/null
2>/dev
/null
&& \
259 echo cksum -a "$algor"
264 [ -z "$3" ] && please_install
"$1" "$4"
268 # Run a compile check of the specified library option to see if it's installed
269 check_for_library
() {
271 LIBRARY_PACKAGES
="$2"
272 LIBTEST_FILE
=.libtest
274 echo "int main(int argc, char **argv) { (void) argc; (void) argv; return 0; }" > "${LIBTEST_FILE}.c"
276 # shellcheck disable=SC2086
277 "$CC" $CFLAGS $LIBRARY_FLAGS "${LIBTEST_FILE}.c" -o "${LIBTEST_FILE}" >/dev
/null
2>&1 || \
278 please_install
"$LIBRARY_PACKAGES"
279 rm -rf "${LIBTEST_FILE}.c" "${LIBTEST_FILE}"
283 echo "${GCC_VERSION}" | cut
-d.
-f1
287 echo "${GCC_VERSION}" | cut
-d.
-f2
291 echo "${GCC_VERSION}" | cut
-d.
-f1-2
295 (echo __GNUC__ |
${CC} -E - 2>/dev
/null ||
echo 0) |
tail -1
299 (echo __GNUC_MINOR__ |
${CC} -E - 2>/dev
/null ||
echo 0) |
tail -1
303 printf "%d.%d" "$(hostcc_major)" "$(hostcc_minor)"
307 [ -x "$(${CC} -print-prog-name=gnat1)" ]
311 hostcc_has_gnat1
&& \
312 searchtool gnatbind
"Free Software Foundation" nofail
> /dev
/null
316 echo "${LANGUAGES}" |
grep -q '\<ada\>'
321 # shellcheck disable=SC2086
322 if [ "${USE_COREBOOT_MIRROR}" -eq 0 ]; then
323 url
="$(eval echo \$$package"_BASE_URL
")"
325 url
="${COREBOOT_MIRROR_URL}"
328 file="$(eval echo \$$package"_ARCHIVE
")"
331 if test -f "tarballs/${file}"; then
332 printf "(cached)... "
334 printf "(downloading from ${url}/${file})"
335 rm -f "tarballs/${file}"
336 cd tarballs ||
exit 1
337 download_showing_percentage
"${url}/${file}"
341 if [ ! -f "tarballs/${file}" ]; then
342 printf "${RED}Failed to download ${file}.${NC}\n"
347 # Compute the hash of the package given in $1, and print it raw (just the
351 # shellcheck disable=SC2086
352 file="$(eval echo \$$package"_ARCHIVE
")"
354 if test -z "$CHECKSUM"; then
355 echo "${RED}\$CHECKSUM program missing. This is bad.${NC}" 1>&2
359 $CHECKSUM "tarballs/$file" 2>/dev
/null |
sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@'
362 error_hash_missing
() {
364 # shellcheck disable=SC2086
365 file="$(eval echo \$$package"_ARCHIVE
")"
367 fullhashfile
="util/crossgcc/sum/$file.cksum"
368 printf "${RED}hash file missing:${NC}\n\n" 1>&2
369 printf "Please verify util/crossgcc/tarball/$file carefully\n" 1>&2
370 printf "(using PGP if possible), and then rename\n" 1>&2
371 printf " ${CYAN}${fullhashfile}.calc${NC}\n" 1>&2
372 printf " to ${CYAN}${fullhashfile}${NC}\n\n" 1>&2
377 # Read the known hash file of the package given in $1, and print it raw.
380 # shellcheck disable=SC2086
381 file="$(eval echo \$$package"_ARCHIVE
")"
382 hashfile
="sum/$file.cksum"
384 if [ ! -f "$hashfile" ]; then
385 calc_hash
="$(compute_hash "$package")" ||
exit 1
386 echo "$calc_hash tarballs/$file" > "${hashfile}.calc"
388 error_hash_missing
"$package"
392 sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' < "$hashfile"
395 error_hash_mismatch
() {
399 # shellcheck disable=SC2086
400 file="$(eval echo \$$package"_ARCHIVE
")"
402 printf "${RED}hash mismatch:${NC}\n\n"
403 printf " expected (known) hash: $known_hash\n"
404 printf "calculated hash of downloaded file: $computed_hash\n\n"
406 printf "If you think this is due to a network error, please delete\n"
407 printf " ${CYAN}util/crossgcc/tarballs/$file${NC}\n"
408 printf "and try again. If the problem persists, it may be due to an\n"
409 printf "administration error on the file server, or you might be\n"
410 printf "subject to a Man-in-the-Middle attack\n\n"
415 # verify_hash - Check that the hash of the file given in $1 matches the known
416 # hash; Bail out on mismatch or missing hash file.
420 known_hash
="$(get_known_hash "$package")" ||
exit "$?"
421 computed_hash
="$(compute_hash "$package")" ||
exit "$?"
423 if [ "$known_hash" != "$computed_hash" ]; then
424 error_hash_mismatch
"$package" "$known_hash" "$computed_hash"
428 printf "${GREEN}hash verified (${known_hash})${NC}\n"
433 # shellcheck disable=SC2086
434 archive
="$(eval echo \$$package"_ARCHIVE
")"
435 # shellcheck disable=SC2086
436 dir
="$(eval echo \$$package"_DIR
")"
437 test -d "${dir}" && test -f "${dir}/.unpack_success" ||
(
438 printf " * "$archive"\n"
440 suffix
=$
(echo "$archive" |
sed 's,.*\.,,')
441 if [ "$suffix" = "gz" ] && [ -n "$PIGZ" ]; then FLAGS
="-I pigz -xf"
442 elif [ "$suffix" = "gz" ]; then FLAGS
=zxf
443 elif [ "$suffix" = "bz2" ] && [ -n "$LBZIP2" ]; then FLAGS
="-I lbzip2 -xf"
444 elif [ "$suffix" = "bz2" ]; then FLAGS
=jxf
445 elif [ "$suffix" = "xz" ]; then FLAGS
="--xz -xf"
446 elif [ "$suffix" = "lzma" ]; then FLAGS
="--lzma -xf"
448 # shellcheck disable=SC2086
449 $TAR $FLAGS "tarballs/$archive"
450 for patch in patches
/${dir}_
*.
patch; do
451 test -r "$patch" ||
continue
452 printf " o $(basename "$patch")\n"
453 (cd "${dir}" ||
exit 1; $PATCH -s -N -p1 <"../${patch}") ||
{
454 printf "\n${RED}Failed $patch.${NC}\n"
458 touch "${dir}/.unpack_success"
464 # shellcheck disable=SC2039
465 type "$1" >/dev
/null
2>&1
470 echo "$PACKAGES" |
grep -q "\<$1\>"
473 package_uses_targetarch
()
475 if [ "$1" = "GCC" ] ||
[ "$1" = "BINUTILS" ]; then
490 fn_exists
"build_$package" ||
return
494 if [ -f "$success" ]; then
495 printf "Skipping $package v$version for $host_target as it is already built\n"
497 printf "Building $package v$version for $host_target ... "
499 cd "$builddir" ||
exit 1
501 "build_${package}" "$host_target" > build.log
2>&1
503 if [ ! -f "$builddir/.failed" ]; then
506 printf "${RED}failed${NC}. Check '$builddir/build.log'.\n"
509 printf "${green}ok${NC}\n"
516 # shellcheck disable=SC2086
517 version
="$(eval echo \$$package"_VERSION
")"
518 generic_build
"$package" host "build-$package" "${DESTDIR}${TARGETDIR}/.${package}.${version}.success" "$version"
524 # shellcheck disable=SC2086
525 version
="$(eval echo \$$package"_VERSION
")"
526 generic_build
"$package" target
"build-${TARGETARCH}-$package" "${DESTDIR}${TARGETDIR}/.${TARGETARCH}-${package}.${version}.success" "$version"
531 if package_uses_targetarch
"$1"; then
532 if [ $BOOTSTRAP -eq 1 ] && [ ! -f "${DESTDIR}${TARGETDIR}/.GCC.${GCC_VERSION}.success" ]; then
535 build_for_target
"$1"
549 if [ $SAVETEMPS -ne 0 ]; then
550 printf "Leaving temporary files around... ${green}ok${NC}\n"
554 printf "Cleaning up temporary files... "
555 for package
in $PACKAGES; do
556 # shellcheck disable=SC2086
557 rm -rf "build-${TARGETARCH}-$package" "build-$package" "$(eval echo \$$package"_DIR
")"
560 printf "${green}ok${NC}\n"
565 printf "Usage: $0 [-V] [-c] [-p <platform>] [-d <target directory>] [-D <dest dir>] [-C] [-G] [-S]\n"
566 printf " $0 [-V|--version]\n"
567 printf " $0 [-h|--help]\n\n"
570 printf " [-W|--print-version Print machine readable version\n"
571 printf " [-V|--version] print version number and exit\n"
572 printf " [-h|--help] print this help and exit\n"
573 printf " [-c|--clean] remove temporary files before build\n"
574 printf " [-t|--savetemps] don't remove temporary files after build\n"
575 printf " [-y|--ccache] Use ccache when building cross compiler\n"
576 printf " [-n|--nocolor] don't print color codes in output\n"
577 printf " [-u|--urls] print the urls for all packages\n"
578 printf " [-j|--jobs <num>] run <num> jobs in parallel in make\n"
579 printf " [-s]--supported <tool> print supported version of a tool\n"
580 printf " [-d|--directory <target dir>] target directory to install cross compiler to\n"
581 printf " (defaults to $TARGETDIR)\n\n"
582 printf " [-D|--destdir <dest dir>] destination directory to install cross compiler to\n"
583 printf " (for RPM builds, default unset)\n"
584 printf " [-P|--package <package>] Build a specific package: GCC, CLANG, IASL\n"
585 printf " (defaults to $PACKAGE)\n"
586 printf "GCC specific options:\n"
587 printf " [-b|--bootstrap] bootstrap the host compiler before building\n"
588 printf " the cross compiler\n"
589 printf " [-p|--platform <platform>] target platform to build cross compiler for\n"
590 printf " (defaults to $TARGETARCH)\n"
591 printf " [-l|--languages <languages>] comma separated list of target languages\n"
592 printf " (defaults to $DEFAULT_LANGUAGES)\n"
593 printf "Platforms for GCC:\n"
594 printf " x86_64 i386-elf i386-mingw32 riscv-elf arm aarch64\n"
595 printf " powerpc64le-linux-gnu nds32le-elf\n\n"
599 printf "${blue}Welcome to the ${red}coreboot${blue} cross toolchain builder v$CROSSGCC_VERSION ${NC}\n\n"
607 Copyright (C) 2008-2010 by coresystems GmbH
608 Copyright (C) 2011 by Sage Electronic Engineering
610 This program is free software; you can redistribute it and/or modify
611 it under the terms of the GNU General Public License as published by
612 the Free Software Foundation; version 2 of the License.
614 This program is distributed in the hope that it will be useful,
615 but WITHOUT ANY WARRANTY; without even the implied warranty of
616 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
617 GNU General Public License for more details.
622 have_hostcflags_from_gmp
() {
623 grep -q __GMP_CFLAGS
"$DESTDIR$TARGETDIR/include/gmp.h" >/dev
/null
2>&1
626 set_hostcflags_from_gmp
() {
627 # Now set CFLAGS to match GMP CFLAGS but strip out -pedantic
628 # as GCC 4.6.x fails if it's there.
629 HOSTCFLAGS
="$(grep __GMP_CFLAGS "$DESTDIR$TARGETDIR/include
/gmp.h
" |cut -d\" -f2 |\
635 # Check if GCC enables `-pie` by default (possible since GCC 6).
636 # We need PIC in all static libraries then.
637 if $CC -dumpspecs 2>/dev
/null |
grep -q '[{;][[:space:]]*:-pie\>'
639 OPTIONS
="$OPTIONS --with-pic"
642 # shellcheck disable=SC2086
643 CC
="$(hostcc host)" CXX
="$(hostcxx host)" \
644 ..
/${GMP_DIR}/configure \
647 --prefix="$TARGETDIR" \
648 $OPTIONS ||
touch .failed
649 # shellcheck disable=SC2086
650 $MAKE $JOBS ||
touch .failed
651 $MAKE install DESTDIR
=$DESTDIR ||
touch .failed
655 set_hostcflags_from_gmp
659 test "$UNAME" = "Darwin" && CFLAGS
="$CFLAGS -force_cpusubtype_ALL"
660 CC
="$(hostcc host)" CXX
="$(hostcxx host)" \
661 ..
/${MPFR_DIR}/configure \
663 --prefix="$TARGETDIR" \
664 --infodir="$TARGETDIR/info" \
665 --with-gmp="$DESTDIR$TARGETDIR" \
666 CFLAGS
="$HOSTCFLAGS" ||
touch .failed
667 # shellcheck disable=SC2086
668 $MAKE $JOBS ||
touch .failed
669 $MAKE install DESTDIR
=$DESTDIR ||
touch .failed
673 # work around build problem of libgmp.la
674 if [ "$DESTDIR" != "" ]; then
675 perl
-pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libgmp.la"
680 CC
="$(hostcc host)" CXX
="$(hostcxx host)" \
681 ..
/${MPC_DIR}/configure \
683 --prefix="$TARGETDIR" \
684 --infodir="$TARGETDIR/info" \
685 --with-mpfr="$DESTDIR$TARGETDIR" \
686 --with-gmp="$DESTDIR$TARGETDIR" \
687 CFLAGS
="$HOSTCFLAGS" ||
touch .failed
689 # work around build problem of libmpfr.la
690 if [ "$DESTDIR" != "" ]; then
691 perl
-pi -e "s,$TARGETDIR/lib/libgmp.la,$DESTDIR\$&," "$DESTDIR$TARGETDIR/lib/libmpfr.la"
694 # shellcheck disable=SC2086
695 $MAKE $JOBS ||
touch .failed
696 $MAKE install DESTDIR
=$DESTDIR ||
touch .failed
698 # work around build problem of libmpfr.la
699 if [ "$DESTDIR" != "" ]; then
700 perl
-pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libmpfr.la"
707 if [ $TARGETARCH = "x86_64-elf" ]; then
708 ADDITIONALTARGET
=",i386-elf"
710 # shellcheck disable=SC2086
711 CC
="$(hostcc target)" CXX
="$(hostcxx target)" \
712 ..
/binutils-
${BINUTILS_VERSION}/configure \
713 --prefix="$TARGETDIR" \
714 --target=${TARGETARCH} \
715 --enable-targets=${TARGETARCH}${ADDITIONALTARGET} \
723 ${BINUTILS_OPTIONS} \
724 CFLAGS
="$HOSTCFLAGS" \
725 CXXFLAGS
="$HOSTCFLAGS" ||
touch .failed
726 # shellcheck disable=SC2086
727 $MAKE $JOBS ||
touch .failed
728 $MAKE install DESTDIR
=$DESTDIR ||
touch .failed
732 # shellcheck disable=SC2086
733 CC
="$(hostcc host)" CXX
="$(hostcxx host)" \
734 CFLAGS
="$HOSTCFLAGS" \
735 CFLAGS_FOR_BUILD
="$HOSTCFLAGS" \
736 CFLAGS_FOR_TARGET
="$HOSTCFLAGS -fPIC" \
737 CXXFLAGS
="$HOSTCFLAGS" \
738 CXXFLAGS_FOR_BUILD
="$HOSTCFLAGS" \
739 CXXFLAGS_FOR_TARGET
="$HOSTCFLAGS -fPIC" \
740 ..
/gcc-
${GCC_VERSION}/configure \
741 --prefix="$TARGETDIR" \
742 --libexecdir="$TARGETDIR/lib" \
749 --disable-libquadmath \
751 --disable-libsanitizer \
753 --enable-languages="${LANGUAGES}" \
754 --with-gmp="$DESTDIR$TARGETDIR" \
755 --with-mpfr="$DESTDIR$TARGETDIR" \
756 --with-mpc="$DESTDIR$TARGETDIR" \
757 --with-pkgversion="coreboot bootstrap v$CROSSGCC_VERSION" \
759 # shellcheck disable=SC2086
760 $MAKE $JOBS BOOT_CFLAGS
="$HOSTCFLAGS" BUILD_CONFIG
="" bootstrap
&& \
762 install-target-libgcc \
763 maybe-install-target-libada \
764 maybe-install-target-libstdc
++-v3 \
765 DESTDIR
=$DESTDIR ||
touch .failed
769 # Work around crazy code generator in GCC that confuses CLANG.
770 $CC --version |
grep clang
>/dev
/null
2>&1 && \
771 CLANGFLAGS
="-fbracket-depth=1024"
772 [ -n "$CXX" ] && $CXX --version |
grep clang
>/dev
/null
2>&1 && \
773 CLANGCXXFLAGS
="-fbracket-depth=1024"
775 # GCC does not honor HOSTCFLAGS at all. CFLAGS are used for
776 # both target and host object files.
777 # There's a work-around called CFLAGS_FOR_BUILD and CFLAGS_FOR_TARGET
778 # but it does not seem to work properly. At least the host library
779 # libiberty is not compiled with CFLAGS_FOR_BUILD.
780 # Also set the CXX version of the flags because GCC is now compiled
782 # shellcheck disable=SC2086
783 CC
="$(hostcc target)" CXX
="$(hostcxx target)" \
784 CFLAGS_FOR_TARGET
="-O2 -Dinhibit_libc" \
785 CFLAGS
="$HOSTCFLAGS $CLANGFLAGS" \
786 CFLAGS_FOR_BUILD
="$HOSTCFLAGS $CLANGFLAGS" \
787 CXXFLAGS
="$HOSTCFLAGS $CLANGCXXFLAGS" \
788 CXXFLAGS_FOR_BUILD
="$HOSTCFLAGS $CLANGCXXFLAGS" \
789 ..
/gcc-
${GCC_VERSION}/configure \
790 --prefix="$TARGETDIR" \
791 --libexecdir="$TARGETDIR/lib" \
792 --target=${TARGETARCH} \
798 --enable-ld=default \
800 --disable-bootstrap \
802 --disable-libquadmath \
807 --enable-targets=all \
808 --disable-libatomic \
810 --disable-decimal-float \
812 --enable-languages="${LANGUAGES}" \
814 --with-gmp="$DESTDIR$TARGETDIR" \
815 --with-mpfr="$DESTDIR$TARGETDIR" \
816 --with-mpc="$DESTDIR$TARGETDIR" \
819 --with-pkgversion="coreboot toolchain v$CROSSGCC_VERSION" \
821 mkdir
-p gcc
/$TARGETARCH && \
822 rm -f "gcc/$TARGETARCH/$GCC_VERSION" && \
823 ln -s "$DESTDIR$TARGETDIR/$TARGETARCH/bin" "gcc/$TARGETARCH/$GCC_VERSION" && \
824 $MAKE $JOBS CFLAGS_FOR_BUILD
="$HOSTCFLAGS" all-gcc
&& \
825 $MAKE install-gcc DESTDIR
="$DESTDIR" ||
touch .failed
827 if [ ! -f .failed
] && [ "$(echo $TARGETARCH | grep -c -- -mingw32)" -eq 0 ]; then
828 # shellcheck disable=SC2086
829 $MAKE $JOBS CFLAGS_FOR_BUILD
="$HOSTCFLAGS" all-target-libgcc
&& \
830 $MAKE install-target-libgcc DESTDIR
=$DESTDIR ||
touch .failed
835 if [ "$1" = host ]; then
844 cd ..
/$IASL_DIR/generate
/unix ||
exit 1
847 test "$UNAME" = "Darwin" && HOST
="_APPLE"
848 test "$UNAME" = "FreeBSD" && HOST
="_FreeBSD"
849 test "$UNAME" = "Cygwin" && HOST
="_CYGWIN"
850 HOST
="$HOST" CFLAGS
="$CFLAGS" \
851 OPT_CFLAGS
="-O -D_FORTIFY_SOURCE=2 -D COREBOOT_TOOLCHAIN_VERSION='\"coreboot toolchain v$CROSSGCC_VERSION\"' " \
852 $MAKE $JOBS CC
="$(hostcc host)" iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract
853 mkdir
-p "$DESTDIR$TARGETDIR/bin/"
854 (cd "$DESTDIR$TARGETDIR/bin" && rm -f iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract
) ||
touch "$RDIR/.failed"
855 (cd bin
&& cp iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract
"$DESTDIR$TARGETDIR/bin") ||
touch "$RDIR/.failed"
860 ln -nsf "$LLVM_DIR" ..
/llvm
861 ln -nsf "$CLANG_DIR" ..
/clang
862 ln -nsf "$CTE_DIR" ..
/clang-tools-extra
863 ln -nsf "$CRT_DIR" ..
/compiler-rt
864 ln -nsf "$LLVMCMAKE_DIR" ..
/cmake
866 $CMAKE -G "Unix Makefiles" \
867 -DCMAKE_INSTALL_PREFIX="$DESTDIR$TARGETDIR" \
868 -DCLANG_VENDOR="coreboot toolchain v$CROSSGCC_VERSION - " \
869 -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;compiler-rt" \
870 -DLLVM_INCLUDE_BENCHMARKS="OFF" \
871 -DLLVM_INCLUDE_TESTS="OFF" \
872 -DLLVM_INCLUDE_EXAMPLES="OFF" \
873 -DCMAKE_BUILD_TYPE=Release \
874 -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;PowerPC;RISCV;X86" \
875 ..
/llvm ||
touch .failed
876 # shellcheck disable=SC2086
877 $MAKE $JOBS ||
touch .failed
878 $MAKE install ||
touch .failed
880 rm -f ..
/llvm ..
/clang ..
/clang-tools-extra ..
/compiler-rt ..
/cmake
882 cp -a ..
/$CLANG_DIR/tools
/scan-build
/* "$DESTDIR$TARGETDIR/bin"
883 cp -a ..
/$CLANG_DIR/tools
/scan-view
/* "$DESTDIR$TARGETDIR/bin"
885 # create symlinks to work around broken --print-librt-file-name
886 # when used with -target.
887 cd "$DESTDIR$TARGETDIR/lib/clang/${CLANG_VERSION}/lib" ||
exit 1
888 for i
in */libclang_rt.builtins
*.a
; do
894 CC
="$(hostcc host)" CXX
="$(hostcxx host)" CFLAGS
="$HOSTCFLAGS" \
895 ..
/${CMAKE_DIR}/configure \
896 --parallel=${THREADS} \
897 --prefix="$TARGETDIR" ||
touch .failed
898 # shellcheck disable=SC2086
899 $MAKE $JOBS ||
touch .failed
900 $MAKE install DESTDIR
=$DESTDIR ||
touch .failed
904 CC
="$(hostcc host)" CXX
="$(hostcxx host)" CFLAGS
="$HOSTCFLAGS" \
905 ..
/${NASM_DIR}/configure \
906 --prefix="$TARGETDIR" ||
touch .failed
907 # shellcheck disable=SC2086
908 $MAKE $JOBS ||
touch .failed
909 $MAKE install DESTDIR
=$DESTDIR ||
touch .failed
915 case "$PRINTSUPPORTED" in
916 BINUTILS|binutils
) printf "%s\n" "$BINUTILS_VERSION";;
917 CLANG|clang
) printf "%s\n" "$CLANG_VERSION";;
918 GCC|gcc
) printf "%s\n" "$GCC_VERSION";;
919 GMP|gmp
) printf "%s\n" "$GMP_VERSION";;
920 IASL|iasl
) printf "%s\n" "$IASL_VERSION";;
921 MPC|mpc
) printf "%s\n" "$MPC_VERSION";;
922 MPFR|mpfr
) printf "%s\n" "$MPFR_VERSION";;
923 NASM|nasm
) printf "%s\n" "${NASM_VERSION}";;
924 *) printf "Unknown tool %s\n" "$PRINTSUPPORTED";;
928 trap exit_handler
1 2 3 15
930 # Look if we have getopt. If not, build it.
932 getopt
- > /dev
/null
2>/dev
/null || gcc
-o getopt getopt.c
934 # parse parameters.. try to find out whether we're running GNU getopt
935 getoptbrand
="$(getopt -V 2>/dev/null | sed -e '1!d' -e 's,^\(......\).*,\1,')"
936 if [ "${getoptbrand}" = "getopt" ]; then
937 # Detected GNU getopt that supports long options.
938 args
=$
(getopt
-l print-version
,version
,help,clean
,directory
:,bootstrap
,bootstrap-only
,platform
:,languages
:,package
:,jobs:,destdir
:,savetemps
,scripting
,ccache
,supported
:,urls
,nocolor
,mirror
-o WVhcd
:bBp
:l
:P
:j
:D
:tSys
:unm
-- "$@")
942 # Detected non-GNU getopt
943 args
=$
(getopt WVhcd
:bBp
:l
:P
:j
:D
:tSys
:unm $
*)
945 # shellcheck disable=SC2086
949 if [ $getopt_ret != 0 ]; then
956 -W|
--print-version) shift; echo $CROSSGCC_VERSION; exit 0;;
957 -V|
--version) shift; myversion
; exit 0;;
958 -h|
--help) shift; myhelp
; exit 0;;
959 -c|
--clean) shift; clean
=1;;
960 -t|
--savetemps) shift; SAVETEMPS
=1;;
961 -d|
--directory) shift; TARGETDIR
="$1"; shift;;
962 -b|
--bootstrap) shift; BOOTSTRAP
=1;;
963 -B|
--bootstrap-only) shift; BOOTSTRAPONLY
=1; BOOTSTRAP
=1;;
964 -p|
--platform) shift; TARGETARCH
="$1"; shift;;
965 -l|
--languages) shift; LANGUAGES
="$1"; shift;;
966 -m|
--mirror) shift; USE_COREBOOT_MIRROR
=1;;
967 -D|
--destdir) shift; DESTDIR
="$1"; shift;;
968 -j|
--jobs) shift; THREADS
="$1"; JOBS
="-j $1"; shift;;
969 -P|
--package) shift; PACKAGE
="$1"; shift;;
970 -y|
--ccache) shift; USECCACHE
=1;;
971 -s|
--supported) shift; PRINTSUPPORTED
="$1"; shift;;
972 -u|
--urls) shift; printf "%s\n" "$ALL_ARCHIVES"; exit 0;;
973 -n|
--nocolor) shift; \
974 unset red RED green GREEN blue BLUE cyan CYAN NC
;;
980 if [ $# -gt 0 ]; then
981 printf "Excessive arguments: $*\n"
986 if [ -n "$PRINTSUPPORTED" ]; then
991 #print toolchain builder version string as the header
994 printf "Building toolchain using %d thread(s).\n\n" "$THREADS"
996 case "$TARGETARCH" in
998 x86_64
*) TARGETARCH
=x86_64-elf
;;
1001 riscv-elf
) TARGETARCH
=riscv64-elf
1002 GCC_OPTIONS
="$GCC_OPTIONS --with-isa-spec=20191213"
1003 BINUTILS_OPTIONS
="$BINUTILS_OPTIONS --with-isa-spec=20191213";;
1004 powerpc64
*-linux*) ;;
1005 i386
*) TARGETARCH
=i386-elf
;;
1006 arm
*) TARGETARCH
=arm-eabi
;;
1007 aarch64
*) TARGETARCH
=aarch64-elf
;;
1009 *) printf "${red}WARNING: Unsupported architecture $TARGETARCH.${NC}\n\n"; ;;
1012 # Figure out which packages to build
1016 echo "Target architecture is $TARGETARCH"
1017 NAME
="${TARGETARCH} cross GCC"
1018 PACKAGES
="GMP MPFR MPC BINUTILS GCC"
1022 LLVM_VERSION
=${CLANG_VERSION}
1023 PACKAGES
="CMAKE LLVM CLANG CRT CTE LLVMCMAKE"
1024 CMAKE
=${DESTDIR}${TARGETDIR}/bin
/cmake
1027 NAME
="IASL ACPI compiler"
1039 printf "${red}ERROR: Unsupported package $PACKAGE. (Supported packages are GCC, CLANG, IASL, and NASM)${NC}\n\n";
1044 # Find all the required tools:
1046 TAR
=$
(searchtool
tar) ||
exit $?
1047 PATCH
=$
(searchtool
patch) ||
exit $?
1048 MAKE
=$
(searchtool
make) ||
exit $?
1049 SHA1SUM
=$
(searchtool
sha1sum)
1050 #SHA512SUM=$(searchtool sha512sum)
1051 #MD5SUM=$(searchtool md5sum)
1053 LBZIP2
=$
(searchtool lbzip2
"" nofail
)
1054 PIGZ
=$
(searchtool pigz
"" nofail
)
1056 searchtool
m4 > /dev
/null
1057 searchtool bison
> /dev
/null
1058 searchtool flex flex
> /dev
/null
1059 searchtool
bzip2 "bzip2," > /dev
/null
1060 searchtool xz
"XZ Utils" "" "xz-utils" > /dev
/null
1062 if searchtool wget
"GNU" nofail
> /dev
/null
; then
1063 download_showing_percentage
() {
1065 printf "... ${red} 0%%"
1066 wget
--tries=3 "$url" 2>&1 |
while read -r line
; do
1067 echo "$line" |
grep -o "[0-9]\+%" |
awk '{printf("\b\b\b\b%4s", $1)}'
1071 elif searchtool curl
"^curl " > /dev
/null
; then
1072 download_showing_percentage
() {
1075 curl
-O --progress-bar --location --retry 3 "$url"
1079 # Allow $CC override from the environment.
1080 if [ -n "$CC" ]; then
1081 if [ ! -x "$(command -v "$CC" 2>/dev/null)" ]; then
1082 printf "${RED}ERROR:${red} CC is set to '%s' but wasn't found.${NC}\n" "$CC"
1086 if searchtool gnatgcc
"Free Software Foundation" nofail
> /dev
/null
; then
1088 elif searchtool gcc
"Free Software Foundation" nofail
> /dev
/null
; then
1091 searchtool cc
'^' nofail
> /dev
/null || please_install gcc
1096 # We can leave $CXX empty if it's not set since *buildgcc* never
1097 # calls it directly. This way configure scripts can search for
1098 # themselves and we still override it when a bootstrapped g++ is
1099 # to be used (cf. hostcxx()).
1100 if [ -n "$CXX" ]; then
1101 if [ ! -x "$(command -v "$CXX" 2>/dev/null)" ]; then
1102 printf "${RED}ERROR:${red} CXX is set to '%s' but wasn't found.${NC}\n" "$CXX"
1106 searchtool g
++ "Free Software Foundation" nofail
> /dev
/null || \
1107 searchtool clang
"clang version" nofail
> /dev
/null || \
1108 searchtool clang
"LLVM" "" "g++" > /dev
/null
1111 check_for_library
"-lz" "zlib (zlib1g-dev or zlib-devel)"
1113 if [ "$HALT_FOR_TOOLS" -ne 0 ]; then
1117 # This initial cleanup is useful when updating the toolchain script.
1119 if [ "$clean" = "1" ]; then
1123 # Set up host compiler and flags needed for various OSes
1125 if is_package_enabled
"GCC"; then
1126 # sane preset: let the configure script figure out things by itself
1127 # more importantly, avoid any values that might already linger in the variable
1129 if [ "$UNAME" = "Darwin" ]; then
1130 #GCC_OPTIONS="$GCC_OPTIONS --enable-threads=posix"
1132 # generally the OS X compiler can create x64 binaries.
1133 # Per default it generated i386 binaries in 10.5 and x64
1134 # binaries in 10.6 (even if the kernel is 32bit)
1135 # For some weird reason, 10.5 autodetects an ABI=64 though
1136 # so we're setting the ABI explicitly here.
1137 if [ "$(sysctl -n hw.optional.x86_64 2>/dev/null)" -eq 1 ] 2>/dev
/null
; then
1143 # In Xcode 4.5.2 the default compiler is clang.
1144 # However, this compiler fails to compile gcc 4.7.x. As a
1145 # workaround it's possible to compile gcc with llvm-gcc.
1146 if $CC -v 2>&1 |
grep -q LLVM
; then
1149 elif [ "$UNAME" = "Linux" ] ||
[ "$UNAME" = "Cygwin" ]; then
1150 # gmp is overeager with detecting 64bit CPUs even if they run
1151 # a 32bit kernel and userland.
1152 if [ "$(uname -m 2>/dev/null)" = "i686" ]; then
1155 elif [ "$UNAME" = "NetBSD" ]; then
1156 # same for NetBSD but this one reports an i386
1157 if [ "$(uname -m 2>/dev/null)" = "i386" ]; then
1161 if [ -z "${LANGUAGES}" ]; then
1163 printf "\nFound compatible Ada compiler, enabling Ada support by default.\n\n"
1164 LANGUAGES
="ada,${DEFAULT_LANGUAGES}"
1166 printf "\n${red}WARNING${NC}\n"
1167 printf "No compatible Ada compiler (GNAT) found. You can continue without\n"
1168 printf "Ada support, but this will limit the features of ${blue}coreboot${NC} (e.g.\n"
1169 printf "native graphics initialization won't be available on most Intel\n"
1170 printf "boards).\n\n"
1172 printf "Usually, you can install GNAT with your package management system\n"
1173 printf "(the package is called \`gnat\` or \`gcc-ada\`). It has to match the\n"
1174 printf "\`gcc\` package in version. If there are multiple versions of GCC in-\n"
1175 printf "stalled, you can point this script to the matching version through\n"
1176 printf "the \`CC\` and \`CXX\` environment variables.\n\n"
1178 printf "e.g. on Ubuntu 14.04, if \`gcc\` is \`gcc-4.8\`:\n"
1179 printf " apt-get install gnat-4.8 && make crossgcc\n\n"
1181 printf "on Ubuntu 16.04, if \`gcc\` is \`gcc-5\`:\n"
1182 printf " apt-get install gnat-5 && make crossgcc\n"
1184 LANGUAGES
="${DEFAULT_LANGUAGES}"
1187 if [ "$BOOTSTRAP" != 1 ] && \
1188 { [ "$(hostcc_major)" -lt 4 ] || \
1189 { [ "$(hostcc_major)" -eq 4 ] && \
1190 [ "$(hostcc_minor)" -lt 9 ] ; } ; }
1192 printf "\n${red}WARNING${NC}\n"
1193 printf "Building coreboot requires a host compiler newer than 4.9.x while\n"
1194 printf "yours is $(hostcc_version).\n"
1195 printf "Enabling bootstrapping to provide a sufficiently new compiler:\n"
1196 printf "This will take significantly longer than a usual build.\n"
1197 printf "Alternatively you can abort now and update your host compiler.\n"
1201 if ada_requested
; then
1202 if ! have_gnat
; then
1203 please_install gnat gcc-ada
1209 export HOSTCFLAGS
="-Os"
1210 if have_hostcflags_from_gmp
; then
1211 set_hostcflags_from_gmp
1214 if [ "$USECCACHE" = 1 ]; then
1218 # Prepare target directory for building GCC
1219 # (dependencies must be in the PATH)
1220 mkdir
-p "$DESTDIR$TARGETDIR/bin"
1221 mkdir
-p "$DESTDIR$TARGETDIR/share"
1222 export PATH
=$DESTDIR$TARGETDIR/bin
:$PATH
1224 # Download, unpack, patch and build all packages
1226 printf "Downloading and verifying tarballs ...\n"
1228 for P
in $PACKAGES; do
1229 download
"$P" ||
exit "$?"
1230 verify_hash
"$P" ||
exit "$?"
1232 printf "Downloaded tarballs ... ${green}ok${NC}\n"
1234 printf "Unpacking and patching ...\n"
1235 for P
in $PACKAGES; do
1236 unpack_and_patch
$P ||
exit 1
1238 printf "Unpacked and patched ... ${green}ok${NC}\n"
1240 if [ -n "$BOOTSTRAPONLY" ]; then
1241 printf "Building bootstrap compiler only ...\n"
1242 for pkg
in GMP MPFR MPC GCC
; do
1248 printf "Building packages ...\n"
1249 for package
in $PACKAGES; do
1252 printf "Packages built ... ${green}ok${NC}\n"
1254 # Adding git information of current tree to target directory
1255 # for reproducibility
1256 PROGNAME
=$
(basename "$0")
1257 rm -f "$DESTDIR$TARGETDIR/share/$PROGNAME-*"
1258 cp "$PROGNAME" "$DESTDIR$TARGETDIR/share/$PROGNAME-$CROSSGCC_VERSION"
1260 # Adding edk2 tools template
1261 mkdir
-p "$DESTDIR$TARGETDIR/share/edk2config"
1262 sed -e "s,@@PREFIX@@,$TARGETDIR,g" edk2tools.txt
> "$DESTDIR$TARGETDIR/share/edk2config/tools_def.txt"
1263 printf "Copied EDK2 tools template ... ${green}ok${NC}\n"
1267 printf "\n${green}You can now run $NAME from $TARGETDIR.${NC}\n"