CC := clang
CPPFLAGS := \
    -D_POSIX_C_SOURCE=202405L \
    -D_DEFAULT_SOURCE \
    -MMD -MP
CFLAGS := \
    -std=c2y \
    -fdefer-ts \
    -fstack-protector-strong \
    -pedantic-errors \
    -Wall \
    -Wextra \
    -Werror \
    -Wconversion \
    -Wformat-security \
    -Wformat=2 \
    -Wmissing-prototypes \
    -Wnull-dereference \
    -Wpadded \
    -Wshadow \
    -Wstack-protector \
    -Wstrict-prototypes \
    -Wunreachable-code \
    -Wunused-macros
LDFLAGS :=
LDLIBS :=

PKG_CONFIG := pkg-config
DEPS := \
    libsodium \
    liburing
CFLAGS += $(shell $(PKG_CONFIG) --cflags $(DEPS))
LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L $(DEPS))
LDLIBS += $(shell $(PKG_CONFIG) --libs-only-l --libs-only-other $(DEPS))

DEBUG ?= 0
ifeq ($(DEBUG),1)
    CFLAGS += \
        -O0 \
        -g3 \
        -fno-omit-frame-pointer \
        -fsanitize=address,undefined \
        -Wno-error=unreachable-code \
        -Wno-error=unused \
        -Wno-error=unused-macros \
        -Wno-error=unused-parameter
    LDFLAGS += -fsanitize=address,undefined
    BUILD_DIR := build/debug
else ifeq ($(DEBUG),0)
    CPPFLAGS += -DNDEBUG
    CFLAGS += -O2 -flto -march=native
    LDFLAGS += -flto
    BUILD_DIR := build/release
else
    $(error Invalid DEBUG $(DEBUG))
endif

SRCS := $(shell find src -type f -name '*.c')
OBJS := $(SRCS:src/%.c=$(BUILD_DIR)/%.o)
EXE := colloid

.PHONY: all clean

all: $(BUILD_DIR)/$(EXE)

$(BUILD_DIR)/%.o: src/%.c
	@mkdir -p $(@D)
	$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

$(BUILD_DIR)/$(EXE): $(OBJS)
	@mkdir -p $(@D)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)

clean:
	rm -fr build

-include $(OBJS:.o=.d)

$(OBJS:.o=.d): ;
