# Makefile adapted from Minisat: https://github.com/niklasso/minisat/blob/master/Makefile

###################################################################################################

.PHONY:	r d p sh lr ld lp lsh all clean
all:	r lr lsh

CURRENT_DIR = $(shell pwd)

## Configurable options ###########################################################################

CXX ?= g++

# Name of IPASIR solver library
IPASIRSOLVER ?= cadical
# Location of IPASIR solver library
IPASIRLIBDIR ?= $(CURRENT_DIR)/lib/cadical-2.1.3/build
#IPASIRLIBDIR ?= $(CURRENT_DIR)/lib/cadical-1.9.5/build
#IPASIRLIBDIR ?= $(CURRENT_DIR)/lib/cadical-1.7.0/build

# Directory to store object files, libraries, executables, and dependencies:
BUILD_DIR      ?= build

# Include debug-symbols in release builds
MUTOKSIA_RELSYM ?= 

# Sets of compile flags for different build types
MUTOKSIA_REL    ?= -O3 -D NDEBUG
MUTOKSIA_DEB    ?= -O0 -D DEBUG 
MUTOKSIA_PRF    ?= -O3 -D NDEBUG
MUTOKSIA_FPIC   ?= -fpic

ifneq "$(CXX)" "clang++"
MUTOKSIA_REL    += -flto
endif

# Target file names
MUTOKSIA      = mu-toksia#         Name of the main executable.
MUTOKSIA_SLIB = lib$(MUTOKSIA).a#  Name of the static library.
MUTOKSIA_DLIB = lib$(MUTOKSIA).so# Name of the shared library.

# Shared Library Version
SOMAJOR=2025
SOMINOR=06
SORELEASE?=.06#   Declare empty to leave out from library file name.

MUTOKSIA_CXXFLAGS = -I include -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS -Wall -Wno-parentheses -Wextra -Wno-unused-parameter -std=c++20
#MUTOKSIA_CXXFLAGS += -D GR_IN_ST
MUTOKSIA_CXXFLAGS += -D AD_IN_ST
#MUTOKSIA_CXXFLAGS += -D CO_IN_ST
MUTOKSIA_CXXFLAGS += -D CO_IN_PR
MUTOKSIA_CXXFLAGS += -D CO_IN_SST
MUTOKSIA_CXXFLAGS += -D CO_IN_ID
MUTOKSIA_CXXFLAGS += -D ST_EXISTS_STG
#MUTOKSIA_CXXFLAGS += -D ST_EXISTS_SST
MUTOKSIA_CXXFLAGS += -D DYNAMIC_MODE
MUTOKSIA_LDFLAGS  = -Wall -lz -flto -L$(IPASIRLIBDIR) -l$(IPASIRSOLVER)

ifeq (Darwin,$(findstring Darwin,$(shell uname)))
	SHARED_LDFLAGS += -shared -Wl,-dylib_install_name,$(MUTOKSIA_DLIB).$(SOMAJOR)
	RELEASE_LDFLAGS +=
else
	SHARED_LDFLAGS += -shared -Wl,-soname,$(MUTOKSIA_DLIB).$(SOMAJOR)
	RELEASE_LDFLAGS += 
endif

ECHO=@echo
ifeq ($(VERB),)
VERB=@
else
VERB=
endif

