[TOOLCHAIN] Building cross compiler, debugger and bootloader

This commit is contained in:
2016-07-22 20:49:27 +02:00
parent 0ffcf4316d
commit 94999611d4
7 changed files with 315 additions and 0 deletions

107
util/build_toolchain.sh Executable file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/env bash
. util/toolchain_helpers.sh
bindir=${TOOLCHAIN}/bin
packages=(binutils gcc gdb)
if [[ `uname` == 'Darwin' ]]; then
packages=("${packages[@]}" objconv)
fi
packages=("${packages[@]}" grub)
# Binutils 2.26
# Build with --with-sysroot for use in the future
binutils_checkfile=${bindir}/${TARGET}-ld
binutils_filename=binutils-2.26
binutils_url=ftp://ftp.gnu.org/gnu/binutils/${binutils_filename}.tar.gz
binutils_config="--target=${TARGET} \
--with-sysroot \
--disable-nls \
--disable-werror"
# GCC 6.1.0
# Build with --without-headers for now - this will be replaced later
gcc_checkfile=${bindir}/${TARGET}-gcc
gcc_filename=gcc-6.1.0
gcc_url=ftp://ftp.gnu.org/gnu/gcc/${gcc_filename}/${gcc_filename}.tar.gz
gcc_config="--target=${TARGET} \
--disable-nls \
--enable-languages=c,c++ \
--without-headers"
gcc_make="all-gcc all-target-libgcc"
gcc_install="install-gcc install-target-libgcc"
# GDB 7.12
gdb_checkfile=${bindir}/x86_64-elf-linux-gdb
gdb_filename=gdb-7.12
gdb_url=ftp://ftp.gnu.org/gnu/gdb/${gdb_filename}.tar.gz
gdb_config="--target=x86_64-elf-linux \
--disable-debug \
--disable-dependency-tracking \
--with-python=/usr"
# objconv
# This is required for building grub on OSX
objconv_checkfile=${bindir}/objconv
objconv_filename=objconv
objconv_url=git://github.com/vertis/objconv.git
function objconv_install() {
# Download and build objconv
local package=objconv
pushd ${STASH}/${package} >/dev/null
echo "Compiling"
g++ -o ${TOOLCHAIN}/bin/objconv -O2 src/*.cpp \
>/dev/null 2>>"${STASH}/error-${package}.log" || fail
popd >/dev/null
}
# GRUB
# The target x86_64-elf is close enough to what we want
# Make sure to use the right target compiler chains
grub_checkfile=${bindir}/grub-mkimage
grub_filename=grub
grub_url=git://git.savannah.gnu.org/grub.git
grub_config="--target=x86_64-elf \
--disable-werror \
TARGET_CC=${TARGET}-gcc \
TARGET_OBJCOPY=${TARGET}-objcopy \
TARGET_STRIP=${TARGET}-strip \
TARGET_NM=${TARGET}-nm \
TARGET_RANLIB=${TARGET}-ranlib"
grub_patchcmd="autogen.sh"
function checkall() {
for package in "${packages[@]}"
do
check ${package} || return 1
done
return 0
}
function main() {
# If called with -c the script will check if a rebuild is necessary
while getopts "c" OPTION
do
case ${OPTION} in
c)
checkall
exit $?
;;
esac
done
print_info "Preparing toolchain"
mkdir -p "${STASH}"
PATH=${TOOLCHAIN}/bin:${PATH}
for package in "${packages[@]}"
do
build_package ${package} || return 1
done
}
main "${@}"

36
util/helpers.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
function print_info() {
echo -e "[\\033[36mINFO\\033[0m] $@"
}
function print_ok() {
echo -e "[\\033[32mOK\\033[0m] $@"
}
function print_warning() {
echo -e "[\\033[33mWARNING\\033[0m] $@"
}
function print_error() {
echo -e "[\\033[31mERROR\\033[0m] $@"
}
function die() {
print_error $@
exit 1
}
function check_toolchain() {
if [[ -z ${MITTOS64+x} ]]; then
die "TOOLCHAIN is not set. Please source activate"
exit 1
fi
}
check_toolchain
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
# Test output functions
print_info "This is an information message"
print_ok "This is OK"
print_warning "Be careful"
print_error "Something bad happened"
fi

120
util/toolchain_helpers.sh Normal file
View File

@@ -0,0 +1,120 @@
#!/usr/bin/env bash
. util/helpers.sh
# check_toolchain
readonly STASH=${TOOLCHAIN}/stash
readonly PREFIX=${TOOLCHAIN}
function fail() {
print_error "Something went wrong"
print_info "You may be able to find some information about what in ${STASH}/error-PACKAGE"
die "Building toolchain failed"
}
function download() {
# download url
# Downloads the file at url unless cached
# Return true if a file was downloaded
local url=$1
pushd "${STASH}" >/dev/null
if [[ ${url} == git* ]]; then
local filename=$(basename "${url}" .git)
if [[ ! -d ${filename} ]]; then
echo "Cloning" "${filename}"
/usr/bin/env git clone --depth 1 "${url}" \
>/dev/null 2>&1 || fail
print_ok "Clone complete"
return 0
else
print_ok "Using cached ${filename}"
return 1
fi
else
local filename=$(basename "${url}")
if [[ ! -f ${filename} ]]; then
echo "Downloading" "${filename}"
/usr/bin/env curl -# -O "${url}" || fail
/usr/bin/env tar -xf "${filename}" || fail
print_ok "Download complete"
return 0
else
print_ok "Using cached" "${filename}"
return 1
fi
fi
popd >/dev/null
}
function check() {
# check package
# Check if a package is installed
# Returns true if installed
local package=$1
local file=${package}_checkfile
if [[ -f ${!file} ]]; then
return 0
fi
return 1
}
function config_make_install() {
local package=$1
local filename=${package}_filename
local config=${package}_config
local make=${package}_make
local install=${package}_install
mkdir -p "${STASH}/build-${package}"
pushd "${STASH}/build-${package}" >/dev/null || fail
rm -rf ./*
echo "Configuring"
../${!filename}/configure \
--prefix=${PREFIX} \
${!config-} \
>/dev/null 2>>"${STASH}/error-${package}.log" || fail
echo "Building"
make --jobs=100 ${!make-all} \
>/dev/null 2>>"${STASH}/error-${package}.log" || fail
echo "Installing"
make ${!install-install} \
>/dev/null 2>>"${STASH}/error-${package}.log" || fail
popd >/dev/null
}
function build_package() {
local package=$1
local filename=${package}_filename
local url=${package}_url
local patch=${package}_patchcmd
if check ${package}; then
print_ok "Package ${package} already built"
return 0
fi
print_info "Building ${package}"
echo "Downloading"
if download ${!url}; then
pushd "${STASH}/${!filename}" >/dev/null || fail
echo "Applying patches / preparing to build"
eval ${!patch}
popd >/dev/null
fi
echo "Building and installing"
if type -t "${package}_install" >/dev/null; then
eval "${package}_install"
else
config_make_install ${package}
fi
print_ok "Build complete"
}