########## fre:ac options makefile ##########

VERSION	  = 1.1
REVISION  = 0

SMOOTHVER = 0.9
BOCAVER	  = 1.0

# Find source folder and set vpath
SRCDIR = $(abspath $(dir $(firstword $(MAKEFILE_LIST))))

vpath %.c   "$(SRCDIR)"
vpath %.cc  "$(SRCDIR)"
vpath %.cpp "$(SRCDIR)"
vpath %.m   "$(SRCDIR)"
vpath %.mm  "$(SRCDIR)"
vpath %.rc  "$(SRCDIR)"
vpath %.ico "$(SRCDIR)"

# Define makein and cleanin macros
ifeq ("$(SRCDIR)","$(CURDIR)")
	makein  = cd $(1) && $(MAKE) $(2) && cd ..
	cleanin = cd $(1) && $(MAKE) clean && cd ..
else
	makein  = mkdir -p $(1) && cd $(1) && $(MAKE) -f "$(SRCDIR)"/$(1)/Makefile $(2) && cd ..
	cleanin = mkdir -p $(1) && cd $(1) && $(MAKE) -f "$(SRCDIR)"/$(1)/Makefile clean && cd .. && (rmdir $(1) || true)
endif

# Find architecture and system
UNAME = $(shell uname)
MACHINE = $(shell $(CC) -dumpmachine)

ifneq ($(findstring arm,$(MACHINE)),)
	ifneq ($(BUILD_ARM),False)
		BUILD_ARM = True
	endif
else ifneq ($(findstring aarch64,$(MACHINE)),)
	ifneq ($(BUILD_ARM64),False)
		BUILD_ARM64 = True
	endif
else ifneq ($(findstring mips,$(MACHINE)),)
	ifneq ($(BUILD_MIPS),False)
		BUILD_MIPS = True
	endif
else ifneq ($(findstring powerpc64,$(MACHINE)),)
	ifneq ($(BUILD_PPC64),False)
		BUILD_PPC64 = True
	endif
else ifneq ($(findstring powerpc,$(MACHINE)),)
	ifneq ($(BUILD_PPC),False)
		BUILD_PPC = True
	endif
else ifneq ($(findstring riscv64,$(MACHINE)),)
	ifneq ($(BUILD_RISCV64),False)
		BUILD_RISCV64 = True
	endif
else ifneq ($(findstring x86_64,$(MACHINE)),)
	ifneq ($(BUILD_ARM64),True)
	ifneq ($(BUILD_X86),True)
	ifneq ($(BUILD_X86_64),False)
		BUILD_X86_64 = True
	endif
	endif
	endif
else ifneq ($(findstring amd64,$(MACHINE)),)
	ifneq ($(BUILD_ARM64),True)
	ifneq ($(BUILD_X86),True)
	ifneq ($(BUILD_X86_64),False)
		BUILD_X86_64 = True
	endif
	endif
	endif
else ifneq ($(findstring i586,$(MACHINE))$(findstring i686,$(MACHINE)),)
	ifneq ($(BUILD_ARM64),True)
	ifneq ($(BUILD_X86),False)
	ifneq ($(BUILD_X86_64),True)
		BUILD_X86 = True
	endif
	endif
	endif
endif

# Treat MSYS and MinGW the same
ifneq ($(findstring MSYS,$(UNAME)),)
	UNAME = MINGW
endif

ifneq ($(findstring MINGW,$(UNAME)),)
#	Set executable and shared object extensions
	EXECUTABLE = .exe
	SHARED = .dll

#	Build on Win32
	BUILD_WIN32 = True
else
#	Set executable and shared object extensions
	EXECUTABLE = 
	SHARED = .so

	BUILD_UNIX = True

	ifeq ($(UNAME),Linux)
		BUILD_LINUX = True
	else ifeq ($(UNAME),FreeBSD)
		BUILD_FREEBSD = True
	else ifeq ($(UNAME),OpenBSD)
		BUILD_OPENBSD = True
	else ifeq ($(UNAME),NetBSD)
		BUILD_NETBSD = True
	else ifeq ($(UNAME),SunOS)
		BUILD_SOLARIS = True
	else ifeq ($(UNAME),Haiku)
		BUILD_HAIKU = True
	else ifeq ($(UNAME),GNU)
		BUILD_GNU = True
	else ifeq ($(UNAME),Darwin)
