# 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
ifeq ($(BUILD_ENV_),MinGW)
  EXEEXT = .exe
else
  EXEEXT =
endif
  CFLAGS ?= -Wall -O2
  CXXFLAGS ?= -Wall -O2
  CP_CFLAGS = -MMD -MP
ifeq ($(filter-out OSX OSX_Universal,$(BUILD_ENV_)),)
  CP_CXXFLAGS = -MMD -MP -mmacosx-version-min=10.9 -std=c++11 -stdlib=libc++
  LINKFLAGS += -mmacosx-version-min=10.9 -stdlib=libc++
  LINKNATIVE += -mmacosx-version-min=10.9 -stdlib=libc++
else
  CP_CXXFLAGS = -MMD -MP -std=c++11
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 i386 -arch x86_64
    CP_CFLAGS += -force_cpusubtype_ALL -arch i386 -arch x86_64
    LINKFLAGS += -force_cpusubtype_ALL -arch i386 -arch x86_64
  endif
  LINKLIB = /usr/bin/libtool -static -o $@ $^
  LINKBIN = $(CXX) $(LINKFLAGS) -o $@ $^ $(LIBS)
  LINKNATIVE = $(HOSTCXX) -o $@ $^
  ifeq ($(origin CC),default)
    CC     = clang
  endif
  ifeq ($(origin CXX),default)
    CXX    = clang++
  endif
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) -o $@ $^
  ifeq ($(origin CC),default)
    CC     = clang
  endif
  ifeq ($(origin CXX),default)
    CXX    = clang++
  endif
else
  LINKLIB = ar rcT $@ $^
  LINKBIN = $(CXX) $(LINKFLAGS) -o $@ -Wl,--start-group $^ -Wl,--end-group $(LIBS)
  LINKNATIVE = $(HOSTCXX) -o $@ $^
  ifeq ($(origin CC),default)
    CC     = gcc
    #CC     = icc
  endif
  ifeq ($(origin CXX),default)
    CXX    = g++
    #CXX    = icpc
  endif
endif
ifeq ($(origin YACC),default)
  YACC   = bison -y
endif
  YFLAGS ?= -v
ifeq ($(origin LEX),default)
  LEX    = flex
endif


else ifeq ($(BUILD_ENV_),Cygwin)
  # use these for Cygwin:
  LIBEXT = .a
  OBJEXT = .o
  EXEEXT = .exe
  CFLAGS ?= -Wall -O2
  CXXFLAGS ?= -Wall -O2
  CP_CFLAGS = -MMD -MP
  CP_CXXFLAGS = -MMD -MP -std=c++11 -U__STRICT_ANSI__
  LINKFLAGS = -static -std=c++11
  LINKLIB = ar rcT $@ $^
  LINKBIN = $(CXX) $(LINKFLAGS) -o $@ -Wl,--start-group $^ -Wl,--end-group $(LIBS) -static
  LINKNATIVE = $(HOSTCXX) -std=c++11 -o $@ $^ -static
ifeq ($(origin CC),default)
  #CC = gcc
  CC = i686-w64-mingw32-gcc
endif
ifeq ($(origin CXX),default)
  #CXX    = g++
  CXX = i686-w64-mingw32-g++
endif
ifeq ($(origin YACC),default)
  YACC   = bison -y
endif
  YFLAGS ?= -v
ifeq ($(origin LEX),default)
  LEX    = flex
endif


else ifeq ($(BUILD_ENV_),MSVC)
  # use these for Visual Studio:
  LIBEXT = .lib
  OBJEXT = .obj
  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$@ $^ $(LIBS)
  LINKNATIVE = $(HOSTCXX) /Fe$@ $^
ifeq ($(origin CC),default)
  CC = cl
endif
ifeq ($(origin CXX),default)
  CXX = cl
endif
ifeq ($(origin YACC),default)
  YACC   = bison -y
endif
  YFLAGS ?= -v
ifeq ($(origin LEX),default)
  LEX    = flex
endif


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


first_target: all

HOSTCXX ?= $(CXX)

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

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

.SUFFIXES: .cc .d .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, %.d, $(filter %.cpp, $(SRC))) \
		$(patsubst %.cc, %$(OBJEXT), $(filter %.cc, $(SRC))) \
		$(patsubst %.cc, %.d, $(filter %.cc, $(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=.d)
D_FILES = $(D_FILES1:.cpp=.d)

-include $(D_FILES)

