[TOOLCHAIN] Building cross compiler, debugger and bootloader
This commit is contained in:
parent
0ffcf4316d
commit
94999611d4
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
toolchain/
|
10
Makefile
Normal file
10
Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Check that the build environment is setup
|
||||||
|
# Idea taken from https://github.com/klange/toaruos
|
||||||
|
ifeq ($(MITTOS64),)
|
||||||
|
$(error Build environment is not activated. Please source activate)
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
|
||||||
|
all:
|
||||||
|
|
17
README.md
17
README.md
@ -2,3 +2,20 @@ MITTOS64
|
|||||||
========
|
========
|
||||||
|
|
||||||
By Thomas Lovén - 2016
|
By Thomas Lovén - 2016
|
||||||
|
|
||||||
|
For development, start by sourcing `activate.sh`
|
||||||
|
|
||||||
|
source ./activate.sh
|
||||||
|
|
||||||
|
Running `make` will automatically download and compile a cross compiler
|
||||||
|
toolchain and the grub bootloader.
|
||||||
|
|
||||||
|
It will also download and build objconv, which is required for building grub
|
||||||
|
under OSX. This will probably fail if you're not on a mac.
|
||||||
|
|
||||||
|
Building the cross compiler requires a c compiler as well as gmp, mpfr and mpc.
|
||||||
|
The c compiler installed by xcode command line tools will do. It's installed
|
||||||
|
automatically if you install homebrew. The rest of the packages can be
|
||||||
|
installed with homebrew. You'll also want homebrews ctags.
|
||||||
|
|
||||||
|
homebrew install gmp mpfr libmpc ctags
|
||||||
|
24
activate
Executable file
24
activate
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# This file should be sourced before building mittos64:
|
||||||
|
# $ source ./activate
|
||||||
|
|
||||||
|
export MITTOS64=mittos64
|
||||||
|
. util/helpers.sh
|
||||||
|
|
||||||
|
export BUILDROOT=`pwd`
|
||||||
|
export TOOLCHAIN=${BUILDROOT}/toolchain
|
||||||
|
export PATH=${TOOLCHAIN}/bin:${PATH}
|
||||||
|
export TARGET=x86_64-elf
|
||||||
|
|
||||||
|
# shortcuts for some useful tools
|
||||||
|
alias dbg="x86_64-elf-linux-gdb"
|
||||||
|
alias objd="${TARGET}-objdump"
|
||||||
|
function decomp()
|
||||||
|
{
|
||||||
|
${TARGET}-objdump -S $1 | vim - -R
|
||||||
|
}
|
||||||
|
|
||||||
|
export PS1="(mittos64)${PS1}"
|
||||||
|
|
||||||
|
util/build_toolchain.sh -c || util/build_toolchain.sh
|
107
util/build_toolchain.sh
Executable file
107
util/build_toolchain.sh
Executable 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
36
util/helpers.sh
Executable 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
120
util/toolchain_helpers.sh
Normal 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"
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user