HDRS = $(wildcard src/*.h)
SRCS = $(wildcard src/*.cpp)
OBJS = $(filter-out %Main.o, $(SRCS:.cpp=.o))

r:	$(BUILD_DIR)/release/bin/$(MUTOKSIA)
d:	$(BUILD_DIR)/debug/bin/$(MUTOKSIA)
p:	$(BUILD_DIR)/profile/bin/$(MUTOKSIA)
sh:	$(BUILD_DIR)/dynamic/bin/$(MUTOKSIA)

lr:	$(BUILD_DIR)/release/lib/$(MUTOKSIA_SLIB)
ld:	$(BUILD_DIR)/debug/lib/$(MUTOKSIA_SLIB)
lp:	$(BUILD_DIR)/profile/lib/$(MUTOKSIA_SLIB)
lsh:	$(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB).$(SOMAJOR).$(SOMINOR)$(SORELEASE)

## Build-type Compile-flags:
$(BUILD_DIR)/release/%.o:			MUTOKSIA_CXXFLAGS += $(MUTOKSIA_REL) $(MUTOKSIA_RELSYM)
$(BUILD_DIR)/debug/%.o:				MUTOKSIA_CXXFLAGS += $(MUTOKSIA_DEB) -g
$(BUILD_DIR)/profile/%.o:			MUTOKSIA_CXXFLAGS += $(MUTOKSIA_PRF) -pg
$(BUILD_DIR)/dynamic/%.o:			MUTOKSIA_CXXFLAGS += $(MUTOKSIA_REL) $(MUTOKSIA_FPIC)

## Build-type Link-flags:
$(BUILD_DIR)/profile/bin/$(MUTOKSIA):		MUTOKSIA_LDFLAGS += -pg
$(BUILD_DIR)/release/bin/$(MUTOKSIA):		MUTOKSIA_LDFLAGS += $(RELEASE_LDFLAGS) $(MUTOKSIA_RELSYM)

## Executable dependencies
$(BUILD_DIR)/release/bin/$(MUTOKSIA):	 	$(BUILD_DIR)/release/src/Main.o $(BUILD_DIR)/release/lib/$(MUTOKSIA_SLIB)
$(BUILD_DIR)/debug/bin/$(MUTOKSIA):	 	$(BUILD_DIR)/debug/src/Main.o $(BUILD_DIR)/debug/lib/$(MUTOKSIA_SLIB)
$(BUILD_DIR)/profile/bin/$(MUTOKSIA):	 	$(BUILD_DIR)/profile/src/Main.o $(BUILD_DIR)/profile/lib/$(MUTOKSIA_SLIB)
# need the main-file be compiled with fpic?
$(BUILD_DIR)/dynamic/bin/$(MUTOKSIA):	 	$(BUILD_DIR)/dynamic/src/Main.o $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB)

## Library dependencies
$(BUILD_DIR)/release/lib/$(MUTOKSIA_SLIB):	$(foreach o,$(OBJS),$(BUILD_DIR)/release/$(o))
$(BUILD_DIR)/debug/lib/$(MUTOKSIA_SLIB):		$(foreach o,$(OBJS),$(BUILD_DIR)/debug/$(o))
$(BUILD_DIR)/profile/lib/$(MUTOKSIA_SLIB):	$(foreach o,$(OBJS),$(BUILD_DIR)/profile/$(o))
$(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB).$(SOMAJOR).$(SOMINOR)$(SORELEASE)\
 $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB).$(SOMAJOR)\
 $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB):	$(foreach o,$(OBJS),$(BUILD_DIR)/dynamic/$(o))

## Compile rules
$(BUILD_DIR)/release/%.o:	%.cpp
	$(ECHO) Compiling: $@
	$(VERB) mkdir -p $(dir $@)
	$(VERB) $(CXX) $(MUTOKSIA_CXXFLAGS) $(CXXFLAGS) -c -o $@ $< -MMD -MF $(BUILD_DIR)/release/$*.d

$(BUILD_DIR)/profile/%.o:	%.cpp
	$(ECHO) Compiling: $@
	$(VERB) mkdir -p $(dir $@)
	$(VERB) $(CXX) $(MUTOKSIA_CXXFLAGS) $(CXXFLAGS) -c -o $@ $< -MMD -MF $(BUILD_DIR)/profile/$*.d

$(BUILD_DIR)/debug/%.o:	%.cpp
	$(ECHO) Compiling: $@
	$(VERB) mkdir -p $(dir $@)
	$(VERB) $(CXX) $(MUTOKSIA_CXXFLAGS) $(CXXFLAGS) -c -o $@ $< -MMD -MF $(BUILD_DIR)/debug/$*.d

$(BUILD_DIR)/dynamic/%.o:	%.cpp
	$(ECHO) Compiling: $@
	$(VERB) mkdir -p $(dir $@)
	$(VERB) $(CXX) $(MUTOKSIA_CXXFLAGS) $(CXXFLAGS) -c -o $@ $< -MMD -MF $(BUILD_DIR)/dynamic/$*.d

## Linking rule
$(BUILD_DIR)/release/bin/$(MUTOKSIA) $(BUILD_DIR)/debug/bin/$(MUTOKSIA) $(BUILD_DIR)/profile/bin/$(MUTOKSIA) $(BUILD_DIR)/dynamic/bin/$(MUTOKSIA):
	$(ECHO) Linking Binary: $@
	$(VERB) mkdir -p $(dir $@)
	$(VERB) $(CXX) $^ $(LDFLAGS) $(MUTOKSIA_LDFLAGS) -o $@

## Static Library rule
%/lib/$(MUTOKSIA_SLIB):
	$(ECHO) Linking Static Library: $@
	$(VERB) mkdir -p $(dir $@)
	$(VERB) $(AR) -rcs $@ $^

## Shared Library rule
$(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB).$(SOMAJOR).$(SOMINOR)$(SORELEASE)\
 $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB).$(SOMAJOR)\
 $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB):
	$(ECHO) Linking Shared Library: $@
	$(VERB) mkdir -p $(dir $@)
	$(VERB) $(CXX) $^ $(SHARED_LDFLAGS) $(MUTOKSIA_LDFLAGS) $(LDFLAGS) -o $@
	$(VERB) ln -sf $(MUTOKSIA_DLIB).$(SOMAJOR).$(SOMINOR)$(SORELEASE) $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB).$(SOMAJOR)
	$(VERB) ln -sf $(MUTOKSIA_DLIB).$(SOMAJOR) $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB)

clean:
	rm -f $(foreach t, release debug profile dynamic, $(foreach o, $(SRCS:.cpp=.o), $(BUILD_DIR)/$t/$o)) \
          $(foreach t, release debug profile dynamic, $(foreach d, $(SRCS:.cpp=.d), $(BUILD_DIR)/$t/$d)) \
	  $(foreach t, release debug profile dynamic, $(BUILD_DIR)/$t/bin/$(MUTOKSIA)) \
	  $(foreach t, release debug profile, $(BUILD_DIR)/$t/lib/$(MUTOKSIA_SLIB)) \
	  $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB).$(SOMAJOR).$(SOMINOR)$(SORELEASE)\
	  $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB).$(SOMAJOR)\
	  $(BUILD_DIR)/dynamic/lib/$(MUTOKSIA_DLIB)

## Include generated dependencies
-include $(foreach s, $(SRCS:.cc=.d), $(BUILD_DIR)/release/$s)
-include $(foreach s, $(SRCS:.cc=.d), $(BUILD_DIR)/debug/$s)
-include $(foreach s, $(SRCS:.cc=.d), $(BUILD_DIR)/profile/$s)
-include $(foreach s, $(SRCS:.cc=.d), $(BUILD_DIR)/dynamic/$s)
