# Directories
INCLUDE_DIRS = include thirdparty/inja/include thirdparty/nlohmann/include
SRC_DIR = src
BUILD_DIR = build

# Compiler and linker settings
CXX = g++
LIBS = 
CXXFLAGS = -std=c++17 $(foreach dir,$(INCLUDE_DIRS),-I$(dir))

# Source and object files
SRC = $(wildcard $(SRC_DIR)/*.cpp)

# Target executable
UNAME := $(shell uname -s)
BUILD_DIR := $(BUILD_DIR)/$(UNAME)
OBJ_DIR := $(BUILD_DIR)/objs
BIN = $(BUILD_DIR)/main

# Object files corresponding to the source files (now in obj directory)
OBJS = $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(basename $(notdir $(SRC)))))

# development target with debugging
dev: CXXFLAGS += -g -Wall -Wformat
dev: all

# Release target
release: CXXFLAGS += -O3
release: all

# Create directories for build output
dirs:
	@mkdir -p $(BUILD_DIR)
	@mkdir -p $(OBJ_DIR)

# Clear build directory
clear:
	@find $(OBJ_DIR) -type f -name '*.o' -exec rm -f {} +

# Pattern rule for source files in src directory
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
	$(CXX) $(CXXFLAGS) -c -o $@ $<

all: dirs clear $(BIN)
	@echo Build complete

$(BIN): $(OBJS)
	$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)

clean:
	rm -rf $(BUILD_DIR)