ifndef PLATFORM
PLATFORM = linux
endif

ifeq ($(PLATFORM),linux)
LINUX = 1
else ifeq ($(PLATFORM),w32)
WINDOWS = 1
CXX = i686-w64-mingw32-g++
else ifeq ($(PLATFORM),w64)
WINDOWS = 1
CXX = x86_64-w64-mingw32-g++
else
$(error Unknown platform '$(PLATFORM)')
endif

ifdef LINUX
CXXFLAGS += -pthread
LDFLAGS += -pthread
LDLIBS_GRAPHICS += -lX11
endif

ifdef WINDOWS
CXXFLAGS += -D_WIN32_WINNT=0x0600
LDFLAGS += -static
LDLIBS_GRAPHICS += -lgdi32
LDLIBS_NET += -lws2_32
EXE = .exe
endif

# C++ standard
CXXFLAGS += -std=gnu++20

# Warnings
CXXFLAGS += -Wall -Wextra -Wno-unused-parameter
ifdef WINDOWS
CXXFLAGS += -Wno-format
endif

# Optimize
CXXFLAGS += -O3

# Debug
CXXFLAGS += -g3

# Profile
#CXXFLAGS += -pg
#LDFLAGS += -pg

# Address sanitizer
#CXXFLAGS += -fsanitize=address
#LDFLAGS += -fsanitize=address

# Undefined behavior sanitizer
#CXXFLAGS += -fsanitize=undefined
#LDFLAGS += -fsanitize=undefined

# Dependencies
CPPFLAGS += -MMD -MF $(patsubst %.o,%.d,$@) -MT $@ -MP

# Parallel make
MAKEFLAGS += $(MAKEFLAGS_PARALLEL)

# Architecture
ifdef LINUX
CXXFLAGS += -march=native -mtune=native
endif
ifdef WINDOWS
#CXXFLAGS += -march=alderlake -mtune=alderlake # Desktop
#CXXFLAGS += -march=skylake -mtune=skylake # Laptop
endif

%$(EXE): %.o
	$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

%.o: %.cpp
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<

LDLIBS =
LDLIBS += $(LDLIBS_$(PLATFORM))
LDLIBS += $(LDLIBS_$(patsubst %$(EXE),%,$@))
LDLIBS += $(LDLIBS_$(PLATFORM)_$(patsubst %$(EXE),%,$@))
LDLIBS_linux +=
LDLIBS_test +=
LDLIBS_linux_test +=
STDOBJS =
TARGETOBJS = LittlemanTarget.o
ALLPROGS = compile
ALLPROGS += $(ALLPROGS_$(PLATFORM))
ALLPROGS_linux +=

ALLPROGS_EXE = $(patsubst %,%$(EXE),$(ALLPROGS))

.PHONY: all
all: $(ALLPROGS_EXE)

compile$(EXE): compile.o FileUtils.o StringUtils.o TargetFactory.o $(TARGETOBJS) Compiler.o Parser.o TypeChecker.o TypeTable.o SymTable.o IrGenerator.o IrUtils.o Optimizer.o RegisterAllocator.o StackAllocator.o AccumAllocator.o DumpIr.o

.PHONY: clean
clean:
	rm -f *.o *.d $(ALLPROGS_EXE)

ifneq ($(MAKECMDGOALS),clean)
include $(patsubst %.o,%.d,$(wildcard *.o))
endif
