############################
EXEC    = olivechess
VERSION = 0.3.3
############################

CXX      = g++
CXXFLAGS = -W -Wall -ansi -O3 -I$(INC_DIR) -std=c++14 -pedantic
LDFLAGS  = -lpthread # -static -static-libgcc -static-libstdc++

# Note: static build can be a problem on OSX

#################
#    FOLDERS    #
#################

INC_DIR     := include
SRC_DIR     := src
OBJ_DIR     := obj
BIN_DEB_DIR := bin/debug
BIN_REL_DIR := bin/release
CFG_DIR     := cfg
IMG_DIR     := img

####################
#   OS SPECIFICS   #
####################

ifeq ($(OS),Windows_NT)
	EXT+=.exe
	UNAME_S = Windows
	UNAME_P := $(PROCESSOR_ARCHITECTURE)
  
	ifeq ($(UNAME_P),x86)
		ifndef PROCESSOR_ARCHITEW6432
			CXXFLAGS += -D IA32
			CXXFLAGS += -D WIN32
			ARCH = x32
		else
			CXXFLAGS += -DIS_64BIT
			ARCH = x64
		endif
	endif
	ifeq ($(UNAME_P),AMD64)
		CXXFLAGS += -DIS_64BIT
		ARCH = x64
	endif
else
	UNAME_S := $(shell uname -s)
	UNAME_P := $(shell uname -p)
	ARCH := $(shell uname -m)
	ifeq ($(UNAME_S),Linux)
		CXXFLAGS += -D LINUX
	endif
	ifeq ($(UNAME_S),Darwin)
	# hack for osx - 64b machines can have
	# a 32b boot kernel (uname -p gives i386)
	UNAME_P := $(shell uname -m)
		CXXFLAGS += -D OSX
	endif
	ifneq ($(filter %86,$(UNAME_P)),)
		CXXFLAGS += -D IA32
		ARCH = x32
	endif
	ifeq ($(UNAME_P),x86_64)
		CXXFLAGS += -DIS_64BIT
		ARCH = x64
	endif
	ifneq ($(filter arm%,$(UNAME_P)),)
		CXXFLAGS += -D ARM
		ARCH = arm
	endif
endif
 
ifdef ARCH
	PACKNAME := $(EXEC)_$(VERSION)_$(UNAME_S)_$(ARCH)
else
	PACKNAME := $(EXEC)_$(VERSION)
endif
 
ifdef EXT
	BINARY = $(PACKNAME)$(EXT)
else
	BINARY = $(PACKNAME)
endif

##################
#   BUILD TYPE   #
##################

debug: CXXFLAGS += -DDEBUG -g
debug: LDFLAGS += -DDEBUG -g
debug: $(BIN_DEB_DIR)/$(BINARY)

release: CXXFLAGS += -DNDEBUG -g0
release: LDFLAGS += -DNDEBUG -g0
release: $(BIN_REL_DIR)/$(BINARY)

all: mrproper debug mrproper release


##################
#   BUILD RULES  #
##################

#-------------- !!! WARNING !!! ---------------#
#  *.o debug and release files might be mixed  #
#----------------------------------------------#

$(BIN_DEB_DIR)/$(BINARY): $(OBJ_DIR)/main.o $(OBJ_DIR)/engine.o $(OBJ_DIR)/bitboard.o $(OBJ_DIR)/eval.o $(OBJ_DIR)/movegen.o $(OBJ_DIR)/notation.o $(OBJ_DIR)/position.o $(OBJ_DIR)/search.o $(OBJ_DIR)/thread.o $(OBJ_DIR)/uci.o $(OBJ_DIR)/watch.o $(OBJ_DIR)/testools.o $(OBJ_DIR)/transpose.o
	$(CXX) -o $@ $(OBJ_DIR)/*.o $(LDFLAGS)

$(BIN_REL_DIR)/$(BINARY): $(OBJ_DIR)/main.o $(OBJ_DIR)/engine.o $(OBJ_DIR)/bitboard.o $(OBJ_DIR)/eval.o $(OBJ_DIR)/movegen.o $(OBJ_DIR)/notation.o $(OBJ_DIR)/position.o $(OBJ_DIR)/search.o $(OBJ_DIR)/thread.o $(OBJ_DIR)/uci.o $(OBJ_DIR)/watch.o $(OBJ_DIR)/testools.o $(OBJ_DIR)/transpose.o
	$(CXX) -o $@ $(OBJ_DIR)/*.o $(LDFLAGS)

$(INC_DIR)/version.h: Makefile
	$(file >$(INC_DIR)/version.h,#include <string>)
	$(file >>$(INC_DIR)/version.h,static const std::string Version = "$(VERSION)";)

$(OBJ_DIR)/main.o: $(SRC_DIR)/main.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)

$(OBJ_DIR)/engine.o: $(SRC_DIR)/engine.cpp $(INC_DIR)/version.h
	$(CXX) -o $@ -c $(SRC_DIR)/engine.cpp $(CXXFLAGS)
 
$(OBJ_DIR)/search.o: $(SRC_DIR)/search.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/movegen.o: $(SRC_DIR)/movegen.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/eval.o: $(SRC_DIR)/eval.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/transpose.o: $(SRC_DIR)/transpose.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/position.o: $(SRC_DIR)/position.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/notation.o: $(SRC_DIR)/notation.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/uci.o: $(SRC_DIR)/uci.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/bitboard.o: $(SRC_DIR)/bitboard.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/thread.o: $(SRC_DIR)/thread.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/watch.o: $(SRC_DIR)/watch.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)
 
$(OBJ_DIR)/testools.o: $(SRC_DIR)/testools.cpp
	$(CXX) -o $@ -c $< $(CXXFLAGS)


###################
#  SPECIAL RULES  #
###################

package: mrproper release
	zip $(BIN_REL_DIR)/$(PACKNAME).zip -j -9 $(BIN_REL_DIR)/$(BINARY) $(IMG_DIR)/logo.bmp $(CFG_DIR)/polyglot.ini
 
clean:
	rm -f $(BIN_DEB_DIR)/* $(BIN_REL_DIR)/* $(OBJ_DIR)/*.o
 
mrproper:
	rm -f $(OBJ_DIR)/*.o $(BIN_REL_DIR)/*.zip
