#!/bin/sh if [ -e build.ninja ]; then echo The build.ninja file already exists. echo Remove it with clean-build.sh. exit fi if [ "$#" -eq 0 ]; then echo This script must be run with at least one flag. The recognized flags are: echo echo " -- Do nothing, but silence this message." echo echo " --cxx-flags FLAGS Add FLAGS to the flags sent to the C++ compiler. The flags" echo " should be quoted, so that they are all read by this script" echo " as one argument." echo echo " --debug Enable debugging symbols." echo echo " --ld-flags FLAGS Add FLAGS to the flags sent to ld. The flags should be" echo " quoted, so that they are all read by this script as one" echo " argument." echo echo " --no-optimize Disable compiler optimizations. This might help with using" echo " the debugger. A bug could only appear when optimizations" echo " are enabled, so it might be necessary to run the debugger" echo " without this flag." echo echo These options can be combined. exit fi set -e CXX_FLAGS="-std=c++17 -ffreestanding -fno-exceptions -fno-rtti -mno-sse -I include -Wall -Wextra" LD_FLAGS="-L build/libraries" OPTIMIZE_CXX_FLAGS="-O2" DEBUG_CXX_FLAGS="" NO_DEBUG_LD_FLAGS="-s" EXTRA_CXX_FLAGS="" EXTRA_LD_FLAGS="" while [ "$#" -gt 0 ]; do case "$1" in --cxx-flags) shift EXTRA_CXX_FLAGS="$EXTRA_CXX_FLAGS $1" ;; --debug) DEBUG_CXX_FLAGS="-ggdb" NO_DEBUG_LD_FLAGS="" ;; --ld-flags) shift EXTRA_LD_FLAGS="$EXTRA_LD_FLAGS $1" ;; --no-optimize) OPTIMIZE_CXX_FLAGS="" ;; --) ;; *) echo Unknown argument. exit esac shift done CXX_FLAGS="$CXX_FLAGS $OPTIMIZE_CXX_FLAGS $DEBUG_CXX_FLAGS $EXTRA_CXX_FLAGS" LD_FLAGS="$LD_FLAGS $NO_DEBUG_LD_FLAGS $EXTRA_LD_FLAGS" rules() { echo "rule asm" echo " command = nasm -f elf64 \$in -o \$out" echo "rule cxx" echo " depfile = \$out.d" echo " command = c++ -c -MD -MF \$out.d $CXX_FLAGS \$in -o \$out" echo "rule core_ld" echo " depfile = \$out.d" echo " command = ld $LD_FLAGS -T src/core/link.ld \$in -o \$out" echo "rule service_ld" echo " depfile = \$out.d" echo " command = ld $LD_FLAGS -T src/service/link.ld \$in -o \$out" echo "rule disk" echo " command =" \ "rm -rf build/disk &&" \ "cp -r disk build/disk &&" \ "mkdir -p build/disk/EFI/BOOT &&" \ "mkdir -p build/disk/limine &&" \ "mkdir -p build/disk/calcite/service &&" \ "cp dependencies/limine-binary/BOOTX64.EFI build/disk/EFI/BOOT/ &&" \ "cp dependencies/limine-binary/limine-uefi-cd.bin build/disk/limine/ &&" \ "cp dependencies/limine-binary/limine-bios-cd.bin build/disk/limine/ &&" \ "cp dependencies/limine-binary/limine-bios.sys build/disk/limine/ &&" \ "cp build/core.elf build/disk/calcite/ &&" \ "cp build/service/*.elf build/disk/calcite/service/ &&" \ "xorriso -as mkisofs -R -r -J -b limine/limine-bios-cd.bin -no-emul-boot -boot-load-size 4" \ "-boot-info-table -hfsplus -apm-block-size 2048 --efi-boot limine/limine-uefi-cd.bin" \ "-efi-boot-part --efi-boot-image --protective-msdos-label build/disk -o build/disk.iso &&" \ "dependencies/limine-binary/limine bios-install build/disk.iso" } build_core() { echo "build build/core/core.cxx.o: cxx src/core/core.cxx" echo "build build/core/core.asm.o: asm src/core/core.asm" echo "build build/core.elf: core_ld build/core/core.cxx.o build/core/core.asm.o" } build_service() { SERVICE="$1" OBJECTS="" for SOURCE in $(find "src/service/$SERVICE" -regex '.*\.cxx'); do OBJECT="$(echo $SOURCE | sed 's/src/build/').o" echo "build $OBJECT: cxx $SOURCE" OBJECTS="$OBJECTS $OBJECT" done for SOURCE in $(find "src/service/$SERVICE" -regex '.*\.asm'); do OBJECT="$(echo $SOURCE | sed 's/src/build/').o" echo "build $OBJECT: asm $SOURCE" OBJECTS="$OBJECTS $OBJECT" done echo "build build/service/$SERVICE.elf: service_ld$OBJECTS" } build_disk() { echo "build build/disk.iso: disk | $@" } default() { echo "default build/disk.iso" } rules >> build.ninja DISK_DEPS="build/core.elf" build_core >> build.ninja for DIRECTORY in src/service/*; do if [ -d "$DIRECTORY" ]; then SERVICE="$(basename $DIRECTORY)" DISK_DEPS="$DISK_DEPS build/service/$SERVICE.elf" build_service $SERVICE >> build.ninja fi done build_disk $DISK_DEPS >> build.ninja default >> build.ninja