#		Set shared object extension
		SHARED = .dylib

		BUILD_OSX = True
	endif
endif

# Set default commands
ifndef OBJC
	OBJC	= $(CC)
endif

ifndef OBJCXX
	OBJCXX	= $(CXX)
endif

ifeq ($(LD),ld)
	LD	= $(CXX)
endif

LDCONFIG	= /sbin/ldconfig

INSTALL		= install

ifeq ($(BUILD_SOLARIS),True)
	INSTALL = ginstall
endif

INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA	= $(INSTALL) -m 644

# Set output folders
BINDIR = bin
LIBDIR = lib

ifeq ($(BUILD_WIN32),True)
	ifeq ($(BUILD_X86_64),True)
		BINDIR = bin64
		LIBDIR = lib64
	endif
endif

# Set install folders
ifndef prefix
	prefix = /usr/local

	ifeq ($(BUILD_HAIKU),True)
		prefix = /system/non-packaged
	endif
endif

bindir	   = $(prefix)/bin
libdir	   = $(prefix)/lib
includedir = $(prefix)/include
datadir	   = $(prefix)/share

ifeq ($(BUILD_HAIKU),True)
	includedir = $(prefix)/develop/headers
	datadir	   = $(prefix)/data
endif

# Set release specific options
ifeq ($(findstring release,$(config)),release)
	ifeq ($(BUILD_FREEBSD),True)
		override CC	= clang
		override CXX	= clang++
		override OBJC	= clang
		override OBJCXX	= clang++

		override LD	= clang++
	else ifeq ($(BUILD_OSX),True)
		override CC	= gcc
		override CXX	= g++
		override OBJC	= gcc
		override OBJCXX	= g++

		override LD	= g++
	endif

	override CFLAGS	     = -pipe -g0 -Wall -Os -DFREAC_DATE=\"$(shell date +"%Y%m%d")\"
	override CXXFLAGS    =
	override OBJCFLAGS   =
	override OBJCXXFLAGS =
	override LDFLAGS     = -pipe

	ifneq ($(RTTI),True)
		ifneq ($(BUILD_HAIKU),True)
			override CXXFLAGS    += -fno-rtti
			override OBJCXXFLAGS += -fno-rtti
		endif
	endif

	ifneq ($(EXCEPTION),True)
		override CXXFLAGS    += -fno-exceptions
		override OBJCXXFLAGS += -fno-exceptions
	endif

	ifeq ($(BUILD_OSX),True)
#		Find macOS and Xcode version
		XCODEVERSION = $(shell xcodebuild -version | head -n1)
		MACOSVERSION = $(MACOSX_DEPLOYMENT_TARGET)

		ifeq ($(MACOSVERSION),)
			MACOSVERSION = $(shell sw_vers | awk '$$1 == "ProductVersion:" { print $$2 }')
		endif

		XCODE_LE3   = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#\#* }; if [ \$${v%%.*} -le  3 ]; then echo True; fi")
		XCODE_LE9   = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#\#* }; if [ \$${v%%.*} -le  9 ]; then echo True; fi")
		XCODE_EQ12  = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#\#* }; if [ \$${v%%.*} -eq 12 ]; then echo True; fi")
		XCODE_GE13  = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#\#* }; if [ \$${v%%.*} -ge 13 ]; then echo True; fi")
		XCODE_N_GE2 = $(shell bash -c "v='$(XCODEVERSION)'; v=\$${v\#*.};   if [ \$${v%%.*} -ge  2 ]; then echo True; fi")

		MACOS_GE11  = $(shell bash -c "v='$(MACOSVERSION)';                 if [ \$${v%%.*} -ge 11 ]; then echo True; fi")

