# Build platform
# (use one of AUTO, Unix, OSX, OSX_Universal, MSVC, Cygwin, MinGW)

ifeq ($(BUILD_ENV),AUTO)
uname = $(shell uname)
ifeq ($(uname),windows32)
  BUILD_ENV_ := MSVC
else ifeq ($(uname),Darwin)
  BUILD_ENV_ := OSX
else ifeq ($(uname),FreeBSD)
  BUILD_ENV_ := FreeBSD
else ifeq ($(filter-out MINGW32_%, $(uname)),)
  BUILD_ENV_ := MinGW
else ifeq ($(filter-out CYGWIN_%, $(uname)),)
  BUILD_ENV_ := Cygwin
else
  BUILD_ENV_ := Unix
endif
else
  BUILD_ENV_ := $(BUILD_ENV)
endif

ifeq ($(filter-out Unix MinGW OSX OSX_Universal FreeBSD,$(BUILD_ENV_)),)
  # Linux-ish
  LIBEXT = .a
  OBJEXT = .o
  DEPEXT = .d
ifeq ($(BUILD_ENV_),MinGW)
  EXEEXT = .exe
else
  EXEEXT =
endif
  CFLAGS ?= -Wall -O2
  CP_CFLAGS = -MMD -MP
  CXXFLAGS ?= -Wall -O2
ifeq ($(filter-out OSX OSX_Universal,$(BUILD_ENV_)),)
  CP_CXXFLAGS += -MMD -MP -mmacosx-version-min=10.15 -std=c++11 -stdlib=libc++
  CP_CFLAGS += -mmacosx-version-min=10.15
  LINKFLAGS += -mmacosx-version-min=10.15 -stdlib=libc++
  LINKNATIVE += -mmacosx-version-min=10.15 -stdlib=libc++
else
  CP_CXXFLAGS += -MMD -MP -std=c++11
endif
ifeq ($(filter -O%,$(CXXFLAGS)),)
  CP_CXXFLAGS += -O2
endif
  #LINKFLAGS = -static
ifeq ($(filter-out OSX OSX_Universal,$(BUILD_ENV_)),)
  ifeq ($(BUILD_ENV_),OSX_Universal)
    # MacOS Fat Binaries
    CP_CXXFLAGS += -force_cpusubtype_ALL -arch arm64 -arch x86_64
    CP_CFLAGS += -force_cpusubtype_ALL -arch arm64 -arch x86_64
    LINKFLAGS += -force_cpusubtype_ALL -arch arm64 -arch x86_64
  endif
  LINKLIB = /usr/bin/libtool -static -o $@ $^
  LINKBIN = $(CXX) $(LINKFLAGS) -o $@ $^ $(LIBS)
  LINKNATIVE = $(HOSTCXX) $(HOSTLINKFLAGS) -o $@ $^
  ifeq ($(origin CC),default)
    CC     = clang
  endif
  ifeq ($(origin CXX),default)
    CXX    = clang++
  endif
  YFLAGS ?= -v
else ifeq ($(filter-out FreeBSD,$(BUILD_ENV_)),)
  CP_CXXFLAGS +=
  LINKLIB = ar rcT $@ $^
  LINKBIN = $(CXX) $(LINKFLAGS) -o $@ -Wl,--start-group $^ -Wl,--end-group $(LIBS)
  LINKNATIVE = $(HOSTCXX) $(HOSTLINKFLAGS) -o $@ $^
  ifeq ($(origin CC),default)
    CC     = clang
  endif
  ifeq ($(origin CXX),default)
    CXX    = clang++
  endif
  YFLAGS ?= -v -Werror
else
  LINKLIB = ar rcT $@ $^
  LINKBIN = $(CXX) $(LINKFLAGS) -o $@ -Wl,--start-group $^ -Wl,--end-group $(LIBS)
  LINKNATIVE = $(HOSTCXX) $(HOSTLINKFLAGS) -o $@ $^
  ifeq ($(origin CC),default)
    CC     = gcc
    #CC     = icc
  endif
  ifeq ($(origin CXX),default)
    CXX    = g++
    #CXX    = icpc
  endif
  YFLAGS ?= -v -Werror
endif
ifeq ($(origin YACC),default)
  YACC   = bison
endif
ifeq ($(origin LEX),default)
  LEX    = flex
endif


else ifeq ($(BUILD_ENV_),Cygwin)
  # use these for Cygwin:
  LIBEXT = .a
  OBJEXT = .o
  DEPEXT = .d
  EXEEXT = .exe
  CFLAGS ?= -Wall -O2
  CXXFLAGS ?= -Wall -O2
  CP_CFLAGS = -MMD -MP
  CP_CXXFLAGS += -MMD -MP -std=c++11 -U__STRICT_ANSI__
  # Cygwin-g++ has problems with statically linking exception code.
  # If linking fails, remove -static.
  LINKFLAGS = -static -std=c++11
  LINKLIB = ar rcT $@ $^
  LINKBIN = $(CXX) $(LINKFLAGS) -o $@ -Wl,--start-group $^ -Wl,--end-group $(LIBS)
  LINKNATIVE = $(HOSTCXX) $(HOSTLINKFLAGS) -std=c++11 -o $@ $^ -static
ifeq ($(origin CC),default)
  #CC = gcc
  CC = x86_64-w64-mingw32-gcc
endif
ifeq ($(origin CXX),default)
  #CXX    = g++
  CXX = x86_64-w64-mingw32-g++
