[code lang=”bash”]
#! /bin/bash
##############################################################################
# Building gcc-12.2.0 aarch64 cross-compiler for Raspberry Pi5
# based on Slackware script for gcc-12.2.0 aarch64 cross-compiler for Raspberry Pi
##############################################################################
# Installation directory – edit INSTALL_PATH as required
INSTALL_PATH=${HOME}/cross-gcc-rpi5
# Required build packages-versions [* newer versions may exist]
BINUTILS_VERSION=binutils-2.40
CLOOG_VERSION=cloog-0.18.1
GCC_VERSION=gcc-12.2.0
GLIBC_VERSION=glibc-2.36
GMP_VERSION=gmp-6.2.1
ISL_VERSION=isl-0.24
MPFR_VERSION=mpfr-4.2.0
MPC_VERSION=mpc-1.3.1
ARCH=armv8-a+fp+simd
# RPi GitHub Linux source – working branch [e.g. rpi-4.19.y | rpi-5.15.y | rpi-5.19.y ]
DEV_BRANCH=rpi-6.6.y
# Halt build process on error [with output]
set -euo pipefail
IFS=$’\n\t’
# Uncomment for additional error output when testing/debugging
#trap ‘previous_command=$this_command; this_command=$BASH_COMMAND’ DEBUG
#trap ‘echo "exit $? due to $previous_command"’ EXIT
# Build variables
PRGNAM=cross-compiler-aarch64
ARCH_TARGET=aarch64-linux
LINUX_ARCH=arm64
QUADLET=aarch64-unknown-linux-gnu # aarch64-arm-none-eabi
LINUX_FLAVOUR=linux-rpi
RPI_GITURL_LINUX=https://github.com/raspberrypi
BUILD_LANGUAGES="–enable-languages=c,c++" # –enable-languages=all,ada,c,c++,fortran,go,jit,lto,objc,obj-c++
ALT_CONFIG_OPTIONS="–disable-multilib" # –disable-threads –disable-shared –disable-multiarch
TEST_CONFIG_OPTIONS="–with-arch=armv8-a –with-tune=cortex-a72 –with-fpu=vfpv3-d16 –with-float=hard" #
RPI4_CONFIG_OPTIONS="–prefix=$INSTALL_PATH –target=arm-linux-gnueabihf –enable-languages=c,c++ –with-arch=${ARCH} –with-fpu=vfp –with-float=hard –disable-multilib" #
PARALLEL_JOBS=-j4 # https://www.gnu.org/software/make/manual/html_node/Parallel.html
BUILDDIR=($PWD)
CWD="$BUILDDIR"/build-cc
# Define CONFIG_OPTIONS for build
CONFIG_OPTIONS=$ALT_CONFIG_OPTIONS
# Uncomment to log EVERYTHING during build process [** WARNING! HUGE log filesize! **]
#LOGFLE=${PRGNAM}_build_$(date +"%F").log
#exec 1> >(logger -s -t $(basename $0)) 2>&1 > $LOGFLE
# Output aesthetics
echo
echo " ############################################"
echo " ## $PRGNAM "
echo " ## Build: $GCC_VERSION Kernel ${DEV_BRANCH} "
echo " ## Timestamp: $(date ‘+%F %T’) "
echo " ############################################"
echo
echo "Starting $PRGNAM build …"
mkdir -p "$CWD"
cd "$CWD" || { echo "Cannot create ${CWD}"; exit 1; }
# INSTALL_PATH needs to be at the front of $PATH
# Command: export PATH=/tmp/.gcc-cross/bin:$PATH
echo "Checking $ARCH_TARGET $INSTALL_PATH/bin \$PATH …"
if [[ ! "$PATH" =~ $INSTALL_PATH ]]; then
export PATH=/"${INSTALL_PATH}"/bin:$PATH
# echo -e $INSTALL_PATH/bin:$(cat $PATH) > $PATH || exit 1
else
echo "Found $INSTALL_PATH\/bin in \$PATH : OK! … "
fi
# Prerequisite packages
BISON_REQ=$(which bison)
FLEX_REQ=$(which flex)
GAWK_REQ=$(which gawk)
GIT_REQ=$(which git)
# Check prerequisites are installed, or exit
if [ ! -e "$BISON_REQ" ]; then
echo "ERROR: bison not found!"
echo "Install bison before you run this script!"
exit 1
elif [ ! -e "$FLEX_REQ" ]; then
echo "ERROR: flex not found!"
echo "Install flex before you run this script!"
exit 1
elif [ ! -e "$GAWK_REQ" ]; then
echo "ERROR: gawk not found!"
echo "Install gawk before you run this script!"
exit 1
elif [ ! -e "$GIT_REQ" ]; then
echo "ERROR: git not found!"
echo "Install git before you run this script!"
exit 1
else
echo "Prerequisite packages are installed …"
fi
# Download RPi kernel source ** this may take a while **
cd "$CWD"
echo "Checking kernel $DEV_BRANCH source …"
if [ ! -e $LINUX_FLAVOUR/Makefile ]; then
echo "Downloading kernel $DEV_BRANCH source …"
git clone –depth=1 $RPI_GITURL_LINUX/linux.git –branch $DEV_BRANCH $LINUX_FLAVOUR
fi
cd $LINUX_FLAVOUR
echo "Checking kernel $DEV_BRANCH branch for updates …"
git checkout -f $DEV_BRANCH
cd "$CWD"
# Download gcc and related packages to build cross-compiler
echo "Downloading packages …"
if [ ! -d "$CWD"/$BINUTILS_VERSION ]; then
wget -nc –progress=bar https://ftp.gnu.org/gnu/binutils/$BINUTILS_VERSION.tar.gz
tar -xvf $BINUTILS_VERSION.tar.gz
fi
if [ ! -d "$CWD"/$GCC_VERSION ]; then
wget -nc –progress=bar https://ftp.gnu.org/gnu/gcc/$GCC_VERSION/$GCC_VERSION.tar.gz
tar -xvf $GCC_VERSION.tar.gz
fi
if [ ! -d "$CWD"/$GLIBC_VERSION ]; then
wget -nc –progress=bar https://ftp.gnu.org/gnu/glibc/$GLIBC_VERSION.tar.xz
tar -xvf $GLIBC_VERSION.tar.xz
fi
if [ ! -d "$CWD"/$GMP_VERSION ]; then
wget -nc –progress=bar https://ftp.gnu.org/gnu/gmp/$GMP_VERSION.tar.xz
tar -xvf $GMP_VERSION.tar.xz
fi
if [ ! -d "$CWD"/$MPFR_VERSION ]; then
wget -nc –progress=bar https://ftp.gnu.org/gnu/mpfr/$MPFR_VERSION.tar.xz
tar -xvf $MPFR_VERSION.tar.xz
fi
if [ ! -d "$CWD"/$MPC_VERSION ]; then
wget -nc –progress=bar https://ftp.gnu.org/gnu/mpc/$MPC_VERSION.tar.gz
tar -xvf $MPC_VERSION.tar.gz
fi
if [ ! -d "$CWD"/$ISL_VERSION ]; then
wget -nc –progress=bar ftp://gcc.gnu.org/pub/gcc/infrastructure/$ISL_VERSION.tar.bz2
tar -xvf $ISL_VERSION.tar.bz2
fi
if [ ! -d "$CWD"/$CLOOG_VERSION ]; then
wget -nc –progress=bar ftp://gcc.gnu.org/pub/gcc/infrastructure/$CLOOG_VERSION.tar.gz
tar -xvf $CLOOG_VERSION.tar.gz
fi
# Create symbolic links so gcc builds these dependencies automatically
echo "Creating symbolic links in gcc …"
cd "$CWD"/$GCC_VERSION
ln -sf ../$MPFR_VERSION mpfr
ln -sf ../$GMP_VERSION gmp
ln -sf ../$MPC_VERSION mpc
ln -sf ../$ISL_VERSION isl
ln -sf ../$CLOOG_VERSION cloog
# Create aarch64 cross-compiler install directory
echo "Creating $INSTALL_PATH directory …"
rm -rf $INSTALL_PATH
mkdir -p $INSTALL_PATH
chown "$(whoami)" $INSTALL_PATH
cd "$CWD"
# Build binutils
echo "Building binutils …"
rm -rf build-binutils
mkdir build-binutils
cd build-binutils
../$BINUTILS_VERSION/configure –prefix=$INSTALL_PATH –target=$ARCH_TARGET $CONFIG_OPTIONS
make $PARALLEL_JOBS
echo "Installing binutils …"
make install
# Install Linux kernel headers
echo "Installing kernel headers …"
cd "$CWD"/$LINUX_FLAVOUR
make ARCH=$LINUX_ARCH INSTALL_HDR_PATH=$INSTALL_PATH/$ARCH_TARGET headers_install
cd "$CWD"
# Build gcc C and C++ cross-compilers
echo "Building gcc $ARCH_TARGET C,C++ cross-compiler …"
mkdir -p build-gcc
cd build-gcc
../$GCC_VERSION/configure –prefix=$INSTALL_PATH –target=$ARCH_TARGET $BUILD_LANGUAGES $CONFIG_OPTIONS
make $PARALLEL_JOBS all-gcc
echo "Installing gcc $ARCH_TARGET cross-compiler to $INSTALL_PATH …"
make $PARALLEL_JOBS install-gcc
# create gcc-12.2.0 libsanitizer asan_linux-cpp.patch file
cd "$CWD"
touch asan_linux-cpp.patch
cat << EOF > asan_linux-cpp.patch
— gcc-12.2.0/libsanitizer/asan/asan_linux.cpp 2022-09-17 08:36:38.000000000 +0100
+++ asan_linux.cpp 2022-09-17 08:37:30.000000000 +0100
@@ -77,6 +77,10 @@
asan_rt_version_t __asan_rt_version;
}
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
namespace __asan {
void InitializePlatformInterceptors() {}
EOF
# Patch gcc-12.2.x/libsanitizerasan/asan_linux.cpp [or the build will fail]
ASANLINUXCC=$CWD/$GCC_VERSION/libsanitizer/asan/asan_linux.cpp
if [ ! -f "$ASANLINUXCC".orig ]; then
echo "Patching $ASANLINUXCC …"
patch -b "$ASANLINUXCC" asan_linux-cpp.patch || exit 1
# sarpiSP64
echo "$ASANLINUXCC has been PATCHED! …"
echo "Backup of original: $ASANLINUXCC.orig …"
sleep 10
fi
# Build and install glibc’s standard C library headers and startup files
echo "Building glibc library headers …"
mkdir -p build-glibc
cd build-glibc
../$GLIBC_VERSION/configure –prefix=$INSTALL_PATH/$ARCH_TARGET –build="$MACHTYPE" –host=$ARCH_TARGET –target=$ARCH_TARGET –with-headers=$INSTALL_PATH/$ARCH_TARGET/include $CONFIG_OPTIONS libc_cv_forced_unwind=yes
make $PARALLEL_JOBS install-bootstrap-headers=yes install-headers
make $PARALLEL_JOBS csu/subdir_lib
echo "Installing glibc library headers …"
install csu/crt1.o csu/crti.o csu/crtn.o $INSTALL_PATH/$ARCH_TARGET/lib
$ARCH_TARGET-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $INSTALL_PATH/$ARCH_TARGET/lib/libc.so
touch $INSTALL_PATH/$ARCH_TARGET/include/gnu/stubs.h
# Build glibc support library
echo "Building glibc support library …"
cd "$CWD"/build-gcc
make $PARALLEL_JOBS all-target-libgcc
echo "Installing glibc support library …"
make install-target-libgcc
# Finish building glibc’s standard C library and install it
echo "Completing glibc C library …"
cd "$CWD"/build-glibc
make $PARALLEL_JOBS
echo "Installing glibc C library …"
make install
# Finish building gcc’s C++ library and install it
echo "Completing glibc C++ library …"
cd "$CWD"/build-gcc
make $PARALLEL_JOBS
echo "Installing glibc C++ library …"
make install
cd "$CWD"
# Check status of aarch64-linux-gcc cross-compiler
echo "Checking status of $ARCH_TARGET-gcc cross-compiler …"
ARCH_TARGET_STATUS=$(which $ARCH_TARGET-gcc)
$ARCH_TARGET-gcc -v
if [ ! -e "$ARCH_TARGET_STATUS" ]; then
# ERROR!
echo "ERROR: $ARCH_TARGET-gcc not responding!"
echo "$(date +"%F %T") : $PRGNAM FAILED! …"
exit 1
else
# Done!
echo "Verifying $ARCH_TARGET-gcc \$PATH …"
echo "PATH: $PATH"
echo "Status: $ARCH_TARGET-gcc : READY!"
echo "$(date +"%F %T") : $PRGNAM build complete …"
fi
exit 0
[/code]