# Makefile for a C++ project with optimizations

# Compiler
CXX = g++
# Compiler flags
CXXFLAGS = -std=c++20 -Wall

# Optimization flags
OPT_FLAGS = -O3 -march=native

# add Debug flags
# CXXFLAGS += -DDEBUG

PROFILE = performance

# Source file
ifneq (,$(findstring memory-,$(PROFILE)))
SRCS = memory.cpp quicksort.cpp mergesort.cpp
CXXFLAGS += -DFILL_$(subst memory-,,$(PROFILE))
else
SRCS = performance.cpp quicksort.cpp mergesort.cpp
endif

# Object files directory
BUILD_DIR = build
# Object files
OBJS = $(patsubst %.cpp,$(BUILD_DIR)/%.o,$(SRCS))
# Executable names
QUICK_SORT_TARGET = quicksort
MERGE_SORT_TARGET = mergesort

# Rule to build the quicksort executable
$(QUICK_SORT_TARGET): CXXFLAGS += -DQUICK_SORT
$(QUICK_SORT_TARGET): $(OBJS)
	$(CXX) $(CXXFLAGS) $(OPT_FLAGS) -o $@_$(PROFILE) $^
	$(MAKE) clean-folder

# Rule to build the mergesort executable
$(MERGE_SORT_TARGET): CXXFLAGS += -DMERGE_SORT
$(MERGE_SORT_TARGET): $(OBJS)
	$(CXX) $(CXXFLAGS) $(OPT_FLAGS) -o $@_$(PROFILE) $^
	$(MAKE) clean-folder

# Rule to build object files
$(BUILD_DIR)/%.o: %.cpp
	@mkdir -p $(BUILD_DIR)
	$(CXX) $(CXXFLAGS) -c -o $@ $<

# Clean rule
clean-folder:
	rm -rf $(BUILD_DIR)

# Clean rule
clean:
	rm -rf $(BUILD_DIR) $(QUICK_SORT_TARGET) $(MERGE_SORT_TARGET)