Skip to content

Commit

Permalink
build: add setup toolchain script
Browse files Browse the repository at this point in the history
  • Loading branch information
d0p1s4m4 committed Nov 28, 2023
1 parent 1f5009e commit 2635e48
Showing 1 changed file with 264 additions and 0 deletions.
264 changes: 264 additions & 0 deletions tools/setup-toolchain
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
#!/bin/bash
# Copyright © 2023, d0p1
#
# This file is part of Fukurō.
#
# This software is governed by the CeCILL license under French law and
# abiding by the rules of distribution of free software. You can use,
# modify and/ or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
# "http://cecill.info".
#
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty and the software's author, the holder of the
# economic rights, and the successive licensors have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean that it is complicated to manipulate, and that also
# therefore means that it is reserved for developers and experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and, more generally, to use and operate it in the
# same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.

set -o errexit
set -o nounset
set -o pipefail

BINUTILS_VERSION=2.41
BINUTILS_ARCHIVE="binutils-${BINUTILS_VERSION}.tar.gz"
BINUTILS_URL="https://ftp.gnu.org/gnu/binutils/${BINUTILS_ARCHIVE}"
BINUTILS_SHA256="48d00a8dc73aa7d2394a7dc069b96191d95e8de8f0da6dc91da5cce655c20e45"

GCC_VERSION=13.2.0
GCC_ARCHIVE="gcc-${GCC_VERSION}.tar.gz"
GCC_URL="https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/${GCC_ARCHIVE}"
GCC_SHA256="8cb4be3796651976f94b9356fa08d833524f62420d6292c5033a9a26af315078"

cerror="\033[31m"
cwarn="\033[33m"
cok="\033[32m"
creset="\033[0m"

target_triple=riscv-elf
install_prefix="${HOME}/.toolchain"
do_sha256_check=yes
do_force=no
do_update=no
do_build_binutils=no
do_build_gcc=no

warn() {
printf "[${cwarn}WARN${creset}] %s\n" "$1"
}

fatal() {
printf "[${cerror}FATAL${creset}] %s\n" "$1"
exit 255
}

finish() {
if [ -d "${install_prefix}/build" ]; then
(
cd "${install_prefix}/build"
rm -rf "binutils-${BINUTILS_VERSION}"
rm -rf "gcc-${GCC_VERSION}"
)
fi
}
trap finish EXIT ERR

setup() {
wget_exe=`which wget`
curl_exe=`which curl`
sha256sum_exe=`which sha256sum`

if [ x"$sha256sum_exe" = "x" ]; then
warn "sha256sum not found; sha256 check will be skipped"
do_sha256_check=no
fi
}

verify() {
printf "checking %s sha256 hash... " "$1"
if [ x"$do_sha256_check" = "xyes" ]; then
sha256sum -c <(printf "%s %s\n" "$2" "$1") > /dev/null && printf "${cok}OK${creset}\n" || (printf "${cerror}FAILED${creset}\n" && false)
else
printf "${cwarn}SKIP${creset}\n"
fi
}

check_current_binutils_version() {
printf "checking binutils version... "
if "${target_triple}-ld" --version | grep "${BINUTILS_VERSION}" >/dev/null; then
printf "${cok}OK${creset}\n"
else
printf "${cwarn}MISSMATCH${creset}\n"
if [ x"$do_update" = "xyes" ]; then
do_build_binutils=yes
fi
fi
}

check_current_binutils() {
printf "checking for %s-ld... " "${target_triple}"
if command -v "${target_triple}-ld" > /dev/null; then
printf "${cok}FOUND${creset}\n"

check_current_binutils_version
else
printf "${cerror}NO${creset}\n"
do_build_binutils=yes
fi
}

check_current_gcc_version() {
printf "checking gcc version... "
if "${target_triple}-gcc" --version | grep "${GCC_VERSION}" >/dev/null; then
printf "${cok}OK${creset}\n"
else
printf "${cwarn}MISSMATCH${creset}\n"
if [ x"$do_update" = "xyes" ]; then
do_build_gcc=yes
fi
fi
}

check_current_gcc() {
printf "checking for %s-gcc... " "${target_triple}"
if command -v "${target_triple}-gcc" > /dev/null; then
printf "${cok}FOUND${creset}\n"

check_current_gcc_version
else
printf "${cerror}NO${creset}\n"
do_build_gcc=yes
fi
}

download() {
for i in 1 2 3; do
if [ ! -f "$1" ]; then
$wget_exe -O "$1" "$2"
fi

if verify "$1" "$3"; then
break
else
rm "$1"
fi
done

test -f "$1"
}

build_binutils() {
(
cd "${install_prefix}/build"
download "${BINUTILS_ARCHIVE}" "${BINUTILS_URL}" "${BINUTILS_SHA256}"

printf "extract %s\n" "${BINUTILS_ARCHIVE}"
tar -xf "${BINUTILS_ARCHIVE}"
(
cd "binutils-${BINUTILS_VERSION}"
mkdir -p build
(
cd build
../configure --target="${target_triple}" --prefix="${install_prefix}" --with-sysroot --disable-nls --disable-werror
make -j $(nproc)
make install
)
)
)
}

build_gcc() {
(
cd "${install_prefix}/build"
download "${GCC_ARCHIVE}" "${GCC_URL}" "${GCC_SHA256}"

printf "extract %s\n" "${GCC_ARCHIVE}"
tar -xf "${GCC_ARCHIVE}"
(
cd "gcc-${GCC_VERSION}"
mkdir -p build
(
cd build
../configure --target="${target_triple}" --prefix="${install_prefix}" --with-sysroot --disable-nls --enable-languages=c --with-newlib
make -j $(nproc) all-gcc
make -j $(nproc) all-target-libgcc
make -j $(nproc) install-gcc
make -j $(nproc) install-target-libgcc
)
)
)
}

usage() {
cat <<EOF
Usage: $0 [-t <triple>][-p <prefix>][-f][-h]
-t <triple> toolchain triple (default: $target_triple)
-p <prefix> install prefix path (default: $install_prefix)
-f force rebuild (eg: ignore cache when CI build)
-u update if toolchain version missmatch (default: no)
-h display this help and exit
Report bugs to: <https://github.com/d0p1s4m4/Fukuro>
EOF

exit 0
}

main() {
setup

while getopts 't:p:fh' opt; do
case "$opt" in
t)
target_triple="${OPTARG}"
;;
p)
install_target="${OPTARG%%/}"
;;
f)
do_force=yes
;;
u)
do_update=yes
;;
?|h)
usage "${@}"
;;
esac
done

PATH="${install_prefix}/bin:${PATH}"
mkdir -p "${install_prefix}/build"

if [ x"$do_force" = "xyes" ]; then
do_build_binutils=yes
do_build_gcc=yes
else
check_current_binutils
check_current_gcc
fi

if [ x"$do_build_binutils" = "xyes" ]; then
build_binutils
fi

if [ x"$do_build_gcc" = "xyes" ]; then
build_gcc
fi
}

main "${@}"

0 comments on commit 2635e48

Please sign in to comment.