#		Build universal binaries
		ifneq ($(BUILD_X86_64),False)
			BUILD_X86_64 = True
		endif
		ifeq ($(XCODE_LE9),True)
			ifneq ($(BUILD_X86),False)
				BUILD_X86 = True
			endif

			ifeq ($(XCODE_LE3),True)
				ifneq ($(BUILD_PPC),False)
					BUILD_PPC = True
				endif
			endif
		else ifeq ($(XCODE_EQ12),True)
			ifeq ($(XCODE_N_GE2),True)
				ifeq ($(MACOS_GE11),True)
					ifneq ($(BUILD_ARM64),False)
						BUILD_ARM64 = True
					endif
				endif
			endif
		else ifeq ($(XCODE_GE13),True)
			ifeq ($(MACOS_GE11),True)
				ifneq ($(BUILD_ARM64),False)
					BUILD_ARM64 = True
				endif
			endif
		endif

#		Set build flags
		override LDFLAGS += -Wl,-x

		ifeq ($(BUILD_X86),True)
			override CFLAGS	 += -arch i386 -Xarch_i386 -march=prescott
			override LDFLAGS += -arch i386
		endif
		ifeq ($(BUILD_X86_64),True)
			ifeq ($(MACOS_GE11),True)
				override CFLAGS	 += -arch x86_64 -Xarch_x86_64 -march=haswell
			else
				override CFLAGS	 += -arch x86_64 -Xarch_x86_64 -march=core2
			endif

			override LDFLAGS += -arch x86_64
		endif
		ifeq ($(BUILD_PPC),True)
			override CFLAGS	 += -arch ppc -Xarch_ppc -mcpu=G4
			override LDFLAGS += -arch ppc
		endif
		ifeq ($(BUILD_PPC64),True)
			override CFLAGS	 += -arch ppc64 -Xarch_ppc64 -mcpu=G5
			override LDFLAGS += -arch ppc64
		endif
		ifeq ($(BUILD_ARM64),True)
			override CFLAGS	 += -arch arm64
			override LDFLAGS += -arch arm64
		endif
	else
		override LDFLAGS += -s

		ifeq ($(BUILD_X86),True)
			override CFLAGS	 += -m32
			override LDFLAGS += -m32
		else ifeq ($(BUILD_X86_64),True)
			override CFLAGS	 += -m64
			override LDFLAGS += -m64
		endif
	endif

	override CXXFLAGS    += $(CFLAGS)
	override OBJCFLAGS   += $(CFLAGS)
	override OBJCXXFLAGS += $(CFLAGS)

	ifneq ($(BUILD_WIN32),True)
	ifneq ($(BUILD_OSX),True)
		override LDFLAGS += -Wl,-rpath,.
	endif
	endif
endif

# Set debug specific options
ifeq ($(findstring debug,$(config)),debug)
	override CFLAGS	     = -pipe -g -Wall -DDEBUG
	override CXXFLAGS    =
	override OBJCFLAGS   =
	override OBJCXXFLAGS =
	override LDFLAGS     = -pipe

	ifneq ($(RTTI),True)
		ifneq ($(BUILD_HAIKU),True)
			override CXXFLAGS    += -fno-rtti
			override OBJCXXFLAGS += -fno-rtti
		endif
	endif

	ifneq ($(EXCEPTION),True)
		override CXXFLAGS    += -fno-exceptions
		override OBJCXXFLAGS += -fno-exceptions
	endif

	override CXXFLAGS    += $(CFLAGS)
	override OBJCFLAGS   += $(CFLAGS)
	override OBJCXXFLAGS += $(CFLAGS)

	ifneq ($(BUILD_WIN32),True)
	ifneq ($(BUILD_OSX),True)
		override LDFLAGS += -Wl,-rpath,.
	endif
	endif
endif

# Flags needed for Windows ARM64 toolchain
ifeq ($(BUILD_WIN32),True)
	ifeq ($(BUILD_ARM64),True)
		override CFLAGS	 += -target aarch64-w64-mingw32
		override LDFLAGS += -target aarch64-w64-mingw32
	endif
endif

# Clear config variable
config =
