blob: f4379ad1576af8ace492baf811ddc38fc55dab2d [file] [log] [blame]
Martin Roth0ad5fbd2020-12-24 12:06:38 -07001#!/usr/bin/env sh
Martin Roth987d42d2018-07-22 11:45:29 -06002# shellcheck disable=SC2030,SC2031,SC2059
3# The above line must be directly after the shebang line.
4# Disables these warnings:
5# 2030 - Modification of var is local (to subshell caused by pipeline).
6# shell check 0.4.6 gets confused by the read -t 1 command and interprets
7# the '1' as $1 getting modified.
8# 2031 - var was modified in a subshell. That change might be lost.
9# caused by shell check bug with SC2030? This causes any $1 from that
10# point on to be flagged.
11# 2059 - Don't use variables in the printf format string. Use printf "..%s.." "$foo".
12# This is used for all of our color printing.
13
Stefan Reinauer074d9132009-09-26 16:43:17 +000014#
Patrick Georgi7333a112020-05-08 20:48:04 +020015# SPDX-License-Identifier: GPL-2.0-only
Stefan Reinauer074d9132009-09-26 16:43:17 +000016
Martin Roth987d42d2018-07-22 11:45:29 -060017cd "$(dirname "$0")" || exit 1
Patrick Georgi8135dba2015-03-17 21:05:20 +010018
Felix Singer02750d02021-10-17 15:43:21 +020019if [ -z "$CROSSGCC_VERSION" ]; then
20 CROSSGCC_VERSION="$(git log -n 1 --pretty=%cd --date=short .)_$(git log -n 1 --pretty=%h .)"
21fi
Stefan Reinauer074d9132009-09-26 16:43:17 +000022
23# default settings
Stefan Reinauer85b07d62015-06-09 14:45:14 -070024PACKAGE=GCC
Stefan Reinauerd7649122015-06-09 11:44:25 -070025TARGETDIR=$(pwd)/xgcc
Stefan Reinauer074d9132009-09-26 16:43:17 +000026TARGETARCH=i386-elf
Nico Huber66c2c1a2016-09-20 13:09:29 +020027DEFAULT_LANGUAGES=c
28LANGUAGES=
Stefan Reinauer074d9132009-09-26 16:43:17 +000029DESTDIR=
Stefan Reinauer85b07d62015-06-09 14:45:14 -070030SAVETEMPS=0
Nico Huber234d2462016-01-26 16:10:17 +010031BOOTSTRAP=0
Martin Roth2c6a8062016-11-14 11:58:39 -070032THREADS=1
Martin Rothe59868c2023-08-20 20:21:17 -060033FETCH_ONLY=0
Martin Roth3b32af92022-11-27 12:55:31 -070034USE_COREBOOT_MIRROR=0
35COREBOOT_MIRROR_URL="https://www.coreboot.org/releases/crossgcc-sources"
Stefan Reinauer074d9132009-09-26 16:43:17 +000036
Stefan Reinauer699ac272015-06-05 12:43:28 -070037# GCC toolchain version numbers
Elyes Haouas02e4d322023-08-01 04:49:56 +020038GMP_VERSION=6.3.0
Elyes Haouasf3ae1a12023-08-22 18:04:52 +020039MPFR_VERSION=4.2.1
Elyes Haouasd15a9f92022-12-10 06:00:08 +010040MPC_VERSION=1.3.1
Felix Singeracdd8dd2024-04-06 05:32:25 +000041GCC_VERSION=14.1.0
Elyes Haouas824ba492024-02-17 10:15:46 +010042BINUTILS_VERSION=2.42
Felix Singer41fdb882024-04-04 13:36:09 +000043IASL_VERSION=20240321
Stefan Reinauer14ce2132015-06-05 13:01:13 -070044# CLANG version number
Elyes Haouasb4949d32024-05-20 10:05:23 +020045CLANG_VERSION=18.1.6
Felix Singer6b4036e2024-04-04 13:42:46 +000046CMAKE_VERSION=3.29.3
Elyes Haouas00900392024-04-13 10:38:20 +020047NASM_VERSION=2.16.03
Stefan Reinauer074d9132009-09-26 16:43:17 +000048
Martin Roth3b32af92022-11-27 12:55:31 -070049# Filename for each package
50GMP_ARCHIVE="gmp-${GMP_VERSION}.tar.xz"
51MPFR_ARCHIVE="mpfr-${MPFR_VERSION}.tar.xz"
52MPC_ARCHIVE="mpc-${MPC_VERSION}.tar.gz"
53GCC_ARCHIVE="gcc-${GCC_VERSION}.tar.xz"
54BINUTILS_ARCHIVE="binutils-${BINUTILS_VERSION}.tar.xz"
Felix Singer055c6d52024-02-24 18:52:54 +010055IASL_ARCHIVE="acpica-unix-${IASL_VERSION}.tar.gz"
Martin Roth3b32af92022-11-27 12:55:31 -070056# CLANG toolchain FILE locations
Arthur Heymanscccada22024-02-23 16:47:49 +010057LLD_ARCHIVE="lld-${CLANG_VERSION}.src.tar.xz"
Martin Roth3b32af92022-11-27 12:55:31 -070058LLVM_ARCHIVE="llvm-${CLANG_VERSION}.src.tar.xz"
59CLANG_ARCHIVE="clang-${CLANG_VERSION}.src.tar.xz"
60CRT_ARCHIVE="compiler-rt-${CLANG_VERSION}.src.tar.xz"
61CTE_ARCHIVE="clang-tools-extra-${CLANG_VERSION}.src.tar.xz"
62LLVMCMAKE_ARCHIVE="cmake-${CLANG_VERSION}.src.tar.xz"
Arthur Heymanscccada22024-02-23 16:47:49 +010063LIBUNWIND_ARCHIVE="libunwind-${CLANG_VERSION}.src.tar.xz"
Martin Roth3b32af92022-11-27 12:55:31 -070064CMAKE_ARCHIVE="cmake-${CMAKE_VERSION}.tar.gz"
65NASM_ARCHIVE="nasm-${NASM_VERSION}.tar.bz2"
66
67# These URLs are sanitized by the jenkins toolchain test builder, so if
Martin Roth1484c032016-03-08 09:37:14 -070068# 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.
Stefan Reinauer074d9132009-09-26 16:43:17 +000070
Martin Roth3b32af92022-11-27 12:55:31 -070071# GCC toolchain archive locations
72GMP_BASE_URL="https://ftpmirror.gnu.org/gmp"
73MPFR_BASE_URL="https://ftpmirror.gnu.org/mpfr"
74MPC_BASE_URL="https://ftpmirror.gnu.org/mpc"
75GCC_BASE_URL="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}"
76BINUTILS_BASE_URL="https://ftpmirror.gnu.org/binutils"
Felix Singer41fdb882024-04-04 13:36:09 +000077IASL_BASE_URL="https://downloadmirror.intel.com/819451"
Martin Roth3b32af92022-11-27 12:55:31 -070078# CLANG toolchain archive locations
79LLVM_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
80CLANG_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
81CRT_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
82CTE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
83LLVMCMAKE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
Arthur Heymanscccada22024-02-23 16:47:49 +010084LLD_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
85LIBUNWIND_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
Martin Roth3b32af92022-11-27 12:55:31 -070086CMAKE_BASE_URL="https://cmake.org/files/v${CMAKE_VERSION%.*}"
87NASM_BASE_URL="https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}"
88
89ALL_ARCHIVES="$GMP_BASE_URL/$GMP_ARCHIVE $MPFR_BASE_URL/$MPFR_ARCHIVE $MPC_BASE_URL/$MPC_ARCHIVE \
90 $GCC_BASE_URL/$GCC_ARCHIVE $BINUTILS_BASE_URL/$BINUTILS_ARCHIVE $IASL_BASE_URL/$IASL_ARCHIVE \
Arthur Heymanscccada22024-02-23 16:47:49 +010091 $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"
Martin Roth58c68d52016-03-01 15:22:42 -070094
Stefan Reinauer699ac272015-06-05 12:43:28 -070095# GCC toolchain directories
Stefan Reinauer074d9132009-09-26 16:43:17 +000096GMP_DIR="gmp-${GMP_VERSION}"
97MPFR_DIR="mpfr-${MPFR_VERSION}"
Stefan Reinauer5f1ad892010-05-17 11:02:25 +000098MPC_DIR="mpc-${MPC_VERSION}"
Martin Roth987d42d2018-07-22 11:45:29 -060099# shellcheck disable=SC2034
Stefan Reinauer074d9132009-09-26 16:43:17 +0000100GCC_DIR="gcc-${GCC_VERSION}"
Martin Roth987d42d2018-07-22 11:45:29 -0600101# shellcheck disable=SC2034
Stefan Reinauer074d9132009-09-26 16:43:17 +0000102BINUTILS_DIR="binutils-${BINUTILS_VERSION}"
Felix Singer055c6d52024-02-24 18:52:54 +0100103IASL_DIR="acpica-unix-${IASL_VERSION}"
Stefan Reinauer14ce2132015-06-05 13:01:13 -0700104# CLANG toolchain directories
Arthur Heymanscccada22024-02-23 16:47:49 +0100105LLD_DIR="lld-${CLANG_VERSION}.src"
Stefan Reinauer14ce2132015-06-05 13:01:13 -0700106LLVM_DIR="llvm-${CLANG_VERSION}.src"
Elyes HAOUAS8f1853c2020-08-02 09:46:15 +0200107CLANG_DIR="clang-${CLANG_VERSION}.src"
Stefan Reinauer14ce2132015-06-05 13:01:13 -0700108CRT_DIR="compiler-rt-${CLANG_VERSION}.src"
109CTE_DIR="clang-tools-extra-${CLANG_VERSION}.src"
Elyes Haouasc8870b12022-09-16 12:10:00 +0200110LLVMCMAKE_DIR="cmake-${CLANG_VERSION}.src"
Arthur Heymanscccada22024-02-23 16:47:49 +0100111LIBUNWIND_DIR="libunwind-${CLANG_VERSION}.src"
Stefan Reinauer3b593492017-06-19 17:28:54 -0700112CMAKE_DIR="cmake-${CMAKE_VERSION}"
Martin Rothd70f5fa2019-05-26 17:24:19 -0600113NASM_DIR="nasm-${NASM_VERSION}"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000114
Patrick Georgi6321f522015-02-27 23:36:26 +0100115unset MAKELEVEL MAKEFLAGS
116
Patrick Georgi1861ff72011-10-31 12:15:55 +0100117red='\033[0;31m'
118RED='\033[1;31m'
119green='\033[0;32m'
120GREEN='\033[1;32m'
121blue='\033[0;34m'
Patrick Georgi1861ff72011-10-31 12:15:55 +0100122CYAN='\033[1;36m'
123NC='\033[0m' # No Color
Stefan Reinauer074d9132009-09-26 16:43:17 +0000124
Martin Roth987d42d2018-07-22 11:45:29 -0600125UNAME=$(if uname | grep -iq cygwin; then echo Cygwin; else uname; fi)
Martin Roth88463822016-01-07 11:03:36 -0700126HALT_FOR_TOOLS=0
Stefan Reinauer0d2119d2013-07-10 14:27:56 -0700127
Nico Huber08bb8372017-06-24 19:50:35 +0200128hostcc()
129{
130 # $1 "host" or "target"
Martin Roth987d42d2018-07-22 11:45:29 -0600131 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then
132 echo "$DESTDIR$TARGETDIR/bin/gcc"
Nico Huber08bb8372017-06-24 19:50:35 +0200133 else
Martin Roth987d42d2018-07-22 11:45:29 -0600134 echo "$CC"
Nico Huber08bb8372017-06-24 19:50:35 +0200135 fi
136}
137
138hostcxx()
139{
140 # $1 "host" or "target"
Martin Roth987d42d2018-07-22 11:45:29 -0600141 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then
142 echo "$DESTDIR$TARGETDIR/bin/g++"
Nico Huber08bb8372017-06-24 19:50:35 +0200143 else
Martin Roth987d42d2018-07-22 11:45:29 -0600144 echo "$CXX"
Nico Huber08bb8372017-06-24 19:50:35 +0200145 fi
146}
147
Patrick Georgi198d23c2012-12-08 08:02:44 +0100148normalize_dirs()
149{
Martin Roth987d42d2018-07-22 11:45:29 -0600150 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"
Martin Roth1039d272022-01-31 10:17:43 -0700153 rm -rf "$DESTDIR$TARGETDIR/lib32" "$DESTDIR$TARGETDIR/lib64"
Patrick Georgi198d23c2012-12-08 08:02:44 +0100154
Martin Roth987d42d2018-07-22 11:45:29 -0600155 perl -pi -e "s,/lib32,/lib," "$DESTDIR$TARGETDIR"/lib/*.la
156 perl -pi -e "s,/lib64,/lib," "$DESTDIR$TARGETDIR"/lib/*.la
Patrick Georgi198d23c2012-12-08 08:02:44 +0100157}
158
Nico Hubercd87e1b2017-06-24 20:35:59 +0200159countdown()
160{
161 tout=${1:-10}
162
Martin Roth987d42d2018-07-22 11:45:29 -0600163 printf "\nPress Ctrl-C to abort, Enter to continue... %2ds" "$tout"
164 while [ "$tout" -gt 0 ]; do
Nico Hubercd87e1b2017-06-24 20:35:59 +0200165 sleep 1
166 tout=$((tout - 1))
167 printf "\b\b\b%2ds" $tout
168 done
169 printf "\n"
170}
171
172timeout()
173{
174 tout=${1:-10}
175
176 # Ignore SIGUSR1, should interrupt `read` though.
177 trap false USR1
178 # Clean up in case the user aborts.
179 trap 'kill $counter > /dev/null 2>&1' EXIT
180
Martin Roth987d42d2018-07-22 11:45:29 -0600181 (countdown "$tout"; kill -USR1 $$)&
Nico Hubercd87e1b2017-06-24 20:35:59 +0200182 counter=$!
183
184 # Some shells with sh compatibility mode (e.g. zsh, mksh) only
185 # let us interrupt `read` if a non-standard -t parameter is given.
Martin Roth987d42d2018-07-22 11:45:29 -0600186 # shellcheck disable=SC2034,SC2039,SC2162
Nico Hubercd87e1b2017-06-24 20:35:59 +0200187 if echo | read -t 1 foo 2>/dev/null; then
188 read -t $((tout + 1)) foo
189 else
190 read foo
191 fi
192
193 kill $counter > /dev/null 2>&1
194 trap - USR1 EXIT
195}
196
Stefan Reinauer93a96302015-06-15 12:36:53 -0700197please_install()
198{
Martin Roth88463822016-01-07 11:03:36 -0700199 HALT_FOR_TOOLS=1
Martin Roth987d42d2018-07-22 11:45:29 -0600200 # shellcheck disable=SC1091
Patrick Georgi5da95dc2015-07-17 23:33:05 +0200201 test -r /etc/os-release && . /etc/os-release
Alex Thiessen72d10892018-01-12 01:45:53 +0000202 # vanilla debian doesn't define `ID_LIKE`, just `ID`
203 if [ -z "${ID_LIKE}" ] && [ -n "${ID}" ]; then
204 ID_LIKE=${ID}
205 fi
Stefan Reinauer93a96302015-06-15 12:36:53 -0700206 case "$ID_LIKE" in
207 debian) solution="sudo apt-get install $1" ;;
208 suse) solution="sudo zypper install $1" ;;
209 *) solution="using your OS packaging system" ;;
210 esac
211
Patrick Georgidf1ff232017-01-07 09:28:43 +0100212 printf "${RED}ERROR:${red} Missing tool: Please install '$1'. (eg $solution)${NC}\n" >&2
Martin Rothe3963172016-01-06 13:54:32 -0700213 if [ -n "$2" ]; then
Patrick Georgidf1ff232017-01-07 09:28:43 +0100214 printf "${RED}ERROR:${red} or install '$2'.${NC}\n" >&2
Martin Rothe3963172016-01-06 13:54:32 -0700215 fi
Stefan Reinauer93a96302015-06-15 12:36:53 -0700216}
217
Patrick Georgib7062882015-02-24 10:52:14 +0100218searchtool()
Stefan Reinauer074d9132009-09-26 16:43:17 +0000219{
220 # $1 short name
Patrick Georgib7062882015-02-24 10:52:14 +0100221 # $2 search string
222 # $3 soft fail if set
Martin Rothe3963172016-01-06 13:54:32 -0700223 # $4 alternative package to install on failure
Patrick Georgib7062882015-02-24 10:52:14 +0100224 # result: file name of that tool on stdout
225 # or no output if nothing suitable was found
226 search=GNU
227 if [ -n "$2" ]; then
228 search="$2"
229 fi
Stefan Reinauer074d9132009-09-26 16:43:17 +0000230 for i in "$1" "g$1" "gnu$1"; do
Martin Roth987d42d2018-07-22 11:45:29 -0600231 if [ -x "$(command -v "$i" 2>/dev/null)" ]; then
Stefan Reinauerdbc00872015-06-09 11:50:05 -0700232 if [ "$(cat /dev/null | $i --version 2>&1 | grep -c "$search")" \
233 -gt 0 ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600234 echo "$i"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000235 return
236 fi
237 fi
238 done
Andrew Wub67e9a12014-04-28 18:13:44 +0800239 # A workaround for OSX 10.9 and some BSDs, whose nongnu
240 # patch and tar also work.
Martin Roth987d42d2018-07-22 11:45:29 -0600241 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"
Zheng Bao36156ff2012-09-28 16:18:58 +0800245 return
246 fi
247 fi
248 fi
Martin Roth987d42d2018-07-22 11:45:29 -0600249 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
zbao5cf758d2015-09-01 22:28:57 -0400252 #xxxsum [file]
Martin Roth987d42d2018-07-22 11:45:29 -0600253 echo "$1"
zbao5cf758d2015-09-01 22:28:57 -0400254 return
Martin Roth987d42d2018-07-22 11:45:29 -0600255 elif [ -x "$(command -v "$algor" 2>/dev/null)" ]; then
zbao5cf758d2015-09-01 22:28:57 -0400256 #xxx [file]
Martin Roth987d42d2018-07-22 11:45:29 -0600257 echo "$algor"
zbao5cf758d2015-09-01 22:28:57 -0400258 return
Martin Rothd55f5eb2017-06-15 11:37:26 -0600259 elif [ -x "$(command -v openssl 2>/dev/null)" ]; then
zbao5cf758d2015-09-01 22:28:57 -0400260 #openssl xxx [file]
Martin Roth987d42d2018-07-22 11:45:29 -0600261 echo openssl "$algor"
zbao5cf758d2015-09-01 22:28:57 -0400262 return
Martin Rothd55f5eb2017-06-15 11:37:26 -0600263 elif [ -x "$(command -v cksum 2>/dev/null)" ]; then
zbao5cf758d2015-09-01 22:28:57 -0400264 #cksum -a xxx [file]
265 #cksum has special options in NetBSD. Actually, NetBSD will use the second case above.
Martin Roth987d42d2018-07-22 11:45:29 -0600266 echo "buildgcc" | cksum -a "$algor" > /dev/null 2>/dev/null && \
267 echo cksum -a "$algor"
zbao5cf758d2015-09-01 22:28:57 -0400268 return
zbao939dc842015-04-30 04:44:07 +0800269 fi
270 fi
Martin Rothe3963172016-01-06 13:54:32 -0700271
Martin Roth987d42d2018-07-22 11:45:29 -0600272 [ -z "$3" ] && please_install "$1" "$4"
Patrick Georgib7062882015-02-24 10:52:14 +0100273 false
Stefan Reinauer074d9132009-09-26 16:43:17 +0000274}
275
Martin Roth591790f2016-03-20 20:39:04 -0600276# Run a compile check of the specified library option to see if it's installed
277check_for_library() {
Martin Roth987d42d2018-07-22 11:45:29 -0600278 LIBRARY_FLAGS="$1"
279 LIBRARY_PACKAGES="$2"
280 LIBTEST_FILE=.libtest
Martin Roth591790f2016-03-20 20:39:04 -0600281
282 echo "int main(int argc, char **argv) { (void) argc; (void) argv; return 0; }" > "${LIBTEST_FILE}.c"
283
Martin Roth987d42d2018-07-22 11:45:29 -0600284 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200285 "$CC" $CFLAGS $LIBRARY_FLAGS "${LIBTEST_FILE}.c" -o "${LIBTEST_FILE}" >/dev/null 2>&1 || \
Martin Roth591790f2016-03-20 20:39:04 -0600286 please_install "$LIBRARY_PACKAGES"
287 rm -rf "${LIBTEST_FILE}.c" "${LIBTEST_FILE}"
288}
289
Nico Huberaee7f462016-09-20 12:55:19 +0200290buildcc_major() {
291 echo "${GCC_VERSION}" | cut -d. -f1
292}
293
Nico Huber26267a72016-12-04 02:45:58 +0100294buildcc_minor() {
295 echo "${GCC_VERSION}" | cut -d. -f2
296}
297
Nico Huberaee7f462016-09-20 12:55:19 +0200298buildcc_version() {
299 echo "${GCC_VERSION}" | cut -d. -f1-2
300}
301
302hostcc_major() {
303 (echo __GNUC__ | ${CC} -E - 2>/dev/null || echo 0) | tail -1
304}
305
306hostcc_minor() {
307 (echo __GNUC_MINOR__ | ${CC} -E - 2>/dev/null || echo 0) | tail -1
308}
309
310hostcc_version() {
311 printf "%d.%d" "$(hostcc_major)" "$(hostcc_minor)"
312}
313
Nico Huber75797162016-09-20 13:01:57 +0200314hostcc_has_gnat1() {
315 [ -x "$(${CC} -print-prog-name=gnat1)" ]
316}
317
Nico Hubercd87e1b2017-06-24 20:35:59 +0200318have_gnat() {
319 hostcc_has_gnat1 && \
320 searchtool gnatbind "Free Software Foundation" nofail > /dev/null
321}
322
Nico Huber75797162016-09-20 13:01:57 +0200323ada_requested() {
324 echo "${LANGUAGES}" | grep -q '\<ada\>'
325}
326
Stefan Reinauer88935482015-06-05 09:51:10 -0700327download() {
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700328 package=$1
Martin Roth987d42d2018-07-22 11:45:29 -0600329 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700330 if [ "${USE_COREBOOT_MIRROR}" -eq 0 ]; then
331 url="$(eval echo \$$package"_BASE_URL")"
332 else
333 url="${COREBOOT_MIRROR_URL}"
334 fi
Stefan Reinauer699ac272015-06-05 12:43:28 -0700335
Martin Roth3b32af92022-11-27 12:55:31 -0700336 file="$(eval echo \$$package"_ARCHIVE")"
337 printf " * ${file} "
Stefan Reinauer88935482015-06-05 09:51:10 -0700338
Martin Roth3b32af92022-11-27 12:55:31 -0700339 if test -f "tarballs/${file}"; then
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200340 printf "(cached)... "
zbaod22b9ea2015-08-30 23:35:16 -0400341 else
Martin Roth3b32af92022-11-27 12:55:31 -0700342 printf "(downloading from ${url}/${file})"
343 rm -f "tarballs/${file}"
Martin Roth987d42d2018-07-22 11:45:29 -0600344 cd tarballs || exit 1
Martin Roth3b32af92022-11-27 12:55:31 -0700345 download_showing_percentage "${url}/${file}"
Stefan Reinauer88935482015-06-05 09:51:10 -0700346 cd ..
zbaod22b9ea2015-08-30 23:35:16 -0400347 fi
348
Martin Roth3b32af92022-11-27 12:55:31 -0700349 if [ ! -f "tarballs/${file}" ]; then
350 printf "${RED}Failed to download ${file}.${NC}\n"
Stefan Reinauerdbc00872015-06-09 11:50:05 -0700351 exit 1
352 fi
Stefan Reinauer88935482015-06-05 09:51:10 -0700353}
354
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200355# Compute the hash of the package given in $1, and print it raw (just the
356# hexadecimal hash).
357compute_hash() {
358 package=$1
Martin Roth987d42d2018-07-22 11:45:29 -0600359 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700360 file="$(eval echo \$$package"_ARCHIVE")"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200361
362 if test -z "$CHECKSUM"; then
363 echo "${RED}\$CHECKSUM program missing. This is bad.${NC}" 1>&2
364 exit 1
365 fi
366
367 $CHECKSUM "tarballs/$file" 2>/dev/null | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@'
368}
369
370error_hash_missing() {
371 package="$1"
Martin Roth987d42d2018-07-22 11:45:29 -0600372 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700373 file="$(eval echo \$$package"_ARCHIVE")"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200374
375 fullhashfile="util/crossgcc/sum/$file.cksum"
376 printf "${RED}hash file missing:${NC}\n\n" 1>&2
377 printf "Please verify util/crossgcc/tarball/$file carefully\n" 1>&2
378 printf "(using PGP if possible), and then rename\n" 1>&2
379 printf " ${CYAN}${fullhashfile}.calc${NC}\n" 1>&2
380 printf " to ${CYAN}${fullhashfile}${NC}\n\n" 1>&2
381
382 exit 1
383}
384
385# Read the known hash file of the package given in $1, and print it raw.
386get_known_hash() {
387 package=$1
Martin Roth987d42d2018-07-22 11:45:29 -0600388 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700389 file="$(eval echo \$$package"_ARCHIVE")"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200390 hashfile="sum/$file.cksum"
391
392 if [ ! -f "$hashfile" ]; then
393 calc_hash="$(compute_hash "$package")" || exit 1
394 echo "$calc_hash tarballs/$file" > "${hashfile}.calc"
395
396 error_hash_missing "$package"
397 exit 1
398 fi
399
Martin Roth987d42d2018-07-22 11:45:29 -0600400 sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' < "$hashfile"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200401}
402
403error_hash_mismatch() {
404 package=$1
405 known_hash="$2"
406 computed_hash="$3"
Martin Roth987d42d2018-07-22 11:45:29 -0600407 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700408 file="$(eval echo \$$package"_ARCHIVE")"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200409
410 printf "${RED}hash mismatch:${NC}\n\n"
411 printf " expected (known) hash: $known_hash\n"
412 printf "calculated hash of downloaded file: $computed_hash\n\n"
413
414 printf "If you think this is due to a network error, please delete\n"
415 printf " ${CYAN}util/crossgcc/tarballs/$file${NC}\n"
416 printf "and try again. If the problem persists, it may be due to an\n"
417 printf "administration error on the file server, or you might be\n"
418 printf "subject to a Man-in-the-Middle attack\n\n"
419
420 exit 1
421}
422
423# verify_hash - Check that the hash of the file given in $1 matches the known
424# hash; Bail out on mismatch or missing hash file.
425verify_hash() {
426 package=$1
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200427
428 known_hash="$(get_known_hash "$package")" || exit "$?"
429 computed_hash="$(compute_hash "$package")" || exit "$?"
430
431 if [ "$known_hash" != "$computed_hash" ]; then
432 error_hash_mismatch "$package" "$known_hash" "$computed_hash"
433 exit 1
434 fi
435
Jonathan Neuschäfercb76069e2018-10-01 09:45:49 +0200436 printf "${GREEN}hash verified (${known_hash})${NC}\n"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200437}
438
Stefan Reinauer88935482015-06-05 09:51:10 -0700439unpack_and_patch() {
Martin Roth987d42d2018-07-22 11:45:29 -0600440 package="$1"
441 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700442 archive="$(eval echo \$$package"_ARCHIVE")"
Martin Roth987d42d2018-07-22 11:45:29 -0600443 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700444 dir="$(eval echo \$$package"_DIR")"
Martin Roth987d42d2018-07-22 11:45:29 -0600445 test -d "${dir}" && test -f "${dir}/.unpack_success" || (
Martin Roth3b32af92022-11-27 12:55:31 -0700446 printf " * "$archive"\n"
Stefan Reinauer88935482015-06-05 09:51:10 -0700447 FLAGS=zxf
Martin Roth987d42d2018-07-22 11:45:29 -0600448 suffix=$(echo "$archive" | sed 's,.*\.,,')
Martin Roth95f7b222016-03-20 12:38:48 -0600449 if [ "$suffix" = "gz" ] && [ -n "$PIGZ" ]; then FLAGS="-I pigz -xf"
450 elif [ "$suffix" = "gz" ]; then FLAGS=zxf
451 elif [ "$suffix" = "bz2" ] && [ -n "$LBZIP2" ]; then FLAGS="-I lbzip2 -xf"
452 elif [ "$suffix" = "bz2" ]; then FLAGS=jxf
453 elif [ "$suffix" = "xz" ]; then FLAGS="--xz -xf"
454 elif [ "$suffix" = "lzma" ]; then FLAGS="--lzma -xf"
455 fi
Martin Roth987d42d2018-07-22 11:45:29 -0600456 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700457 $TAR $FLAGS "tarballs/$archive"
Stefan Reinauer88935482015-06-05 09:51:10 -0700458 for patch in patches/${dir}_*.patch; do
Martin Roth987d42d2018-07-22 11:45:29 -0600459 test -r "$patch" || continue
460 printf " o $(basename "$patch")\n"
461 (cd "${dir}" || exit 1; $PATCH -s -N -p1 <"../${patch}") || {
Stefan Reinauer88935482015-06-05 09:51:10 -0700462 printf "\n${RED}Failed $patch.${NC}\n"
Stefan Reinauer916b8452015-06-09 11:54:49 -0700463 exit 1
464 }
Stefan Reinauer88935482015-06-05 09:51:10 -0700465 done
Martin Roth987d42d2018-07-22 11:45:29 -0600466 touch "${dir}/.unpack_success"
Stefan Reinauer88935482015-06-05 09:51:10 -0700467 )
468}
469
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700470fn_exists()
471{
Martin Roth987d42d2018-07-22 11:45:29 -0600472 # shellcheck disable=SC2039
473 type "$1" >/dev/null 2>&1
Patrick Georgi74c06422015-03-25 18:40:13 +0100474}
475
Patrick Georgif2c15f52015-06-11 21:07:31 +0200476is_package_enabled()
477{
478 echo "$PACKAGES" |grep -q "\<$1\>"
479}
480
Martin Roth444ece22016-04-01 18:46:29 -0600481package_uses_targetarch()
482{
Patrick Georgif32eed12021-10-16 10:50:00 +0200483 if [ "$1" = "GCC" ] || [ "$1" = "BINUTILS" ]; then
Martin Roth444ece22016-04-01 18:46:29 -0600484 true
485 else
486 false
487 fi
488}
489
Nico Huber11ea2b32016-01-26 16:09:31 +0100490generic_build()
491{
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700492 package=$1
Nico Huber11ea2b32016-01-26 16:09:31 +0100493 host_target=$2
494 builddir=$3
495 success=$4
Martin Rothc295d5e2016-11-14 11:56:11 -0700496 version=$5
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700497
Martin Roth987d42d2018-07-22 11:45:29 -0600498 fn_exists "build_$package" || return
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700499
Nico Huber11ea2b32016-01-26 16:09:31 +0100500 mkdir -p "$builddir"
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700501
Nico Huber11ea2b32016-01-26 16:09:31 +0100502 if [ -f "$success" ]; then
Martin Roth2c6a8062016-11-14 11:58:39 -0700503 printf "Skipping $package v$version for $host_target as it is already built\n"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700504 else
Martin Roth2c6a8062016-11-14 11:58:39 -0700505 printf "Building $package v$version for $host_target ... "
Nico Huber11ea2b32016-01-26 16:09:31 +0100506 DIR="$PWD"
Martin Roth987d42d2018-07-22 11:45:29 -0600507 cd "$builddir" || exit 1
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700508 rm -f .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600509 "build_${package}" "$host_target" > build.log 2>&1
510 cd "$DIR" || exit 1
Nico Huber11ea2b32016-01-26 16:09:31 +0100511 if [ ! -f "$builddir/.failed" ]; then
512 touch "$success";
513 else
Idwer Volleringe2ef3cf2017-08-15 00:53:13 +0200514 printf "${RED}failed${NC}. Check '$builddir/build.log'.\n"
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700515 exit 1
516 fi
517 printf "${green}ok${NC}\n"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700518 fi
519}
520
Nico Huber11ea2b32016-01-26 16:09:31 +0100521build_for_host()
522{
Martin Rothc295d5e2016-11-14 11:56:11 -0700523 package="$1"
Martin Roth987d42d2018-07-22 11:45:29 -0600524 # shellcheck disable=SC2086
Martin Rothc295d5e2016-11-14 11:56:11 -0700525 version="$(eval echo \$$package"_VERSION")"
Patrick Georgi1b593e52016-11-25 15:27:41 +0100526 generic_build "$package" host "build-$package" "${DESTDIR}${TARGETDIR}/.${package}.${version}.success" "$version"
Nico Huber11ea2b32016-01-26 16:09:31 +0100527}
528
529build_for_target()
530{
Martin Rothc295d5e2016-11-14 11:56:11 -0700531 package="$1"
Martin Roth987d42d2018-07-22 11:45:29 -0600532 # shellcheck disable=SC2086
Martin Rothc295d5e2016-11-14 11:56:11 -0700533 version="$(eval echo \$$package"_VERSION")"
Patrick Georgi1b593e52016-11-25 15:27:41 +0100534 generic_build "$package" target "build-${TARGETARCH}-$package" "${DESTDIR}${TARGETDIR}/.${TARGETARCH}-${package}.${version}.success" "$version"
Nico Huber11ea2b32016-01-26 16:09:31 +0100535}
536
537build()
538{
Martin Roth987d42d2018-07-22 11:45:29 -0600539 if package_uses_targetarch "$1"; then
540 if [ $BOOTSTRAP -eq 1 ] && [ ! -f "${DESTDIR}${TARGETDIR}/.GCC.${GCC_VERSION}.success" ]; then
Nico Huber234d2462016-01-26 16:10:17 +0100541 build_for_host GCC
542 fi
Martin Roth987d42d2018-07-22 11:45:29 -0600543 build_for_target "$1"
Nico Huber11ea2b32016-01-26 16:09:31 +0100544 else
Martin Roth987d42d2018-07-22 11:45:29 -0600545 build_for_host "$1"
Nico Huber11ea2b32016-01-26 16:09:31 +0100546 fi
547}
548
Nico Huber18c74d62017-06-24 20:35:59 +0200549exit_handler()
Zheng Baobb003c82016-08-05 13:41:51 +0800550{
551 printf "${NC}Stop\n"
552 exit 1
553}
554
Stefan Reinauer074d9132009-09-26 16:43:17 +0000555cleanup()
556{
Stefan Reinauer88e83e52016-04-06 15:39:48 -0700557 if [ $SAVETEMPS -ne 0 ]; then
558 printf "Leaving temporary files around... ${green}ok${NC}\n"
559 return
560 fi
561
Stefan Reinauer074d9132009-09-26 16:43:17 +0000562 printf "Cleaning up temporary files... "
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700563 for package in $PACKAGES; do
Martin Roth987d42d2018-07-22 11:45:29 -0600564 # shellcheck disable=SC2086
565 rm -rf "build-${TARGETARCH}-$package" "build-$package" "$(eval echo \$$package"_DIR")"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700566 done
zbaoff3f15c2015-08-26 22:00:31 -0400567 rm -f getopt
Stefan Reinauer074d9132009-09-26 16:43:17 +0000568 printf "${green}ok${NC}\n"
569}
570
571myhelp()
572{
Stefan Reinauer14ce2132015-06-05 13:01:13 -0700573 printf "Usage: $0 [-V] [-c] [-p <platform>] [-d <target directory>] [-D <dest dir>] [-C] [-G] [-S]\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000574 printf " $0 [-V|--version]\n"
575 printf " $0 [-h|--help]\n\n"
576
577 printf "Options:\n"
Felix Singer60c56be2021-10-17 14:54:12 +0200578 printf " [-W|--print-version Print machine readable version\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000579 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"
Patrick Georgic1a75b12011-11-04 21:37:14 +0100583 printf " [-y|--ccache] Use ccache when building cross compiler\n"
Nico Huber152e78e2016-09-20 15:38:40 +0200584 printf " [-n|--nocolor] don't print color codes in output\n"
585 printf " [-u|--urls] print the urls for all packages\n"
Patrick Georgi73166c72010-04-14 20:42:42 +0000586 printf " [-j|--jobs <num>] run <num> jobs in parallel in make\n"
Martin Roth588c79d2016-03-20 12:03:20 -0600587 printf " [-s]--supported <tool> print supported version of a tool\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000588 printf " [-d|--directory <target dir>] target directory to install cross compiler to\n"
Martin Roth588c79d2016-03-20 12:03:20 -0600589 printf " (defaults to $TARGETDIR)\n\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000590 printf " [-D|--destdir <dest dir>] destination directory to install cross compiler to\n"
Stefan Reinauer2c3cd122011-11-01 21:43:50 +0100591 printf " (for RPM builds, default unset)\n"
Martin Rothe59868c2023-08-20 20:21:17 -0600592 printf " [-f|--fetch] Download tarballs, but don't build anything\n"
Patrick Georgif32eed12021-10-16 10:50:00 +0200593 printf " [-P|--package <package>] Build a specific package: GCC, CLANG, IASL\n"
Stefan Reinauer85b07d62015-06-09 14:45:14 -0700594 printf " (defaults to $PACKAGE)\n"
595 printf "GCC specific options:\n"
Nico Huber234d2462016-01-26 16:10:17 +0100596 printf " [-b|--bootstrap] bootstrap the host compiler before building\n"
597 printf " the cross compiler\n"
Stefan Reinauer85b07d62015-06-09 14:45:14 -0700598 printf " [-p|--platform <platform>] target platform to build cross compiler for\n"
599 printf " (defaults to $TARGETARCH)\n"
Nico Huberbb313bf2015-09-08 12:30:27 +0200600 printf " [-l|--languages <languages>] comma separated list of target languages\n"
Nico Huber66c2c1a2016-09-20 13:09:29 +0200601 printf " (defaults to $DEFAULT_LANGUAGES)\n"
Patrick Georgif32eed12021-10-16 10:50:00 +0200602 printf "Platforms for GCC:\n"
Julius Wernerf96d9052019-08-16 15:35:39 -0700603 printf " x86_64 i386-elf i386-mingw32 riscv-elf arm aarch64\n"
Jonathan Neuschäferf14f6402016-03-11 20:22:23 +0100604 printf " powerpc64le-linux-gnu nds32le-elf\n\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000605}
606
Martin Rothedf965a2015-11-25 16:58:33 -0700607printversion() {
Martin Roth7014f822020-12-21 15:49:33 -0700608 printf "${blue}Welcome to the ${red}coreboot${blue} cross toolchain builder v$CROSSGCC_VERSION ${NC}\n\n"
Martin Rothedf965a2015-11-25 16:58:33 -0700609}
610
Stefan Reinauer074d9132009-09-26 16:43:17 +0000611myversion()
612{
Martin Rothedf965a2015-11-25 16:58:33 -0700613 printversion
Stefan Reinauer074d9132009-09-26 16:43:17 +0000614
615 cat << EOF
Stefan Reinauer5f1ad892010-05-17 11:02:25 +0000616Copyright (C) 2008-2010 by coresystems GmbH
Marc Jones2aac3f62011-08-08 16:07:50 -0600617Copyright (C) 2011 by Sage Electronic Engineering
Stefan Reinauer074d9132009-09-26 16:43:17 +0000618
619This program is free software; you can redistribute it and/or modify
620it under the terms of the GNU General Public License as published by
621the Free Software Foundation; version 2 of the License.
622
623This program is distributed in the hope that it will be useful,
624but WITHOUT ANY WARRANTY; without even the implied warranty of
625MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
626GNU General Public License for more details.
627
628EOF
629}
630
Nico Huber5f72f962016-01-31 23:05:19 +0100631have_hostcflags_from_gmp() {
Martin Roth987d42d2018-07-22 11:45:29 -0600632 grep -q __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" >/dev/null 2>&1
Nico Huber5f72f962016-01-31 23:05:19 +0100633}
634
635set_hostcflags_from_gmp() {
636 # Now set CFLAGS to match GMP CFLAGS but strip out -pedantic
637 # as GCC 4.6.x fails if it's there.
Martin Roth987d42d2018-07-22 11:45:29 -0600638 HOSTCFLAGS="$(grep __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" |cut -d\" -f2 |\
Idwer Volleringba349ab2016-07-24 02:10:19 +0200639 sed s,-pedantic,,)"
Martin Roth987d42d2018-07-22 11:45:29 -0600640 export HOSTCFLAGS
Nico Huber5f72f962016-01-31 23:05:19 +0100641}
642
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700643build_GMP() {
Nico Huber8bbd5962016-12-22 16:05:54 +0100644 # Check if GCC enables `-pie` by default (possible since GCC 6).
645 # We need PIC in all static libraries then.
Nico Huber2c1c02e2017-01-02 20:51:28 +0100646 if $CC -dumpspecs 2>/dev/null | grep -q '[{;][[:space:]]*:-pie\>'
Nico Huber8bbd5962016-12-22 16:05:54 +0100647 then
648 OPTIONS="$OPTIONS --with-pic"
649 fi
650
Martin Roth987d42d2018-07-22 11:45:29 -0600651 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200652 CC="$(hostcc host)" CXX="$(hostcxx host)" \
Felix Singerf8157af2022-11-23 10:12:26 +0100653 ../${GMP_DIR}/configure \
654 --disable-shared \
655 --enable-fat \
656 --prefix="$TARGETDIR" \
657 $OPTIONS || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600658 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700659 $MAKE $JOBS || touch .failed
660 $MAKE install DESTDIR=$DESTDIR || touch .failed
661
662 normalize_dirs
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700663
Nico Huber5f72f962016-01-31 23:05:19 +0100664 set_hostcflags_from_gmp
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700665}
666
667build_MPFR() {
Martin Roth987d42d2018-07-22 11:45:29 -0600668 test "$UNAME" = "Darwin" && CFLAGS="$CFLAGS -force_cpusubtype_ALL"
Nico Huber08bb8372017-06-24 19:50:35 +0200669 CC="$(hostcc host)" CXX="$(hostcxx host)" \
Felix Singerf8157af2022-11-23 10:12:26 +0100670 ../${MPFR_DIR}/configure \
671 --disable-shared \
672 --prefix="$TARGETDIR" \
Martin Roth987d42d2018-07-22 11:45:29 -0600673 --infodir="$TARGETDIR/info" \
Felix Singerf8157af2022-11-23 10:12:26 +0100674 --with-gmp="$DESTDIR$TARGETDIR" \
675 CFLAGS="$HOSTCFLAGS" || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600676 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700677 $MAKE $JOBS || touch .failed
678 $MAKE install DESTDIR=$DESTDIR || touch .failed
679
680 normalize_dirs
681
682 # work around build problem of libgmp.la
683 if [ "$DESTDIR" != "" ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600684 perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libgmp.la"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700685 fi
686}
687
688build_MPC() {
Nico Huber08bb8372017-06-24 19:50:35 +0200689 CC="$(hostcc host)" CXX="$(hostcxx host)" \
Felix Singerf8157af2022-11-23 10:12:26 +0100690 ../${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
Patrick Georgi790aab62017-04-26 17:35:35 +0200697
698 # work around build problem of libmpfr.la
699 if [ "$DESTDIR" != "" ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600700 perl -pi -e "s,$TARGETDIR/lib/libgmp.la,$DESTDIR\$&," "$DESTDIR$TARGETDIR/lib/libmpfr.la"
Patrick Georgi790aab62017-04-26 17:35:35 +0200701 fi
702
Martin Roth987d42d2018-07-22 11:45:29 -0600703 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700704 $MAKE $JOBS || touch .failed
705 $MAKE install DESTDIR=$DESTDIR || touch .failed
706
Patrick Georgi790aab62017-04-26 17:35:35 +0200707 # work around build problem of libmpfr.la
708 if [ "$DESTDIR" != "" ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600709 perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libmpfr.la"
Patrick Georgi790aab62017-04-26 17:35:35 +0200710 fi
711
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700712 normalize_dirs
713}
714
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700715build_BINUTILS() {
Nico Huberae6187f2016-12-22 22:16:39 +0100716 if [ $TARGETARCH = "x86_64-elf" ]; then
Stefan Reinauer682a90c2015-06-09 14:59:58 -0700717 ADDITIONALTARGET=",i386-elf"
718 fi
Patrick Georgif0d5f672022-09-08 20:25:46 +0200719 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200720 CC="$(hostcc target)" CXX="$(hostcxx target)" \
Felix Singerf8157af2022-11-23 10:12:26 +0100721 ../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 \
Elias Souza17d9d892023-02-18 12:53:34 -0300730 --disable-docs \
731 --disable-texinfo \
Patrick Georgif67005d2024-01-28 01:20:43 +0100732 ${TARGET_BINUTILS_OPTIONS} \
Nico Huber010ecf802016-12-22 16:19:37 +0100733 CFLAGS="$HOSTCFLAGS" \
Felix Singerf8157af2022-11-23 10:12:26 +0100734 CXXFLAGS="$HOSTCFLAGS" || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600735 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700736 $MAKE $JOBS || touch .failed
737 $MAKE install DESTDIR=$DESTDIR || touch .failed
738}
739
Nico Huber234d2462016-01-26 16:10:17 +0100740bootstrap_GCC() {
Martin Roth987d42d2018-07-22 11:45:29 -0600741 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200742 CC="$(hostcc host)" CXX="$(hostcxx host)" \
Nico Huber234d2462016-01-26 16:10:17 +0100743 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 \
Felix Singerf8157af2022-11-23 10:12:26 +0100750 --prefix="$TARGETDIR" \
751 --libexecdir="$TARGETDIR/lib" \
Nico Huber234d2462016-01-26 16:10:17 +0100752 --enable-bootstrap \
Felix Singerf8157af2022-11-23 10:12:26 +0100753 --disable-werror \
754 --disable-nls \
755 --disable-shared \
756 --disable-multilib \
757 --disable-libssp \
758 --disable-libquadmath \
759 --disable-libcc1 \
Patrick Georgi97a9df42017-04-26 22:18:18 +0200760 --disable-libsanitizer \
Felix Singerf8157af2022-11-23 10:12:26 +0100761 ${GCC_OPTIONS} \
762 --enable-languages="${LANGUAGES}" \
763 --with-gmp="$DESTDIR$TARGETDIR" \
764 --with-mpfr="$DESTDIR$TARGETDIR" \
Martin Roth987d42d2018-07-22 11:45:29 -0600765 --with-mpc="$DESTDIR$TARGETDIR" \
Martin Roth7014f822020-12-21 15:49:33 -0700766 --with-pkgversion="coreboot bootstrap v$CROSSGCC_VERSION" \
Nico Huber234d2462016-01-26 16:10:17 +0100767 && \
Martin Roth987d42d2018-07-22 11:45:29 -0600768 # shellcheck disable=SC2086
Nico Huber234d2462016-01-26 16:10:17 +0100769 $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 \
Nico Huber08bb8372017-06-24 19:50:35 +0200774 DESTDIR=$DESTDIR || touch .failed
Nico Huber234d2462016-01-26 16:10:17 +0100775}
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700776
Nico Huber234d2462016-01-26 16:10:17 +0100777build_cross_GCC() {
Stefan Reinauer45f77b82016-04-03 20:52:01 -0700778 # Work around crazy code generator in GCC that confuses CLANG.
Aaron Durbinb2229dc2016-04-07 16:58:10 -0500779 $CC --version | grep clang >/dev/null 2>&1 && \
Patrick Georgia7a5a562017-06-26 07:21:46 +0200780 CLANGFLAGS="-fbracket-depth=1024"
Nico Huber3f12d932017-08-31 23:11:18 +0200781 [ -n "$CXX" ] && $CXX --version | grep clang >/dev/null 2>&1 && \
Patrick Georgia7a5a562017-06-26 07:21:46 +0200782 CLANGCXXFLAGS="-fbracket-depth=1024"
Stefan Reinauer45f77b82016-04-03 20:52:01 -0700783
Maximilian Brune73213492024-01-18 18:15:17 +0600784 # standard code model is medlow but all mainboards are compiled with medany code model
785 if [ "${TARGETARCH}" = "riscv64-elf" ]; then
786 CFLAGS_FOR_TARGET_EXTRA="-mcmodel=medany"
787 fi
788
Stefan Reinauerd0f83722015-06-09 11:52:28 -0700789 # GCC does not honor HOSTCFLAGS at all. CFLAGS are used for
790 # both target and host object files.
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700791 # 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.
Stefan Reinauer45f77b82016-04-03 20:52:01 -0700794 # Also set the CXX version of the flags because GCC is now compiled
795 # using C++.
Martin Roth987d42d2018-07-22 11:45:29 -0600796 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200797 CC="$(hostcc target)" CXX="$(hostcxx target)" \
Maximilian Brune73213492024-01-18 18:15:17 +0600798 CFLAGS_FOR_TARGET="${CFLAGS_FOR_TARGET_EXTRA} -O2 -Dinhibit_libc" \
Patrick Georgia7a5a562017-06-26 07:21:46 +0200799 CFLAGS="$HOSTCFLAGS $CLANGFLAGS" \
800 CFLAGS_FOR_BUILD="$HOSTCFLAGS $CLANGFLAGS" \
801 CXXFLAGS="$HOSTCFLAGS $CLANGCXXFLAGS" \
802 CXXFLAGS_FOR_BUILD="$HOSTCFLAGS $CLANGCXXFLAGS" \
803 ../gcc-${GCC_VERSION}/configure \
Felix Singerf8157af2022-11-23 10:12:26 +0100804 --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 \
Patrick Georgi0a97d7e2016-01-25 09:51:22 +0100818 --disable-threads \
Felix Singerf8157af2022-11-23 10:12:26 +0100819 --enable-interwork \
820 --enable-multilib \
821 --enable-targets=all \
822 --disable-libatomic \
823 --disable-libcc1 \
824 --disable-decimal-float \
825 ${GCC_OPTIONS} \
Patrick Georgif67005d2024-01-28 01:20:43 +0100826 ${TARGET_GCC_OPTIONS} \
Felix Singerf8157af2022-11-23 10:12:26 +0100827 --enable-languages="${LANGUAGES}" \
Ronald G. Minnich7ee16b72016-02-12 21:54:59 +0000828 --with-system-zlib \
Felix Singerf8157af2022-11-23 10:12:26 +0100829 --with-gmp="$DESTDIR$TARGETDIR" \
830 --with-mpfr="$DESTDIR$TARGETDIR" \
Martin Roth987d42d2018-07-22 11:45:29 -0600831 --with-mpc="$DESTDIR$TARGETDIR" \
Felix Singerf8157af2022-11-23 10:12:26 +0100832 --with-gnu-as \
833 --with-gnu-ld \
Martin Roth7014f822020-12-21 15:49:33 -0700834 --with-pkgversion="coreboot toolchain v$CROSSGCC_VERSION" \
Nico Huber659f40b2018-05-23 17:06:53 +0200835 && \
Patrick Georgi095db332018-06-26 21:00:58 +0200836 mkdir -p gcc/$TARGETARCH && \
Nico Hubere87fcd42020-12-21 00:11:54 +0100837 rm -f "gcc/$TARGETARCH/$GCC_VERSION" && \
Martin Roth987d42d2018-07-22 11:45:29 -0600838 ln -s "$DESTDIR$TARGETDIR/$TARGETARCH/bin" "gcc/$TARGETARCH/$GCC_VERSION" && \
Nico Huber659f40b2018-05-23 17:06:53 +0200839 $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-gcc && \
Martin Roth987d42d2018-07-22 11:45:29 -0600840 $MAKE install-gcc DESTDIR="$DESTDIR" || touch .failed
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700841
Martin Roth987d42d2018-07-22 11:45:29 -0600842 if [ ! -f .failed ] && [ "$(echo $TARGETARCH | grep -c -- -mingw32)" -eq 0 ]; then
843 # shellcheck disable=SC2086
Nico Huber659f40b2018-05-23 17:06:53 +0200844 $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-target-libgcc && \
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700845 $MAKE install-target-libgcc DESTDIR=$DESTDIR || touch .failed
846 fi
847}
848
Nico Huber234d2462016-01-26 16:10:17 +0100849build_GCC() {
850 if [ "$1" = host ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600851 bootstrap_GCC "$1"
Nico Huber234d2462016-01-26 16:10:17 +0100852 else
Martin Roth987d42d2018-07-22 11:45:29 -0600853 build_cross_GCC "$1"
Nico Huber234d2462016-01-26 16:10:17 +0100854 fi
855}
856
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700857build_IASL() {
858 RDIR=$PWD
Martin Roth987d42d2018-07-22 11:45:29 -0600859 cd ../$IASL_DIR/generate/unix || exit 1
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700860 CFLAGS="$HOSTCFLAGS"
861 HOST="_LINUX"
Stefan Reinauera295ac12024-02-08 21:18:05 -0800862 test "$UNAME" = "Darwin" && HOST="_APPLE" && OPT_LDFLAGS="-Wl,-no_fixup_chains"
Martin Roth987d42d2018-07-22 11:45:29 -0600863 test "$UNAME" = "FreeBSD" && HOST="_FreeBSD"
864 test "$UNAME" = "Cygwin" && HOST="_CYGWIN"
Nico Huber08bb8372017-06-24 19:50:35 +0200865 HOST="$HOST" CFLAGS="$CFLAGS" \
Stefan Reinauera295ac12024-02-08 21:18:05 -0800866 OPT_LDFLAGS="$OPT_LDFLAGS" \
Martin Roth7014f822020-12-21 15:49:33 -0700867 OPT_CFLAGS="-O -D_FORTIFY_SOURCE=2 -D COREBOOT_TOOLCHAIN_VERSION='\"coreboot toolchain v$CROSSGCC_VERSION\"' " \
Elyes HAOUAS157851f2020-05-29 10:20:14 +0200868 $MAKE $JOBS CC="$(hostcc host)" iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract
Patrick Georgi54f86a52021-05-11 15:06:37 +0200869 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"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700872}
873
874build_LLVM() {
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700875
Arthur Heymanscccada22024-02-23 16:47:49 +0100876 ln -nsf "$LLD_DIR" ../lld
Patrick Georgi5a76a532021-06-03 08:48:26 +0200877 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
Elyes Haouasc8870b12022-09-16 12:10:00 +0200881 ln -nsf "$LLVMCMAKE_DIR" ../cmake
Arthur Heymanscccada22024-02-23 16:47:49 +0100882 ln -nsf "$LIBUNWIND_DIR" ../libunwind
Martin Roth987d42d2018-07-22 11:45:29 -0600883
Felix Singerf8157af2022-11-23 10:12:26 +0100884 $CMAKE -G "Unix Makefiles" \
885 -DCMAKE_INSTALL_PREFIX="$DESTDIR$TARGETDIR" \
Martin Roth7014f822020-12-21 15:49:33 -0700886 -DCLANG_VENDOR="coreboot toolchain v$CROSSGCC_VERSION - " \
Arthur Heymanscccada22024-02-23 16:47:49 +0100887 -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;compiler-rt;lld" \
Felix Singerf8157af2022-11-23 10:12:26 +0100888 -DLLVM_INCLUDE_BENCHMARKS="OFF" \
Felix Singer52191f22022-11-23 10:20:11 +0100889 -DLLVM_INCLUDE_TESTS="OFF" \
890 -DLLVM_INCLUDE_EXAMPLES="OFF" \
Felix Singerf8157af2022-11-23 10:12:26 +0100891 -DCMAKE_BUILD_TYPE=Release \
Felix Singer3e7438b2022-11-23 10:02:10 +0100892 -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;PowerPC;RISCV;X86" \
893 ../llvm || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600894 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700895 $MAKE $JOBS || touch .failed
896 $MAKE install || touch .failed
897
Arthur Heymanscccada22024-02-23 16:47:49 +0100898 rm -f ../llvm ../clang ../clang-tools-extra ../compiler-rt ../cmake ../lld ../libunwind
Patrick Georgi5a76a532021-06-03 08:48:26 +0200899
Elyes HAOUAS8f1853c2020-08-02 09:46:15 +0200900 cp -a ../$CLANG_DIR/tools/scan-build/* "$DESTDIR$TARGETDIR/bin"
901 cp -a ../$CLANG_DIR/tools/scan-view/* "$DESTDIR$TARGETDIR/bin"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700902}
903
Stefan Reinauer3b593492017-06-19 17:28:54 -0700904build_CMAKE() {
Nico Huber08bb8372017-06-24 19:50:35 +0200905 CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" \
Felix Singerf8157af2022-11-23 10:12:26 +0100906 ../${CMAKE_DIR}/configure \
Felix Singer3a5507f2023-04-01 11:32:56 +0200907 --parallel=${THREADS} \
Felix Singerf8157af2022-11-23 10:12:26 +0100908 --prefix="$TARGETDIR" || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600909 # shellcheck disable=SC2086
Stefan Reinauer3b593492017-06-19 17:28:54 -0700910 $MAKE $JOBS || touch .failed
911 $MAKE install DESTDIR=$DESTDIR || touch .failed
Stefan Reinauer3b593492017-06-19 17:28:54 -0700912}
913
Martin Rothd70f5fa2019-05-26 17:24:19 -0600914build_NASM() {
Elyes Haouas8d50e422023-01-28 12:54:28 +0100915 CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" \
Felix Singerf8157af2022-11-23 10:12:26 +0100916 ../${NASM_DIR}/configure \
917 --prefix="$TARGETDIR" || touch .failed
Martin Rothd70f5fa2019-05-26 17:24:19 -0600918 # shellcheck disable=SC2086
919 $MAKE $JOBS || touch .failed
920 $MAKE install DESTDIR=$DESTDIR || touch .failed
921
922 normalize_dirs
923}
924
Stefan Reinauerc66fd3c2017-06-21 14:57:28 -0700925print_supported() {
926 case "$PRINTSUPPORTED" in
Martin Rothedf965a2015-11-25 16:58:33 -0700927 BINUTILS|binutils) printf "%s\n" "$BINUTILS_VERSION";;
928 CLANG|clang) printf "%s\n" "$CLANG_VERSION";;
Martin Rothedf965a2015-11-25 16:58:33 -0700929 GCC|gcc) printf "%s\n" "$GCC_VERSION";;
Martin Rothedf965a2015-11-25 16:58:33 -0700930 GMP|gmp) printf "%s\n" "$GMP_VERSION";;
931 IASL|iasl) printf "%s\n" "$IASL_VERSION";;
Martin Rothedf965a2015-11-25 16:58:33 -0700932 MPC|mpc) printf "%s\n" "$MPC_VERSION";;
933 MPFR|mpfr) printf "%s\n" "$MPFR_VERSION";;
Martin Rothd70f5fa2019-05-26 17:24:19 -0600934 NASM|nasm) printf "%s\n" "${NASM_VERSION}";;
Stefan Reinauerc66fd3c2017-06-21 14:57:28 -0700935 *) printf "Unknown tool %s\n" "$PRINTSUPPORTED";;
Martin Rothedf965a2015-11-25 16:58:33 -0700936 esac
937}
Stefan Reinauer074d9132009-09-26 16:43:17 +0000938
Nico Huber18c74d62017-06-24 20:35:59 +0200939trap exit_handler 1 2 3 15
Zheng Baobb003c82016-08-05 13:41:51 +0800940
Patrick Georgi6bba29f2010-01-29 17:40:52 +0000941# Look if we have getopt. If not, build it.
942export PATH=$PATH:.
943getopt - > /dev/null 2>/dev/null || gcc -o getopt getopt.c
944
Stefan Reinauer074d9132009-09-26 16:43:17 +0000945# parse parameters.. try to find out whether we're running GNU getopt
Nico Huber27e8412b2017-12-05 22:02:21 +0100946getoptbrand="$(getopt -V 2>/dev/null | sed -e '1!d' -e 's,^\(......\).*,\1,')"
Peter Stuge09377b72011-08-21 06:24:55 +0200947if [ "${getoptbrand}" = "getopt" ]; then
Stefan Reinauer074d9132009-09-26 16:43:17 +0000948 # Detected GNU getopt that supports long options.
Martin Rothe59868c2023-08-20 20:21:17 -0600949 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 -- "$@")
Nico Huber78df0bf2016-09-20 14:11:53 +0200950 getopt_ret=$?
Nico Hubercc414dd2016-09-20 13:59:38 +0200951 eval set -- "$args"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000952else
953 # Detected non-GNU getopt
Martin Roth3b32af92022-11-27 12:55:31 -0700954 args=$(getopt WVhcd:bBp:l:P:j:D:tSys:unm $*)
Nico Huber78df0bf2016-09-20 14:11:53 +0200955 getopt_ret=$?
Martin Roth987d42d2018-07-22 11:45:29 -0600956 # shellcheck disable=SC2086
Stefan Reinauer074d9132009-09-26 16:43:17 +0000957 set -- $args
958fi
959
Nico Huber78df0bf2016-09-20 14:11:53 +0200960if [ $getopt_ret != 0 ]; then
Stefan Reinauer074d9132009-09-26 16:43:17 +0000961 myhelp
962 exit 1
963fi
964
965while true ; do
966 case "$1" in
Felix Singer60c56be2021-10-17 14:54:12 +0200967 -W|--print-version) shift; echo $CROSSGCC_VERSION; exit 0;;
Patrick Georgi9681cdc2017-09-22 18:57:10 +0200968 -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;;
Martin Roth3b32af92022-11-27 12:55:31 -0700977 -m|--mirror) shift; USE_COREBOOT_MIRROR=1;;
Patrick Georgi9681cdc2017-09-22 18:57:10 +0200978 -D|--destdir) shift; DESTDIR="$1"; shift;;
Martin Rothe59868c2023-08-20 20:21:17 -0600979 -f|--fetch) shift; FETCH_ONLY=1;;
Patrick Georgi9681cdc2017-09-22 18:57:10 +0200980 -j|--jobs) shift; THREADS="$1"; JOBS="-j $1"; shift;;
981 -P|--package) shift; PACKAGE="$1"; shift;;
Patrick Georgi9681cdc2017-09-22 18:57:10 +0200982 -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; \
Martin Roth4a53db02016-03-01 15:21:07 -0700986 unset red RED green GREEN blue BLUE cyan CYAN NC;;
Patrick Georgid2e0dd52013-06-09 08:05:45 +0200987 --) shift; break;;
Patrick Georgid2e0dd52013-06-09 08:05:45 +0200988 *) break;;
Stefan Reinauer074d9132009-09-26 16:43:17 +0000989 esac
990done
991
Nico Huberbd74d562016-09-20 14:16:43 +0200992if [ $# -gt 0 ]; then
993 printf "Excessive arguments: $*\n"
994 myhelp
995 exit 1
996fi
997
Stefan Reinauerc66fd3c2017-06-21 14:57:28 -0700998if [ -n "$PRINTSUPPORTED" ]; then
999 print_supported
Martin Rothedf965a2015-11-25 16:58:33 -07001000 exit 0
1001fi
1002
1003#print toolchain builder version string as the header
1004printversion
1005
Martin Roth2c6a8062016-11-14 11:58:39 -07001006printf "Building toolchain using %d thread(s).\n\n" "$THREADS"
1007
Ronald G. Minnichb460a662013-05-26 05:33:35 -07001008case "$TARGETARCH" in
Timothy Pearsona9f62352015-12-30 18:59:00 -06001009 x86_64-elf) ;;
1010 x86_64*) TARGETARCH=x86_64-elf;;
1011 i386-elf) ;;
1012 i386-mingw32) ;;
Patrick Georgif0d5f672022-09-08 20:25:46 +02001013 riscv-elf) TARGETARCH=riscv64-elf
Patrick Georgif67005d2024-01-28 01:20:43 +01001014 TARGET_GCC_OPTIONS="$TARGET_GCC_OPTIONS --with-isa-spec=20191213"
1015 TARGET_BINUTILS_OPTIONS="$TARGET_BINUTILS_OPTIONS --with-isa-spec=20191213";;
Patrick Georgi0a97d7e2016-01-25 09:51:22 +01001016 powerpc64*-linux*) ;;
Timothy Pearsona9f62352015-12-30 18:59:00 -06001017 i386*) TARGETARCH=i386-elf;;
Stefan Reinauer27522ad2016-01-29 17:31:34 -08001018 arm*) TARGETARCH=arm-eabi;;
Timothy Pearsona9f62352015-12-30 18:59:00 -06001019 aarch64*) TARGETARCH=aarch64-elf;;
Martin Roth3e0f74d2016-03-08 12:07:04 -07001020 nds32le-elf) ;;
Timothy Pearsona9f62352015-12-30 18:59:00 -06001021 *) printf "${red}WARNING: Unsupported architecture $TARGETARCH.${NC}\n\n"; ;;
Ronald G. Minnichb460a662013-05-26 05:33:35 -07001022esac
1023
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001024# Figure out which packages to build
Stefan Reinauer699ac272015-06-05 12:43:28 -07001025
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001026case "$PACKAGE" in
1027 GCC|gcc)
Stefan Reinauer81693d42017-06-21 15:25:36 -07001028 echo "Target architecture is $TARGETARCH"
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001029 NAME="${TARGETARCH} cross GCC"
Nico Huberafda56e2017-12-07 17:50:53 +01001030 PACKAGES="GMP MPFR MPC BINUTILS GCC"
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001031 ;;
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001032 CLANG|clang)
Stefan Reinauer81693d42017-06-21 15:25:36 -07001033 NAME="LLVM clang"
1034 LLVM_VERSION=${CLANG_VERSION}
Arthur Heymanscccada22024-02-23 16:47:49 +01001035 PACKAGES="CMAKE LLVM CLANG CRT CTE LLVMCMAKE LLD LIBUNWIND"
Stefan Reinauerca117e72017-06-19 17:29:08 -07001036 CMAKE=${DESTDIR}${TARGETDIR}/bin/cmake
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001037 ;;
1038 IASL|iasl)
1039 NAME="IASL ACPI compiler"
1040 PACKAGES=IASL
1041 ;;
Stefan Reinauer3b593492017-06-19 17:28:54 -07001042 CMAKE|cmake)
1043 NAME="CMake"
1044 PACKAGES=CMAKE
1045 ;;
Martin Rothd70f5fa2019-05-26 17:24:19 -06001046 NASM|nasm)
1047 NAME="NASM"
1048 PACKAGES=NASM
1049 ;;
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001050 *)
Patrick Georgif32eed12021-10-16 10:50:00 +02001051 printf "${red}ERROR: Unsupported package $PACKAGE. (Supported packages are GCC, CLANG, IASL, and NASM)${NC}\n\n";
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001052 exit 1
1053 ;;
1054esac
Peter Stugeceacd772011-06-09 04:54:16 +02001055
Stefan Reinauer66e93352015-06-16 22:38:23 +02001056# Find all the required tools:
1057
1058TAR=$(searchtool tar) || exit $?
1059PATCH=$(searchtool patch) || exit $?
1060MAKE=$(searchtool make) || exit $?
1061SHA1SUM=$(searchtool sha1sum)
zbao5cf758d2015-09-01 22:28:57 -04001062#SHA512SUM=$(searchtool sha512sum)
1063#MD5SUM=$(searchtool md5sum)
Stefan Reinauer66e93352015-06-16 22:38:23 +02001064CHECKSUM=$SHA1SUM
Martin Roth95f7b222016-03-20 12:38:48 -06001065LBZIP2=$(searchtool lbzip2 "" nofail)
1066PIGZ=$(searchtool pigz "" nofail)
Stefan Reinauer66e93352015-06-16 22:38:23 +02001067
1068searchtool m4 > /dev/null
1069searchtool bison > /dev/null
1070searchtool flex flex > /dev/null
Stefan Reinauer66e93352015-06-16 22:38:23 +02001071searchtool bzip2 "bzip2," > /dev/null
Nico Huber0ff3b392017-03-12 16:07:33 +01001072searchtool xz "XZ Utils" "" "xz-utils" > /dev/null
Stefan Reinauer66e93352015-06-16 22:38:23 +02001073
Patrick Georgidf1ff232017-01-07 09:28:43 +01001074if searchtool wget "GNU" nofail > /dev/null; then
1075 download_showing_percentage() {
1076 url=$1
Stefan Reinauer81693d42017-06-21 15:25:36 -07001077 printf "... ${red} 0%%"
Martin Roth82a30a12020-11-07 15:17:45 -07001078 wget --tries=3 "$url" 2>&1 | while read -r line; do
Zheng Baob9217822022-08-15 18:29:45 +08001079 echo "$line" | grep -o "\<[0-9]\{1,3\}%" | awk '{printf("\b\b\b\b%4s", $1)}'
Patrick Georgidf1ff232017-01-07 09:28:43 +01001080 done
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +02001081 printf "${NC}... "
Patrick Georgidf1ff232017-01-07 09:28:43 +01001082 }
1083elif searchtool curl "^curl " > /dev/null; then
1084 download_showing_percentage() {
1085 url=$1
1086 echo
Idwer Vollering5190f422020-11-24 15:13:16 +01001087 curl -O --progress-bar --location --retry 3 "$url"
Patrick Georgidf1ff232017-01-07 09:28:43 +01001088 }
1089fi
1090
Nico Huber08bb8372017-06-24 19:50:35 +02001091# Allow $CC override from the environment.
1092if [ -n "$CC" ]; then
1093 if [ ! -x "$(command -v "$CC" 2>/dev/null)" ]; then
1094 printf "${RED}ERROR:${red} CC is set to '%s' but wasn't found.${NC}\n" "$CC"
1095 HALT_FOR_TOOLS=1
1096 fi
1097else
Patrick Georgi8f2cdad2017-07-10 11:48:34 +02001098 if searchtool gnatgcc "Free Software Foundation" nofail > /dev/null; then
Felix Singerc374dee2023-10-04 03:10:52 +00001099 # 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.
Patrick Georgi8f2cdad2017-07-10 11:48:34 +02001106 CC=gnatgcc
Felix Singerc374dee2023-10-04 03:10:52 +00001107 if ! hostcc_has_gnat1; then
1108 CC=gcc
1109 fi
Patrick Georgi8f2cdad2017-07-10 11:48:34 +02001110 elif searchtool gcc "Free Software Foundation" nofail > /dev/null; then
Nico Huber08bb8372017-06-24 19:50:35 +02001111 CC=gcc
1112 else
1113 searchtool cc '^' nofail > /dev/null || please_install gcc
1114 CC=cc
1115 fi
1116fi
Martin Roth591790f2016-03-20 20:39:04 -06001117
Nico Huber08bb8372017-06-24 19:50:35 +02001118# We can leave $CXX empty if it's not set since *buildgcc* never
1119# calls it directly. This way configure scripts can search for
1120# themselves and we still override it when a bootstrapped g++ is
1121# to be used (cf. hostcxx()).
1122if [ -n "$CXX" ]; then
1123 if [ ! -x "$(command -v "$CXX" 2>/dev/null)" ]; then
1124 printf "${RED}ERROR:${red} CXX is set to '%s' but wasn't found.${NC}\n" "$CXX"
1125 HALT_FOR_TOOLS=1
1126 fi
1127else
1128 searchtool g++ "Free Software Foundation" nofail > /dev/null || \
1129 searchtool clang "clang version" nofail > /dev/null || \
1130 searchtool clang "LLVM" "" "g++" > /dev/null
1131fi
1132
1133check_for_library "-lz" "zlib (zlib1g-dev or zlib-devel)"
Nico Huber156d87c2016-09-20 12:59:53 +02001134
Martin Roth88463822016-01-07 11:03:36 -07001135if [ "$HALT_FOR_TOOLS" -ne 0 ]; then
1136 exit 1
1137fi
1138
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001139# This initial cleanup is useful when updating the toolchain script.
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001140
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001141if [ "$clean" = "1" ]; then
1142 cleanup
1143fi
Stefan Reinauer074d9132009-09-26 16:43:17 +00001144
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001145# Set up host compiler and flags needed for various OSes
Stefan Reinauer074d9132009-09-26 16:43:17 +00001146
Patrick Georgif2c15f52015-06-11 21:07:31 +02001147if is_package_enabled "GCC"; then
Patrick Georgie8253fe2017-07-18 11:35:35 +02001148# sane preset: let the configure script figure out things by itself
1149# more importantly, avoid any values that might already linger in the variable
1150OPTIONS="ABI="
Martin Roth987d42d2018-07-22 11:45:29 -06001151if [ "$UNAME" = "Darwin" ]; then
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001152 #GCC_OPTIONS="$GCC_OPTIONS --enable-threads=posix"
1153
1154 # generally the OS X compiler can create x64 binaries.
1155 # Per default it generated i386 binaries in 10.5 and x64
1156 # binaries in 10.6 (even if the kernel is 32bit)
1157 # For some weird reason, 10.5 autodetects an ABI=64 though
1158 # so we're setting the ABI explicitly here.
Martin Roth987d42d2018-07-22 11:45:29 -06001159 if [ "$(sysctl -n hw.optional.x86_64 2>/dev/null)" -eq 1 ] 2>/dev/null; then
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001160 OPTIONS="ABI=64"
Stefan Reinauera295ac12024-02-08 21:18:05 -08001161 elif [ "$(sysctl -n hw.optional.arm64 2>/dev/null)" -eq 1 ] 2>/dev/null; then
1162 OPTIONS="ABI=64"
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001163 else
1164 OPTIONS="ABI=32"
1165 fi
Stefan Reinauer9491b4d2011-10-11 22:37:59 -07001166
Stefan Reinauer4266b922012-12-05 16:18:32 -08001167 # 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.
Stefan Reinauer9491b4d2011-10-11 22:37:59 -07001170 if $CC -v 2>&1 | grep -q LLVM; then
Stefan Reinauer4266b922012-12-05 16:18:32 -08001171 CC=llvm-gcc
Stefan Reinauer9491b4d2011-10-11 22:37:59 -07001172 fi
Martin Roth987d42d2018-07-22 11:45:29 -06001173elif [ "$UNAME" = "Linux" ] || [ "$UNAME" = "Cygwin" ]; then
Patrick Georgiddb8f802015-07-04 17:45:54 +02001174 # gmp is overeager with detecting 64bit CPUs even if they run
1175 # a 32bit kernel and userland.
1176 if [ "$(uname -m 2>/dev/null)" = "i686" ]; then
1177 OPTIONS="ABI=32"
1178 fi
Martin Roth987d42d2018-07-22 11:45:29 -06001179elif [ "$UNAME" = "NetBSD" ]; then
Nico Huberde45c592016-01-20 23:22:33 +01001180 # same for NetBSD but this one reports an i386
1181 if [ "$(uname -m 2>/dev/null)" = "i386" ]; then
1182 OPTIONS="ABI=32"
1183 fi
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001184fi
Nico Huber66c2c1a2016-09-20 13:09:29 +02001185if [ -z "${LANGUAGES}" ]; then
Nico Hubercd87e1b2017-06-24 20:35:59 +02001186 if have_gnat; then
Nico Huber66c2c1a2016-09-20 13:09:29 +02001187 printf "\nFound compatible Ada compiler, enabling Ada support by default.\n\n"
1188 LANGUAGES="ada,${DEFAULT_LANGUAGES}"
1189 else
Nico Hubercd87e1b2017-06-24 20:35:59 +02001190 printf "\n${red}WARNING${NC}\n"
1191 printf "No compatible Ada compiler (GNAT) found. You can continue without\n"
1192 printf "Ada support, but this will limit the features of ${blue}coreboot${NC} (e.g.\n"
1193 printf "native graphics initialization won't be available on most Intel\n"
1194 printf "boards).\n\n"
1195
1196 printf "Usually, you can install GNAT with your package management system\n"
1197 printf "(the package is called \`gnat\` or \`gcc-ada\`). It has to match the\n"
1198 printf "\`gcc\` package in version. If there are multiple versions of GCC in-\n"
1199 printf "stalled, you can point this script to the matching version through\n"
1200 printf "the \`CC\` and \`CXX\` environment variables.\n\n"
1201
1202 printf "e.g. on Ubuntu 14.04, if \`gcc\` is \`gcc-4.8\`:\n"
1203 printf " apt-get install gnat-4.8 && make crossgcc\n\n"
1204
1205 printf "on Ubuntu 16.04, if \`gcc\` is \`gcc-5\`:\n"
1206 printf " apt-get install gnat-5 && make crossgcc\n"
1207 timeout 30
Nico Huber66c2c1a2016-09-20 13:09:29 +02001208 LANGUAGES="${DEFAULT_LANGUAGES}"
1209 fi
1210fi
Patrick Georgif2741aa2020-07-06 16:35:56 +02001211if [ "$BOOTSTRAP" != 1 ] && \
1212 { [ "$(hostcc_major)" -lt 4 ] || \
1213 { [ "$(hostcc_major)" -eq 4 ] && \
1214 [ "$(hostcc_minor)" -lt 9 ] ; } ; }
1215then
1216 printf "\n${red}WARNING${NC}\n"
1217 printf "Building coreboot requires a host compiler newer than 4.9.x while\n"
1218 printf "yours is $(hostcc_version).\n"
1219 printf "Enabling bootstrapping to provide a sufficiently new compiler:\n"
1220 printf "This will take significantly longer than a usual build.\n"
1221 printf "Alternatively you can abort now and update your host compiler.\n"
1222 timeout 15
1223 BOOTSTRAP=1
1224fi
Nico Hubercd87e1b2017-06-24 20:35:59 +02001225if ada_requested; then
Patrick Georgif2741aa2020-07-06 16:35:56 +02001226 if ! have_gnat; then
Nico Hubercd87e1b2017-06-24 20:35:59 +02001227 please_install gnat gcc-ada
1228 exit 1
1229 fi
Nico Hubercd87e1b2017-06-24 20:35:59 +02001230fi
Stefan Reinauer14ce2132015-06-05 13:01:13 -07001231fi # GCC
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001232
Nico Huber5f72f962016-01-31 23:05:19 +01001233export HOSTCFLAGS="-Os"
1234if have_hostcflags_from_gmp; then
1235 set_hostcflags_from_gmp
1236fi
1237
Patrick Georgic1a75b12011-11-04 21:37:14 +01001238if [ "$USECCACHE" = 1 ]; then
1239 CC="ccache $CC"
1240fi
1241
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001242# Prepare target directory for building GCC
1243# (dependencies must be in the PATH)
Martin Roth987d42d2018-07-22 11:45:29 -06001244mkdir -p "$DESTDIR$TARGETDIR/bin"
1245mkdir -p "$DESTDIR$TARGETDIR/share"
Stefan Reinauer16bd7892012-12-07 23:57:01 +01001246export PATH=$DESTDIR$TARGETDIR/bin:$PATH
1247
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001248# Download, unpack, patch and build all packages
1249
Idwer Vollering458e7df2020-09-25 12:26:51 +02001250printf "Downloading and verifying tarballs ...\n"
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001251mkdir -p tarballs
1252for P in $PACKAGES; do
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +02001253 download "$P" || exit "$?"
1254 verify_hash "$P" || exit "$?"
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001255done
Martin Roth03625172016-02-17 14:44:14 -07001256printf "Downloaded tarballs ... ${green}ok${NC}\n"
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001257
Martin Rothe59868c2023-08-20 20:21:17 -06001258if [ ${FETCH_ONLY} -eq 1 ]; then
1259 exit 0
1260fi
1261
Elyes HAOUASb0f19882018-06-09 11:59:00 +02001262printf "Unpacking and patching ...\n"
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001263for P in $PACKAGES; do
1264 unpack_and_patch $P || exit 1
1265done
1266printf "Unpacked and patched ... ${green}ok${NC}\n"
1267
Patrick Georgi9681cdc2017-09-22 18:57:10 +02001268if [ -n "$BOOTSTRAPONLY" ]; then
Elyes HAOUASb0f19882018-06-09 11:59:00 +02001269 printf "Building bootstrap compiler only ...\n"
Nico Huberafda56e2017-12-07 17:50:53 +01001270 for pkg in GMP MPFR MPC GCC; do
Patrick Georgi9681cdc2017-09-22 18:57:10 +02001271 build_for_host $pkg
1272 done
1273 exit 0
1274fi
1275
Elyes HAOUASb0f19882018-06-09 11:59:00 +02001276printf "Building packages ...\n"
Stefan Reinauer1c70e052015-06-09 11:47:28 -07001277for package in $PACKAGES; do
1278 build $package
1279done
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001280printf "Packages built ... ${green}ok${NC}\n"
Stefan Reinauer14ce2132015-06-05 13:01:13 -07001281
Stefan Reinauer699ac272015-06-05 12:43:28 -07001282# Adding git information of current tree to target directory
1283# for reproducibility
Stefan Reinauerd7649122015-06-09 11:44:25 -07001284PROGNAME=$(basename "$0")
Stefan Reinauer88352d72016-04-06 15:57:03 -07001285rm -f "$DESTDIR$TARGETDIR/share/$PROGNAME-*"
Felix Singer62fcffb2021-10-19 13:25:18 +02001286cp "$PROGNAME" "$DESTDIR$TARGETDIR/share/$PROGNAME-$CROSSGCC_VERSION"
Zheng Bao30b895f2013-02-06 18:04:40 +08001287
Patrick Georgi0c2df6f2017-11-22 16:14:09 -05001288# Adding edk2 tools template
1289mkdir -p "$DESTDIR$TARGETDIR/share/edk2config"
1290sed -e "s,@@PREFIX@@,$TARGETDIR,g" edk2tools.txt > "$DESTDIR$TARGETDIR/share/edk2config/tools_def.txt"
1291printf "Copied EDK2 tools template ... ${green}ok${NC}\n"
1292
Stefan Reinauer88e83e52016-04-06 15:39:48 -07001293cleanup
Stefan Reinauer074d9132009-09-26 16:43:17 +00001294
Stefan Reinauer81693d42017-06-21 15:25:36 -07001295printf "\n${green}You can now run $NAME from $TARGETDIR.${NC}\n"