RISC-V operating system
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
rovo/build_cross_toolchain.sh

283 lines
5.9 KiB

#!/bin/sh
BUILD_GCC=true
BUILD_BINUTILS=true
BUILD_GDB=true
START_SHELL=false
PROJECT_ROOT="$(pwd)"
CROSS_ROOT="$PROJECT_ROOT/cross"
PREFIX="$CROSS_ROOT"
CROSS_BUILD_DIR="$PROJECT_ROOT/.cross_build"
TARGET=''
CPUS=1
# Get the target arch
if [ -z "$ARCH" ]; then
ARCH="$1"
shift
if [ -z "$ARCH" ]; then
echo "Must define an arch"
exit 1
fi
fi
case "$ARCH" in
'x86_64-elf'|'x86_64'|'x64'|'amd64')
TARGET='x86_64-elf'
CONFIG_EXTRA_GCC="$CONFIG_EXTRA_GCC --enable-multilib"
;;
'i686-elf'|'i386'|'x32'|'386')
TARGET='i686-elf'
CONFIG_EXTRA_GCC="$CONFIG_EXTRA_GCC --enable-multilib"
;;
'riscv-64-elf'|'rv64'|'riscv64')
TARGET='riscv-64-elf'
;;
*)
echo "arch=$ARCH not implemented"
exit 1
;;
esac
# Get the build target
while [ "${1:-}" != "" ]; do
case "$1" in
"--no-gcc")
BUILD_GCC=false
;;
"--no-binutils")
BUILD_BINUTILS=false
;;
"--no-gdb")
BUILD_GDB=false
;;
"--start-shell")
START_SHELL=true
BUILD_GCC=false
BUILD_BINUTILS=false
BUILD_GDB=false
;;
esac
shift
done
# TODO: add some more options to speed up the build / disable unnecessary features
# https://gitlab.archlinux.org/archlinux/packaging/packages/riscv64-linux-gnu-binutils/-/blob/main/PKGBUILD
CONFIG_EXTRA_BINUTILS="\
--without-zstd \
--with-sysroot \
--enable-languages=c \
--disable-nls \
--disable-werror"
# TODO: add some more options to speed up the build / disable unnecessary features
# https://gitlab.archlinux.org/archlinux/packaging/packages/riscv64-linux-gnu-gcc/-/blob/main/PKGBUILD
CONFIG_EXTRA_GCC="\
--without-zstd \
--disable-nls \
--enable-languages=c \
--without-headers"
CONFIG_EXTRA_GDB="\
--with-sysroot \
--disable-nls \
--disable-werror \
--without-headers \
--enable-languages=c \
--enable-tui=yes \
--with-expat"
#CONFIG_HOST="$(gcc -dumpmachine)"
FTP_MIRROR="https://ftpmirror.gnu.org"
gdb_version='13.1'
gcc_version='12.2.0'
binutils_version='2.37'
gcc_url="$FTP_MIRROR/gcc/gcc-$gcc_version"
binutils_url="$FTP_MIRROR/binutils"
gdb_url="$FTP_MIRROR/gdb"
gdb_build_log=gdb-log-"$(date +%F_%H-%M)".log
gcc_build_log=gcc-log-"$(date +%F_%H-%M)".log
binutils_build_log=binutils-log-"$(date +%F_%H-%M)".log
# check if the user wants a particular version
if [ -n "$GDB_VERSION" ]; then
gdb_version="$GDB_VERSION"
fi
# sanity check
if [ -z "$TARGET" ]; then
echo "Target not specified, how'd you get this far?"
exit 1
fi
# get the right number of cpus
# and some extra fixes
case $(uname) in
'OpenBSD')
CPUS="$(sysctl -n hw.ncpu)"
CPUS=$((CPUS + 1))
CONFIG_EXTRA_GCC="$CONFIG_EXTRA_GCC --with-gmp=/usr/local"
# use GNU make
alias make=gmake
;;
'Linux')
CPUS="$(nproc)"
CPUS=$((CPUS + 1))
;;
*)
;;
esac
gpg_verify() {
keyring="$1"
pkg="$2"
sig="$3"
gpg --verify --keyring "$keyring" "$sig" "$pkg"
return $?
}
download_sources() {
pkg="$1"
sig="$2"
url="$3"
wget -nv -O "$pkg" "$url/$pkg" || return $?
wget -nv -O "$sig" "$url/$sig" || return $?
}
download_and_build() {
pkg_name="$1"
pkg_version="$2"
pkg_config="$3"
pkg_url="$4"
pkg_ark="$pkg_name-$pkg_version.tar.xz"
pkg_sig="$pkg_name-$pkg_version.tar.xz.sig"
# Get the archives and signature if they are not already present
if ! [ -e "$pkg_ark" ] || ! [ -e "$pkg_sig" ]; then
download_sources "$pkg_ark" "$pkg_sig" "$pkg_url" || return 1
fi
# Verify the archive
if ! gpg_verify ./gnu-keyring.gpg "$pkg_ark" "$pkg_sig"; then
echo "Package signature was incorrect, please remove the donwloaded sources and try again"
return 1
fi
# Extract the archive
xz -k -d "$pkg_ark"
tar -xf "$pkg_name-$pkg_version.tar" && rm -f "$pkg_name-$pkg_version.tar"
# FIXME: this forces a comlete rebuild
#if [ -d "build-$pkg_name-$TARGET" ]; then
# rm -rf "build-$pkg_name-$TARGET"
#fi
mkdir -p "build-$pkg_name-$TARGET"
cd "build-$pkg_name-$TARGET" || exit 1
oldpath="$PATH"
export PATH="$PREFIX/bin:$PATH"
# shellcheck disable=SC2086
../"$pkg_name-$pkg_version"/configure \
--target="$TARGET" \
$pkg_config \
--prefix="$PREFIX" || return 1
case "$pkg_name" in
'gcc')
make all-gcc || return 1
make all-target-libgcc || return 1
make install-gcc || return 1
make install-target-libgcc || return 1
;;
'binutils')
make -j$CPUS || return 1
make install || return 1
;;
'gdb')
make all-gdb || return 1
make install-gdb || return 1
;;
esac
export PATH="$oldpath"
cd ..
return 0
}
#set -x
mkdir -p "$PREFIX"
mkdir -p "$CROSS_BUILD_DIR/$TARGET"
cd "$CROSS_BUILD_DIR/$TARGET" || exit 1
# get the gnu keyring, used to verify the archives
if [ $BUILD_GCC = true ] || [ $BUILD_BINUTILS = true ] || [ $BUILD_GDB = true ]; then
if ! [ -e gnu-keyring.gpg ]; then
wget -O gnu-keyring.gpg https://ftp.gnu.org/gnu/gnu-keyring.gpg
fi
fi
if [ $BUILD_BINUTILS = true ]; then
echo "### BUILDING BINUTILS ###"
download_and_build binutils "$binutils_version" "$CONFIG_EXTRA_BINUTILS" \
"$binutils_url" > ../"$binutils_build_log" 2>&1
res=$?
if ! [ $res -eq 0 ]; then
echo "Error building binutils, check $CROSS_BUILD_DIR/$binutils_build_log for more details"
exit 1
fi
fi
if [ $BUILD_GCC = true ]; then
echo "### BUILDING GCC ###"
download_and_build gcc "$gcc_version" "$CONFIG_EXTRA_GCC" \
"$gcc_url" > ../"$gcc_build_log" 2>&1
res=$?
if ! [ $res -eq 0 ]; then
echo "Error building gcc, check $CROSS_BUILD_DIR/$gcc_build_log for more details"
exit 1
fi
fi
if [ $BUILD_GDB = true ]; then
echo "### BUILDING GDB ###"
download_and_build gdb "$gdb_version" "$CONFIG_EXTRA_GDB" \
"$gdb_url" > ../"$gdb_build_log" 2>&1
res=$?
if ! [ $res -eq 0 ]; then
echo "Error building gdb, check $CROSS_BUILD_DIR/$gdb_build_log for more details"
exit 1
fi
fi
cd "$PROJECT_ROOT" || exit 1
if [ $START_SHELL = true ]; then
PATH="$CROSS_ROOT/bin:$PATH"
export PATH TARGET ARCH
echo "### Starting $SHELL with correct PATH and TARGET ###"
exec "$SHELL" || exit 1
fi
# TODO: validate that all things are where they should