root_dir := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
source_dir := $(root_dir)/src
object_dir := $(root_dir)/build
linker_script := $(root_dir)/linker.ld
output_dir := $(root_dir)/output

LD := ld
CXX := clang++
CXXFLAGS := -std=c++20 -fpie -fno-strict-aliasing -fno-stack-protector -fno-asynchronous-unwind-tables -fno-exceptions -fno-rtti -fno-common -fno-c++-static-destructors -mno-red-zone -mgeneral-regs-only -ffreestanding -O2 -g -Wall -Wextra -Wno-reserved-identifier -I$(root_dir)/include

source_files := $(shell find $(source_dir) -type f -name "*.cpp")
object_files := $(patsubst $(source_dir)/%,$(object_dir)/%.o,$(source_files))

$(object_files): $(object_dir)%.o : $(source_dir)%
	@mkdir -p $(dir $@)
	@echo "Compiling $<"
	@$(CXX) $(CXXFLAGS) -c $< -o $@

kernel.bin: $(object_files)
	@mkdir -p $(output_dir)
	@echo "Linking kernel"
	@$(LD) --build-id=none --no-relax --no-warn-rwx-segments -nostdlib -o $(output_dir)/kernel.bin -T $(linker_script) $(object_files)
	@echo "Disassembling kernel"
	@objdump -dC $(output_dir)/kernel.bin > $(output_dir)/kernel.asm
	@objdump -DC $(output_dir)/kernel.bin > $(output_dir)/kernel_full.asm
	@echo "Dumping strings"
	@strings -t x $(output_dir)/kernel.bin > $(output_dir)/kernel.strings
	@echo "Hexdumping sections"
	@objdump -sC $(output_dir)/kernel.bin > $(output_dir)/kernel.hex


iso: kernel.bin
	@echo "Creating ISO"
	@cp $(output_dir)/kernel.bin $(root_dir)/iso/boot/kernel.bin
	@grub-mkrescue -d /usr/lib/grub/i386-pc -o $(output_dir)/kernel.iso iso

all: kernel.bin iso

clean:
	@rm -rf $(object_dir) $(output_dir) iso/boot/kernel.bin