#######################################################################
##
## Auto detect Operating System
##
#######################################################################

ifneq "" "$(findstring -linux-,$(MAKE_HOST))"
	OS=linux
else ifneq "" "$(VSINSTALLDIR)"
	OS=visual
else ifneq "" "$(findstring cmd.exe,$(COMSPEC))"
	OS=mingw
else
	OS=""
endif

ifeq "$(OS)" ""
  $(error Cannot figure out which OS to build for."
endif
$(info Building for $(OS)...)


#######################################################################
##
## List of all OBJ files
##
#######################################################################

OBJ_ERIS=\
	obj/$(OS)/eris/lapi.obj \
	obj/$(OS)/eris/lcode.obj \
	obj/$(OS)/eris/lctype.obj \
	obj/$(OS)/eris/ldebug.obj \
	obj/$(OS)/eris/ldo.obj \
	obj/$(OS)/eris/ldump.obj \
	obj/$(OS)/eris/lfunc.obj \
	obj/$(OS)/eris/lgc.obj \
	obj/$(OS)/eris/llex.obj \
	obj/$(OS)/eris/lmem.obj \
	obj/$(OS)/eris/lobject.obj \
	obj/$(OS)/eris/lopcodes.obj \
	obj/$(OS)/eris/lparser.obj \
	obj/$(OS)/eris/lstate.obj \
	obj/$(OS)/eris/lstring.obj \
	obj/$(OS)/eris/ltable.obj \
	obj/$(OS)/eris/ltm.obj \
	obj/$(OS)/eris/lundump.obj \
	obj/$(OS)/eris/lvm.obj \
	obj/$(OS)/eris/lzio.obj \
	obj/$(OS)/eris/lauxlib.obj \
	obj/$(OS)/eris/lbaselib.obj \
	obj/$(OS)/eris/lbitlib.obj \
	obj/$(OS)/eris/lcorolib.obj \
	obj/$(OS)/eris/ldblib.obj \
	obj/$(OS)/eris/liolib.obj \
	obj/$(OS)/eris/lmathlib.obj \
	obj/$(OS)/eris/loslib.obj \
	obj/$(OS)/eris/lstrlib.obj \
	obj/$(OS)/eris/ltablib.obj \
	obj/$(OS)/eris/loadlib.obj \
	obj/$(OS)/eris/linit.obj \
	obj/$(OS)/eris/eris.obj \

OBJ_CORE=\
	obj/$(OS)/core/invocation.obj\
	obj/$(OS)/core/spookyv2.obj\
	obj/$(OS)/core/eng-malloc.obj\
	obj/$(OS)/core/debugcollector.obj\
	obj/$(OS)/core/drivenengine.obj\
	obj/$(OS)/core/util.obj\
	obj/$(OS)/core/luastack.obj\
	obj/$(OS)/core/traceback.obj\
	obj/$(OS)/core/planemap.obj\
	obj/$(OS)/core/pprint.obj\
	obj/$(OS)/core/luaconsole.obj\
	obj/$(OS)/core/idalloc.obj\
	obj/$(OS)/core/globaldb.obj\
	obj/$(OS)/core/sched.obj\
	obj/$(OS)/core/http.obj\
	obj/$(OS)/core/json.obj\
	obj/$(OS)/core/table.obj\
	obj/$(OS)/core/gui.obj\
	obj/$(OS)/core/luasnap.obj\
	obj/$(OS)/core/animqueue.obj\
	obj/$(OS)/core/streambuffer.obj\
	obj/$(OS)/core/source.obj\
	obj/$(OS)/core/world-core.obj\
	obj/$(OS)/core/world-accessor.obj\
	obj/$(OS)/core/world-difftab.obj\
	obj/$(OS)/core/world-diffxmit.obj\
	obj/$(OS)/core/world-pairtab.obj\
	obj/$(OS)/core/world-testing.obj\
	obj/$(OS)/core/textgame.obj\
	obj/$(OS)/core/lpxserver.obj\
	obj/$(OS)/core/lpxclient.obj\
	obj/$(OS)/core/eng-tests.obj\
	obj/$(OS)/core/printbuffer.obj\
	obj/$(OS)/core/serializelua.obj\


OBJ_DRV=\
	obj/$(OS)/drv/driver.obj\
	obj/$(OS)/drv/drvutil.obj\
	obj/$(OS)/drv/sslutil.obj\


#######################################################################
##
## Make rules for linux
##
#######################################################################

ifeq "$(OS)" "linux"
	OPT=-g -O0
	LUPREX_EXE=luprex
	LUPREXLIB_DLL=luprexlib.so
	LUPREXSTATIC_EXE=luprexstatic
	COMPILE=g++ -Wall $(OPT) -std=c++17 -fvisibility=hidden -c -MMD -fPIC -o
	LINKDLL=g++ -Wall $(OPT) -std=c++17 -export-dynamic -Wl,--no-allow-shlib-undefined -Wl,-z,defs -shared -o
	LINKEXE=g++ -Wall $(OPT) -std=c++17 -o
	MAKEDEPS=true
	MAKEPDB=true
	OPENSSL_INCLUDE=-I./ext/openssl-3.0.1/inc
	LUA_FLAGS=-DLUA_USE_APICHECK -DLUA_USE_POSIX 
	LIBS=-L./ext/openssl-3.0.1/lib/linux -lssl -lcrypto -ldl
endif


#######################################################################
##
## Make rules for mingw
##
#######################################################################

ifeq "$(OS)" "mingw"
	OPT=-g -O0
	LUPREX_EXE=luprex.exe
	LUPREXLIB_DLL=luprexlib.dll
	LUPREXSTATIC_EXE=luprexstatic.exe
	COMPILE=g++ -Wall $(OPT) -std=c++17 -fvisibility=hidden -c -MMD -fPIC -o
	LINKDLL=g++ -Wall $(OPT) -std=c++17 -Wl,--no-allow-shlib-undefined -shared -o
	LINKEXE=g++ -Wall $(OPT) -std=c++17 -o
	MAKEDEPS=true
	MAKEPDB=./ext/cv2pdb.exe
	OPENSSL_INCLUDE=-I./ext/openssl-3.0.1/inc
	LUA_FLAGS=-DLUA_USE_APICHECK -DLUA_COMPAT_ALL
	LIBS=-L./ext/openssl-3.0.1/lib/mingw -lssl -lcrypto -lws2_32 -lcrypt32 -lcryptui
endif


#######################################################################
##
## Make rules for visual
##
#######################################################################

ifeq "$(OS)" "visual"
	ifeq "" "$(VSINSTALLDIR)"
		$(error You must use vcvars64.bat to set up the visual studio environment variables)
	endif
	OPT=/Od /Zi
	LUPREX_EXE=luprex.exe
	LUPREXLIB_DLL=luprexlib.dll
	LUPREXSTATIC_EXE=luprexstatic.exe
	COMPILE=CL $(OPT) /std:c++17 /EHsc /nologo /MD /TP /c /Fo:
	LINKDLL=CL $(OPT) /std:c++17 /EHsc /nologo /LDd /Fe:
	LINKEXE=CL $(OPT) /std:c++17 /EHsc /nologo /Fe:
	MAKEDEPS=g++ -Wall -std=c++17 -MMD -E -o
	MAKEPDB=true
	OPENSSL_INCLUDE=-I./ext/openssl-3.1.0/inc
	LUA_FLAGS=-DLUA_USE_APICHECK -DLUA_COMPAT_ALL
	LIBS=ext/openssl-3.1.0/lib/visual/libcrypto.lib ext/openssl-3.1.0/lib/visual/libssl.lib ws2_32.lib crypt32.lib cryptui.lib user32.lib advapi32.lib
endif

#######################################################################
##
## Make Rules
##
#######################################################################

all: build/$(OS)/$(LUPREX_EXE) build/$(OS)/$(LUPREXSTATIC_EXE) build/$(OS)/$(LUPREXLIB_DLL)

build/$(OS)/$(LUPREX_EXE): build/$(OS)/$(LUPREXLIB_DLL) $(OBJ_DRV)
	$(LINKEXE) $@ $(OBJ_DRV) $(LIBS)
	$(MAKEPDB) $@

build/$(OS)/$(LUPREXSTATIC_EXE): $(OBJ_DRV) $(OBJ_ERIS) $(OBJ_CORE)
	$(LINKEXE) $@ $^ $(LIBS)
	$(MAKEPDB) $@

build/$(OS)/$(LUPREXLIB_DLL): $(OBJ_ERIS) $(OBJ_CORE)
	$(LINKDLL) $@ $^
	$(MAKEPDB) $@

obj/$(OS)/eris/%.obj: ext/eris-master/src/%.c
	$(MAKEDEPS) $@d $(LUA_FLAGS) $<
	$(COMPILE) $@ $(LUA_FLAGS) $<

obj/$(OS)/core/%.obj: cpp/core/%.cpp
	$(MAKEDEPS) $@d -I./ext/eris-master/src -I./cpp/wrap -I./cpp/core $<
	$(COMPILE) $@ -I./ext/eris-master/src -I./cpp\wrap -I./cpp/core $<

obj/$(OS)/drv/%.obj: cpp/drv/%.cpp
	$(MAKEDEPS) $@d $(OPENSSL_INCLUDE) -I./src/drv $<
	$(COMPILE) $@ $(OPENSSL_INCLUDE) -I./src/drv $<

clean:
	rm -f luprex* luprex*.* *.pdb build/*/* obj/*/*/*

clean-os:
	rm -f luprex* luprex*.* *.pdb build/$(OS)/* obj/$(OS)/*/*

#######################################################################
##
## Automatically generated Make Dependencies
##
#######################################################################

-include $(OBJ_ERIS:%.obj=%.d)
-include $(OBJ_CORE:%.obj=%.d)
-include $(OBJ_DRV:%.obj=%.d)