endif
ifeq ($(origin YACC),default)
  YACC   = bison -y -Wno-error=yacc
endif
  YFLAGS ?= -v -Werror
ifeq ($(origin LEX),default)
  LEX    = flex
endif


else ifeq ($(BUILD_ENV_),MSVC)
  # use these for Visual Studio:
  LIBEXT = .lib
  OBJEXT = .obj
  DEPEXT = .dep
  EXEEXT = .exe
  CFLAGS ?= /W3 /O2 /GF
  CXXFLAGS ?= /W3 /D_CRT_SECURE_NO_WARNINGS /O2 /GF
  CP_CFLAGS =
  CP_CXXFLAGS +=
  LINKLIB = lib /NOLOGO /OUT:$@ $^
  LINKBIN = $(CXX) $(LINKFLAGS) /Fe$@ /Z7 /nologo $^ DbgHelp.lib $(LIBS)
  LINKNATIVE = $(HOSTCXX) $(HOSTLINKFLAGS) /Fe$@ /nologo /EHsc $^
ifeq ($(origin CC),default)
  CC = cl
endif
ifeq ($(origin CXX),default)
  CXX = cl
endif
ifeq ($(origin YACC),default)
  YACC   = win_bison -y -Wno-error=yacc
endif
  YFLAGS ?= -v -Werror
ifeq ($(origin LEX),default)
  LEX    = win_flex
endif


else
  $(error Invalid setting for BUILD_ENV: $(BUILD_ENV_))
endif

ifneq ($(IPASIR),)
  CP_CXXFLAGS += -DHAVE_IPASIR
endif

ifneq ($(PICOSAT),)
  CP_CXXFLAGS += -DHAVE_PICOSAT
endif

ifneq ($(LINGELING),)
  CP_CXXFLAGS += -DHAVE_LINGELING
endif

ifneq ($(CHAFF),)
  CP_CXXFLAGS += -DHAVE_CHAFF
endif

ifneq ($(BOOLEFORCE),)
  CP_CXXFLAGS += -DHAVE_BOOLEFORCE
endif

ifneq ($(MINISAT),)
  CP_CXXFLAGS += -DHAVE_MINISAT
endif

ifneq ($(MINISAT2),)
  CP_CXXFLAGS += -DHAVE_MINISAT2
endif

ifneq ($(GLUCOSE),)
  CP_CXXFLAGS += -DHAVE_GLUCOSE
endif

ifneq ($(CADICAL),)
  CP_CXXFLAGS += -DHAVE_CADICAL
endif


ifneq ($(CUDD),)
  CP_CXXFLAGS += -DHAVE_CUDD
ifeq ($(CPROVER_DIR),)
  INCLUDES += -I $(CUDD) -I $(CUDD)/cudd
else
  INCLUDES += -I ../$(CPROVER_DIR)/src/solvers/$(CUDD)
  INCLUDES += -I ../$(CPROVER_DIR)/src/solvers/$(CUDD)/cudd
endif
endif


first_target: all

HOSTCXX ?= $(CXX)
HOSTLINKFLAGS ?= $(LINKFLAGS)

CP_CFLAGS += $(CFLAGS) $(CP_EXTRA_CFLAGS) $(INCLUDES)
CP_CXXFLAGS += $(CXXFLAGS) $(CP_EXTRA_CXXFLAGS) $(INCLUDES)

OBJ += $(patsubst %.cpp, %$(OBJEXT), $(filter %.cpp, $(SRC)))
OBJ += $(patsubst %.cc, %$(OBJEXT), $(filter %.cc, $(SRC)))
OBJ += $(patsubst %.c, %$(OBJEXT), $(filter %.c, $(SRC)))

.SUFFIXES: .cc $(DEPEXT) .cpp

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

%.o:%.cc
	$(CXX) -c $(CP_CXXFLAGS) -o $@ $<

%.o:%.c
	$(CC) -c $(CP_CFLAGS) -o $@ $<

# this one is for Visual Studio's compiler:
%.obj:%.cpp
	$(CXX) $(CP_CXXFLAGS) /nologo /c /EHsc $< /Fo$@

%.obj:%.cc
	$(CXX) $(CP_CXXFLAGS) /nologo /c /EHsc $< /Fo$@

%.obj:%.c
	$(CC) $(CP_CFLAGS) /nologo /c /EHsc $< /Fo$@

clean:
	$(RM) $(patsubst %.cpp, %$(OBJEXT), $(filter %.cpp, $(SRC))) \
		$(patsubst %.cpp, %$(DEPEXT), $(filter %.cpp, $(SRC))) \
		$(patsubst %.cc, %$(OBJEXT), $(filter %.cc, $(SRC))) \
		$(patsubst %.cc, %$(DEPEXT), $(filter %.cc, $(SRC))) \
		$(patsubst %.c, %$(OBJEXT), $(filter %.c, $(SRC))) \
		$(patsubst %.c, %$(DEPEXT), $(filter %.c, $(SRC))) \
		$(CLEANFILES)

.PHONY: first_target clean all
.PHONY: sources generated_files

sources: Makefile
	@echo $(SRC)

#
# include a dependency file if one exists
#

# ifeq (.depend,$(wildcard .depend))
# include .depend
# endif

D_FILES1 = $(SRC:.c=$(DEPEXT))
D_FILES = $(D_FILES1:.cpp=$(DEPEXT))

-include $(D_FILES)
