summaryrefslogtreecommitdiff
path: root/build.sh
diff options
context:
space:
mode:
Diffstat (limited to 'build.sh')
-rwxr-xr-xbuild.sh231
1 files changed, 231 insertions, 0 deletions
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..bb9c67a
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,231 @@
+#!/bin/bash
+
+set -e
+
+if [ -z "${CROSSCC_i686}" ]; then
+ CROSSCC_i686=i686-elf-gcc
+fi
+
+if [ -z "${CROSSAS_i686}" ]; then
+ CROSSAS_i686=i686-elf-as
+fi
+
+if [ -z "${CROSSCC_x8664}" ]; then
+ CROSSCC_x8664=x86_64-elf-gcc
+fi
+
+if [ -z "${CROSSAS_x8664}" ]; then
+ CROSSAS_x8664=x86_64-elf-as
+fi
+
+if [ -z "${CROSSLD_i686}" ]; then
+ CROSSLD_i686=i686-elf-ld
+fi
+
+if [ -z "${CROSSLD_x8664}" ]; then
+ CROSSLD_x8664=x86_64-elf-ld
+fi
+
+if [ -z "${STAGE1_DIR}" ]; then
+ STAGE1_DIR="./stage1/"
+fi
+
+if [ -z "${STAGE2_DIR}" ]; then
+ STAGE2_DIR="$(pwd)/stage2"
+fi
+
+if [ -z "${BUILD_DIR}" ]; then
+ BUILD_DIR="$(pwd)/build"
+fi
+mkdir -p "${BUILD_DIR}"
+
+if [ -z "${TARGET}" ]; then
+ TARGET="$(pwd)/bootloader"
+fi
+
+GLOBAL_CFLAGS=(-I./include -ffreestanding -m32 -nostdlib)
+
+LINKER_LD="linker.ld"
+
+# Stage 1
+
+STAGE1_LD="${STAGE1_DIR}/linker.ld"
+
+STAGE1_C_FILES=$(find "${STAGE1_DIR}" -name "*.c")
+STAGE1_AS_FILES=$(find "${STAGE1_DIR}" -name "*.S")
+
+STAGE1_AS_TARGET="${BUILD_DIR}/stage1_as.o"
+STAGE1_CC_TARGET="${BUILD_DIR}/stage1_cc.o"
+
+STAGE1_TARGET="${BUILD_DIR}/stage1.bin"
+
+# Stage 2
+
+STAGE2_LD="${STAGE1_DIR}/linker.ld"
+
+STAGE2_C_FILES=$(find "${STAGE2_DIR}" -name "*.c")
+STAGE2_AS_FILES=$(find "${STAGE2_DIR}" -name "*.S")
+
+STAGE2_AS_TARGET="${BUILD_DIR}/stage2_as.o"
+STAGE2_CC_TARGET="${BUILD_DIR}/stage2_cc.o"
+
+STAGE1_DIR="$(pwd)/stage1"
+STAGE2_DIR="$(pwd)/stage2"
+
+function usage {
+ echo -e "Custom build system."
+ echo -e "Available commands:"
+ echo -e " ${0} all"
+ echo -e " ${0} run"
+ echo -e " ${0} build_drive"
+ echo -e " ${0} clean"
+ echo -e " ${0} stage1"
+}
+
+function build_lib {
+ macro="$1"
+
+ set -e
+
+ local lib_cfiles=$(find "./lib/" -name "*.c")
+
+ mkdir -p "${BUILD_DIR}/lib"
+ for i in ${lib_cfiles[@]}; do
+ "${CROSSCC_i686}" -m32 -c "$i" "${GLOBAL_CFLAGS[@]}" -o "${BUILD_DIR}/${i}.o" -D${macro}
+ echo -e " [CC] ${i}"
+ done
+
+ echo "[LIB] Compiled libraries."
+}
+
+function stage1 {
+ set -e
+
+ if [[ -e "${BUILD_DIR}/${STAGE1_DIR}" ]] && [[ -f "${BUILD_DIR}/${STAGE1_DIR}" ]]; then
+ mkdir -p "${BUILD_DIR}/${STAGE1_DIR}"
+ echo -e "Creating the stage 1 build directory ${BUILD_DIR}/${STAGE1_DIR}"
+ fi
+
+ echo -e "Producing stage 1 binaries..."
+
+ if [[ ${#STAGE1_AS_FILES[@]} -gt 0 ]] && [[ -n "${STAGE1_AS_FILES[@]}" ]]; then
+ echo -e "[STAGE1] Found assembly files: "
+ for i in ${STAGE1_AS_FILES[@]}; do
+ mkdir -p "${BUILD_DIR}/${i}"
+ "${CROSSAS_i686}" "$i" -o "${BUILD_DIR}/${i}.o"
+ echo -e " [AS]: $i"
+ done
+ echo -e " [AS] Assembled stage 1."
+ else
+ echo -e "[STAGE1] No assembly files were found."
+ fi
+
+ if [[ ${#STAGE1_C_FILES[@]} -gt 0 ]] && [[ -n "${STAGE1_C_FILES[@]}" ]]; then
+ echo -e "[STAGE1] Found C files: "
+ for i in ${STAGE1_C_FILES[@]}; do
+ "${CROSSCC_i686}" -c "$i" -o "${BUILD_DIR}/${i}.o" "${GLOBAL_CFLAGS[@]}"
+ echo -e " [CC]: $i"
+ done
+ echo -e " [CC] Compiled stage 1."
+ else
+ echo -e "[STAGE1] No C files were found."
+ fi
+
+ if [[ ${#STAGE1_C_FILES[@]} -eq 0 ]] && [[ ${#STAGE1_AS_FILES[@]} -eq 0 ]]; then
+ echo -e "[STAGE1] No stage1 files were found!"
+ exit 1
+ fi
+
+ echo -e "Stage 1 binaries completed."
+}
+
+function stage2 {
+ if [[ -e "${BUILD_DIR}/${STAGE1_DIR}" ]] && [[ -f "${BUILD_DIR}/${STAGE1_DIR}" ]]; then
+ mkdir -p "${BUILD_DIR}/${STAGE1_DIR}"
+ fi
+
+ ${CROSSAS_i686} "${STAGE2_AS_FILES}" -o "${STAGE2_AS_TARGET}"
+ echo -e " [AS] Assembled stage 2."
+ ${CROSSCC_x8664} "${STAGE2_C_FILES}" -o "${STAGE2_CC_TARGET}"
+ echo -e " [CC] Compiled stage 2."
+}
+
+function link {
+ set -e
+
+ local linker_files=()
+
+ echo -e "[LINK] Linking files..."
+
+ for i in $(find "${BUILD_DIR}" -name "*.o"); do
+ linker_files+=("$i")
+ echo -e " [L] Added: $i"
+ done
+
+ "${CROSSLD_i686}" -T "${LINKER_LD}" "${linker_files[@]}" -o "${STAGE1_TARGET}"
+
+ echo -e "[LINK] Linking complete."
+}
+
+function clean {
+ if [[ -e "${BUILD_DIR}" && -d "${BUILD_DIR}" ]]; then
+ echo -e "[CLEAN] Deleting build/ directory..."
+ rm -rf "${BUILD_DIR}"
+ fi
+
+ if [[ -e "$(pwd)/disk.img" && -f "$(pwd)/disk.img" ]]; then
+ echo -e "[CLEAN] Deleting disk.img..."
+ rm "$(pwd)/disk.img"
+ fi
+ echo -e "[CLEAN] Project cleaned."
+}
+
+function build_image {
+ dd if="${STAGE1_TARGET}" of="$(pwd)/disk.img" bs=512 count=15
+}
+
+function run {
+ qemu-system-x86_64 -drive format=raw,file="$(pwd)/disk.img"
+}
+
+function debug {
+ qemu-system-x86_64 -drive format=raw,file="$(pwd)/disk.img" -S -s
+}
+
+function compile {
+ echo "[COMPILE] Compiling and preparing the entire build."
+ clean
+ mkdir -p ./build/
+ build_lib "STAGE1"
+ stage1
+ link
+ build_image
+ echo "[COMPILE] DONE"
+}
+
+function run {
+ qemu-system-x86_64 -drive format=raw,file=disk.img
+}
+
+case "$1" in
+ "all") compile ;;
+ "run") compile && run ;;
+ "debug") compile && debug ;;
+ "stage1") stage1 ;;
+ "build_drive") build_image ;;
+ "clean") clean ;;
+ "help"|"usage")
+ usage
+ exit 0
+ ;;
+ "")
+ echo -e "You must specify a command."
+ echo -e "Type '${0} usage' or '${0} help' for more information."
+ exit 1
+ ;;
+ *)
+ echo -e "Command not found: '${1}'"
+ usage
+ exit 1
+ ;;
+esac