.SILENT:


###############################
# Feature stuff
###############################
override SPECTRE_MITIGATION = @SPECTRE_MITIGATION@
override SERIAL_DEBUG = @SERIAL_DEBUG@

ifeq ($(SPECTRE_MITIGATION), 1)
	override SPECTRE_FLAGS=-D__SPECTRE_MITIGATION
else
	override SPECTRE_FLAGS=
endif

ifeq ($(SERIAL_DEBUG), 1)
	override SERIAL_DEBUG_FLAGS=-D__SERIAL_DEBUG
else
	override SERIAL_DEBUG_FLAGS=
endif


###############################
# CFLAGS, QEMU flags + misc
###############################
override ARCH = @ARCH@
override HYRA_VERSION = @PACKAGE_VERSION@
override PROMPT := printf "%s\t\t%s\n"
override KERNEL_DEFINES =  -DHYRA_VERSION="\"$(HYRA_VERSION)\""\
			   -DHYRA_BUILDDATE="\"@HYRA_BUILDDATE@\""\
			   -DHYRA_BUILDBRANCH="\"@HYRA_BUILDBRANCH@\""\
			   -DHYRA_ARCH="\"@ARCH@\""\
			   $(SPECTRE_FLAGS)\
			   $(SERIAL_DEBUG_FLAGS)
override KERNEL_CFLAGS = @KERNEL_CFLAGS@ $(KERNEL_DEFINES)
override KERNEL_LDFLAGS = -nostdlib -znoexecstack -zmax-page-size=0x1000 -static -Tconf/link-$(ARCH).ld
override QEMU_FLAGS = @QEMU_FLAGS@

######################
# Binutils stuff
######################
ifeq ($(ARCH), amd64)
	override CC = $(shell pwd)/cross/bin/x86_64-hyra-gcc
	override LD = $(shell pwd)/cross/bin/x86_64-hyra-ld
else
	override CC = $(shell pwd)/cross/bin/$(ARCH)-hyra-gcc
	override LD = $(shell pwd)/cross/bin/$(ARCH)-hyra-ld
endif
override AS = $(CC)
override USRDIR=$(shell pwd)/base/usr/
override LIBC = libc.a
override USER_MKFLGS = CC=$(CC) LD=$(LD) LIBC=$(LIBC) USRDIR=$(USRDIR)

##########################
# Architecture specifics
##########################
override ALL_ARCH_CFILES = find sys/ -name "*.c" |  grep "sys/arch/$(ARCH).*"
override ALL_ARCH_ASM_FILES = find sys/ -name "*.S" | grep "sys/arch/$(ARCH).*"
override QEMU = @QEMU@

##########################
# General kernel sources
##########################
override KERNEL_CFILES = $(shell find sys/ -name "*.c" | grep -v "sys/arch/*" | grep -v sys/kern/ksyms.c) $(shell $(ALL_ARCH_CFILES))
override KERNEL_ASMFILES = $(shell find sys/ -name "*.S" | grep -v "sys/arch/*") $(shell $(ALL_ARCH_ASM_FILES))

########################
# Objects & header deps
########################
override KERNEL_OBJECTS = $(KERNEL_CFILES:.c=.o)
override KERNEL_ASMOBJECTS = $(KERNEL_ASMFILES:.S=.S.o)
override KERNEL_HEADER_DEPS = $(KERNEL_CFILES:.c=.d)

.PHONY: all
all: base lib userland base/boot/hyra-kernel
		rm -f sys/include/machine
		rm -rf iso_root

base/usr/sbin/init:
	cd usr.sbin/; make $(USER_MKFLGS)
	mv usr.sbin/init/init base/usr/sbin/

# TODO: Make this more flexible
.PHONY: userland
userland: base/usr/sbin/init

base:
	mkdir -p base/usr/lib/
	mkdir -p base/usr/sbin/
	mkdir -p base/boot/
	cd base/usr/; ln -sf ../../lib/libc/include/ .

.PHONY: lib
lib:
	cd lib/; make $(USER_MKFLGS)
	cp lib/libc/build/libc.a base/usr/lib/

.PHONY: run
run:
	$(QEMU) $(QEMU_FLAGS)

.PHONY: cross
cross:
	bash tools/cross.sh $(ARCH)

.PHONY: clean
distclean:
	make clean
	rm -f $(KERNEL_ASMOBJECTS) $(KERNEL_OBJECTS) $(KERNEL_HEADER_DEPS)
	rm -f sys/include/machine
	rm -f base/usr/sbin/init
	cd lib/; make clean

.PHONY: clean
clean:
	rm -f $(KERNEL_ASMOBJECTS) $(KERNEL_OBJECTS) $(KERNEL_HEADER_DEPS)
	rm -f sys/include/machine

sys/include/machine/:
	cd sys/include/; ln -sf arch/$(ARCH) machine

base/boot/hyra-kernel: $(KERNEL_OBJECTS) $(KERNEL_ASMOBJECTS)
	rm -rf iso_root
	$(PROMPT) " LD " $(shell pwd)/base/boot/hyra-kernel
	$(LD) $(KERNEL_LDFLAGS) $(KERNEL_OBJECTS) $(KERNEL_ASMOBJECTS) -o base/boot/hyra-kernel
	tools/ksyms sys/kern/ksyms.c base/boot/hyra-kernel
	# === Generating symbols ===
	$(CC) -c $(KERNEL_CFLAGS) $(KERNEL_DEFINES) sys/kern/ksyms.c -o sys/kern/ksyms.o
	$(LD) $(KERNEL_LDFLAGS) $(KERNEL_OBJECTS) $(KERNEL_ASMOBJECTS) \
		sys/kern/ksyms.o -o base/boot/hyra-kernel
	cd base/; tar -cvf ../initramfs.tar * --format=ustar &> /dev/null
	$(PROMPT) " RAMFS " $(shell pwd)/initramfs.tar
	# === Building ISO ===
	mkdir -p iso_root/boot/
	mkdir -p iso_root/EFI/BOOT/
	cp stand/limine/BOOTX64.EFI iso_root/EFI/BOOT/
	cp conf/limine.cfg stand/limine/limine-bios.sys \
		stand/limine/limine-bios-cd.bin stand/limine/limine-uefi-cd.bin iso_root/
	cp base/boot/* iso_root/boot/
	mv initramfs.tar iso_root/boot/
	xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4\
		-boot-info-table --efi-boot limine-uefi-cd.bin -efi-boot-part \
		--efi-boot-image --protective-msdos-label iso_root -o Hyra.iso > /dev/null
	stand/limine/limine bios-install Hyra.iso
	$(PROMPT) " ISO " $(shell pwd)/Hyra.iso

-include $(KERNEL_HEADER_DEPS)
%.o: %.c sys/include/machine/
	$(PROMPT) " CC " $<
	$(CC) -c $(KERNEL_CFLAGS) $(KERNEL_DEFINES) $< -o $@

%.S.o: %.S
	$(PROMPT) " AS " $<
	$(CC) -c $< -o $@ -D__$(ARCH)__ -I sys/include/