# Java include directory pathnames
# The Windows files need to be copied from a Windows JDK installation
include_linux   = jni/linux
include_windows = jni/windows

# Default goal
.PHONY: default
default:
	@echo $(include_linux)
	@echo "Planet Virtual Boy Emulator"
	@echo "  https://www.planetvb.com/"
	@echo "  December 26, 2020"
	@echo
	@echo "Intended build environment: Debian i386 or amd64"
	@echo "  gcc-multilib"
	@echo "  mingw-w64"
	@echo "  openjdk-15-jdk"
	@echo
	@echo "Usage: make <recipe>"
	@echo "  Package recipes:"
	@echo "    build    Compiles the native modules and desktop application"
	@echo "    clean    Deletes all output files"
	@echo "    core     Check the native core library for style errors"
	@echo "    desktop  Compiles the Java desktop application"
	@echo "    native   Builds all native modules"
	@echo "    pack     Bundles everything in a .jar file"
	@echo "    release  Produces a .jar and deletes all intermediate files"
	@echo "  Native recipes:"
	@echo "    lin32    Builds native module linux_x86"
	@echo "    lin64    Builds native module linux_x86-64"
	@echo "    win32    Builds native module windows_x86"
	@echo "    win64    Builds native module windows_x86-64"
	@echo



###############################################################################
#                               Package Recipes                               #
###############################################################################

# Perform a full build process of the native modules and desktop application
.PHONY: build
build:
	@make -s core
	@make -s desktop
	@make -s native

# Delete all output files
.PHONY: clean
clean: clean_most
	@rm -f pvbemu_*.jar

# Check the native core library for style errors
.PHONY: core
core:
	@echo "  Checking native core library for style errors"
	$(eval coreargs = -c -Isrc/core/include -Werror -Wall -Wextra -Wpedantic \
        -fno-strict-aliasing -fsyntax-only src/core/vue.c)
	@gcc -std=c90 $(coreargs)
	@gcc -std=c90 -D VUE_BIGENDIAN $(coreargs)
	@gcc -std=c99 $(coreargs)
	@gcc -std=c99 -D VUE_BIGENDIAN $(coreargs)
	@gcc -std=c11 $(coreargs)
	@gcc -std=c11 -D VUE_BIGENDIAN $(coreargs)

# Compile the Java desktop application
.PHONY: desktop
desktop: clean_desktop
	@echo "  Compiling Java desktop application"
	@javac -sourcepath src/desktop --release 10 -Xlint:unchecked \
        -Xlint:deprecation -h src/desktop/vue -d . src/desktop/Main.java

# Build all native modules
.PHONY: native
native:
	@make -s lin32
	@make -s lin64
	@make -s win32
	@make -s win64

# Package the release into a .jar file
.PHONY: pack
pack:
	$(eval jarname = "pvbemu_`date +%Y%m%d`.jar")
	@echo "  Bundling into $(jarname)"
	@jar -cfe $(jarname) Main *.class license.txt \
        app images locale native util vue

# Performs a full build and packages it into a .jar
.PHONY: release
release:
	@make -s build
	@make -s pack
	@echo "  Removing temporary files"
	@make -s clean_most

# Delete only Java .class files
.PHONY: clean_desktop
clean_desktop:
	@rm -r -f *.class app util vue

# Delete everything but the .jar
.PHONY: clean_most
clean_most: clean_desktop
	@rm -f src/desktop/vue/vue_NativeVue.h native/*.dll native/*.so



###############################################################################
#                               Native Recipes                                #
###############################################################################

# JNI header file
src/desktop/vue/vue_NativeVue.h: src/desktop/vue/NativeVue.java
	@javac -h src/desktop/vue -sourcepath src/desktop -d . \
        src/desktop/vue/NativeVue.java
	@sleep 3

# linux_x86
.PHONY: lin32_pre
lin32_pre: src/desktop/vue/vue_NativeVue.h
	$(eval name    = linux_x86)
	$(eval prefix  = `uname -m`-linux-gnu-)
	$(eval include = -I$(include_linux) -I$(include_linux)/linux)
	$(eval gccargs = -m32 -lm)
	$(eval ext     = .so)
.PHONY: lin32
lin32: lin32_pre native_common

# linux_x86-64
.PHONY: lin64_pre
lin64_pre: src/desktop/vue/vue_NativeVue.h
	$(eval name    = linux_x86-64)
	$(eval prefix  = `uname -m`-linux-gnu-)
	$(eval include = -I$(include_linux) -I$(include_linux)/linux)
	$(eval gccargs = -m64 -lm)
	$(eval ext     = .so)
.PHONY: lin64
lin64: lin64_pre native_common

# windows_x86
.PHONY: win32_pre
win32_pre: src/desktop/vue/vue_NativeVue.h
	$(eval name    = windows_x86)
	$(eval prefix  = i686-w64-mingw32-)
	$(eval include = -I$(include_windows) -I$(include_windows)/win32)
	$(eval ext     = .dll)
.PHONY: win32
win32: win32_pre native_common

# windows_x86-64
.PHONY: win64_pre
win64_pre: src/desktop/vue/vue_NativeVue.h
	$(eval name    = windows_x86-64)
	$(eval prefix  = x86_64-w64-mingw32-)
	$(eval include = -I$(include_windows) -I$(include_windows)/win32)
	$(eval ext     = .dll)
.PHONY: win64
win64: win64_pre native_common

# Common recipe for building native modules
.PHONY: native_common
native_common:
	@echo "  Building native module $(name)"
	@$(prefix)gcc $(include) -Isrc/core/include $(gccargs) -s -shared -O2 \
        -fno-strict-aliasing -fPIC -Werror \
        -o native/$(name)$(ext) src/desktop/vue/NativeVue.c src/core/vue.c