# ---------------------------------------------------------------------------
# Options
# ---------------------------------------------------------------------------

DEBUG  ?= 0
NALYZE ?= 0
ASAN   ?= 0
STATIC ?= 0
FLTO   ?= 0
FPGO   ?= 0
STRIP  ?= 0
CPU    ?= 0
MARCH  ?= 0
MTUNE  ?= 0
THREAD ?= 1

# ---------------------------------------------------------------------------
# Directories
# ---------------------------------------------------------------------------

SUBDIR_APP := frontend
SUBDIR_LIB := libslunkcrypt

# ---------------------------------------------------------------------------
# Flags
# ---------------------------------------------------------------------------

CONFIG =
LDFLGS = -lpthread
CFLAGS = -I$(SUBDIR_LIB)/include -std=gnu99 -Wall

ifneq ($(CPU),0)
  CFLAGS += -m$(firstword $(CPU))
endif
ifneq ($(TARGET),)
  CFLAGS += --target=$(firstword $(TARGET))
  LDFLGS += --target=$(firstword $(TARGET))
endif

ifneq ($(MARCH),0)
  CFLAGS += -march=$(firstword $(MARCH))
endif
ifneq ($(MTUNE),0)
  CFLAGS += -mtune=$(firstword $(MTUNE))
endif

ifneq ($(ASAN),0)
  CONFIG := _a
  CFLAGS += -O1 -g -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls
else ifneq ($(DEBUG),0)
  CONFIG := _g
  CFLAGS += -Og -g
else
  CFLAGS += -O3 -DNDEBUG
ifneq ($(FLTO),0)
  CFLAGS += -flto
endif
ifneq ($(FPGO),0)
  CFLAGS += -fprofile-$(firstword $(FPGO))
endif
endif
ifneq ($(NALYZE),0)
  CFLAGS += -fanalyzer
endif

MACHINE := $(shell $(CC) -dumpmachine || echo unknown)

ifeq ($(MACHINE),$(filter %mingw32 %-windows-gnu %-cygwin %-cygnus,$(MACHINE)))
  SUFFIX := .exe
else
  SUFFIX :=
endif

ifeq ($(THREAD),0)
  CFLAGS += -DSLUNKBUILD_NOTHREADS
endif

ifneq ($(STRIP),0)
  LDFLGS += -s
endif

ifeq ($(STATIC),1)
  LDFLGS += -static
endif

ifeq ($(MACHINE),$(filter %-w64-mingw32 %w64-windows-gnu,$(MACHINE)))
  LDFLGS += -mconsole -municode
endif

# ---------------------------------------------------------------------------
# File names
# ---------------------------------------------------------------------------

OUTNAME_APP := slunkcrypt$(CONFIG)$(SUFFIX)
OUTNAME_LIB := libslunkcrypt$(CONFIG)-1.a

OUTPATH_APP := $(SUBDIR_APP)/bin/$(OUTNAME_APP)
OUTPATH_LIB := $(SUBDIR_LIB)/lib/$(OUTNAME_LIB)

SOURCES_APP := $(wildcard $(SUBDIR_APP)/src/*.c)
OBJECTS_APP := $(patsubst $(SUBDIR_APP)/src/%.c,$(SUBDIR_APP)/obj/%$(CONFIG).o,$(SOURCES_APP))

SOURCES_LIB := $(wildcard $(SUBDIR_LIB)/src/*.c)
OBJECTS_LIB := $(patsubst $(SUBDIR_LIB)/src/%.c,$(SUBDIR_LIB)/obj/%$(CONFIG).o,$(SOURCES_LIB))

ifneq ($(filter %-mingw32 %-windows-gnu %-cygwin %-cygnus,$(MACHINE)),)
  RCFILES_APP := $(wildcard $(SUBDIR_APP)/res/*.rc)
  OBJECTS_APP += $(patsubst $(SUBDIR_APP)/res/%.rc,$(SUBDIR_APP)/obj/%.rsrc.o,$(RCFILES_APP))
endif

# ---------------------------------------------------------------------------
# Targets
# ---------------------------------------------------------------------------

.PHONY: all clean

all: $(OUTPATH_APP)

$(OUTPATH_APP): $(OBJECTS_APP) $(OUTPATH_LIB)
	@mkdir -p $(@D)
	$(CC) $(CFLAGS) $^ -o $@ $(LDFLGS)

$(OUTPATH_LIB): $(OBJECTS_LIB)
	@mkdir -p $(@D)
	$(AR) rcs $@ $^

$(SUBDIR_APP)/obj/%$(CONFIG).o: $(SUBDIR_APP)/src/%.c
	@mkdir -p $(@D)
	$(CC) $(CFLAGS) -c $< -o $@

$(SUBDIR_APP)/obj/%.rsrc.o: $(SUBDIR_APP)/res/%.rc
	@mkdir -p $(@D)
	windres -o $@ $<

$(SUBDIR_LIB)/obj/%$(CONFIG).o: $(SUBDIR_LIB)/src/%.c
	@mkdir -p $(@D)
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	$(RM) $(SUBDIR_APP)/obj/*.o $(SUBDIR_APP)/obj/*.gcda $(SUBDIR_APP)/lib/*.a $(SUBDIR_APP)/bin/*$(SUFFIX)
	$(RM) $(SUBDIR_LIB)/obj/*.o $(SUBDIR_LIB)/obj/*.gcda $(SUBDIR_LIB)/lib/*.a $(SUBDIR_LIB)/bin/*$(SUFFIX)

