########## smooth options makefile ##########

VERSION	 = 0.9
REVISION = 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 %.js  "$(SRCDIR)"
vpath %.py  "$(SRCDIR)"
vpath %.rc  "$(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 powerpc,$(MACHINE)),)
	ifneq ($(BUILD_PPC),False)
		BUILD_PPC = True
	endif
else ifneq ($(findstring powerpc64,$(MACHINE)),)
	ifneq ($(BUILD_PPC64),False)
		BUILD_PPC64 = 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 ($(BUILD_ARM64),True)
	ifneq ($(BUILD_X86),False)
	ifneq ($(BUILD_X86_64),True)
		BUILD_X86 = True
	endif
	endif
	endif
endif

# Disable threads based timers
BUILD_THREADSTIMER = False

# Do not build V8 JavaScript library by default
BUILD_V8 = False

# 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 using Win32 backends
	BUILD_WIN32 = True

#	Disable GDI+ backend by default
	BUILD_GDIPLUS = False
else
#	Set executable and shared object extensions
	EXECUTABLE = 
	SHARED = .so

	BUILD_UNIX = True

#	Build using XLib backends
	BUILD_XLIB = True

#	Build using Cairo graphics backend
	BUILD_CAIRO = True

#	Build using POSIX threads
	BUILD_POSIXTHREADS = True

#	Build using POSIX timers
	BUILD_POSIXTIMER = True

	ifeq ($(UNAME),Linux)
		BUILD_LINUX = True
	else ifeq ($(UNAME),FreeBSD)
		BUILD_FREEBSD = True
	else ifeq ($(UNAME),OpenBSD)
		BUILD_OPENBSD = True

# 		Enable threads based timers
		BUILD_POSIXTIMER = False
		BUILD_THREADSTIMER = True
	else ifeq ($(UNAME),NetBSD)
		BUILD_NETBSD = True
	else ifeq ($(UNAME),SunOS)
		BUILD_SOLARIS = True
	else ifeq ($(UNAME),Haiku)
		BUILD_HAIKU = True

#		Disable POSIX timer backend
		BUILD_POSIXTIMER = False

#		Disable XLib and Cairo backends
		BUILD_XLIB = False
		BUILD_CAIRO = False
	else ifeq ($(UNAME),GNU)
		BUILD_GNU = True

# 		Enable threads based timers
		BUILD_POSIXTIMER = False
		BUILD_THREADSTIMER = True
	else ifeq ($(UNAME),Darwin)
#		Set shared object extension
		SHARED = .dylib

		BUILD_OSX = True

#		Disable XLib and Cairo backends
		BUILD_XLIB = False
		BUILD_CAIRO = False

# 		Disable POSIX timers
		BUILD_POSIXTIMER = False
	endif
endif

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

ifndef OBJCXX
	OBJCXX	= $(CXX)
endif

ifeq ($(LD),ld)
	LD	= $(CC)
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

# Decide which libraries to use
ifeq ($(findstring bundledlibbz2,$(config)),bundledlibbz2)
	USE_BUNDLED_LIBBZ2 = True
else ifeq ($(findstring systemlibbz2,$(config)),systemlibbz2)
	USE_BUNDLED_LIBBZ2 = False
else
	ifeq ($(BUILD_WIN32),True)
		USE_BUNDLED_LIBBZ2 = True
	endif
endif

ifeq ($(findstring bundledlibcpuid,$(config)),bundledlibcpuid)
	USE_BUNDLED_LIBCPUID = True
else ifeq ($(findstring systemlibcpuid,$(config)),systemlibcpuid)
	USE_BUNDLED_LIBCPUID = False
else
	USE_BUNDLED_LIBCPUID = True
endif

ifeq ($(findstring bundledlibcurl,$(config)),bundledlibcurl)
	USE_BUNDLED_LIBCURL = True
else ifeq ($(findstring systemlibcurl,$(config)),systemlibcurl)
	USE_BUNDLED_LIBCURL = False
