# ---------- Variables --------- #

# Target directory
BUILD = build

# Paths to source, include, dependency, and object files
SRC = src
INC = src/include
DEP = $(BUILD)/dep
OBJ = $(BUILD)/obj
ALL = $(SRC) $(INC) $(BUILD) $(DEP) $(OBJ)

# Executable
TARGET := $(BUILD)/main.out

# compiler and compiler flags
CC = clang++
CFLAGS = -I$(INC) -std=gnu++26
SOFLAG = -fpic -shared -dynamic -ldl

# list of static object files
SOURCES = $(wildcard $(SRC)/*.cc)
HEADERS = $(wildcard $(INC)/*.hh)
OBJECTS = $(addprefix $(OBJ)/,$(notdir $(SOURCES:.cc=.o)))

# ----------- Targets ---------- #
# Some targets aren't real
.PHONY: all clean run dump bear
# Don't autodelete object files:
.PRECIOUS: $(OBJ)/%.o

all: $(BUILD) $(DEP) $(OBJ) $(TARGET)

dump:
	@echo "SOURCES: $(SOURCES)"
	@echo "HEADERS: $(HEADERS)"
	@echo "OBJECTS: $(OBJECTS)"
	@echo " TARGET: $(TARGET)"
	@echo "  PATHS: $(ALL)"

clean:
	-rm -r $(BUILD)

bear: clean
	bear -- make all

run: $(TARGET)
	-$(addprefix ./,$(addsuffix ;,$(TARGET)))

fmt:
	clang-format --verbose -i $(SOURCES) $(HEADERS)

# Create directories for output
$(BUILD) $(DEP) $(OBJ):
	mkdir -p $@

# Make the executable
$(BUILD)/%.out: $(OBJECTS)
	$(CC) $(CFLAGS) -o $@ $^
# Make the plugins
$(BUILD)/%.so: $(OBJ)/%.o $(DEP) $(OBJ)
	$(CC) $(CFLAGS) $(SOFLAG) -o $@ $^
# Make the object and dependency files
$(OBJ)/%.o: $(SRC)/%.cc $(DEP) $(OBJ)
	$(CC) $(CFLAGS) -MMD -MF $(DEP)/$(@F:.o=.d) -o $@ -c $<


# --------- Dependency inclusions --------- #
-include $(wildcard $(DEP)/*.d)
