CSRCS   := $(wildcard src/*.c)
CPPSRCS := $(wildcard src/*.cpp)
ASRCS   := $(wildcard src/*.S)

# Objektdateien in getrennte Build-Unterordner umleiten!
COBJS   := $(CSRCS:src/%.c=build/c/%.o)
CPPOBJS := $(CPPSRCS:src/%.cpp=build/cpp/%.o)
AOBJS   := $(ASRCS:src/%.S=build/asm/%.o)

AllOBJS := $(COBJS) $(CPPOBJS) $(AOBJS)
LOADADDR = 0x80000

# Befehl zum Erstellen von Ordnern (je nach Betriebssystem)
ifeq ($(MSYSTEM),)
    MKDIR = if not exist $(subst /,\,$1) mkdir $(subst /,\,$1)
else
    MKDIR = mkdir -p $1
endif

GCCFLAGS = -DAARCH=64 -mcpu=cortex-a72 -mlittle-endian -Wall -O0 -ffreestanding \
           -nostartfiles -nostdlib -nostdinc -g -I ./include

AFLAGS   = -DAARCH=64 -mcpu=cortex-a72 -mlittle-endian -I ./include -O0 -g

CFLAGS   = -DAARCH=64 -mcpu=cortex-a72 -mlittle-endian -Wall -fsigned-char -ffreestanding -g \
           -I ./include -O0 -fno-exceptions 

CPPFLAGS = -fno-exceptions -fno-rtti -nostdinc++ -DAARCH=64 -mcpu=cortex-a72 -mlittle-endian -Wall -fsigned-char \
           -ffreestanding -g -I ./include -O0 -mstrict-align -std=c++14 -Wno-aligned-new

all: new clean kernel8.img

# --- Kompilier-Regeln mit automatischer Ordner-Erstellung ---

build/asm/%.o: src/%.S
	@$(call MKDIR,build/asm)
	@echo "as $@"
	@aarch64-none-elf-gcc $(AFLAGS) -c $< -o $@

build/c/%.o: src/%.c
	@$(call MKDIR,build/c)
	@echo "gcc $@"
	@aarch64-none-elf-gcc $(CFLAGS) -c $< -o $@

build/cpp/%.o: src/%.cpp
	@$(call MKDIR,build/cpp)
	@echo "g++ $@"
	@aarch64-none-elf-g++ $(CPPFLAGS) -c $< -o $@

kernel8.img: $(AllOBJS)
	@echo "============================================================================="
	@echo "Linking..."
	@aarch64-none-elf-ld -o kernel8.elf -Map kernel8.map -nostdlib \
		--section-start=.init=$(LOADADDR) --no-warn-rwx-segments \
		-g -T linker.ld $(AllOBJS)
	aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img

clean:
ifeq ($(MSYSTEM),)
# --- Native Windows Umgebung (CMD / PowerShell) ---
	@if exist kernel8.elf del /q /f kernel8.elf
	@if exist kernel8.img del /q /f kernel8.img
	@if exist kernel8.map del /q /f kernel8.map
	@if exist build rmdir /s /q build
else
# --- MSYS2 / Unix-ähnliche Umgebung ---
	/bin/rm -rf kernel8.elf kernel8.map build *.img > /dev/null 2>&1 || true
endif

new:
ifeq ($(MSYSTEM),)
	@cls
else
	/bin/clear
endif