From 312b2c570eb073fd42e595ed275c8f681dac5497 Mon Sep 17 00:00:00 2001
From: Jonathan Peppers <jonathan.peppers@microsoft.com>
Date: Mon, 18 Dec 2017 10:40:08 -0600
Subject: [PATCH 1/2] [build] option to filter by JI_MAX_JDK on make prepare

Context:
https://stackoverflow.com/questions/47627499/does-android-studio-3-support-java-9-for-android-development

At the current time, we will not be able to use JDK 9 for Android. Some
of our build agents (VSTS), now have JDK 9 installed, so we need to
make a few changes to make sure JDK 8 is picked up instead.

Changes:
- Create a `JI_MAX_JDK` option, as a way for `xamarin-android` to
exclude JDK 9
- Create new `JI_JAVAC_PATH` and `JI_JAR_PATH` make variables, which
will be the full path to `javac` and `jar`
- Use `awk` to filter on <= `JI_MAX_JDK`
- Use `sed` to find the JDK version number, see options of folder names
below
- `sort -n` should be used to sort numerically
- Set `JI_JAVAC_PATH` and `JI_JAR_PATH` to their full paths
- Support both `Darwin` and `Linux`, Windows support is handled in
`xamarin-android` currently

~~Known JDK folder names~~

macOS:
```
1.6.0.jdk
jdk1.7.0_79.jdk
jdk1.8.0_101.jdk
jdk1.8.0_152.jdk
jdk-9.0.1.jdk
```

Ubuntu:
```
java-8-openjdk-amd64
java-9-openjdk-amd64
```
---
 build-tools/scripts/jdk.mk | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/build-tools/scripts/jdk.mk b/build-tools/scripts/jdk.mk
index f8ace67ca..e3167e66f 100644
--- a/build-tools/scripts/jdk.mk
+++ b/build-tools/scripts/jdk.mk
@@ -6,6 +6,9 @@
 #   $(OS): Optional; **uname**(1) value of the host operating system
 #   $(CONFIGURATION): Build configuration name, e.g. Debug or Release
 #   $(RUNTIME): `mono` executable for the host operating system
+#   $(JI_MAX_JDK):
+#       Maximum allowed JDK version, blank by default.
+#       `xamarin-android` will need to specify 8 here
 #
 # Outputs:
 #
@@ -21,6 +24,16 @@
 #       Location of the Java native library that contains e.g. JNI_CreateJavaVM().
 
 OS           ?= $(shell uname)
+JI_JAVAC_PATH = javac
+JI_JAR_PATH   = jar
+
+
+# Filter on <= JI_MAX_JDK
+ifneq ($(JI_MAX_JDK),)
+_VERSION_MAX  := | awk '$$1 <= $(JI_MAX_JDK)'
+endif #JI_MAX_JDK
+# Sort numerically on version numbers with `sort -n`, filtering on $(JI_MAX_JDK) if needed
+_VERSION_SORT := sed 's/[^0-9]*\([0-9.]*\)/\1 &/' $(_VERSION_MAX) | sort -n | sed 's/^[0-9.]* //g' | tail -1
 
 ifeq ($(OS),Darwin)
 
@@ -58,7 +71,9 @@ _LOCAL_JDK_HEADERS                = LocalJDK/System/Library/Frameworks/JavaVM.fr
 _APPLE_JDK6_URL                   = http://adcdownload.apple.com/Developer_Tools/java_for_os_x_2013005_developer_package/java_for_os_x_2013005_dp__11m4609.dmg
 
 ifneq ($(_DARWIN_JDK_FALLBACK_DIRS),)
-_DARWIN_JDK_ROOT      := $(shell ls -dtr $(_DARWIN_JDK_FALLBACK_DIRS) | sort | tail -1)
+_DARWIN_JDK_ROOT      := $(shell ls -dtr $(_DARWIN_JDK_FALLBACK_DIRS) | $(_VERSION_SORT))
+JI_JAVAC_PATH         = $(_DARWIN_JDK_ROOT)/Contents/Home/bin/javac
+JI_JAR_PATH           = $(_DARWIN_JDK_ROOT)/Contents/Home/bin/jar
 JI_JDK_INCLUDE_PATHS  = \
 	$(_DARWIN_JDK_ROOT)/$(_DARWIN_JDK_JNI_INCLUDE_DIR) \
 	$(_DARWIN_JDK_ROOT)/$(_DARWIN_JDK_JNI_OS_INCLUDE_DIR)
