CC        ?= clang
CFLAGS    ?= -std=c23 -Wall -Wextra -Wpedantic -Wmissing-prototypes -Wstrict-prototypes -Os
CFLAGS    += -ffunction-sections -fdata-sections -fno-unwind-tables -fno-asynchronous-unwind-tables
CFLAGS    += -D_POSIX_C_SOURCE=199309L
LDFLAGS   ?= -flto=thin -Wl,--gc-sections -Wl,--strip-all

PREFIX    ?= /usr/local
DESTDIR   ?=

SRCDIR    := src
INCDIR    := include
BUILDDIR  := build
VENDORDIR := vendor
PROTODIR  := protocols
TARGET    := keybar

PKGS      := wayland-client fcft pixman-1 dbus-1

CFLAGS    += `pkg-config --cflags $(PKGS)` -I$(INCDIR) -I$(VENDORDIR) -I$(BUILDDIR)
LDFLAGS   += `pkg-config --libs $(PKGS)` -lm

WAYLAND_SCANNER := wayland-scanner
PROTOCOLS       := $(wildcard $(PROTODIR)/*.xml)

PROTO_INC       := $(patsubst $(PROTODIR)/%.xml,$(BUILDDIR)/%.h,$(PROTOCOLS))
PROTO_SRC       := $(patsubst $(PROTODIR)/%.xml,$(BUILDDIR)/%.c,$(PROTOCOLS))
PROTO_OBJ       := $(patsubst $(PROTODIR)/%.xml,$(BUILDDIR)/%.o,$(PROTOCOLS))

SRCS := $(wildcard $(SRCDIR)/*.c) \
		$(wildcard $(SRCDIR)/modules/*.c) \
		$(wildcard $(SRCDIR)/platform/*.c) \
		$(wildcard $(SRCDIR)/compositor/*.c) \
		$(wildcard $(SRCDIR)/graphics/*.c) \
		$(wildcard $(SRCDIR)/integration/*.c) \
		$(wildcard $(VENDORDIR)/*.c) \
		$(wildcard $(SRCDIR)/*.S)

SRCS := $(filter-out $(SRCDIR)/xdg-shell.c,$(SRCS))
SRCS := $(filter-out $(SRCDIR)/wlr-layer-shell-unstable-v1.c,$(SRCS))

OBJS := $(patsubst $(SRCDIR)/%.c,$(BUILDDIR)/%.o,$(filter-out $(VENDORDIR)/%,$(filter %.c,$(SRCS)))) \
		$(patsubst $(VENDORDIR)/%.c,$(BUILDDIR)/%.o,$(filter $(VENDORDIR)/%,$(SRCS))) \
		$(patsubst $(SRCDIR)/%.S,$(BUILDDIR)/%.o,$(filter %.S,$(SRCS)))

DEPS := $(OBJS:.o=.d) $(PROTO_OBJ:.o=.d)

.PHONY: all clean install uninstall

all: $(TARGET)

$(TARGET): $(OBJS) $(PROTO_OBJ) $(PROTO_INC)
	$(CC) $(CFLAGS) -o $@ $(OBJS) $(PROTO_OBJ) $(LDFLAGS)

$(BUILDDIR)/%.h: $(PROTODIR)/%.xml
	@mkdir -p build
	$(WAYLAND_SCANNER) client-header < $< > $@

$(BUILDDIR)/%.c: $(PROTODIR)/%.xml
	@mkdir -p build
	$(WAYLAND_SCANNER) private-code < $< > $@

$(BUILDDIR)/%.o: $(SRCDIR)/%.c $(PROTO_INC)
	@mkdir -p build build/modules
	$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<

$(BUILDDIR)/%.o: $(VENDORDIR)/%.c $(PROTO_INC)
	@mkdir -p build
	$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<

$(BUILDDIR)/%.o: $(BUILDDIR)/%.c $(PROTO_INC)
	@mkdir -p build
	$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<

$(BUILDDIR)/%.o: $(BUILDDIR)/x86/%.S $(PROTO_INC)
	@mkdir -p build
	$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<

$(BUILDDIR)/platform/%.o: $(SRCDIR)/platform/%.c $(PROTO_INC)
	@mkdir -p $(dir $@)
	$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<

$(BUILDDIR)/compositor/%.o: $(SRCDIR)/compositor/%.c $(PROTO_INC)
	@mkdir -p $(dir $@)
	$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<

$(BUILDDIR)/graphics/%.o: $(SRCDIR)/graphics/%.c $(PROTO_INC)
	@mkdir -p $(dir $@)
	$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<

$(BUILDDIR)/integration/%.o: $(SRCDIR)/integration/%.c $(PROTO_INC)
	@mkdir -p $(dir $@)
	$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<

clean:
	rm -rf $(BUILDDIR) $(TARGET)

install: $(TARGET)
	install -d $(DESTDIR)$(PREFIX)/bin
	install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/

uninstall:
	rm -f $(DESTDIR)$(PREFIX)/bin/$(TARGET)

-include $(DEPS)
