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.
283 lines
5.9 KiB
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
|
|
|