@@ -108,7 +123,7 @@ _LINUX_JAVA_ROOT            = $(JAVA_HOME)
 endif # No default Java location, $JAVA_HOME check
 
 ifeq ($(wildcard $(_DESKTOP_JAVA_INCLUDE_DIRS)),)
-LATEST_JDK            := $(shell ls -dtr $(_LINUX_JAVA_FALLBACK_DIRS) | sort | tail -1)
+LATEST_JDK                  := $(shell ls -dtr $(_LINUX_JAVA_FALLBACK_DIRS) | $(_VERSION_SORT))
 _DESKTOP_JAVA_INCLUDE_DIRS  = $(LATEST_JDK)/$(_LINUX_JAVA_JNI_INCLUDE_DIR)
 _LINUX_JAVA_ROOT            = $(LATEST_JDK)
 endif # No $JAVA_HOME, find the latest version
@@ -125,6 +140,9 @@ JI_JVM_PATH                 = $(_LINUX_JAVA_ROOT)/jre/lib/$(_LINUX_JAVA_ARCH_32)
 endif # (2)
 endif # (1)
 
+JI_JAVAC_PATH               = $(_LINUX_JAVA_ROOT)/bin/javac
+JI_JAR_PATH                 = $(_LINUX_JAVA_ROOT)/bin/jar
+
 endif   # Linux
 
 $(JI_JVM_PATH):
@@ -148,7 +166,7 @@ bin/Build$(CONFIGURATION)/JdkInfo.props: $(JI_JDK_INCLUDE_PATHS) $(JI_JVM_PATH)
 	echo '    </When>' >> "$@"
 	echo '  </Choose>' >> "$@"
 	echo '  <PropertyGroup>' >> "$@"
-	echo "    <JavaCPath Condition=\" '\$$(JavaCPath)' == '' \">javac</JavaCPath>" >> "$@"
-	echo "    <JarPath Condition=\" '\$$(JarPath)' == '' \">jar</JarPath>" >> "$@"
+	echo "    <JavaCPath Condition=\" '\$$(JavaCPath)' == '' \">$(JI_JAVAC_PATH)</JavaCPath>" >> "$@"
+	echo "    <JarPath Condition=\" '\$$(JarPath)' == '' \">$(JI_JAR_PATH)</JarPath>" >> "$@"
 	echo '  </PropertyGroup>' >> "$@"
 	echo '</Project>' >> "$@"

From 1c437a1b4659258c3dbb021167d4920aa213122b Mon Sep 17 00:00:00 2001
From: Jonathan Pryor <jonpryor@vt.edu>
Date: Wed, 20 Dec 2017 21:23:22 -0500
Subject: [PATCH 2/2] Add comment to elaborate on `$(_VERSION_SORT)`.

---
 build-tools/scripts/jdk.mk | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/build-tools/scripts/jdk.mk b/build-tools/scripts/jdk.mk
index e3167e66f..823fd9e56 100644
--- a/build-tools/scripts/jdk.mk
+++ b/build-tools/scripts/jdk.mk
@@ -32,7 +32,10 @@ JI_JAR_PATH   = jar
 ifneq ($(JI_MAX_JDK),)
 _VERSION_MAX  := | awk '$$1 <= $(JI_MAX_JDK)'
 endif #JI_MAX_JDK
+
 # Sort numerically on version numbers with `sort -n`, filtering on $(JI_MAX_JDK) if needed
+# Replace each line so it starts with a number (sed 's/...'\1 &/), sort on the leading number, then remove the leading number.
+# Grab the last path name printed.
 _VERSION_SORT := sed 's/[^0-9]*\([0-9.]*\)/\1 &/' $(_VERSION_MAX) | sort -n | sed 's/^[0-9.]* //g' | tail -1
 
 ifeq ($(OS),Darwin)