else
	ifeq ($(BUILD_WIN32),True)
		USE_BUNDLED_LIBCURL = True
	endif
endif

ifeq ($(findstring bundledlibfribidi,$(config)),bundledlibfribidi)
	USE_BUNDLED_LIBFRIBIDI = True
else ifeq ($(findstring systemlibfribidi,$(config)),systemlibfribidi)
	USE_BUNDLED_LIBFRIBIDI = False
else
	ifeq ($(BUILD_OSX),True)
		USE_BUNDLED_LIBFRIBIDI = True
	else ifeq ($(BUILD_WIN32),True)
		USE_BUNDLED_LIBFRIBIDI = True
	endif
endif

ifeq ($(findstring bundledlibiconv,$(config)),bundledlibiconv)
	USE_BUNDLED_LIBICONV = True
else ifeq ($(findstring systemlibiconv,$(config)),systemlibiconv)
	USE_BUNDLED_LIBICONV = False
else
	ifeq ($(BUILD_WIN32),True)
		USE_BUNDLED_LIBICONV = True
	endif
endif

ifeq ($(findstring bundledlibjpeg,$(config)),bundledlibjpeg)
	USE_BUNDLED_LIBJPEG = True
else ifeq ($(findstring systemlibjpeg,$(config)),systemlibjpeg)
	USE_BUNDLED_LIBJPEG = False
else
	ifeq ($(BUILD_OSX),True)
		USE_BUNDLED_LIBJPEG = True
	else ifeq ($(BUILD_SOLARIS),True)
		USE_BUNDLED_LIBJPEG = True
	else ifeq ($(BUILD_WIN32),True)
		USE_BUNDLED_LIBJPEG = True
	endif
endif

ifeq ($(findstring bundledlibpng,$(config)),bundledlibpng)
	USE_BUNDLED_LIBPNG = True
else ifeq ($(findstring systemlibpng,$(config)),systemlibpng)
	USE_BUNDLED_LIBPNG = False
else
	ifeq ($(BUILD_OSX),True)
		USE_BUNDLED_LIBPNG = True
	else ifeq ($(BUILD_WIN32),True)
		USE_BUNDLED_LIBPNG = True
	endif
endif

ifeq ($(findstring bundledlibwebp,$(config)),bundledlibwebp)
	USE_BUNDLED_LIBWEBP = True
else ifeq ($(findstring systemlibwebp,$(config)),systemlibwebp)
	USE_BUNDLED_LIBWEBP = False
else
	USE_BUNDLED_LIBWEBP = True
endif

ifeq ($(findstring bundledlibxml2,$(config)),bundledlibxml2)
	USE_BUNDLED_LIBXML2 = True
else ifeq ($(findstring systemlibxml2,$(config)),systemlibxml2)
	USE_BUNDLED_LIBXML2 = False
else
	ifeq ($(BUILD_WIN32),True)
		USE_BUNDLED_LIBXML2 = True
	endif
endif

ifeq ($(findstring bundledzlib,$(config)),bundledzlib)
	USE_BUNDLED_ZLIB = True
else ifeq ($(findstring systemzlib,$(config)),systemzlib)
	USE_BUNDLED_ZLIB = False
else
	ifeq ($(BUILD_OSX),True)
		USE_BUNDLED_ZLIB = True
	else ifeq ($(BUILD_WIN32),True)
		USE_BUNDLED_ZLIB = True
	endif
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	= gcc
		override OBJC	= gcc
		override OBJCXX	= gcc

		override LD	= gcc
	endif

	override CFLAGS	     = -pipe -g0 -Wall
	override CXXFLAGS    =
	override OBJCFLAGS   =
	override OBJCXXFLAGS =
	override LDFLAGS     = -pipe

	ifneq ($(BUILD_SOLARIS),True)
		override CFLAGS	+= -Os
	endif

	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)
		LDFLAGS_TOOLS += -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_TOOLS += -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 =
