blob: b294da5dfbcfc88991274162f314af7051433f63 [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
Elyes Haouas2731fa62023-02-23 16:23:48 +010041GCC_VERSION=13.2.0
Elyes Haouase54c13e2023-07-30 18:18:41 +020042BINUTILS_VERSION=2.41
Felix Singer90753392023-07-10 23:56:18 +000043IASL_VERSION="R06_28_23"
Stefan Reinauer14ce2132015-06-05 13:01:13 -070044# CLANG version number
Felix Singer2b4d2ed2023-06-23 21:11:06 +000045CLANG_VERSION=16.0.6
Felix Singerc08461d2023-11-01 23:17:30 +000046CMAKE_VERSION=3.27.7
Elyes Haouasa84823d2023-03-16 07:07:02 +010047NASM_VERSION=2.16.01
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 Singer90753392023-07-10 23:56:18 +000055IASL_ARCHIVE="${IASL_VERSION}.tar.gz"
Martin Roth3b32af92022-11-27 12:55:31 -070056# CLANG toolchain FILE locations
57LLVM_ARCHIVE="llvm-${CLANG_VERSION}.src.tar.xz"
58CLANG_ARCHIVE="clang-${CLANG_VERSION}.src.tar.xz"
59CRT_ARCHIVE="compiler-rt-${CLANG_VERSION}.src.tar.xz"
60CTE_ARCHIVE="clang-tools-extra-${CLANG_VERSION}.src.tar.xz"
61LLVMCMAKE_ARCHIVE="cmake-${CLANG_VERSION}.src.tar.xz"
62CMAKE_ARCHIVE="cmake-${CMAKE_VERSION}.tar.gz"
63NASM_ARCHIVE="nasm-${NASM_VERSION}.tar.bz2"
64
65# These URLs are sanitized by the jenkins toolchain test builder, so if
Martin Roth1484c032016-03-08 09:37:14 -070066# a completely new URL is added here, it probably needs to be added
67# to the jenkins build as well, or the builder won't download it.
Stefan Reinauer074d9132009-09-26 16:43:17 +000068
Martin Roth3b32af92022-11-27 12:55:31 -070069# GCC toolchain archive locations
70GMP_BASE_URL="https://ftpmirror.gnu.org/gmp"
71MPFR_BASE_URL="https://ftpmirror.gnu.org/mpfr"
72MPC_BASE_URL="https://ftpmirror.gnu.org/mpc"
73GCC_BASE_URL="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}"
74BINUTILS_BASE_URL="https://ftpmirror.gnu.org/binutils"
Felix Singer90753392023-07-10 23:56:18 +000075IASL_BASE_URL="https://github.com/acpica/acpica/archive/refs/tags"
Martin Roth3b32af92022-11-27 12:55:31 -070076# CLANG toolchain archive locations
77LLVM_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
78CLANG_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
79CRT_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
80CTE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
81LLVMCMAKE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}"
82CMAKE_BASE_URL="https://cmake.org/files/v${CMAKE_VERSION%.*}"
83NASM_BASE_URL="https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}"
84
85ALL_ARCHIVES="$GMP_BASE_URL/$GMP_ARCHIVE $MPFR_BASE_URL/$MPFR_ARCHIVE $MPC_BASE_URL/$MPC_ARCHIVE \
86 $GCC_BASE_URL/$GCC_ARCHIVE $BINUTILS_BASE_URL/$BINUTILS_ARCHIVE $IASL_BASE_URL/$IASL_ARCHIVE \
87 $LLVM_BASE_URL/$LLVM_ARCHIVE $CLANG_BASE_URL/$CLANG_ARCHIVE $LLVMCMAKE_BASE_URL/$LLVMCMAKE_ARCHIVE \
88 $CRT_BASE_URL/$CRT_ARCHIVE $CTE_BASE_URL/$CTE_ARCHIVE $CMAKE_BASE_URL/$CMAKE_ARCHIVE $NASM_BASE_URL/$NASM_ARCHIVE"
Martin Roth58c68d52016-03-01 15:22:42 -070089
Stefan Reinauer699ac272015-06-05 12:43:28 -070090# GCC toolchain directories
Stefan Reinauer074d9132009-09-26 16:43:17 +000091GMP_DIR="gmp-${GMP_VERSION}"
92MPFR_DIR="mpfr-${MPFR_VERSION}"
Stefan Reinauer5f1ad892010-05-17 11:02:25 +000093MPC_DIR="mpc-${MPC_VERSION}"
Martin Roth987d42d2018-07-22 11:45:29 -060094# shellcheck disable=SC2034
Stefan Reinauer074d9132009-09-26 16:43:17 +000095GCC_DIR="gcc-${GCC_VERSION}"
Martin Roth987d42d2018-07-22 11:45:29 -060096# shellcheck disable=SC2034
Stefan Reinauer074d9132009-09-26 16:43:17 +000097BINUTILS_DIR="binutils-${BINUTILS_VERSION}"
Felix Singer90753392023-07-10 23:56:18 +000098IASL_DIR="acpica-${IASL_VERSION}"
Stefan Reinauer14ce2132015-06-05 13:01:13 -070099# CLANG toolchain directories
100LLVM_DIR="llvm-${CLANG_VERSION}.src"
Elyes HAOUAS8f1853c2020-08-02 09:46:15 +0200101CLANG_DIR="clang-${CLANG_VERSION}.src"
Stefan Reinauer14ce2132015-06-05 13:01:13 -0700102CRT_DIR="compiler-rt-${CLANG_VERSION}.src"
103CTE_DIR="clang-tools-extra-${CLANG_VERSION}.src"
Elyes Haouasc8870b12022-09-16 12:10:00 +0200104LLVMCMAKE_DIR="cmake-${CLANG_VERSION}.src"
Stefan Reinauer3b593492017-06-19 17:28:54 -0700105CMAKE_DIR="cmake-${CMAKE_VERSION}"
Martin Rothd70f5fa2019-05-26 17:24:19 -0600106NASM_DIR="nasm-${NASM_VERSION}"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000107
Patrick Georgi6321f522015-02-27 23:36:26 +0100108unset MAKELEVEL MAKEFLAGS
109
Patrick Georgi1861ff72011-10-31 12:15:55 +0100110red='\033[0;31m'
111RED='\033[1;31m'
112green='\033[0;32m'
113GREEN='\033[1;32m'
114blue='\033[0;34m'
Patrick Georgi1861ff72011-10-31 12:15:55 +0100115CYAN='\033[1;36m'
116NC='\033[0m' # No Color
Stefan Reinauer074d9132009-09-26 16:43:17 +0000117
Martin Roth987d42d2018-07-22 11:45:29 -0600118UNAME=$(if uname | grep -iq cygwin; then echo Cygwin; else uname; fi)
Martin Roth88463822016-01-07 11:03:36 -0700119HALT_FOR_TOOLS=0
Stefan Reinauer0d2119d2013-07-10 14:27:56 -0700120
Nico Huber08bb8372017-06-24 19:50:35 +0200121hostcc()
122{
123 # $1 "host" or "target"
Martin Roth987d42d2018-07-22 11:45:29 -0600124 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then
125 echo "$DESTDIR$TARGETDIR/bin/gcc"
Nico Huber08bb8372017-06-24 19:50:35 +0200126 else
Martin Roth987d42d2018-07-22 11:45:29 -0600127 echo "$CC"
Nico Huber08bb8372017-06-24 19:50:35 +0200128 fi
129}
130
131hostcxx()
132{
133 # $1 "host" or "target"
Martin Roth987d42d2018-07-22 11:45:29 -0600134 if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then
135 echo "$DESTDIR$TARGETDIR/bin/g++"
Nico Huber08bb8372017-06-24 19:50:35 +0200136 else
Martin Roth987d42d2018-07-22 11:45:29 -0600137 echo "$CXX"
Nico Huber08bb8372017-06-24 19:50:35 +0200138 fi
139}
140
Patrick Georgi198d23c2012-12-08 08:02:44 +0100141normalize_dirs()
142{
Martin Roth987d42d2018-07-22 11:45:29 -0600143 mkdir -p "$DESTDIR$TARGETDIR/lib"
144 test -d "$DESTDIR$TARGETDIR/lib32" && mv "$DESTDIR$TARGETDIR"/lib32/* "$DESTDIR$TARGETDIR/lib"
145 test -d "$DESTDIR$TARGETDIR/lib64" && mv "$DESTDIR$TARGETDIR"/lib64/* "$DESTDIR$TARGETDIR/lib"
Martin Roth1039d272022-01-31 10:17:43 -0700146 rm -rf "$DESTDIR$TARGETDIR/lib32" "$DESTDIR$TARGETDIR/lib64"
Patrick Georgi198d23c2012-12-08 08:02:44 +0100147
Martin Roth987d42d2018-07-22 11:45:29 -0600148 perl -pi -e "s,/lib32,/lib," "$DESTDIR$TARGETDIR"/lib/*.la
149 perl -pi -e "s,/lib64,/lib," "$DESTDIR$TARGETDIR"/lib/*.la
Patrick Georgi198d23c2012-12-08 08:02:44 +0100150}
151
Nico Hubercd87e1b2017-06-24 20:35:59 +0200152countdown()
153{
154 tout=${1:-10}
155
Martin Roth987d42d2018-07-22 11:45:29 -0600156 printf "\nPress Ctrl-C to abort, Enter to continue... %2ds" "$tout"
157 while [ "$tout" -gt 0 ]; do
Nico Hubercd87e1b2017-06-24 20:35:59 +0200158 sleep 1
159 tout=$((tout - 1))
160 printf "\b\b\b%2ds" $tout
161 done
162 printf "\n"
163}
164
165timeout()
166{
167 tout=${1:-10}
168
169 # Ignore SIGUSR1, should interrupt `read` though.
170 trap false USR1
171 # Clean up in case the user aborts.
172 trap 'kill $counter > /dev/null 2>&1' EXIT
173
Martin Roth987d42d2018-07-22 11:45:29 -0600174 (countdown "$tout"; kill -USR1 $$)&
Nico Hubercd87e1b2017-06-24 20:35:59 +0200175 counter=$!
176
177 # Some shells with sh compatibility mode (e.g. zsh, mksh) only
178 # let us interrupt `read` if a non-standard -t parameter is given.
Martin Roth987d42d2018-07-22 11:45:29 -0600179 # shellcheck disable=SC2034,SC2039,SC2162
Nico Hubercd87e1b2017-06-24 20:35:59 +0200180 if echo | read -t 1 foo 2>/dev/null; then
181 read -t $((tout + 1)) foo
182 else
183 read foo
184 fi
185
186 kill $counter > /dev/null 2>&1
187 trap - USR1 EXIT
188}
189
Stefan Reinauer93a96302015-06-15 12:36:53 -0700190please_install()
191{
Martin Roth88463822016-01-07 11:03:36 -0700192 HALT_FOR_TOOLS=1
Martin Roth987d42d2018-07-22 11:45:29 -0600193 # shellcheck disable=SC1091
Patrick Georgi5da95dc2015-07-17 23:33:05 +0200194 test -r /etc/os-release && . /etc/os-release
Alex Thiessen72d10892018-01-12 01:45:53 +0000195 # vanilla debian doesn't define `ID_LIKE`, just `ID`
196 if [ -z "${ID_LIKE}" ] && [ -n "${ID}" ]; then
197 ID_LIKE=${ID}
198 fi
Stefan Reinauer93a96302015-06-15 12:36:53 -0700199 case "$ID_LIKE" in
200 debian) solution="sudo apt-get install $1" ;;
201 suse) solution="sudo zypper install $1" ;;
202 *) solution="using your OS packaging system" ;;
203 esac
204
Patrick Georgidf1ff232017-01-07 09:28:43 +0100205 printf "${RED}ERROR:${red} Missing tool: Please install '$1'. (eg $solution)${NC}\n" >&2
Martin Rothe3963172016-01-06 13:54:32 -0700206 if [ -n "$2" ]; then
Patrick Georgidf1ff232017-01-07 09:28:43 +0100207 printf "${RED}ERROR:${red} or install '$2'.${NC}\n" >&2
Martin Rothe3963172016-01-06 13:54:32 -0700208 fi
Stefan Reinauer93a96302015-06-15 12:36:53 -0700209}
210
Patrick Georgib7062882015-02-24 10:52:14 +0100211searchtool()
Stefan Reinauer074d9132009-09-26 16:43:17 +0000212{
213 # $1 short name
Patrick Georgib7062882015-02-24 10:52:14 +0100214 # $2 search string
215 # $3 soft fail if set
Martin Rothe3963172016-01-06 13:54:32 -0700216 # $4 alternative package to install on failure
Patrick Georgib7062882015-02-24 10:52:14 +0100217 # result: file name of that tool on stdout
218 # or no output if nothing suitable was found
219 search=GNU
220 if [ -n "$2" ]; then
221 search="$2"
222 fi
Stefan Reinauer074d9132009-09-26 16:43:17 +0000223 for i in "$1" "g$1" "gnu$1"; do
Martin Roth987d42d2018-07-22 11:45:29 -0600224 if [ -x "$(command -v "$i" 2>/dev/null)" ]; then
Stefan Reinauerdbc00872015-06-09 11:50:05 -0700225 if [ "$(cat /dev/null | $i --version 2>&1 | grep -c "$search")" \
226 -gt 0 ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600227 echo "$i"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000228 return
229 fi
230 fi
231 done
Andrew Wub67e9a12014-04-28 18:13:44 +0800232 # A workaround for OSX 10.9 and some BSDs, whose nongnu
233 # patch and tar also work.
Martin Roth987d42d2018-07-22 11:45:29 -0600234 if [ "$UNAME" = "Darwin" ] || [ "$UNAME" = "FreeBSD" ] || [ "$UNAME" = "NetBSD" ] || [ "$UNAME" = "OpenBSD" ]; then
235 if [ "$1" = "patch" ] || [ "$1" = "tar" ]; then
236 if [ -x "$(command -v "$1" 2>/dev/null)" ]; then
237 echo "$1"
Zheng Bao36156ff2012-09-28 16:18:58 +0800238 return
239 fi
240 fi
241 fi
Martin Roth987d42d2018-07-22 11:45:29 -0600242 if echo "$1" | grep -q "sum" ; then
243 algor=$(echo "$1" | sed -e 's,sum,,')
244 if [ -x "$(command -v "$1" 2>/dev/null)" ]; then
zbao5cf758d2015-09-01 22:28:57 -0400245 #xxxsum [file]
Martin Roth987d42d2018-07-22 11:45:29 -0600246 echo "$1"
zbao5cf758d2015-09-01 22:28:57 -0400247 return
Martin Roth987d42d2018-07-22 11:45:29 -0600248 elif [ -x "$(command -v "$algor" 2>/dev/null)" ]; then
zbao5cf758d2015-09-01 22:28:57 -0400249 #xxx [file]
Martin Roth987d42d2018-07-22 11:45:29 -0600250 echo "$algor"
zbao5cf758d2015-09-01 22:28:57 -0400251 return
Martin Rothd55f5eb2017-06-15 11:37:26 -0600252 elif [ -x "$(command -v openssl 2>/dev/null)" ]; then
zbao5cf758d2015-09-01 22:28:57 -0400253 #openssl xxx [file]
Martin Roth987d42d2018-07-22 11:45:29 -0600254 echo openssl "$algor"
zbao5cf758d2015-09-01 22:28:57 -0400255 return
Martin Rothd55f5eb2017-06-15 11:37:26 -0600256 elif [ -x "$(command -v cksum 2>/dev/null)" ]; then
zbao5cf758d2015-09-01 22:28:57 -0400257 #cksum -a xxx [file]
258 #cksum has special options in NetBSD. Actually, NetBSD will use the second case above.
Martin Roth987d42d2018-07-22 11:45:29 -0600259 echo "buildgcc" | cksum -a "$algor" > /dev/null 2>/dev/null && \
260 echo cksum -a "$algor"
zbao5cf758d2015-09-01 22:28:57 -0400261 return
zbao939dc842015-04-30 04:44:07 +0800262 fi
263 fi
Martin Rothe3963172016-01-06 13:54:32 -0700264
Martin Roth987d42d2018-07-22 11:45:29 -0600265 [ -z "$3" ] && please_install "$1" "$4"
Patrick Georgib7062882015-02-24 10:52:14 +0100266 false
Stefan Reinauer074d9132009-09-26 16:43:17 +0000267}
268
Martin Roth591790f2016-03-20 20:39:04 -0600269# Run a compile check of the specified library option to see if it's installed
270check_for_library() {
Martin Roth987d42d2018-07-22 11:45:29 -0600271 LIBRARY_FLAGS="$1"
272 LIBRARY_PACKAGES="$2"
273 LIBTEST_FILE=.libtest
Martin Roth591790f2016-03-20 20:39:04 -0600274
275 echo "int main(int argc, char **argv) { (void) argc; (void) argv; return 0; }" > "${LIBTEST_FILE}.c"
276
Martin Roth987d42d2018-07-22 11:45:29 -0600277 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200278 "$CC" $CFLAGS $LIBRARY_FLAGS "${LIBTEST_FILE}.c" -o "${LIBTEST_FILE}" >/dev/null 2>&1 || \
Martin Roth591790f2016-03-20 20:39:04 -0600279 please_install "$LIBRARY_PACKAGES"
280 rm -rf "${LIBTEST_FILE}.c" "${LIBTEST_FILE}"
281}
282
Nico Huberaee7f462016-09-20 12:55:19 +0200283buildcc_major() {
284 echo "${GCC_VERSION}" | cut -d. -f1
285}
286
Nico Huber26267a72016-12-04 02:45:58 +0100287buildcc_minor() {
288 echo "${GCC_VERSION}" | cut -d. -f2
289}
290
Nico Huberaee7f462016-09-20 12:55:19 +0200291buildcc_version() {
292 echo "${GCC_VERSION}" | cut -d. -f1-2
293}
294
295hostcc_major() {
296 (echo __GNUC__ | ${CC} -E - 2>/dev/null || echo 0) | tail -1
297}
298
299hostcc_minor() {
300 (echo __GNUC_MINOR__ | ${CC} -E - 2>/dev/null || echo 0) | tail -1
301}
302
303hostcc_version() {
304 printf "%d.%d" "$(hostcc_major)" "$(hostcc_minor)"
305}
306
Nico Huber75797162016-09-20 13:01:57 +0200307hostcc_has_gnat1() {
308 [ -x "$(${CC} -print-prog-name=gnat1)" ]
309}
310
Nico Hubercd87e1b2017-06-24 20:35:59 +0200311have_gnat() {
312 hostcc_has_gnat1 && \
313 searchtool gnatbind "Free Software Foundation" nofail > /dev/null
314}
315
Nico Huber75797162016-09-20 13:01:57 +0200316ada_requested() {
317 echo "${LANGUAGES}" | grep -q '\<ada\>'
318}
319
Stefan Reinauer88935482015-06-05 09:51:10 -0700320download() {
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700321 package=$1
Martin Roth987d42d2018-07-22 11:45:29 -0600322 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700323 if [ "${USE_COREBOOT_MIRROR}" -eq 0 ]; then
324 url="$(eval echo \$$package"_BASE_URL")"
325 else
326 url="${COREBOOT_MIRROR_URL}"
327 fi
Stefan Reinauer699ac272015-06-05 12:43:28 -0700328
Martin Roth3b32af92022-11-27 12:55:31 -0700329 file="$(eval echo \$$package"_ARCHIVE")"
330 printf " * ${file} "
Stefan Reinauer88935482015-06-05 09:51:10 -0700331
Martin Roth3b32af92022-11-27 12:55:31 -0700332 if test -f "tarballs/${file}"; then
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200333 printf "(cached)... "
zbaod22b9ea2015-08-30 23:35:16 -0400334 else
Martin Roth3b32af92022-11-27 12:55:31 -0700335 printf "(downloading from ${url}/${file})"
336 rm -f "tarballs/${file}"
Martin Roth987d42d2018-07-22 11:45:29 -0600337 cd tarballs || exit 1
Martin Roth3b32af92022-11-27 12:55:31 -0700338 download_showing_percentage "${url}/${file}"
Stefan Reinauer88935482015-06-05 09:51:10 -0700339 cd ..
zbaod22b9ea2015-08-30 23:35:16 -0400340 fi
341
Martin Roth3b32af92022-11-27 12:55:31 -0700342 if [ ! -f "tarballs/${file}" ]; then
343 printf "${RED}Failed to download ${file}.${NC}\n"
Stefan Reinauerdbc00872015-06-09 11:50:05 -0700344 exit 1
345 fi
Stefan Reinauer88935482015-06-05 09:51:10 -0700346}
347
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200348# Compute the hash of the package given in $1, and print it raw (just the
349# hexadecimal hash).
350compute_hash() {
351 package=$1
Martin Roth987d42d2018-07-22 11:45:29 -0600352 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700353 file="$(eval echo \$$package"_ARCHIVE")"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200354
355 if test -z "$CHECKSUM"; then
356 echo "${RED}\$CHECKSUM program missing. This is bad.${NC}" 1>&2
357 exit 1
358 fi
359
360 $CHECKSUM "tarballs/$file" 2>/dev/null | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@'
361}
362
363error_hash_missing() {
364 package="$1"
Martin Roth987d42d2018-07-22 11:45:29 -0600365 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700366 file="$(eval echo \$$package"_ARCHIVE")"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200367
368 fullhashfile="util/crossgcc/sum/$file.cksum"
369 printf "${RED}hash file missing:${NC}\n\n" 1>&2
370 printf "Please verify util/crossgcc/tarball/$file carefully\n" 1>&2
371 printf "(using PGP if possible), and then rename\n" 1>&2
372 printf " ${CYAN}${fullhashfile}.calc${NC}\n" 1>&2
373 printf " to ${CYAN}${fullhashfile}${NC}\n\n" 1>&2
374
375 exit 1
376}
377
378# Read the known hash file of the package given in $1, and print it raw.
379get_known_hash() {
380 package=$1
Martin Roth987d42d2018-07-22 11:45:29 -0600381 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700382 file="$(eval echo \$$package"_ARCHIVE")"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200383 hashfile="sum/$file.cksum"
384
385 if [ ! -f "$hashfile" ]; then
386 calc_hash="$(compute_hash "$package")" || exit 1
387 echo "$calc_hash tarballs/$file" > "${hashfile}.calc"
388
389 error_hash_missing "$package"
390 exit 1
391 fi
392
Martin Roth987d42d2018-07-22 11:45:29 -0600393 sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' < "$hashfile"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200394}
395
396error_hash_mismatch() {
397 package=$1
398 known_hash="$2"
399 computed_hash="$3"
Martin Roth987d42d2018-07-22 11:45:29 -0600400 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700401 file="$(eval echo \$$package"_ARCHIVE")"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200402
403 printf "${RED}hash mismatch:${NC}\n\n"
404 printf " expected (known) hash: $known_hash\n"
405 printf "calculated hash of downloaded file: $computed_hash\n\n"
406
407 printf "If you think this is due to a network error, please delete\n"
408 printf " ${CYAN}util/crossgcc/tarballs/$file${NC}\n"
409 printf "and try again. If the problem persists, it may be due to an\n"
410 printf "administration error on the file server, or you might be\n"
411 printf "subject to a Man-in-the-Middle attack\n\n"
412
413 exit 1
414}
415
416# verify_hash - Check that the hash of the file given in $1 matches the known
417# hash; Bail out on mismatch or missing hash file.
418verify_hash() {
419 package=$1
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200420
421 known_hash="$(get_known_hash "$package")" || exit "$?"
422 computed_hash="$(compute_hash "$package")" || exit "$?"
423
424 if [ "$known_hash" != "$computed_hash" ]; then
425 error_hash_mismatch "$package" "$known_hash" "$computed_hash"
426 exit 1
427 fi
428
Jonathan Neuschäfercb76069e2018-10-01 09:45:49 +0200429 printf "${GREEN}hash verified (${known_hash})${NC}\n"
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +0200430}
431
Stefan Reinauer88935482015-06-05 09:51:10 -0700432unpack_and_patch() {
Martin Roth987d42d2018-07-22 11:45:29 -0600433 package="$1"
434 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700435 archive="$(eval echo \$$package"_ARCHIVE")"
Martin Roth987d42d2018-07-22 11:45:29 -0600436 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700437 dir="$(eval echo \$$package"_DIR")"
Martin Roth987d42d2018-07-22 11:45:29 -0600438 test -d "${dir}" && test -f "${dir}/.unpack_success" || (
Martin Roth3b32af92022-11-27 12:55:31 -0700439 printf " * "$archive"\n"
Stefan Reinauer88935482015-06-05 09:51:10 -0700440 FLAGS=zxf
Martin Roth987d42d2018-07-22 11:45:29 -0600441 suffix=$(echo "$archive" | sed 's,.*\.,,')
Martin Roth95f7b222016-03-20 12:38:48 -0600442 if [ "$suffix" = "gz" ] && [ -n "$PIGZ" ]; then FLAGS="-I pigz -xf"
443 elif [ "$suffix" = "gz" ]; then FLAGS=zxf
444 elif [ "$suffix" = "bz2" ] && [ -n "$LBZIP2" ]; then FLAGS="-I lbzip2 -xf"
445 elif [ "$suffix" = "bz2" ]; then FLAGS=jxf
446 elif [ "$suffix" = "xz" ]; then FLAGS="--xz -xf"
447 elif [ "$suffix" = "lzma" ]; then FLAGS="--lzma -xf"
448 fi
Martin Roth987d42d2018-07-22 11:45:29 -0600449 # shellcheck disable=SC2086
Martin Roth3b32af92022-11-27 12:55:31 -0700450 $TAR $FLAGS "tarballs/$archive"
Stefan Reinauer88935482015-06-05 09:51:10 -0700451 for patch in patches/${dir}_*.patch; do
Martin Roth987d42d2018-07-22 11:45:29 -0600452 test -r "$patch" || continue
453 printf " o $(basename "$patch")\n"
454 (cd "${dir}" || exit 1; $PATCH -s -N -p1 <"../${patch}") || {
Stefan Reinauer88935482015-06-05 09:51:10 -0700455 printf "\n${RED}Failed $patch.${NC}\n"
Stefan Reinauer916b8452015-06-09 11:54:49 -0700456 exit 1
457 }
Stefan Reinauer88935482015-06-05 09:51:10 -0700458 done
Martin Roth987d42d2018-07-22 11:45:29 -0600459 touch "${dir}/.unpack_success"
Stefan Reinauer88935482015-06-05 09:51:10 -0700460 )
461}
462
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700463fn_exists()
464{
Martin Roth987d42d2018-07-22 11:45:29 -0600465 # shellcheck disable=SC2039
466 type "$1" >/dev/null 2>&1
Patrick Georgi74c06422015-03-25 18:40:13 +0100467}
468
Patrick Georgif2c15f52015-06-11 21:07:31 +0200469is_package_enabled()
470{
471 echo "$PACKAGES" |grep -q "\<$1\>"
472}
473
Martin Roth444ece22016-04-01 18:46:29 -0600474package_uses_targetarch()
475{
Patrick Georgif32eed12021-10-16 10:50:00 +0200476 if [ "$1" = "GCC" ] || [ "$1" = "BINUTILS" ]; then
Martin Roth444ece22016-04-01 18:46:29 -0600477 true
478 else
479 false
480 fi
481}
482
Nico Huber11ea2b32016-01-26 16:09:31 +0100483generic_build()
484{
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700485 package=$1
Nico Huber11ea2b32016-01-26 16:09:31 +0100486 host_target=$2
487 builddir=$3
488 success=$4
Martin Rothc295d5e2016-11-14 11:56:11 -0700489 version=$5
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700490
Martin Roth987d42d2018-07-22 11:45:29 -0600491 fn_exists "build_$package" || return
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700492
Nico Huber11ea2b32016-01-26 16:09:31 +0100493 mkdir -p "$builddir"
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700494
Nico Huber11ea2b32016-01-26 16:09:31 +0100495 if [ -f "$success" ]; then
Martin Roth2c6a8062016-11-14 11:58:39 -0700496 printf "Skipping $package v$version for $host_target as it is already built\n"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700497 else
Martin Roth2c6a8062016-11-14 11:58:39 -0700498 printf "Building $package v$version for $host_target ... "
Nico Huber11ea2b32016-01-26 16:09:31 +0100499 DIR="$PWD"
Martin Roth987d42d2018-07-22 11:45:29 -0600500 cd "$builddir" || exit 1
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700501 rm -f .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600502 "build_${package}" "$host_target" > build.log 2>&1
503 cd "$DIR" || exit 1
Nico Huber11ea2b32016-01-26 16:09:31 +0100504 if [ ! -f "$builddir/.failed" ]; then
505 touch "$success";
506 else
Idwer Volleringe2ef3cf2017-08-15 00:53:13 +0200507 printf "${RED}failed${NC}. Check '$builddir/build.log'.\n"
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700508 exit 1
509 fi
510 printf "${green}ok${NC}\n"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700511 fi
512}
513
Nico Huber11ea2b32016-01-26 16:09:31 +0100514build_for_host()
515{
Martin Rothc295d5e2016-11-14 11:56:11 -0700516 package="$1"
Martin Roth987d42d2018-07-22 11:45:29 -0600517 # shellcheck disable=SC2086
Martin Rothc295d5e2016-11-14 11:56:11 -0700518 version="$(eval echo \$$package"_VERSION")"
Patrick Georgi1b593e52016-11-25 15:27:41 +0100519 generic_build "$package" host "build-$package" "${DESTDIR}${TARGETDIR}/.${package}.${version}.success" "$version"
Nico Huber11ea2b32016-01-26 16:09:31 +0100520}
521
522build_for_target()
523{
Martin Rothc295d5e2016-11-14 11:56:11 -0700524 package="$1"
Martin Roth987d42d2018-07-22 11:45:29 -0600525 # shellcheck disable=SC2086
Martin Rothc295d5e2016-11-14 11:56:11 -0700526 version="$(eval echo \$$package"_VERSION")"
Patrick Georgi1b593e52016-11-25 15:27:41 +0100527 generic_build "$package" target "build-${TARGETARCH}-$package" "${DESTDIR}${TARGETDIR}/.${TARGETARCH}-${package}.${version}.success" "$version"
Nico Huber11ea2b32016-01-26 16:09:31 +0100528}
529
530build()
531{
Martin Roth987d42d2018-07-22 11:45:29 -0600532 if package_uses_targetarch "$1"; then
533 if [ $BOOTSTRAP -eq 1 ] && [ ! -f "${DESTDIR}${TARGETDIR}/.GCC.${GCC_VERSION}.success" ]; then
Nico Huber234d2462016-01-26 16:10:17 +0100534 build_for_host GCC
535 fi
Martin Roth987d42d2018-07-22 11:45:29 -0600536 build_for_target "$1"
Nico Huber11ea2b32016-01-26 16:09:31 +0100537 else
Martin Roth987d42d2018-07-22 11:45:29 -0600538 build_for_host "$1"
Nico Huber11ea2b32016-01-26 16:09:31 +0100539 fi
540}
541
Nico Huber18c74d62017-06-24 20:35:59 +0200542exit_handler()
Zheng Baobb003c82016-08-05 13:41:51 +0800543{
544 printf "${NC}Stop\n"
545 exit 1
546}
547
Stefan Reinauer074d9132009-09-26 16:43:17 +0000548cleanup()
549{
Stefan Reinauer88e83e52016-04-06 15:39:48 -0700550 if [ $SAVETEMPS -ne 0 ]; then
551 printf "Leaving temporary files around... ${green}ok${NC}\n"
552 return
553 fi
554
Stefan Reinauer074d9132009-09-26 16:43:17 +0000555 printf "Cleaning up temporary files... "
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700556 for package in $PACKAGES; do
Martin Roth987d42d2018-07-22 11:45:29 -0600557 # shellcheck disable=SC2086
558 rm -rf "build-${TARGETARCH}-$package" "build-$package" "$(eval echo \$$package"_DIR")"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700559 done
zbaoff3f15c2015-08-26 22:00:31 -0400560 rm -f getopt
Stefan Reinauer074d9132009-09-26 16:43:17 +0000561 printf "${green}ok${NC}\n"
562}
563
564myhelp()
565{
Stefan Reinauer14ce2132015-06-05 13:01:13 -0700566 printf "Usage: $0 [-V] [-c] [-p <platform>] [-d <target directory>] [-D <dest dir>] [-C] [-G] [-S]\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000567 printf " $0 [-V|--version]\n"
568 printf " $0 [-h|--help]\n\n"
569
570 printf "Options:\n"
Felix Singer60c56be2021-10-17 14:54:12 +0200571 printf " [-W|--print-version Print machine readable version\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000572 printf " [-V|--version] print version number and exit\n"
573 printf " [-h|--help] print this help and exit\n"
574 printf " [-c|--clean] remove temporary files before build\n"
575 printf " [-t|--savetemps] don't remove temporary files after build\n"
Patrick Georgic1a75b12011-11-04 21:37:14 +0100576 printf " [-y|--ccache] Use ccache when building cross compiler\n"
Nico Huber152e78e2016-09-20 15:38:40 +0200577 printf " [-n|--nocolor] don't print color codes in output\n"
578 printf " [-u|--urls] print the urls for all packages\n"
Patrick Georgi73166c72010-04-14 20:42:42 +0000579 printf " [-j|--jobs <num>] run <num> jobs in parallel in make\n"
Martin Roth588c79d2016-03-20 12:03:20 -0600580 printf " [-s]--supported <tool> print supported version of a tool\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000581 printf " [-d|--directory <target dir>] target directory to install cross compiler to\n"
Martin Roth588c79d2016-03-20 12:03:20 -0600582 printf " (defaults to $TARGETDIR)\n\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000583 printf " [-D|--destdir <dest dir>] destination directory to install cross compiler to\n"
Stefan Reinauer2c3cd122011-11-01 21:43:50 +0100584 printf " (for RPM builds, default unset)\n"
Martin Rothe59868c2023-08-20 20:21:17 -0600585 printf " [-f|--fetch] Download tarballs, but don't build anything\n"
Patrick Georgif32eed12021-10-16 10:50:00 +0200586 printf " [-P|--package <package>] Build a specific package: GCC, CLANG, IASL\n"
Stefan Reinauer85b07d62015-06-09 14:45:14 -0700587 printf " (defaults to $PACKAGE)\n"
588 printf "GCC specific options:\n"
Nico Huber234d2462016-01-26 16:10:17 +0100589 printf " [-b|--bootstrap] bootstrap the host compiler before building\n"
590 printf " the cross compiler\n"
Stefan Reinauer85b07d62015-06-09 14:45:14 -0700591 printf " [-p|--platform <platform>] target platform to build cross compiler for\n"
592 printf " (defaults to $TARGETARCH)\n"
Nico Huberbb313bf2015-09-08 12:30:27 +0200593 printf " [-l|--languages <languages>] comma separated list of target languages\n"
Nico Huber66c2c1a2016-09-20 13:09:29 +0200594 printf " (defaults to $DEFAULT_LANGUAGES)\n"
Patrick Georgif32eed12021-10-16 10:50:00 +0200595 printf "Platforms for GCC:\n"
Julius Wernerf96d9052019-08-16 15:35:39 -0700596 printf " x86_64 i386-elf i386-mingw32 riscv-elf arm aarch64\n"
Jonathan Neuschäferf14f6402016-03-11 20:22:23 +0100597 printf " powerpc64le-linux-gnu nds32le-elf\n\n"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000598}
599
Martin Rothedf965a2015-11-25 16:58:33 -0700600printversion() {
Martin Roth7014f822020-12-21 15:49:33 -0700601 printf "${blue}Welcome to the ${red}coreboot${blue} cross toolchain builder v$CROSSGCC_VERSION ${NC}\n\n"
Martin Rothedf965a2015-11-25 16:58:33 -0700602}
603
Stefan Reinauer074d9132009-09-26 16:43:17 +0000604myversion()
605{
Martin Rothedf965a2015-11-25 16:58:33 -0700606 printversion
Stefan Reinauer074d9132009-09-26 16:43:17 +0000607
608 cat << EOF
Stefan Reinauer5f1ad892010-05-17 11:02:25 +0000609Copyright (C) 2008-2010 by coresystems GmbH
Marc Jones2aac3f62011-08-08 16:07:50 -0600610Copyright (C) 2011 by Sage Electronic Engineering
Stefan Reinauer074d9132009-09-26 16:43:17 +0000611
612This program is free software; you can redistribute it and/or modify
613it under the terms of the GNU General Public License as published by
614the Free Software Foundation; version 2 of the License.
615
616This program is distributed in the hope that it will be useful,
617but WITHOUT ANY WARRANTY; without even the implied warranty of
618MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
619GNU General Public License for more details.
620
621EOF
622}
623
Nico Huber5f72f962016-01-31 23:05:19 +0100624have_hostcflags_from_gmp() {
Martin Roth987d42d2018-07-22 11:45:29 -0600625 grep -q __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" >/dev/null 2>&1
Nico Huber5f72f962016-01-31 23:05:19 +0100626}
627
628set_hostcflags_from_gmp() {
629 # Now set CFLAGS to match GMP CFLAGS but strip out -pedantic
630 # as GCC 4.6.x fails if it's there.
Martin Roth987d42d2018-07-22 11:45:29 -0600631 HOSTCFLAGS="$(grep __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" |cut -d\" -f2 |\
Idwer Volleringba349ab2016-07-24 02:10:19 +0200632 sed s,-pedantic,,)"
Martin Roth987d42d2018-07-22 11:45:29 -0600633 export HOSTCFLAGS
Nico Huber5f72f962016-01-31 23:05:19 +0100634}
635
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700636build_GMP() {
Nico Huber8bbd5962016-12-22 16:05:54 +0100637 # Check if GCC enables `-pie` by default (possible since GCC 6).
638 # We need PIC in all static libraries then.
Nico Huber2c1c02e2017-01-02 20:51:28 +0100639 if $CC -dumpspecs 2>/dev/null | grep -q '[{;][[:space:]]*:-pie\>'
Nico Huber8bbd5962016-12-22 16:05:54 +0100640 then
641 OPTIONS="$OPTIONS --with-pic"
642 fi
643
Martin Roth987d42d2018-07-22 11:45:29 -0600644 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200645 CC="$(hostcc host)" CXX="$(hostcxx host)" \
Felix Singerf8157af2022-11-23 10:12:26 +0100646 ../${GMP_DIR}/configure \
647 --disable-shared \
648 --enable-fat \
649 --prefix="$TARGETDIR" \
650 $OPTIONS || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600651 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700652 $MAKE $JOBS || touch .failed
653 $MAKE install DESTDIR=$DESTDIR || touch .failed
654
655 normalize_dirs
Stefan Reinauer1c70e052015-06-09 11:47:28 -0700656
Nico Huber5f72f962016-01-31 23:05:19 +0100657 set_hostcflags_from_gmp
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700658}
659
660build_MPFR() {
Martin Roth987d42d2018-07-22 11:45:29 -0600661 test "$UNAME" = "Darwin" && CFLAGS="$CFLAGS -force_cpusubtype_ALL"
Nico Huber08bb8372017-06-24 19:50:35 +0200662 CC="$(hostcc host)" CXX="$(hostcxx host)" \
Felix Singerf8157af2022-11-23 10:12:26 +0100663 ../${MPFR_DIR}/configure \
664 --disable-shared \
665 --prefix="$TARGETDIR" \
Martin Roth987d42d2018-07-22 11:45:29 -0600666 --infodir="$TARGETDIR/info" \
Felix Singerf8157af2022-11-23 10:12:26 +0100667 --with-gmp="$DESTDIR$TARGETDIR" \
668 CFLAGS="$HOSTCFLAGS" || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600669 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700670 $MAKE $JOBS || touch .failed
671 $MAKE install DESTDIR=$DESTDIR || touch .failed
672
673 normalize_dirs
674
675 # work around build problem of libgmp.la
676 if [ "$DESTDIR" != "" ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600677 perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libgmp.la"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700678 fi
679}
680
681build_MPC() {
Nico Huber08bb8372017-06-24 19:50:35 +0200682 CC="$(hostcc host)" CXX="$(hostcxx host)" \
Felix Singerf8157af2022-11-23 10:12:26 +0100683 ../${MPC_DIR}/configure \
684 --disable-shared \
685 --prefix="$TARGETDIR" \
686 --infodir="$TARGETDIR/info" \
687 --with-mpfr="$DESTDIR$TARGETDIR" \
688 --with-gmp="$DESTDIR$TARGETDIR" \
689 CFLAGS="$HOSTCFLAGS" || touch .failed
Patrick Georgi790aab62017-04-26 17:35:35 +0200690
691 # work around build problem of libmpfr.la
692 if [ "$DESTDIR" != "" ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600693 perl -pi -e "s,$TARGETDIR/lib/libgmp.la,$DESTDIR\$&," "$DESTDIR$TARGETDIR/lib/libmpfr.la"
Patrick Georgi790aab62017-04-26 17:35:35 +0200694 fi
695
Martin Roth987d42d2018-07-22 11:45:29 -0600696 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700697 $MAKE $JOBS || touch .failed
698 $MAKE install DESTDIR=$DESTDIR || touch .failed
699
Patrick Georgi790aab62017-04-26 17:35:35 +0200700 # work around build problem of libmpfr.la
701 if [ "$DESTDIR" != "" ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600702 perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libmpfr.la"
Patrick Georgi790aab62017-04-26 17:35:35 +0200703 fi
704
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700705 normalize_dirs
706}
707
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700708build_BINUTILS() {
Nico Huberae6187f2016-12-22 22:16:39 +0100709 if [ $TARGETARCH = "x86_64-elf" ]; then
Stefan Reinauer682a90c2015-06-09 14:59:58 -0700710 ADDITIONALTARGET=",i386-elf"
711 fi
Patrick Georgif0d5f672022-09-08 20:25:46 +0200712 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200713 CC="$(hostcc target)" CXX="$(hostcxx target)" \
Felix Singerf8157af2022-11-23 10:12:26 +0100714 ../binutils-${BINUTILS_VERSION}/configure \
715 --prefix="$TARGETDIR" \
716 --target=${TARGETARCH} \
717 --enable-targets=${TARGETARCH}${ADDITIONALTARGET} \
718 --disable-werror \
719 --disable-nls \
720 --enable-lto \
721 --enable-gold \
722 --enable-multilib \
Elias Souza17d9d892023-02-18 12:53:34 -0300723 --disable-docs \
724 --disable-texinfo \
Patrick Georgif67005d2024-01-28 01:20:43 +0100725 ${TARGET_BINUTILS_OPTIONS} \
Nico Huber010ecf802016-12-22 16:19:37 +0100726 CFLAGS="$HOSTCFLAGS" \
Felix Singerf8157af2022-11-23 10:12:26 +0100727 CXXFLAGS="$HOSTCFLAGS" || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600728 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700729 $MAKE $JOBS || touch .failed
730 $MAKE install DESTDIR=$DESTDIR || touch .failed
731}
732
Nico Huber234d2462016-01-26 16:10:17 +0100733bootstrap_GCC() {
Martin Roth987d42d2018-07-22 11:45:29 -0600734 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200735 CC="$(hostcc host)" CXX="$(hostcxx host)" \
Nico Huber234d2462016-01-26 16:10:17 +0100736 CFLAGS="$HOSTCFLAGS" \
737 CFLAGS_FOR_BUILD="$HOSTCFLAGS" \
738 CFLAGS_FOR_TARGET="$HOSTCFLAGS -fPIC" \
739 CXXFLAGS="$HOSTCFLAGS" \
740 CXXFLAGS_FOR_BUILD="$HOSTCFLAGS" \
741 CXXFLAGS_FOR_TARGET="$HOSTCFLAGS -fPIC" \
742 ../gcc-${GCC_VERSION}/configure \
Felix Singerf8157af2022-11-23 10:12:26 +0100743 --prefix="$TARGETDIR" \
744 --libexecdir="$TARGETDIR/lib" \
Nico Huber234d2462016-01-26 16:10:17 +0100745 --enable-bootstrap \
Felix Singerf8157af2022-11-23 10:12:26 +0100746 --disable-werror \
747 --disable-nls \
748 --disable-shared \
749 --disable-multilib \
750 --disable-libssp \
751 --disable-libquadmath \
752 --disable-libcc1 \
Patrick Georgi97a9df42017-04-26 22:18:18 +0200753 --disable-libsanitizer \
Felix Singerf8157af2022-11-23 10:12:26 +0100754 ${GCC_OPTIONS} \
755 --enable-languages="${LANGUAGES}" \
756 --with-gmp="$DESTDIR$TARGETDIR" \
757 --with-mpfr="$DESTDIR$TARGETDIR" \
Martin Roth987d42d2018-07-22 11:45:29 -0600758 --with-mpc="$DESTDIR$TARGETDIR" \
Martin Roth7014f822020-12-21 15:49:33 -0700759 --with-pkgversion="coreboot bootstrap v$CROSSGCC_VERSION" \
Nico Huber234d2462016-01-26 16:10:17 +0100760 && \
Martin Roth987d42d2018-07-22 11:45:29 -0600761 # shellcheck disable=SC2086
Nico Huber234d2462016-01-26 16:10:17 +0100762 $MAKE $JOBS BOOT_CFLAGS="$HOSTCFLAGS" BUILD_CONFIG="" bootstrap && \
763 $MAKE install-gcc \
764 install-target-libgcc \
765 maybe-install-target-libada \
766 maybe-install-target-libstdc++-v3 \
Nico Huber08bb8372017-06-24 19:50:35 +0200767 DESTDIR=$DESTDIR || touch .failed
Nico Huber234d2462016-01-26 16:10:17 +0100768}
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700769
Nico Huber234d2462016-01-26 16:10:17 +0100770build_cross_GCC() {
Stefan Reinauer45f77b82016-04-03 20:52:01 -0700771 # Work around crazy code generator in GCC that confuses CLANG.
Aaron Durbinb2229dc2016-04-07 16:58:10 -0500772 $CC --version | grep clang >/dev/null 2>&1 && \
Patrick Georgia7a5a562017-06-26 07:21:46 +0200773 CLANGFLAGS="-fbracket-depth=1024"
Nico Huber3f12d932017-08-31 23:11:18 +0200774 [ -n "$CXX" ] && $CXX --version | grep clang >/dev/null 2>&1 && \
Patrick Georgia7a5a562017-06-26 07:21:46 +0200775 CLANGCXXFLAGS="-fbracket-depth=1024"
Stefan Reinauer45f77b82016-04-03 20:52:01 -0700776
Stefan Reinauerd0f83722015-06-09 11:52:28 -0700777 # GCC does not honor HOSTCFLAGS at all. CFLAGS are used for
778 # both target and host object files.
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700779 # There's a work-around called CFLAGS_FOR_BUILD and CFLAGS_FOR_TARGET
780 # but it does not seem to work properly. At least the host library
781 # libiberty is not compiled with CFLAGS_FOR_BUILD.
Stefan Reinauer45f77b82016-04-03 20:52:01 -0700782 # Also set the CXX version of the flags because GCC is now compiled
783 # using C++.
Martin Roth987d42d2018-07-22 11:45:29 -0600784 # shellcheck disable=SC2086
Nico Huber08bb8372017-06-24 19:50:35 +0200785 CC="$(hostcc target)" CXX="$(hostcxx target)" \
Nico Huber3f12d932017-08-31 23:11:18 +0200786 CFLAGS_FOR_TARGET="-O2 -Dinhibit_libc" \
Patrick Georgia7a5a562017-06-26 07:21:46 +0200787 CFLAGS="$HOSTCFLAGS $CLANGFLAGS" \
788 CFLAGS_FOR_BUILD="$HOSTCFLAGS $CLANGFLAGS" \
789 CXXFLAGS="$HOSTCFLAGS $CLANGCXXFLAGS" \
790 CXXFLAGS_FOR_BUILD="$HOSTCFLAGS $CLANGCXXFLAGS" \
791 ../gcc-${GCC_VERSION}/configure \
Felix Singerf8157af2022-11-23 10:12:26 +0100792 --prefix="$TARGETDIR" \
793 --libexecdir="$TARGETDIR/lib" \
794 --target=${TARGETARCH} \
795 --disable-werror \
796 --disable-shared \
797 --enable-lto \
798 --enable-plugins \
799 --enable-gold \
800 --enable-ld=default \
801 --disable-libssp \
802 --disable-bootstrap \
803 --disable-nls \
804 --disable-libquadmath \
805 --without-headers \
Patrick Georgi0a97d7e2016-01-25 09:51:22 +0100806 --disable-threads \
Felix Singerf8157af2022-11-23 10:12:26 +0100807 --enable-interwork \
808 --enable-multilib \
809 --enable-targets=all \
810 --disable-libatomic \
811 --disable-libcc1 \
812 --disable-decimal-float \
813 ${GCC_OPTIONS} \
Patrick Georgif67005d2024-01-28 01:20:43 +0100814 ${TARGET_GCC_OPTIONS} \
Felix Singerf8157af2022-11-23 10:12:26 +0100815 --enable-languages="${LANGUAGES}" \
Ronald G. Minnich7ee16b72016-02-12 21:54:59 +0000816 --with-system-zlib \
Felix Singerf8157af2022-11-23 10:12:26 +0100817 --with-gmp="$DESTDIR$TARGETDIR" \
818 --with-mpfr="$DESTDIR$TARGETDIR" \
Martin Roth987d42d2018-07-22 11:45:29 -0600819 --with-mpc="$DESTDIR$TARGETDIR" \
Felix Singerf8157af2022-11-23 10:12:26 +0100820 --with-gnu-as \
821 --with-gnu-ld \
Martin Roth7014f822020-12-21 15:49:33 -0700822 --with-pkgversion="coreboot toolchain v$CROSSGCC_VERSION" \
Nico Huber659f40b2018-05-23 17:06:53 +0200823 && \
Patrick Georgi095db332018-06-26 21:00:58 +0200824 mkdir -p gcc/$TARGETARCH && \
Nico Hubere87fcd42020-12-21 00:11:54 +0100825 rm -f "gcc/$TARGETARCH/$GCC_VERSION" && \
Martin Roth987d42d2018-07-22 11:45:29 -0600826 ln -s "$DESTDIR$TARGETDIR/$TARGETARCH/bin" "gcc/$TARGETARCH/$GCC_VERSION" && \
Nico Huber659f40b2018-05-23 17:06:53 +0200827 $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-gcc && \
Martin Roth987d42d2018-07-22 11:45:29 -0600828 $MAKE install-gcc DESTDIR="$DESTDIR" || touch .failed
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700829
Martin Roth987d42d2018-07-22 11:45:29 -0600830 if [ ! -f .failed ] && [ "$(echo $TARGETARCH | grep -c -- -mingw32)" -eq 0 ]; then
831 # shellcheck disable=SC2086
Nico Huber659f40b2018-05-23 17:06:53 +0200832 $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-target-libgcc && \
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700833 $MAKE install-target-libgcc DESTDIR=$DESTDIR || touch .failed
834 fi
835}
836
Nico Huber234d2462016-01-26 16:10:17 +0100837build_GCC() {
838 if [ "$1" = host ]; then
Martin Roth987d42d2018-07-22 11:45:29 -0600839 bootstrap_GCC "$1"
Nico Huber234d2462016-01-26 16:10:17 +0100840 else
Martin Roth987d42d2018-07-22 11:45:29 -0600841 build_cross_GCC "$1"
Nico Huber234d2462016-01-26 16:10:17 +0100842 fi
843}
844
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700845build_IASL() {
846 RDIR=$PWD
Martin Roth987d42d2018-07-22 11:45:29 -0600847 cd ../$IASL_DIR/generate/unix || exit 1
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700848 CFLAGS="$HOSTCFLAGS"
849 HOST="_LINUX"
Martin Roth987d42d2018-07-22 11:45:29 -0600850 test "$UNAME" = "Darwin" && HOST="_APPLE"
851 test "$UNAME" = "FreeBSD" && HOST="_FreeBSD"
852 test "$UNAME" = "Cygwin" && HOST="_CYGWIN"
Nico Huber08bb8372017-06-24 19:50:35 +0200853 HOST="$HOST" CFLAGS="$CFLAGS" \
Martin Roth7014f822020-12-21 15:49:33 -0700854 OPT_CFLAGS="-O -D_FORTIFY_SOURCE=2 -D COREBOOT_TOOLCHAIN_VERSION='\"coreboot toolchain v$CROSSGCC_VERSION\"' " \
Elyes HAOUAS157851f2020-05-29 10:20:14 +0200855 $MAKE $JOBS CC="$(hostcc host)" iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract
Patrick Georgi54f86a52021-05-11 15:06:37 +0200856 mkdir -p "$DESTDIR$TARGETDIR/bin/"
857 (cd "$DESTDIR$TARGETDIR/bin" && rm -f iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract) || touch "$RDIR/.failed"
858 (cd bin && cp iasl acpibin acpidump acpiexec acpihelp acpisrc acpixtract "$DESTDIR$TARGETDIR/bin") || touch "$RDIR/.failed"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700859}
860
861build_LLVM() {
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700862
Patrick Georgi5a76a532021-06-03 08:48:26 +0200863 ln -nsf "$LLVM_DIR" ../llvm
864 ln -nsf "$CLANG_DIR" ../clang
865 ln -nsf "$CTE_DIR" ../clang-tools-extra
866 ln -nsf "$CRT_DIR" ../compiler-rt
Elyes Haouasc8870b12022-09-16 12:10:00 +0200867 ln -nsf "$LLVMCMAKE_DIR" ../cmake
Martin Roth987d42d2018-07-22 11:45:29 -0600868
Felix Singerf8157af2022-11-23 10:12:26 +0100869 $CMAKE -G "Unix Makefiles" \
870 -DCMAKE_INSTALL_PREFIX="$DESTDIR$TARGETDIR" \
Martin Roth7014f822020-12-21 15:49:33 -0700871 -DCLANG_VENDOR="coreboot toolchain v$CROSSGCC_VERSION - " \
Patrick Georgi5a76a532021-06-03 08:48:26 +0200872 -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;compiler-rt" \
Felix Singerf8157af2022-11-23 10:12:26 +0100873 -DLLVM_INCLUDE_BENCHMARKS="OFF" \
Felix Singer52191f22022-11-23 10:20:11 +0100874 -DLLVM_INCLUDE_TESTS="OFF" \
875 -DLLVM_INCLUDE_EXAMPLES="OFF" \
Felix Singerf8157af2022-11-23 10:12:26 +0100876 -DCMAKE_BUILD_TYPE=Release \
Felix Singer3e7438b2022-11-23 10:02:10 +0100877 -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;PowerPC;RISCV;X86" \
878 ../llvm || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600879 # shellcheck disable=SC2086
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700880 $MAKE $JOBS || touch .failed
881 $MAKE install || touch .failed
882
Elyes Haouas49119422022-11-21 11:19:14 +0100883 rm -f ../llvm ../clang ../clang-tools-extra ../compiler-rt ../cmake
Patrick Georgi5a76a532021-06-03 08:48:26 +0200884
Elyes HAOUAS8f1853c2020-08-02 09:46:15 +0200885 cp -a ../$CLANG_DIR/tools/scan-build/* "$DESTDIR$TARGETDIR/bin"
886 cp -a ../$CLANG_DIR/tools/scan-view/* "$DESTDIR$TARGETDIR/bin"
Stefan Reinauere7757bd2015-06-05 13:59:44 -0700887}
888
Stefan Reinauer3b593492017-06-19 17:28:54 -0700889build_CMAKE() {
Nico Huber08bb8372017-06-24 19:50:35 +0200890 CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" \
Felix Singerf8157af2022-11-23 10:12:26 +0100891 ../${CMAKE_DIR}/configure \
Felix Singer3a5507f2023-04-01 11:32:56 +0200892 --parallel=${THREADS} \
Felix Singerf8157af2022-11-23 10:12:26 +0100893 --prefix="$TARGETDIR" || touch .failed
Martin Roth987d42d2018-07-22 11:45:29 -0600894 # shellcheck disable=SC2086
Stefan Reinauer3b593492017-06-19 17:28:54 -0700895 $MAKE $JOBS || touch .failed
896 $MAKE install DESTDIR=$DESTDIR || touch .failed
Stefan Reinauer3b593492017-06-19 17:28:54 -0700897}
898
Martin Rothd70f5fa2019-05-26 17:24:19 -0600899build_NASM() {
Elyes Haouas8d50e422023-01-28 12:54:28 +0100900 CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" \
Felix Singerf8157af2022-11-23 10:12:26 +0100901 ../${NASM_DIR}/configure \
902 --prefix="$TARGETDIR" || touch .failed
Martin Rothd70f5fa2019-05-26 17:24:19 -0600903 # shellcheck disable=SC2086
904 $MAKE $JOBS || touch .failed
905 $MAKE install DESTDIR=$DESTDIR || touch .failed
906
907 normalize_dirs
908}
909
Stefan Reinauerc66fd3c2017-06-21 14:57:28 -0700910print_supported() {
911 case "$PRINTSUPPORTED" in
Martin Rothedf965a2015-11-25 16:58:33 -0700912 BINUTILS|binutils) printf "%s\n" "$BINUTILS_VERSION";;
913 CLANG|clang) printf "%s\n" "$CLANG_VERSION";;
Martin Rothedf965a2015-11-25 16:58:33 -0700914 GCC|gcc) printf "%s\n" "$GCC_VERSION";;
Martin Rothedf965a2015-11-25 16:58:33 -0700915 GMP|gmp) printf "%s\n" "$GMP_VERSION";;
916 IASL|iasl) printf "%s\n" "$IASL_VERSION";;
Martin Rothedf965a2015-11-25 16:58:33 -0700917 MPC|mpc) printf "%s\n" "$MPC_VERSION";;
918 MPFR|mpfr) printf "%s\n" "$MPFR_VERSION";;
Martin Rothd70f5fa2019-05-26 17:24:19 -0600919 NASM|nasm) printf "%s\n" "${NASM_VERSION}";;
Stefan Reinauerc66fd3c2017-06-21 14:57:28 -0700920 *) printf "Unknown tool %s\n" "$PRINTSUPPORTED";;
Martin Rothedf965a2015-11-25 16:58:33 -0700921 esac
922}
Stefan Reinauer074d9132009-09-26 16:43:17 +0000923
Nico Huber18c74d62017-06-24 20:35:59 +0200924trap exit_handler 1 2 3 15
Zheng Baobb003c82016-08-05 13:41:51 +0800925
Patrick Georgi6bba29f2010-01-29 17:40:52 +0000926# Look if we have getopt. If not, build it.
927export PATH=$PATH:.
928getopt - > /dev/null 2>/dev/null || gcc -o getopt getopt.c
929
Stefan Reinauer074d9132009-09-26 16:43:17 +0000930# parse parameters.. try to find out whether we're running GNU getopt
Nico Huber27e8412b2017-12-05 22:02:21 +0100931getoptbrand="$(getopt -V 2>/dev/null | sed -e '1!d' -e 's,^\(......\).*,\1,')"
Peter Stuge09377b72011-08-21 06:24:55 +0200932if [ "${getoptbrand}" = "getopt" ]; then
Stefan Reinauer074d9132009-09-26 16:43:17 +0000933 # Detected GNU getopt that supports long options.
Martin Rothe59868c2023-08-20 20:21:17 -0600934 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 +0200935 getopt_ret=$?
Nico Hubercc414dd2016-09-20 13:59:38 +0200936 eval set -- "$args"
Stefan Reinauer074d9132009-09-26 16:43:17 +0000937else
938 # Detected non-GNU getopt
Martin Roth3b32af92022-11-27 12:55:31 -0700939 args=$(getopt WVhcd:bBp:l:P:j:D:tSys:unm $*)
Nico Huber78df0bf2016-09-20 14:11:53 +0200940 getopt_ret=$?
Martin Roth987d42d2018-07-22 11:45:29 -0600941 # shellcheck disable=SC2086
Stefan Reinauer074d9132009-09-26 16:43:17 +0000942 set -- $args
943fi
944
Nico Huber78df0bf2016-09-20 14:11:53 +0200945if [ $getopt_ret != 0 ]; then
Stefan Reinauer074d9132009-09-26 16:43:17 +0000946 myhelp
947 exit 1
948fi
949
950while true ; do
951 case "$1" in
Felix Singer60c56be2021-10-17 14:54:12 +0200952 -W|--print-version) shift; echo $CROSSGCC_VERSION; exit 0;;
Patrick Georgi9681cdc2017-09-22 18:57:10 +0200953 -V|--version) shift; myversion; exit 0;;
954 -h|--help) shift; myhelp; exit 0;;
955 -c|--clean) shift; clean=1;;
956 -t|--savetemps) shift; SAVETEMPS=1;;
957 -d|--directory) shift; TARGETDIR="$1"; shift;;
958 -b|--bootstrap) shift; BOOTSTRAP=1;;
959 -B|--bootstrap-only) shift; BOOTSTRAPONLY=1; BOOTSTRAP=1;;
960 -p|--platform) shift; TARGETARCH="$1"; shift;;
961 -l|--languages) shift; LANGUAGES="$1"; shift;;
Martin Roth3b32af92022-11-27 12:55:31 -0700962 -m|--mirror) shift; USE_COREBOOT_MIRROR=1;;
Patrick Georgi9681cdc2017-09-22 18:57:10 +0200963 -D|--destdir) shift; DESTDIR="$1"; shift;;
Martin Rothe59868c2023-08-20 20:21:17 -0600964 -f|--fetch) shift; FETCH_ONLY=1;;
Patrick Georgi9681cdc2017-09-22 18:57:10 +0200965 -j|--jobs) shift; THREADS="$1"; JOBS="-j $1"; shift;;
966 -P|--package) shift; PACKAGE="$1"; shift;;
Patrick Georgi9681cdc2017-09-22 18:57:10 +0200967 -y|--ccache) shift; USECCACHE=1;;
968 -s|--supported) shift; PRINTSUPPORTED="$1"; shift;;
969 -u|--urls) shift; printf "%s\n" "$ALL_ARCHIVES"; exit 0;;
970 -n|--nocolor) shift; \
Martin Roth4a53db02016-03-01 15:21:07 -0700971 unset red RED green GREEN blue BLUE cyan CYAN NC;;
Patrick Georgid2e0dd52013-06-09 08:05:45 +0200972 --) shift; break;;
Patrick Georgid2e0dd52013-06-09 08:05:45 +0200973 *) break;;
Stefan Reinauer074d9132009-09-26 16:43:17 +0000974 esac
975done
976
Nico Huberbd74d562016-09-20 14:16:43 +0200977if [ $# -gt 0 ]; then
978 printf "Excessive arguments: $*\n"
979 myhelp
980 exit 1
981fi
982
Stefan Reinauerc66fd3c2017-06-21 14:57:28 -0700983if [ -n "$PRINTSUPPORTED" ]; then
984 print_supported
Martin Rothedf965a2015-11-25 16:58:33 -0700985 exit 0
986fi
987
988#print toolchain builder version string as the header
989printversion
990
Martin Roth2c6a8062016-11-14 11:58:39 -0700991printf "Building toolchain using %d thread(s).\n\n" "$THREADS"
992
Ronald G. Minnichb460a662013-05-26 05:33:35 -0700993case "$TARGETARCH" in
Timothy Pearsona9f62352015-12-30 18:59:00 -0600994 x86_64-elf) ;;
995 x86_64*) TARGETARCH=x86_64-elf;;
996 i386-elf) ;;
997 i386-mingw32) ;;
Patrick Georgif0d5f672022-09-08 20:25:46 +0200998 riscv-elf) TARGETARCH=riscv64-elf
Patrick Georgif67005d2024-01-28 01:20:43 +0100999 TARGET_GCC_OPTIONS="$TARGET_GCC_OPTIONS --with-isa-spec=20191213"
1000 TARGET_BINUTILS_OPTIONS="$TARGET_BINUTILS_OPTIONS --with-isa-spec=20191213";;
Patrick Georgi0a97d7e2016-01-25 09:51:22 +01001001 powerpc64*-linux*) ;;
Timothy Pearsona9f62352015-12-30 18:59:00 -06001002 i386*) TARGETARCH=i386-elf;;
Stefan Reinauer27522ad2016-01-29 17:31:34 -08001003 arm*) TARGETARCH=arm-eabi;;
Timothy Pearsona9f62352015-12-30 18:59:00 -06001004 aarch64*) TARGETARCH=aarch64-elf;;
Martin Roth3e0f74d2016-03-08 12:07:04 -07001005 nds32le-elf) ;;
Timothy Pearsona9f62352015-12-30 18:59:00 -06001006 *) printf "${red}WARNING: Unsupported architecture $TARGETARCH.${NC}\n\n"; ;;
Ronald G. Minnichb460a662013-05-26 05:33:35 -07001007esac
1008
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001009# Figure out which packages to build
Stefan Reinauer699ac272015-06-05 12:43:28 -07001010
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001011case "$PACKAGE" in
1012 GCC|gcc)
Stefan Reinauer81693d42017-06-21 15:25:36 -07001013 echo "Target architecture is $TARGETARCH"
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001014 NAME="${TARGETARCH} cross GCC"
Nico Huberafda56e2017-12-07 17:50:53 +01001015 PACKAGES="GMP MPFR MPC BINUTILS GCC"
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001016 ;;
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001017 CLANG|clang)
Stefan Reinauer81693d42017-06-21 15:25:36 -07001018 NAME="LLVM clang"
1019 LLVM_VERSION=${CLANG_VERSION}
Elyes Haouasc8870b12022-09-16 12:10:00 +02001020 PACKAGES="CMAKE LLVM CLANG CRT CTE LLVMCMAKE"
Stefan Reinauerca117e72017-06-19 17:29:08 -07001021 CMAKE=${DESTDIR}${TARGETDIR}/bin/cmake
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001022 ;;
1023 IASL|iasl)
1024 NAME="IASL ACPI compiler"
1025 PACKAGES=IASL
1026 ;;
Stefan Reinauer3b593492017-06-19 17:28:54 -07001027 CMAKE|cmake)
1028 NAME="CMake"
1029 PACKAGES=CMAKE
1030 ;;
Martin Rothd70f5fa2019-05-26 17:24:19 -06001031 NASM|nasm)
1032 NAME="NASM"
1033 PACKAGES=NASM
1034 ;;
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001035 *)
Patrick Georgif32eed12021-10-16 10:50:00 +02001036 printf "${red}ERROR: Unsupported package $PACKAGE. (Supported packages are GCC, CLANG, IASL, and NASM)${NC}\n\n";
Stefan Reinauer85b07d62015-06-09 14:45:14 -07001037 exit 1
1038 ;;
1039esac
Peter Stugeceacd772011-06-09 04:54:16 +02001040
Stefan Reinauer66e93352015-06-16 22:38:23 +02001041# Find all the required tools:
1042
1043TAR=$(searchtool tar) || exit $?
1044PATCH=$(searchtool patch) || exit $?
1045MAKE=$(searchtool make) || exit $?
1046SHA1SUM=$(searchtool sha1sum)
zbao5cf758d2015-09-01 22:28:57 -04001047#SHA512SUM=$(searchtool sha512sum)
1048#MD5SUM=$(searchtool md5sum)
Stefan Reinauer66e93352015-06-16 22:38:23 +02001049CHECKSUM=$SHA1SUM
Martin Roth95f7b222016-03-20 12:38:48 -06001050LBZIP2=$(searchtool lbzip2 "" nofail)
1051PIGZ=$(searchtool pigz "" nofail)
Stefan Reinauer66e93352015-06-16 22:38:23 +02001052
1053searchtool m4 > /dev/null
1054searchtool bison > /dev/null
1055searchtool flex flex > /dev/null
Stefan Reinauer66e93352015-06-16 22:38:23 +02001056searchtool bzip2 "bzip2," > /dev/null
Nico Huber0ff3b392017-03-12 16:07:33 +01001057searchtool xz "XZ Utils" "" "xz-utils" > /dev/null
Stefan Reinauer66e93352015-06-16 22:38:23 +02001058
Patrick Georgidf1ff232017-01-07 09:28:43 +01001059if searchtool wget "GNU" nofail > /dev/null; then
1060 download_showing_percentage() {
1061 url=$1
Stefan Reinauer81693d42017-06-21 15:25:36 -07001062 printf "... ${red} 0%%"
Martin Roth82a30a12020-11-07 15:17:45 -07001063 wget --tries=3 "$url" 2>&1 | while read -r line; do
Martin Roth987d42d2018-07-22 11:45:29 -06001064 echo "$line" | grep -o "[0-9]\+%" | awk '{printf("\b\b\b\b%4s", $1)}'
Patrick Georgidf1ff232017-01-07 09:28:43 +01001065 done
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +02001066 printf "${NC}... "
Patrick Georgidf1ff232017-01-07 09:28:43 +01001067 }
1068elif searchtool curl "^curl " > /dev/null; then
1069 download_showing_percentage() {
1070 url=$1
1071 echo
Idwer Vollering5190f422020-11-24 15:13:16 +01001072 curl -O --progress-bar --location --retry 3 "$url"
Patrick Georgidf1ff232017-01-07 09:28:43 +01001073 }
1074fi
1075
Nico Huber08bb8372017-06-24 19:50:35 +02001076# Allow $CC override from the environment.
1077if [ -n "$CC" ]; then
1078 if [ ! -x "$(command -v "$CC" 2>/dev/null)" ]; then
1079 printf "${RED}ERROR:${red} CC is set to '%s' but wasn't found.${NC}\n" "$CC"
1080 HALT_FOR_TOOLS=1
1081 fi
1082else
Patrick Georgi8f2cdad2017-07-10 11:48:34 +02001083 if searchtool gnatgcc "Free Software Foundation" nofail > /dev/null; then
Felix Singerc374dee2023-10-04 03:10:52 +00001084 # gnatgcc is deprecated and in recent GCC releases its purpose is
1085 # fulfilled by the gcc binary. In case of a deprecated gnatgcc
1086 # version is installed, it doesn't provide the expected output and
1087 # hostcc_has_gnat1() fails. In this case, just set the value of CC
1088 # to gcc.
1089 # TODO: Remove this whole branch when time is appropriate as the
1090 # second branch fulfills our needs.
Patrick Georgi8f2cdad2017-07-10 11:48:34 +02001091 CC=gnatgcc
Felix Singerc374dee2023-10-04 03:10:52 +00001092 if ! hostcc_has_gnat1; then
1093 CC=gcc
1094 fi
Patrick Georgi8f2cdad2017-07-10 11:48:34 +02001095 elif searchtool gcc "Free Software Foundation" nofail > /dev/null; then
Nico Huber08bb8372017-06-24 19:50:35 +02001096 CC=gcc
1097 else
1098 searchtool cc '^' nofail > /dev/null || please_install gcc
1099 CC=cc
1100 fi
1101fi
Martin Roth591790f2016-03-20 20:39:04 -06001102
Nico Huber08bb8372017-06-24 19:50:35 +02001103# We can leave $CXX empty if it's not set since *buildgcc* never
1104# calls it directly. This way configure scripts can search for
1105# themselves and we still override it when a bootstrapped g++ is
1106# to be used (cf. hostcxx()).
1107if [ -n "$CXX" ]; then
1108 if [ ! -x "$(command -v "$CXX" 2>/dev/null)" ]; then
1109 printf "${RED}ERROR:${red} CXX is set to '%s' but wasn't found.${NC}\n" "$CXX"
1110 HALT_FOR_TOOLS=1
1111 fi
1112else
1113 searchtool g++ "Free Software Foundation" nofail > /dev/null || \
1114 searchtool clang "clang version" nofail > /dev/null || \
1115 searchtool clang "LLVM" "" "g++" > /dev/null
1116fi
1117
1118check_for_library "-lz" "zlib (zlib1g-dev or zlib-devel)"
Nico Huber156d87c2016-09-20 12:59:53 +02001119
Martin Roth88463822016-01-07 11:03:36 -07001120if [ "$HALT_FOR_TOOLS" -ne 0 ]; then
1121 exit 1
1122fi
1123
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001124# This initial cleanup is useful when updating the toolchain script.
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001125
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001126if [ "$clean" = "1" ]; then
1127 cleanup
1128fi
Stefan Reinauer074d9132009-09-26 16:43:17 +00001129
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001130# Set up host compiler and flags needed for various OSes
Stefan Reinauer074d9132009-09-26 16:43:17 +00001131
Patrick Georgif2c15f52015-06-11 21:07:31 +02001132if is_package_enabled "GCC"; then
Patrick Georgie8253fe2017-07-18 11:35:35 +02001133# sane preset: let the configure script figure out things by itself
1134# more importantly, avoid any values that might already linger in the variable
1135OPTIONS="ABI="
Martin Roth987d42d2018-07-22 11:45:29 -06001136if [ "$UNAME" = "Darwin" ]; then
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001137 #GCC_OPTIONS="$GCC_OPTIONS --enable-threads=posix"
1138
1139 # generally the OS X compiler can create x64 binaries.
1140 # Per default it generated i386 binaries in 10.5 and x64
1141 # binaries in 10.6 (even if the kernel is 32bit)
1142 # For some weird reason, 10.5 autodetects an ABI=64 though
1143 # so we're setting the ABI explicitly here.
Martin Roth987d42d2018-07-22 11:45:29 -06001144 if [ "$(sysctl -n hw.optional.x86_64 2>/dev/null)" -eq 1 ] 2>/dev/null; then
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001145 OPTIONS="ABI=64"
1146 else
1147 OPTIONS="ABI=32"
1148 fi
Stefan Reinauer9491b4d2011-10-11 22:37:59 -07001149
Stefan Reinauer4266b922012-12-05 16:18:32 -08001150 # In Xcode 4.5.2 the default compiler is clang.
1151 # However, this compiler fails to compile gcc 4.7.x. As a
1152 # workaround it's possible to compile gcc with llvm-gcc.
Stefan Reinauer9491b4d2011-10-11 22:37:59 -07001153 if $CC -v 2>&1 | grep -q LLVM; then
Stefan Reinauer4266b922012-12-05 16:18:32 -08001154 CC=llvm-gcc
Stefan Reinauer9491b4d2011-10-11 22:37:59 -07001155 fi
Martin Roth987d42d2018-07-22 11:45:29 -06001156elif [ "$UNAME" = "Linux" ] || [ "$UNAME" = "Cygwin" ]; then
Patrick Georgiddb8f802015-07-04 17:45:54 +02001157 # gmp is overeager with detecting 64bit CPUs even if they run
1158 # a 32bit kernel and userland.
1159 if [ "$(uname -m 2>/dev/null)" = "i686" ]; then
1160 OPTIONS="ABI=32"
1161 fi
Martin Roth987d42d2018-07-22 11:45:29 -06001162elif [ "$UNAME" = "NetBSD" ]; then
Nico Huberde45c592016-01-20 23:22:33 +01001163 # same for NetBSD but this one reports an i386
1164 if [ "$(uname -m 2>/dev/null)" = "i386" ]; then
1165 OPTIONS="ABI=32"
1166 fi
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001167fi
Nico Huber66c2c1a2016-09-20 13:09:29 +02001168if [ -z "${LANGUAGES}" ]; then
Nico Hubercd87e1b2017-06-24 20:35:59 +02001169 if have_gnat; then
Nico Huber66c2c1a2016-09-20 13:09:29 +02001170 printf "\nFound compatible Ada compiler, enabling Ada support by default.\n\n"
1171 LANGUAGES="ada,${DEFAULT_LANGUAGES}"
1172 else
Nico Hubercd87e1b2017-06-24 20:35:59 +02001173 printf "\n${red}WARNING${NC}\n"
1174 printf "No compatible Ada compiler (GNAT) found. You can continue without\n"
1175 printf "Ada support, but this will limit the features of ${blue}coreboot${NC} (e.g.\n"
1176 printf "native graphics initialization won't be available on most Intel\n"
1177 printf "boards).\n\n"
1178
1179 printf "Usually, you can install GNAT with your package management system\n"
1180 printf "(the package is called \`gnat\` or \`gcc-ada\`). It has to match the\n"
1181 printf "\`gcc\` package in version. If there are multiple versions of GCC in-\n"
1182 printf "stalled, you can point this script to the matching version through\n"
1183 printf "the \`CC\` and \`CXX\` environment variables.\n\n"
1184
1185 printf "e.g. on Ubuntu 14.04, if \`gcc\` is \`gcc-4.8\`:\n"
1186 printf " apt-get install gnat-4.8 && make crossgcc\n\n"
1187
1188 printf "on Ubuntu 16.04, if \`gcc\` is \`gcc-5\`:\n"
1189 printf " apt-get install gnat-5 && make crossgcc\n"
1190 timeout 30
Nico Huber66c2c1a2016-09-20 13:09:29 +02001191 LANGUAGES="${DEFAULT_LANGUAGES}"
1192 fi
1193fi
Patrick Georgif2741aa2020-07-06 16:35:56 +02001194if [ "$BOOTSTRAP" != 1 ] && \
1195 { [ "$(hostcc_major)" -lt 4 ] || \
1196 { [ "$(hostcc_major)" -eq 4 ] && \
1197 [ "$(hostcc_minor)" -lt 9 ] ; } ; }
1198then
1199 printf "\n${red}WARNING${NC}\n"
1200 printf "Building coreboot requires a host compiler newer than 4.9.x while\n"
1201 printf "yours is $(hostcc_version).\n"
1202 printf "Enabling bootstrapping to provide a sufficiently new compiler:\n"
1203 printf "This will take significantly longer than a usual build.\n"
1204 printf "Alternatively you can abort now and update your host compiler.\n"
1205 timeout 15
1206 BOOTSTRAP=1
1207fi
Nico Hubercd87e1b2017-06-24 20:35:59 +02001208if ada_requested; then
Patrick Georgif2741aa2020-07-06 16:35:56 +02001209 if ! have_gnat; then
Nico Hubercd87e1b2017-06-24 20:35:59 +02001210 please_install gnat gcc-ada
1211 exit 1
1212 fi
Nico Hubercd87e1b2017-06-24 20:35:59 +02001213fi
Stefan Reinauer14ce2132015-06-05 13:01:13 -07001214fi # GCC
Stefan Reinauer5f1ad892010-05-17 11:02:25 +00001215
Nico Huber5f72f962016-01-31 23:05:19 +01001216export HOSTCFLAGS="-Os"
1217if have_hostcflags_from_gmp; then
1218 set_hostcflags_from_gmp
1219fi
1220
Patrick Georgic1a75b12011-11-04 21:37:14 +01001221if [ "$USECCACHE" = 1 ]; then
1222 CC="ccache $CC"
1223fi
1224
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001225# Prepare target directory for building GCC
1226# (dependencies must be in the PATH)
Martin Roth987d42d2018-07-22 11:45:29 -06001227mkdir -p "$DESTDIR$TARGETDIR/bin"
1228mkdir -p "$DESTDIR$TARGETDIR/share"
Stefan Reinauer16bd7892012-12-07 23:57:01 +01001229export PATH=$DESTDIR$TARGETDIR/bin:$PATH
1230
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001231# Download, unpack, patch and build all packages
1232
Idwer Vollering458e7df2020-09-25 12:26:51 +02001233printf "Downloading and verifying tarballs ...\n"
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001234mkdir -p tarballs
1235for P in $PACKAGES; do
Jonathan Neuschäfer92d483a2017-09-26 22:33:53 +02001236 download "$P" || exit "$?"
1237 verify_hash "$P" || exit "$?"
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001238done
Martin Roth03625172016-02-17 14:44:14 -07001239printf "Downloaded tarballs ... ${green}ok${NC}\n"
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001240
Martin Rothe59868c2023-08-20 20:21:17 -06001241if [ ${FETCH_ONLY} -eq 1 ]; then
1242 exit 0
1243fi
1244
Elyes HAOUASb0f19882018-06-09 11:59:00 +02001245printf "Unpacking and patching ...\n"
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001246for P in $PACKAGES; do
1247 unpack_and_patch $P || exit 1
1248done
1249printf "Unpacked and patched ... ${green}ok${NC}\n"
1250
Patrick Georgi9681cdc2017-09-22 18:57:10 +02001251if [ -n "$BOOTSTRAPONLY" ]; then
Elyes HAOUASb0f19882018-06-09 11:59:00 +02001252 printf "Building bootstrap compiler only ...\n"
Nico Huberafda56e2017-12-07 17:50:53 +01001253 for pkg in GMP MPFR MPC GCC; do
Patrick Georgi9681cdc2017-09-22 18:57:10 +02001254 build_for_host $pkg
1255 done
1256 exit 0
1257fi
1258
Elyes HAOUASb0f19882018-06-09 11:59:00 +02001259printf "Building packages ...\n"
Stefan Reinauer1c70e052015-06-09 11:47:28 -07001260for package in $PACKAGES; do
1261 build $package
1262done
Stefan Reinauer5dd26352015-06-09 14:52:22 -07001263printf "Packages built ... ${green}ok${NC}\n"
Stefan Reinauer14ce2132015-06-05 13:01:13 -07001264
Stefan Reinauer699ac272015-06-05 12:43:28 -07001265# Adding git information of current tree to target directory
1266# for reproducibility
Stefan Reinauerd7649122015-06-09 11:44:25 -07001267PROGNAME=$(basename "$0")
Stefan Reinauer88352d72016-04-06 15:57:03 -07001268rm -f "$DESTDIR$TARGETDIR/share/$PROGNAME-*"
Felix Singer62fcffb2021-10-19 13:25:18 +02001269cp "$PROGNAME" "$DESTDIR$TARGETDIR/share/$PROGNAME-$CROSSGCC_VERSION"
Zheng Bao30b895f2013-02-06 18:04:40 +08001270
Patrick Georgi0c2df6f2017-11-22 16:14:09 -05001271# Adding edk2 tools template
1272mkdir -p "$DESTDIR$TARGETDIR/share/edk2config"
1273sed -e "s,@@PREFIX@@,$TARGETDIR,g" edk2tools.txt > "$DESTDIR$TARGETDIR/share/edk2config/tools_def.txt"
1274printf "Copied EDK2 tools template ... ${green}ok${NC}\n"
1275
Stefan Reinauer88e83e52016-04-06 15:39:48 -07001276cleanup
Stefan Reinauer074d9132009-09-26 16:43:17 +00001277
Stefan Reinauer81693d42017-06-21 15:25:36 -07001278printf "\n${green}You can now run $NAME from $TARGETDIR.${NC}\n"