MOON_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
MOON_SRC := $(MOON_DIR)/src
MOON_OBJ := $(MOON_DIR)/lib
MOON_BIN := $(MOON_DIR)/bin

CFLAGS := -Wall -Wextra -Werror -Os -ffreestanding -fstack-protector-all -fno-omit-frame-pointer -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -fshort-wchar -mcmodel=kernel -I$(MOON_DIR)/include -isystem $(MOON_DIR)/include/std
CXXFLAGS := -fno-rtti -fno-exceptions
ASMFLAGS := -felf64
LDFLAGS := -T$(MOON_DIR)/moon.ld -nostdlib -lgcc -Wl,--build-id=none -z max-page-size=0x1000

ifneq ($(MOON_BUILD_STABLE), 1)
CFLAGS := ${CFLAGS} -D_MOON_SUFFIX=-$(shell git rev-parse --short HEAD)
endif

ifeq ($(MOON_BUILD_DEBUG), 1)
CFLAGS := -ggdb ${CFLAGS}
endif

rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))

CXX_SRC = $(call rwildcard,$(MOON_SRC),*.cpp)
C_SRC = $(call rwildcard,$(MOON_SRC),*.c)
NASM_SRC = $(call rwildcard,$(MOON_SRC),*.asm)

OBJS = $(patsubst $(MOON_SRC)/%.cpp, $(MOON_OBJ)/%.cpp.o, $(CXX_SRC))
OBJS += $(patsubst $(MOON_SRC)/%.c, $(MOON_OBJ)/%.c.o, $(C_SRC))
OBJS += $(patsubst $(MOON_SRC)/%.asm, $(MOON_OBJ)/%.asm.o, $(NASM_SRC))

default: $(MOON_BIN)/moon.elf

$(MOON_OBJ)/interrupts/handlers.cpp.o: $(MOON_SRC)/interrupts/handlers.cpp
	@mkdir -p $(@D)
	$(CXX) $(CFLAGS) -mgeneral-regs-only $(CXXFLAGS) -o $@ -c $^

$(MOON_OBJ)/main.cpp.o: $(MOON_SRC)/main.cpp
	@mkdir -p $(@D)
	$(CXX) $(CFLAGS) -fno-stack-protector $(CXXFLAGS) -o $@ -c $^

$(MOON_OBJ)/init/Init.cpp.o: $(MOON_SRC)/init/Init.cpp
	@mkdir -p $(@D)
	$(CXX) $(CFLAGS) -fno-stack-protector $(CXXFLAGS) -o $@ -c $^

$(MOON_OBJ)/%.cpp.o: $(MOON_SRC)/%.cpp
	@mkdir -p $(@D)
	$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $^

$(MOON_OBJ)/%.c.o: $(MOON_SRC)/%.c
	@mkdir -p $(@D)
	$(CC) $(CFLAGS) -o $@ -c $^

$(MOON_OBJ)/%.asm.o: $(MOON_SRC)/%.asm
	@mkdir -p $(@D)
	$(ASM) $(ASMFLAGS) -o $@ $^

build: $(OBJS)
	@mkdir -p $(@D)
	$(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o $(MOON_BIN)/moon.elf

clean:
	rm -rf $(MOON_OBJ)/*
	rm -rf $(MOON_BIN)/*

install: $(MOON_BIN)/moon.elf
	@mkdir -p $(@D)
	cp $^ $(LUNA_ROOT)/initrd/boot/moon.elf
	$(LUNA_ROOT)/tools/generate-symbols.sh