changeset 53110:50677f43ac3d jdk-13+2

8215445: Enable building for Windows in WSL Reviewed-by: ihse Contributed-by: andrewluotechnologies@outlook.com, erik.joelsson@oracle.com
author erikj
date Wed, 02 Jan 2019 12:59:26 +0100
parents b99b41325d89
children 315f53a48199
files doc/building.html doc/building.md make/Images.gmk make/autoconf/basics.m4 make/autoconf/basics_windows.m4 make/autoconf/boot-jdk.m4 make/autoconf/build-aux/config.guess make/autoconf/build-aux/config.sub make/autoconf/compare.sh.in make/autoconf/platform.m4 make/autoconf/spec.gmk.in make/autoconf/toolchain.m4 make/autoconf/toolchain_windows.m4 make/gendata/Gendata-java.base.gmk make/gensrc/GensrcBuffer.gmk make/gensrc/GensrcCharsetCoder.gmk make/gensrc/GensrcVarHandles.gmk make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java make/jdk/src/classes/build/tools/spp/Spp.java make/scripts/windowsShortName.bat make/src/native/fixpath.c
diffstat 21 files changed, 560 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- a/doc/building.html	Tue Jan 01 20:09:02 2019 -0500
+++ b/doc/building.html	Wed Jan 02 12:59:26 2019 +0100
@@ -145,7 +145,7 @@
 <li><p>Do not check out the source code in a path which contains spaces. Chances are the build will not work. This is most likely to be an issue on Windows systems.</p></li>
 <li><p>Do not check out the source code in a path which has a very long name or is nested many levels deep. Chances are you will hit an OS limitation during the build.</p></li>
 <li><p>Put the source code on a local disk, not a network share. If possible, use an SSD. The build process is very disk intensive, and having slow disk access will significantly increase build times. If you need to use a network share for the source code, see below for suggestions on how to keep the build artifacts on a local disk.</p></li>
-<li><p>On Windows, extra care must be taken to make sure the <a href="#cygwin">Cygwin</a> environment is consistent. It is recommended that you follow this procedure:</p>
+<li><p>On Windows, if using <a href="#cygwin">Cygwin</a>, extra care must be taken to make sure the environment is consistent. It is recommended that you follow this procedure:</p>
 <ul>
 <li><p>Create the directory that is going to contain the top directory of the JDK clone by using the <code>mkdir</code> command in the Cygwin bash shell. That is, do <em>not</em> create it using Windows Explorer. This will ensure that it will have proper Cygwin attributes, and that it's children will inherit those attributes.</p></li>
 <li><p>Do not put the JDK clone in a path under your Cygwin home directory. This is especially important if your user name contains spaces and/or mixed upper and lower case letters.</p></li>
@@ -201,12 +201,12 @@
 <h3 id="windows">Windows</h3>
 <p>Windows XP is not a supported platform, but all newer Windows should be able to build the JDK.</p>
 <p>On Windows, it is important that you pay attention to the instructions in the <a href="#special-considerations">Special Considerations</a>.</p>
-<p>Windows is the only non-POSIX OS supported by the JDK, and as such, requires some extra care. A POSIX support layer is required to build on Windows. Currently, the only supported such layer is Cygwin. (Msys is no longer supported due to a too old bash; msys2 and the new Windows Subsystem for Linux (WSL) would likely be possible to support in a future version but that would require effort to implement.)</p>
+<p>Windows is the only non-POSIX OS supported by the JDK, and as such, requires some extra care. A POSIX support layer is required to build on Windows. Currently, the only supported such layers are Cygwin and Windows Subsystem for Linux (WSL). (Msys is no longer supported due to a too old bash; msys2 would likely be possible to support in a future version but that would require effort to implement.)</p>
 <p>Internally in the build system, all paths are represented as Unix-style paths, e.g. <code>/cygdrive/c/hg/jdk9/Makefile</code> rather than <code>C:\hg\jdk9\Makefile</code>. This rule also applies to input to the build system, e.g. in arguments to <code>configure</code>. So, use <code>--with-msvcr-dll=/cygdrive/c/msvcr100.dll</code> rather than <code>--with-msvcr-dll=c:\msvcr100.dll</code>. For details on this conversion, see the section on <a href="#fixpath">Fixpath</a>.</p>
 <h4 id="cygwin">Cygwin</h4>
-<p>A functioning <a href="http://www.cygwin.com/">Cygwin</a> environment is thus required for building the JDK on Windows. If you have a 64-bit OS, we strongly recommend using the 64-bit version of Cygwin.</p>
+<p>A functioning <a href="http://www.cygwin.com/">Cygwin</a> environment is required for building the JDK on Windows. If you have a 64-bit OS, we strongly recommend using the 64-bit version of Cygwin.</p>
 <p><strong>Note:</strong> Cygwin has a model of continuously updating all packages without any easy way to install or revert to a specific version of a package. This means that whenever you add or update a package in Cygwin, you might (inadvertently) update tools that are used by the JDK build process, and that can cause unexpected build problems.</p>
-<p>The JDK requires GNU Make 4.0 or greater on Windows. This is usually not a problem, since Cygwin currently only distributes GNU Make at a version above 4.0.</p>
+<p>The JDK requires GNU Make 4.0 or greater in Cygwin. This is usually not a problem, since Cygwin currently only distributes GNU Make at a version above 4.0.</p>
 <p>Apart from the basic Cygwin installation, the following packages must also be installed:</p>
 <ul>
 <li><code>autoconf</code></li>
@@ -217,6 +217,11 @@
 <p>Often, you can install these packages using the following command line:</p>
 <pre><code>&lt;path to Cygwin setup&gt;/setup-x86_64 -q -P autoconf -P make -P unzip -P zip</code></pre>
 <p>Unfortunately, Cygwin can be unreliable in certain circumstances. If you experience build tool crashes or strange issues when building on Windows, please check the Cygwin FAQ on the <a href="https://cygwin.com/faq/faq.html#faq.using.bloda">&quot;BLODA&quot; list</a> and the section on <a href="https://cygwin.com/faq/faq.html#faq.using.fixing-fork-failures">fork() failures</a>.</p>
+<h4 id="windows-subsystem-for-linux-wsl">Windows Subsystem for Linux (WSL)</h4>
+<p>Windows 10 1809 or newer is supported due to a dependency on the wslpath utility and support for environment variable sharing through WSLENV. Version 1803 can work but intermittent build failures have been observed.</p>
+<p>It's possible to build both Windows and Linux binaries from WSL. To build Windows binaries, you must use a Windows boot JDK (located in a Windows-accessible directory). To build Linux binaries, you must use a Linux boot JDK. The default behavior is to build for Windows. To build for Linux, pass <code>--build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu</code> to <code>configure</code>.</p>
+<p>If building Windows binaries, the source code must be located in a Windows- accessible directory. This is because Windows executables (such as Visual Studio and the boot JDK) must be able to access the source code. Also, the drive where the source is stored must be mounted as case-insensitive by changing either /etc/fstab or /etc/wsl.conf in WSL. Individual directories may be corrected using the fsutil tool in case the source was cloned before changing the mount options.</p>
+<p>Note that while it's possible to build on WSL, testing is still not fully supported.</p>
 <h3 id="solaris">Solaris</h3>
 <p>See <code>make/devkit/solaris11.1-package-list.txt</code> for a list of recommended packages to install when building on Solaris. The versions specified in this list is the versions used by the daily builds at Oracle, and is likely to work properly.</p>
 <p>Older versions of Solaris shipped a broken version of <code>objcopy</code>. At least version 2.21.1 is needed, which is provided by Solaris 11 Update 1. Objcopy is needed if you want to have external debug symbols. Please make sure you are using at least version 2.21.1 of objcopy, or that you disable external debug symbols.</p>
--- a/doc/building.md	Tue Jan 01 20:09:02 2019 -0500
+++ b/doc/building.md	Wed Jan 02 12:59:26 2019 +0100
@@ -75,8 +75,8 @@
     network share for the source code, see below for suggestions on how to keep
     the build artifacts on a local disk.
 
-  * On Windows, extra care must be taken to make sure the [Cygwin](#cygwin)
-    environment is consistent. It is recommended that you follow this
+  * On Windows, if using [Cygwin](#cygwin), extra care must be taken to make sure
+    the environment is consistent. It is recommended that you follow this
     procedure:
 
       * Create the directory that is going to contain the top directory of the
@@ -174,10 +174,10 @@
 
 Windows is the only non-POSIX OS supported by the JDK, and as such, requires
 some extra care. A POSIX support layer is required to build on Windows.
-Currently, the only supported such layer is Cygwin. (Msys is no longer
-supported due to a too old bash; msys2 and the new Windows Subsystem for Linux
-(WSL) would likely be possible to support in a future version but that would
-require effort to implement.)
+Currently, the only supported such layers are Cygwin and Windows Subsystem for
+Linux (WSL). (Msys is no longer supported due to a too old bash; msys2 would
+likely be possible to support in a future version but that would require effort
+to implement.)
 
 Internally in the build system, all paths are represented as Unix-style paths,
 e.g. `/cygdrive/c/hg/jdk9/Makefile` rather than `C:\hg\jdk9\Makefile`. This
@@ -188,7 +188,7 @@
 
 #### Cygwin
 
-A functioning [Cygwin](http://www.cygwin.com/) environment is thus required for
+A functioning [Cygwin](http://www.cygwin.com/) environment is required for
 building the JDK on Windows. If you have a 64-bit OS, we strongly recommend
 using the 64-bit version of Cygwin.
 
@@ -198,7 +198,7 @@
 update tools that are used by the JDK build process, and that can cause
 unexpected build problems.
 
-The JDK requires GNU Make 4.0 or greater on Windows. This is usually not a
+The JDK requires GNU Make 4.0 or greater in Cygwin. This is usually not a
 problem, since Cygwin currently only distributes GNU Make at a version above
 4.0.
 
@@ -221,6 +221,30 @@
 https://cygwin.com/faq/faq.html#faq.using.bloda) and the section on [fork()
 failures](https://cygwin.com/faq/faq.html#faq.using.fixing-fork-failures).
 
+#### Windows Subsystem for Linux (WSL)
+
+Windows 10 1809 or newer is supported due to a dependency on the wslpath utility
+and support for environment variable sharing through WSLENV. Version 1803 can
+work but intermittent build failures have been observed.
+
+It's possible to build both Windows and Linux binaries from WSL. To build
+Windows binaries, you must use a Windows boot JDK (located in a
+Windows-accessible directory). To build Linux binaries, you must use a Linux
+boot JDK. The default behavior is to build for Windows. To build for Linux, pass
+`--build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu` to
+`configure`.
+
+If building Windows binaries, the source code must be located in a Windows-
+accessible directory. This is because Windows executables (such as Visual Studio
+and the boot JDK) must be able to access the source code. Also, the drive where
+the source is stored must be mounted as case-insensitive by changing either
+/etc/fstab or /etc/wsl.conf in WSL. Individual directories may be corrected
+using the fsutil tool in case the source was cloned before changing the mount
+options.
+
+Note that while it's possible to build on WSL, testing is still not fully
+supported.
+
 ### Solaris
 
 See `make/devkit/solaris11.1-package-list.txt` for a list of recommended
--- a/make/Images.gmk	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/Images.gmk	Wed Jan 02 12:59:26 2019 +0100
@@ -99,7 +99,8 @@
 	)
         ifeq ($(BUILD_CDS_ARCHIVE), true)
 	  $(call LogWarn, Creating CDS archive for jdk image)
-	  $(JDK_IMAGE_DIR)/bin/java -Xshare:dump -Xmx128M -Xms128M $(LOG_INFO)
+	  $(FIXPATH) $(JDK_IMAGE_DIR)/bin/java \
+	      -Xshare:dump -Xmx128M -Xms128M $(LOG_INFO)
         endif
 	$(TOUCH) $@
 
@@ -114,7 +115,8 @@
 	)
         ifeq ($(BUILD_CDS_ARCHIVE), true)
 	  $(call LogWarn, Creating CDS archive for jre image)
-	  $(JRE_IMAGE_DIR)/bin/java -Xshare:dump -Xmx128M -Xms128M $(LOG_INFO)
+	  $(FIXPATH) $(JRE_IMAGE_DIR)/bin/java \
+	      -Xshare:dump -Xmx128M -Xms128M $(LOG_INFO)
         endif
 	$(TOUCH) $@
 
--- a/make/autoconf/basics.m4	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/basics.m4	Wed Jan 02 12:59:26 2019 +0100
@@ -223,6 +223,8 @@
       BASIC_FIXUP_PATH_CYGWIN($1)
     elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
       BASIC_FIXUP_PATH_MSYS($1)
+    elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+      BASIC_FIXUP_PATH_WSL($1)
     else
       # We're on a unix platform. Hooray! :)
       path="[$]$1"
@@ -270,6 +272,8 @@
       BASIC_FIXUP_EXECUTABLE_CYGWIN($1)
     elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
       BASIC_FIXUP_EXECUTABLE_MSYS($1)
+    elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+      BASIC_FIXUP_EXECUTABLE_WSL($1)
     else
       # We're on a unix platform. Hooray! :)
       # First separate the path from the arguments. This will split at the first
@@ -607,6 +611,7 @@
 
   # These are not required on all platforms
   BASIC_PATH_PROGS(CYGPATH, cygpath)
+  BASIC_PATH_PROGS(WSLPATH, wslpath)
   BASIC_PATH_PROGS(DF, df)
   BASIC_PATH_PROGS(CPIO, [cpio bsdcpio])
   BASIC_PATH_PROGS(NICE, nice)
@@ -618,6 +623,9 @@
     ENABLE_PANDOC="false"
   fi
   AC_SUBST(ENABLE_PANDOC)
+
+  BASIC_PATH_PROGS(LSB_RELEASE, lsb_release)
+  BASIC_PATH_PROGS(CMD, [cmd.exe /mnt/c/Windows/System32/cmd.exe])
 ])
 
 ###############################################################################
@@ -638,11 +646,14 @@
 
   if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
     PATH_SEP=";"
+    EXE_SUFFIX=".exe"
     BASIC_CHECK_PATHS_WINDOWS
   else
     PATH_SEP=":"
+    EXE_SUFFIX=""
   fi
   AC_SUBST(PATH_SEP)
+  AC_SUBST(EXE_SUFFIX)
 
   # We get the top-level directory from the supporting wrappers.
   AC_MSG_CHECKING([for top-level directory])
@@ -987,6 +998,8 @@
             MAKE_EXPECTED_ENV='cygwin'
           elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
             MAKE_EXPECTED_ENV='msys'
+          elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+            MAKE_EXPECTED_ENV='x86_64-pc-linux-gnu'
           else
             AC_MSG_ERROR([Unknown Windows environment])
           fi
@@ -1274,7 +1287,18 @@
     if $DF $DF_LOCAL_ONLY_OPTION $1 > /dev/null 2>&1; then
       $2
     else
-      $3
+      # In WSL, local Windows drives are considered remote by df, but we are
+      # required to build into a directory accessible from windows, so consider
+      # them local here.
+      if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+        if $DF $1 | $GREP -q "^[[A-Z]]:"; then
+          $2
+        else
+          $3
+        fi
+      else
+        $3
+      fi
     fi
   fi
 ])
--- a/make/autoconf/basics_windows.m4	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/basics_windows.m4	Wed Jan 02 12:59:26 2019 +0100
@@ -32,6 +32,13 @@
   elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
     unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
     $1="$unix_path"
+  elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+    # wslpath does not check the input, only call if an actual windows path was
+    # given.
+    if $ECHO "$windows_path" | $GREP -q ["^[a-zA-Z]:[\\\\/]"]; then
+      unix_path=`$WSLPATH -u "$windows_path"`
+      $1="$unix_path"
+    fi
   fi
 ])
 
@@ -44,6 +51,9 @@
   elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
     windows_path=`cmd //c echo $unix_path`
     $1="$windows_path"
+  elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+    windows_path=`$WSLPATH -m "$unix_path"`
+    $1="$windows_path"
   fi
 ])
 
@@ -100,6 +110,31 @@
   fi
 ])
 
+# Helper function which possibly converts a path using DOS-style short mode.
+# If so, the updated path is stored in $new_path.
+# $1: The path to check
+AC_DEFUN([BASIC_MAKE_WINDOWS_SPACE_SAFE_WSL],
+[
+  input_path="$1"
+  # Check if we need to convert this using DOS-style short mode. If the path
+  # contains just simple characters, use it. Otherwise (spaces, weird characters),
+  # take no chances and rewrite it.
+  # Note: m4 eats our [], so we need to use @<:@ and @:>@ instead.
+  has_forbidden_chars=`$ECHO "$input_path" | $GREP [[^-_/:a-zA-Z0-9\\.]]`
+  if test "x$has_forbidden_chars" != x; then
+    # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+    TOPDIR_windows="$TOPDIR"
+    BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([TOPDIR_windows])
+    # First convert to Windows path to make input valid for cmd
+    BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([input_path])
+    new_path=`$CMD /c $TOPDIR_windows/make/scripts/windowsShortName.bat "$input_path" \
+        | $SED -e 's|\r||g' \
+        | $TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+    # Rewrite back to unix style
+    BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([new_path])
+  fi
+])
+
 # FIXME: The BASIC_FIXUP_*_CYGWIN/MSYS is most likely too convoluted
 # and could probably be heavily simplified. However, all changes in this
 # area tend to need lot of testing in different scenarios, and in lack of
@@ -157,6 +192,23 @@
   all_fixpath_prefixes=("${all_fixpath_prefixes@<:@@@:>@}" "${new_path:0:10}")
 ])
 
+AC_DEFUN([BASIC_FIXUP_PATH_WSL],
+[
+  # Input might be given as Windows format, start by converting to
+  # unix format.
+  new_path="[$]$1"
+  BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([new_path])
+
+  # Call helper function which possibly converts this using DOS-style short mode.
+  # If so, the updated path is stored in $new_path.
+  BASIC_MAKE_WINDOWS_SPACE_SAFE_WSL([$new_path])
+
+  if test "x$path" != "x$new_path"; then
+    $1="$new_path"
+    AC_MSG_NOTICE([Rewriting $1 to "$new_path"])
+  fi
+])
+
 AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN],
 [
   # First separate the path from the arguments. This will split at the first
@@ -305,6 +357,79 @@
   fi
 ])
 
+AC_DEFUN([BASIC_FIXUP_EXECUTABLE_WSL],
+[
+  # First separate the path from the arguments. This will split at the first
+  # space.
+  complete="[$]$1"
+  path="${complete%% *}"
+  tmp="$complete EOL"
+  arguments="${tmp#* }"
+
+  # Input might be given as Windows format, start by converting to
+  # unix format.
+  new_path="$path"
+  BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([new_path])
+
+  # Now try to locate executable using which
+  new_path_bak="$new_path"
+  new_path=`$WHICH "$new_path" 2> /dev/null`
+  # bat and cmd files are not considered executable in WSL
+  if test "x$new_path" = x \
+      && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
+      && test "x`$LS \"$path\" 2>/dev/null`" != x; then
+    new_path="$new_path_back"
+  fi
+  if test "x$new_path" = x; then
+    # Oops. Which didn't find the executable.
+    # The splitting of arguments from the executable at a space might have been incorrect,
+    # since paths with space are more likely in Windows. Give it another try with the whole
+    # argument.
+    path="$complete"
+    arguments="EOL"
+    new_path="$path"
+    BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([new_path])
+    new_path_bak="$new_path"
+    new_path=`$WHICH "$new_path" 2> /dev/null`
+    # bat and cmd files are not considered executable in WSL
+    if test "x$new_path" = x \
+        && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
+        && test "x`$LS \"$path\" 2>/dev/null`" != x; then
+      new_path="$new_path_bak"
+    fi
+    if test "x$new_path" = x; then
+      # It's still not found. Now this is an unrecoverable error.
+      AC_MSG_NOTICE([The path of $1, which resolves as "$complete", is not found.])
+      has_space=`$ECHO "$complete" | $GREP " "`
+      if test "x$has_space" != x; then
+        AC_MSG_NOTICE([You might be mixing spaces in the path and extra arguments, which is not allowed.])
+      fi
+      AC_MSG_ERROR([Cannot locate the the path of $1])
+    fi
+  fi
+
+  # In WSL, suffixes must be present for Windows executables
+  if test ! -f "$new_path"; then
+    # Try adding .exe or .cmd
+    if test -f "${new_path}.exe"; then
+      input_to_shortpath="${new_path}.exe"
+    elif test -f "${new_path}.cmd"; then
+      input_to_shortpath="${new_path}.cmd"
+    else
+      AC_MSG_NOTICE([The path of $1, which resolves as "$new_path", is invalid.])
+      AC_MSG_NOTICE([Neither "$new_path" nor "$new_path.exe/cmd" can be found])
+      AC_MSG_ERROR([Cannot locate the the path of $1])
+    fi
+  else
+    input_to_shortpath="$new_path"
+  fi
+
+  # Call helper function which possibly converts this using DOS-style short mode.
+  # If so, the updated path is stored in $new_path.
+  new_path="$input_to_shortpath"
+  BASIC_MAKE_WINDOWS_SPACE_SAFE_WSL([$input_to_shortpath])
+])
+
 # Setup basic configuration paths, and platform-specific stuff related to PATHs.
 AC_DEFUN([BASIC_CHECK_PATHS_WINDOWS],
 [
@@ -353,8 +478,28 @@
     BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(MSYS_ROOT_PATH)
     AC_MSG_RESULT([$MSYS_ROOT_PATH])
     WINDOWS_ENV_ROOT_PATH="$MSYS_ROOT_PATH"
+  elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+    AC_MSG_CHECKING([Windows version])
+    # m4 replaces [ and ] so we use @<:@ and @:>@ instead
+    WINDOWS_VERSION=`$CMD /c ver.exe | $EGREP -o '(@<:@0-9@:>@+\.)+@<:@0-9@:>@+'`
+    AC_MSG_RESULT([$WINDOWS_VERSION])
+
+    AC_MSG_CHECKING([WSL kernel version])
+    WSL_KERNEL_VERSION=`$UNAME -v`
+    AC_MSG_RESULT([$WSL_KERNEL_VERSION])
+
+    AC_MSG_CHECKING([WSL kernel release])
+    WSL_KERNEL_RELEASE=`$UNAME -r`
+    AC_MSG_RESULT([$WSL_KERNEL_RELEASE])
+
+    AC_MSG_CHECKING([WSL distribution])
+    WSL_DISTRIBUTION=`$LSB_RELEASE -d | sed 's/Description:\t//'`
+    AC_MSG_RESULT([$WSL_DISTRIBUTION])
+
+    WINDOWS_ENV_VENDOR='WSL'
+    WINDOWS_ENV_VERSION="$WSL_DISTRIBUTION $WSL_KERNEL_VERSION $WSL_KERNEL_RELEASE (on Windows build $WINDOWS_VERSION)"
   else
-    AC_MSG_ERROR([Unknown Windows environment. Neither cygwin nor msys was detected.])
+    AC_MSG_ERROR([Unknown Windows environment. Neither cygwin, msys, nor wsl was detected.])
   fi
 
   # Test if windows or unix (cygwin/msys) find is first in path.
@@ -395,6 +540,8 @@
           | tr ' ' '\n' | $GREP '^/./' | $SORT | $UNIQ`
       fixpath_argument_list=`echo $all_unique_prefixes  | tr ' ' '@'`
       FIXPATH="$FIXPATH_BIN -m$fixpath_argument_list"
+    elif test "x$OPENJDK_BUILD_OS_ENV" = xwindows.wsl; then
+      FIXPATH="$FIXPATH_BIN -w"
     fi
     FIXPATH_SRC_W="$FIXPATH_SRC"
     FIXPATH_BIN_W="$FIXPATH_BIN"
@@ -412,6 +559,17 @@
       AC_MSG_ERROR([Could not create $FIXPATH_BIN])
     fi
     AC_MSG_RESULT([yes])
+
+    if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+      OLD_WSLENV="$WSLENV"
+      WSLENV=`$ECHO $WSLENV | $SED 's/PATH\/l://'`
+      BASIC_APPEND_TO_PATH(WSLENV, "FIXPATH_PATH")
+      export WSLENV
+      export FIXPATH_PATH=$VS_PATH_WINDOWS
+      AC_MSG_NOTICE([FIXPATH_PATH is $FIXPATH_PATH])
+      AC_MSG_NOTICE([Rewriting WSLENV from $OLD_WSLENV to $WSLENV])
+    fi
+
     AC_MSG_CHECKING([if fixpath.exe works])
     cd $FIXPATH_DIR
     $FIXPATH $CC $FIXPATH_SRC -Fe$FIXPATH_DIR/fixpath2.exe \
--- a/make/autoconf/boot-jdk.m4	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/boot-jdk.m4	Wed Jan 02 12:59:26 2019 +0100
@@ -63,18 +63,18 @@
     # If previous step claimed to have found a JDK, check it to see if it seems to be valid.
     if test "x$BOOT_JDK_FOUND" = xmaybe; then
       # Do we have a bin/java?
-      if test ! -x "$BOOT_JDK/bin/java"; then
+      if test ! -x "$BOOT_JDK/bin/java$EXE_SUFFIX"; then
         AC_MSG_NOTICE([Potential Boot JDK found at $BOOT_JDK did not contain bin/java; ignoring])
         BOOT_JDK_FOUND=no
       else
         # Do we have a bin/javac?
-        if test ! -x "$BOOT_JDK/bin/javac"; then
+        if test ! -x "$BOOT_JDK/bin/javac$EXE_SUFFIX"; then
           AC_MSG_NOTICE([Potential Boot JDK found at $BOOT_JDK did not contain bin/javac; ignoring])
           AC_MSG_NOTICE([(This might be an JRE instead of an JDK)])
           BOOT_JDK_FOUND=no
         else
           # Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
-          BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $HEAD -n 1`
+          BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java$EXE_SUFFIX" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $HEAD -n 1`
           if [ [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ]; then
             AC_MSG_NOTICE([You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead.])
             AC_MSG_NOTICE([Java reports: "$BOOT_JDK_VERSION".])
@@ -101,7 +101,7 @@
             AC_MSG_CHECKING([for Boot JDK])
             AC_MSG_RESULT([$BOOT_JDK])
             AC_MSG_CHECKING([Boot JDK version])
-            BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' '  '`
+            BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java$EXE_SUFFIX" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' '  '`
             AC_MSG_RESULT([$BOOT_JDK_VERSION])
           fi # end check jdk version
         fi # end check javac
@@ -335,11 +335,11 @@
   AC_SUBST(BOOT_JDK)
 
   # Setup tools from the Boot JDK.
-  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVA, java)
-  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVAC, javac)
-  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVADOC, javadoc)
-  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAR, jar)
-  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JARSIGNER, jarsigner)
+  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVA, java$EXE_SUFFIX)
+  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVAC, javac$EXE_SUFFIX)
+  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVADOC, javadoc$EXE_SUFFIX)
+  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAR, jar$EXE_SUFFIX)
+  BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JARSIGNER, jarsigner$EXE_SUFFIX)
 
   # Finally, set some other options...
 
--- a/make/autoconf/build-aux/config.guess	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/build-aux/config.guess	Wed Jan 02 12:59:26 2019 +0100
@@ -60,6 +60,15 @@
   esac
 fi
 
+# Test and fix wsl
+echo $OUT | grep x86_64-unknown-linux-gnu > /dev/null 2> /dev/null
+if test $? = 0; then
+  uname -r | grep Microsoft > /dev/null 2> /dev/null
+  if test $? = 0; then
+    OUT="x86_64-pc-wsl"
+  fi
+fi
+
 # Test and fix architecture string on AIX
 # On AIX 'config.guess' returns 'powerpc' as architecture but 'powerpc' is
 # implicitely handled as 32-bit architecture in 'platform.m4' so we check
--- a/make/autoconf/build-aux/config.sub	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/build-aux/config.sub	Wed Jan 02 12:59:26 2019 +0100
@@ -29,7 +29,13 @@
 
 DIR=`dirname $0`
 
-# First, filter out everything that doesn't begin with "aarch64-"
+# Allow wsl
+if echo $* | grep x86_64-pc-wsl >/dev/null ; then
+    echo $*
+    exit
+fi
+
+# Filter out everything that doesn't begin with "aarch64-"
 if ! echo $* | grep '^aarch64-' >/dev/null ; then
     . $DIR/autoconf-config.sub "$@"
     # autoconf-config.sub exits, so we never reach here, but just in
--- a/make/autoconf/compare.sh.in	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/compare.sh.in	Wed Jan 02 12:59:26 2019 +0100
@@ -31,6 +31,7 @@
 
 export LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@
 
+export OPENJDK_BUILD_OS_ENV="@OPENJDK_BUILD_OS_ENV@"
 export OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
 export OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@"
 export DEBUG_LEVEL="@DEBUG_LEVEL@"
@@ -73,18 +74,23 @@
 export OUTPUTDIR="@OUTPUTDIR@"
 
 if [ "@COMPILE_TYPE@" != "cross" ]; then
-    export JAVAP="@FIXPATH@ $OUTPUTDIR/jdk/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
-    export JIMAGE="@FIXPATH@ $OUTPUTDIR/jdk/bin/jimage"
+  export JAVAP="@FIXPATH@ $OUTPUTDIR/jdk/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
+  export JIMAGE="@FIXPATH@ $OUTPUTDIR/jdk/bin/jimage"
 elif [ "@CREATE_BUILDJDK@" = "true" ]; then
-    export JAVAP="@FIXPATH@ $OUTPUTDIR/buildjdk/jdk/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
-    export JIMAGE="@FIXPATH@ $OUTPUTDIR/buildjdk/jdk/bin/jimage"
+  export JAVAP="@FIXPATH@ $OUTPUTDIR/buildjdk/jdk/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
+  export JIMAGE="@FIXPATH@ $OUTPUTDIR/buildjdk/jdk/bin/jimage"
 else
-    export JAVAP="@FIXPATH@ @BUILD_JDK@/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
-    export JIMAGE="@FIXPATH@ @BUILD_JDK@/bin/jimage"
+  export JAVAP="@FIXPATH@ @BUILD_JDK@/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
+  export JIMAGE="@FIXPATH@ @BUILD_JDK@/bin/jimage"
 fi
 
 if [ "$OPENJDK_TARGET_OS" = "windows" ]; then
-  export PATH="@VS_PATH@"
+  if [ "$OPENJDK_BUILD_OS_ENV" = "windows.wsl" ]; then
+    export FIXPATH_PATH="@VS_PATH_WINDOWS@"
+    export WSLENV="$WSLENV:FIXPATH_PATH:DEBUG_FIXPATH"
+  else
+    export PATH="@VS_PATH@"
+  fi
 fi
 
 # Now locate the main script and run it.
--- a/make/autoconf/platform.m4	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/platform.m4	Wed Jan 02 12:59:26 2019 +0100
@@ -188,6 +188,10 @@
       VAR_OS=windows
       VAR_OS_ENV=windows.cygwin
       ;;
+    *wsl*)
+      VAR_OS=windows
+      VAR_OS_ENV=windows.wsl
+      ;;
     *mingw*)
       VAR_OS=windows
       VAR_OS_ENV=windows.msys
--- a/make/autoconf/spec.gmk.in	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/spec.gmk.in	Wed Jan 02 12:59:26 2019 +0100
@@ -122,7 +122,12 @@
 ifeq ($(OPENJDK_TARGET_OS), windows)
   # On Windows, the Visual Studio toolchain needs the PATH to be adjusted
   # to include Visual Studio tools (this needs to be in cygwin/msys style).
-  export PATH:=@VS_PATH@
+  ifeq ($(OPENJDK_TARGET_OS_ENV), windows.wsl)
+    export FIXPATH_PATH:=@VS_PATH_WINDOWS@
+    export WSLENV:=$(WSLENV):FIXPATH_PATH:DEBUG_FIXPATH
+  else
+    export PATH:=@VS_PATH@
+  endif
 endif
 
 SYSROOT_CFLAGS := @SYSROOT_CFLAGS@
--- a/make/autoconf/toolchain.m4	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/toolchain.m4	Wed Jan 02 12:59:26 2019 +0100
@@ -180,7 +180,6 @@
     SHARED_LIBRARY='[$]1.dll'
     STATIC_LIBRARY='[$]1.lib'
     OBJ_SUFFIX='.obj'
-    EXE_SUFFIX='.exe'
   else
     LIBRARY_PREFIX=lib
     SHARED_LIBRARY_SUFFIX='.so'
@@ -188,7 +187,6 @@
     SHARED_LIBRARY='lib[$]1.so'
     STATIC_LIBRARY='lib[$]1.a'
     OBJ_SUFFIX='.o'
-    EXE_SUFFIX=''
     if test "x$OPENJDK_TARGET_OS" = xmacosx; then
       # For full static builds, we're overloading the SHARED_LIBRARY
       # variables in order to limit the amount of changes required.
@@ -212,7 +210,6 @@
   AC_SUBST(SHARED_LIBRARY)
   AC_SUBST(STATIC_LIBRARY)
   AC_SUBST(OBJ_SUFFIX)
-  AC_SUBST(EXE_SUFFIX)
 ])
 
 # Determine which toolchain type to use, and make sure it is valid for this
@@ -281,13 +278,13 @@
 
   TOOLCHAIN_CC_BINARY_clang="clang"
   TOOLCHAIN_CC_BINARY_gcc="gcc"
-  TOOLCHAIN_CC_BINARY_microsoft="cl"
+  TOOLCHAIN_CC_BINARY_microsoft="cl$EXE_SUFFIX"
   TOOLCHAIN_CC_BINARY_solstudio="cc"
   TOOLCHAIN_CC_BINARY_xlc="xlc_r"
 
   TOOLCHAIN_CXX_BINARY_clang="clang++"
   TOOLCHAIN_CXX_BINARY_gcc="g++"
-  TOOLCHAIN_CXX_BINARY_microsoft="cl"
+  TOOLCHAIN_CXX_BINARY_microsoft="cl$EXE_SUFFIX"
   TOOLCHAIN_CXX_BINARY_solstudio="CC"
   TOOLCHAIN_CXX_BINARY_xlc="xlC_r"
 
@@ -333,9 +330,17 @@
   if test "x$OPENJDK_BUILD_OS" = "xwindows" \
       && test "x$TOOLCHAIN_TYPE" = "xmicrosoft"; then
     TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV
-    # Reset path to VS_PATH. It will include everything that was on PATH at the time we
-    # ran TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV.
-    PATH="$VS_PATH"
+    if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+      # Append VS_PATH. In WSL, VS_PATH will not contain the WSL env path needed
+      # for using basic Unix tools, so need to keep the original PATH.
+      BASIC_APPEND_TO_PATH(PATH, $VS_PATH)
+      BASIC_APPEND_TO_PATH(WSLENV, "PATH/l:LIB:INCLUDE")
+      export WSLENV
+    else
+      # Reset path to VS_PATH. It will include everything that was on PATH at the time we
+      # ran TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV.
+      PATH="$VS_PATH"
+    fi
     # The microsoft toolchain also requires INCLUDE and LIB to be set.
     export INCLUDE="$VS_INCLUDE"
     export LIB="$VS_LIB"
@@ -430,7 +435,7 @@
     # There is no specific version flag, but all output starts with a version string.
     # First line typically looks something like:
     # Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
-    COMPILER_VERSION_OUTPUT=`$COMPILER 2>&1 | $HEAD -n 1 | $TR -d '\r'`
+    COMPILER_VERSION_OUTPUT=`"$COMPILER" 2>&1 | $GREP -v 'ERROR.*UtilTranslatePathList' | $HEAD -n 1 | $TR -d '\r'`
     # Check that this is likely to be Microsoft CL.EXE.
     $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Microsoft.*Compiler" > /dev/null
     if test $? -ne 0; then
@@ -698,7 +703,7 @@
     # In the Microsoft toolchain we have a separate LD command "link".
     # Make sure we reject /usr/bin/link (as determined in CYGWIN_LINK), which is
     # a cygwin program for something completely different.
-    AC_CHECK_PROG([LD], [link],[link],,, [$CYGWIN_LINK])
+    AC_CHECK_PROG([LD], [link$EXE_SUFFIX],[link$EXE_SUFFIX],,, [$CYGWIN_LINK])
     BASIC_FIXUP_EXECUTABLE(LD)
     # Verify that we indeed succeeded with this trick.
     AC_MSG_CHECKING([if the found link.exe is actually the Visual Studio linker])
@@ -750,7 +755,7 @@
   #
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     # The corresponding ar tool is lib.exe (used to create static libraries)
-    AC_CHECK_PROG([AR], [lib],[lib],,,)
+    AC_CHECK_PROG([AR], [lib$EXE_SUFFIX],[lib$EXE_SUFFIX],,,)
   elif test "x$TOOLCHAIN_TYPE" = xgcc; then
     BASIC_CHECK_TOOLS(AR, ar gcc-ar)
   else
@@ -774,12 +779,12 @@
   fi
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
-    AC_CHECK_PROG([MT], [mt], [mt],,, [/usr/bin/mt])
+    AC_CHECK_PROG([MT], [mt$EXE_SUFFIX], [mt$EXE_SUFFIX],,, [/usr/bin/mt])
     BASIC_FIXUP_EXECUTABLE(MT)
     # Setup the resource compiler (RC)
-    AC_CHECK_PROG([RC], [rc], [rc],,, [/usr/bin/rc])
+    AC_CHECK_PROG([RC], [rc$EXE_SUFFIX], [rc$EXE_SUFFIX],,, [/usr/bin/rc])
     BASIC_FIXUP_EXECUTABLE(RC)
-    AC_CHECK_PROG([DUMPBIN], [dumpbin], [dumpbin],,,)
+    AC_CHECK_PROG([DUMPBIN], [dumpbin$EXE_SUFFIX], [dumpbin$EXE_SUFFIX],,,)
     BASIC_FIXUP_EXECUTABLE(DUMPBIN)
     # We need to check for 'msbuild.exe' because at the place where we expect to
     # find 'msbuild.exe' there's also a directory called 'msbuild' and configure
@@ -788,7 +793,7 @@
     # Notice that we intentionally don't fix up the path to MSBUILD because we
     # will call it in a DOS shell during freetype detection on Windows (see
     # 'LIB_SETUP_FREETYPE' in "libraries.m4"
-    AC_CHECK_PROG([MSBUILD], [msbuild.exe], [msbuild.exe],,,)
+    AC_CHECK_PROG([MSBUILD], [msbuild$EXE_SUFFIX], [msbuild$EXE_SUFFIX],,,)
   fi
 
   if test "x$OPENJDK_TARGET_OS" = xsolaris; then
@@ -999,7 +1004,7 @@
   # Check for extra potential brokenness.
   if test  "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     # On Windows, double-check that we got the right compiler.
-    CC_VERSION_OUTPUT=`$CC 2>&1 | $HEAD -n 1 | $TR -d '\r'`
+    CC_VERSION_OUTPUT=`$CC 2>&1 | $GREP -v 'ERROR.*UtilTranslatePathList' | $HEAD -n 1 | $TR -d '\r'`
     COMPILER_CPU_TEST=`$ECHO $CC_VERSION_OUTPUT | $SED -n "s/^.* \(.*\)$/\1/p"`
     if test "x$OPENJDK_TARGET_CPU" = "xx86"; then
       if test "x$COMPILER_CPU_TEST" != "x80x86" -a "x$COMPILER_CPU_TEST" != "xx86"; then
--- a/make/autoconf/toolchain_windows.m4	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/autoconf/toolchain_windows.m4	Wed Jan 02 12:59:26 2019 +0100
@@ -115,7 +115,7 @@
         VCVARSFILES="vc/bin/vcvars32.bat vc/auxiliary/build/vcvars32.bat"
       else
         VCVARSFILES="vc/bin/amd64/vcvars64.bat vc/bin/x86_amd64/vcvarsx86_amd64.bat \
-            vc/auxiliary/build/vcvarsx86_amd64.bat vc/auxiliary/build/vcvars64.bat"
+            VC/Auxiliary/Build/vcvarsx86_amd64.bat VC/Auxiliary/Build/vcvars64.bat"
       fi
 
       for VCVARSFILE in $VCVARSFILES; do
@@ -222,7 +222,6 @@
       [C:/Program Files/$VS_INSTALL_DIR], [well-known name])
   TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}],
       [C:/Program Files (x86)/$VS_INSTALL_DIR], [well-known name])
-
   if test "x$SDK_INSTALL_DIR" != x; then
     if test "x$ProgramW6432" != x; then
       TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([${VS_VERSION}],
@@ -339,7 +338,7 @@
 [
   # Store path to cygwin link.exe to help excluding it when searching for
   # VS linker. This must be done before changing the PATH when looking for VS.
-  AC_PATH_PROG(CYGWIN_LINK, link)
+  AC_PATH_PROG(CYGWIN_LINK, link.exe)
   if test "x$CYGWIN_LINK" != x; then
     AC_MSG_CHECKING([if the first found link.exe is actually the Cygwin link tool])
     "$CYGWIN_LINK" --version > /dev/null
@@ -372,8 +371,13 @@
       # Instead create a shell script which will set the relevant variables when run.
       WINPATH_VS_ENV_CMD="$VS_ENV_CMD"
       BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([WINPATH_VS_ENV_CMD])
-      WINPATH_BASH="$BASH"
-      BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([WINPATH_BASH])
+
+      if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+        WINPATH_BASH="bash"
+      else
+        WINPATH_BASH="$BASH"
+        BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([WINPATH_BASH])
+      fi
 
       # Generate a DOS batch file which runs $VS_ENV_CMD, and then creates a shell
       # script (executable by bash) that will setup the important variables.
@@ -381,41 +385,65 @@
       $ECHO "@echo off" >  $EXTRACT_VC_ENV_BAT_FILE
       # This will end up something like:
       # call C:/progra~2/micros~2.0/vc/bin/amd64/vcvars64.bat
-      $ECHO "call $WINPATH_VS_ENV_CMD $VS_ENV_ARGS" >> $EXTRACT_VC_ENV_BAT_FILE
+      $ECHO "call \"$WINPATH_VS_ENV_CMD\" $VS_ENV_ARGS" >> $EXTRACT_VC_ENV_BAT_FILE
       # In some cases, the VS_ENV_CMD will change directory, change back so
       # the set-vs-env.sh ends up in the right place.
       $ECHO 'cd %~dp0' >> $EXTRACT_VC_ENV_BAT_FILE
-      # These will end up something like:
-      # C:/CygWin/bin/bash -c 'echo VS_PATH=\"$PATH\" > localdevenv.sh
-      # The trailing space for everyone except PATH is no typo, but is needed due
-      # to trailing \ in the Windows paths. These will be stripped later.
-      $ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' \
-          >> $EXTRACT_VC_ENV_BAT_FILE
-      $ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE\;$include \" >> set-vs-env.sh' \
-          >> $EXTRACT_VC_ENV_BAT_FILE
-      $ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB\;$lib \" >> set-vs-env.sh' \
-          >> $EXTRACT_VC_ENV_BAT_FILE
-      $ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' \
-          >> $EXTRACT_VC_ENV_BAT_FILE
-      $ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' \
-          >> $EXTRACT_VC_ENV_BAT_FILE
-      $ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' \
-          >> $EXTRACT_VC_ENV_BAT_FILE
+      if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+        # These will end up something like:
+        # echo VS_PATH=\"$PATH\" > set-vs-env.sh
+        # The trailing space for everyone except PATH is no typo, but is needed due
+        # to trailing \ in the Windows paths. These will be stripped later.
+        # Trying pure CMD extract. This results in windows paths that need to
+        # be converted post extraction, but a simpler script.
+        $ECHO 'echo VS_PATH="%PATH%" > set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO 'echo VS_INCLUDE="%INCLUDE% " >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO 'echo VS_LIB="%LIB% " >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO 'echo VCINSTALLDIR="%VCINSTALLDIR% " >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO 'echo WindowsSdkDir="%WindowsSdkDir% " >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO 'echo WINDOWSSDKDIR="%WINDOWSSDKDIR% " >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+      else
+        # These will end up something like:
+        # C:/CygWin/bin/bash -c 'echo VS_PATH=\"$PATH\" > localdevenv.sh
+        # The trailing space for everyone except PATH is no typo, but is needed due
+        # to trailing \ in the Windows paths. These will be stripped later.
+        $ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE\;$include \" >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB\;$lib \" >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+        $ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' \
+            >> $EXTRACT_VC_ENV_BAT_FILE
+      fi
 
       # Now execute the newly created bat file.
       # The | cat is to stop SetEnv.Cmd to mess with system colors on msys.
       # Change directory so we don't need to mess with Windows paths in redirects.
       cd $VS_ENV_TMP_DIR
-      cmd /c extract-vs-env.bat | $CAT
+      $CMD /c extract-vs-env.bat | $CAT
       cd $CURDIR
 
       if test ! -s $VS_ENV_TMP_DIR/set-vs-env.sh; then
-        AC_MSG_NOTICE([Could not succesfully extract the envionment variables needed for the VS setup.])
+        AC_MSG_NOTICE([Could not succesfully extract the environment variables needed for the VS setup.])
         AC_MSG_NOTICE([Try setting --with-tools-dir to the VC/bin directory within the VS installation])
         AC_MSG_NOTICE([or run "bash.exe -l" from a VS command prompt and then run configure from there.])
         AC_MSG_ERROR([Cannot continue])
       fi
 
+      # Remove windows line endings
+      $SED -i -e 's|\r||g' $VS_ENV_TMP_DIR/set-vs-env.sh
+
       # Now set all paths and other env variables. This will allow the rest of
       # the configure script to find and run the compiler in the proper way.
       AC_MSG_NOTICE([Setting extracted environment variables])
@@ -455,9 +483,29 @@
       AC_SUBST(VS_INCLUDE)
       AC_SUBST(VS_LIB)
 
-      # Convert VS_INCLUDE into SYSROOT_CFLAGS
       OLDIFS="$IFS"
       IFS=";"
+      if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then
+        # Convert VS_PATH to unix style
+        VS_PATH_WINDOWS="$VS_PATH"
+        VS_PATH=""
+        for i in $VS_PATH_WINDOWS; do
+          path=$i
+          # Only process non-empty elements
+          if test "x$path" != x; then
+            IFS="$OLDIFS"
+            # Check that directory exists before calling fixup_path
+            testpath=$path
+            BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath])
+            if test -d "$testpath"; then
+              BASIC_FIXUP_PATH([path])
+              BASIC_APPEND_TO_PATH(VS_PATH, $path)
+            fi
+            IFS=";"
+          fi
+        done
+      fi
+      # Convert VS_INCLUDE into SYSROOT_CFLAGS
       for i in $VS_INCLUDE; do
         ipath=$i
         # Only process non-empty elements
@@ -490,6 +538,8 @@
         fi
       done
       IFS="$OLDIFS"
+
+      AC_SUBST(VS_PATH_WINDOWS)
     fi
   else
     AC_MSG_RESULT([not found])
@@ -600,10 +650,10 @@
       BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(CYGWIN_VS_TOOLS_DIR)
       if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
         POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \
-	    | $GREP -i /x64/ | $HEAD --lines 1`
+        | $GREP -i /x64/ | $HEAD --lines 1`
       else
         POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \
-	    | $GREP -i /x86/ | $HEAD --lines 1`
+        | $GREP -i /x86/ | $HEAD --lines 1`
       fi
       TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL],
           [search of VS100COMNTOOLS])
@@ -616,14 +666,14 @@
     if test "x$CYGWIN_VC_INSTALL_DIR" != x; then
       if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
         POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \
-	    | $GREP x64 | $HEAD --lines 1`
+        | $GREP x64 | $HEAD --lines 1`
       else
         POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \
-	    | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1`
+        | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1`
         if test "x$POSSIBLE_MSVC_DLL" = x; then
           # We're grasping at straws now...
           POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \
-	      | $HEAD --lines 1`
+          | $HEAD --lines 1`
         fi
       fi
 
@@ -693,7 +743,7 @@
   if test "x$USE_UCRT" = "xtrue"; then
     AC_MSG_CHECKING([for UCRT DLL dir])
     if test "x$with_ucrt_dll_dir" != x; then
-      if test -z "$(ls -d "$with_ucrt_dll_dir/*.dll" 2> /dev/null)"; then
+      if test -z "$(ls -d $with_ucrt_dll_dir/*.dll 2> /dev/null)"; then
         AC_MSG_RESULT([no])
         AC_MSG_ERROR([Could not find any dlls in $with_ucrt_dll_dir])
       else
@@ -713,8 +763,16 @@
       fi
       UCRT_DLL_DIR="$CYGWIN_WINDOWSSDKDIR/Redist/ucrt/DLLs/$dll_subdir"
       if test -z "$(ls -d "$UCRT_DLL_DIR/"*.dll 2> /dev/null)"; then
-        AC_MSG_RESULT([no])
-        AC_MSG_ERROR([Could not find any dlls in $UCRT_DLL_DIR])
+        # Try with version subdir
+        UCRT_DLL_DIR="`ls -d $CYGWIN_WINDOWSSDKDIR/Redist/*/ucrt/DLLs/$dll_subdir \
+            2> /dev/null | $SORT -d | $HEAD -n1`"
+        if test -z "$UCRT_DLL_DIR" \
+            || test -z "$(ls -d "$UCRT_DLL_DIR/"*.dll 2> /dev/null)"; then
+          AC_MSG_RESULT([no])
+          AC_MSG_ERROR([Could not find any dlls in $UCRT_DLL_DIR])
+        else
+          AC_MSG_RESULT($UCRT_DLL_DIR)
+        fi
       else
         AC_MSG_RESULT($UCRT_DLL_DIR)
       fi
--- a/make/gendata/Gendata-java.base.gmk	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/gendata/Gendata-java.base.gmk	Wed Jan 02 12:59:26 2019 +0100
@@ -55,7 +55,7 @@
 $(GENDATA_CURDATA): $(TOPDIR)/make/data/currency/CurrencyData.properties $(BUILD_TOOLS_JDK)
 	$(call MakeDir, $(@D))
 	$(RM) $@
-	$(TOOL_GENERATECURRENCYDATA) -o $@.tmp < $<
+	$(TOOL_GENERATECURRENCYDATA) -o $@.tmp -i $<
 	$(MV) $@.tmp $@
 	$(CHMOD) 444 $@
 
--- a/make/gensrc/GensrcBuffer.gmk	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/gensrc/GensrcBuffer.gmk	Wed Jan 02 12:59:26 2019 +0100
@@ -230,7 +230,8 @@
   endif
 
   $$($1_DST): $$($1_DEP) $(GENSRC_BUFFER_DST)/_the.buffer.dir
-	$(TOOL_SPP) < $$($1_SRC) > $$($1_OUT).tmp \
+	$(RM) $$($1_OUT).tmp
+	$(TOOL_SPP) -i$$($1_SRC) -o$$($1_OUT).tmp \
 	    -K$$($1_type) \
 	    -K$$($1_category) \
 	    -K$$($1_streams) \
@@ -260,12 +261,12 @@
         ifeq ($$($1_BIN), 1)
 	  $(SED) -e '/#BIN/,$$$$d' < $$($1_OUT) > $$($1_DST).tmp
 	  $(RM) $$($1_OUT)
-	  $$($1_char_CMD) < $$($1_SRC_BIN) >> $$($1_DST).tmp
-	  $$($1_short_CMD) < $$($1_SRC_BIN) >> $$($1_DST).tmp
-	  $$($1_int_CMD) < $$($1_SRC_BIN) >> $$($1_DST).tmp
-	  $$($1_long_CMD) < $$($1_SRC_BIN) >> $$($1_DST).tmp
-	  $$($1_float_CMD) < $$($1_SRC_BIN) >> $$($1_DST).tmp
-	  $$($1_double_CMD) < $$($1_SRC_BIN) >> $$($1_DST).tmp
+	  $$($1_char_CMD) -i$$($1_SRC_BIN) -o$$($1_DST).tmp
+	  $$($1_short_CMD) -i$$($1_SRC_BIN) -o$$($1_DST).tmp
+	  $$($1_int_CMD) -i$$($1_SRC_BIN) -o$$($1_DST).tmp
+	  $$($1_long_CMD) -i$$($1_SRC_BIN) -o$$($1_DST).tmp
+	  $$($1_float_CMD) -i$$($1_SRC_BIN) -o$$($1_DST).tmp
+	  $$($1_double_CMD) -i$$($1_SRC_BIN) -o$$($1_DST).tmp
 	  $(PRINTF) "}\n" >> $$($1_DST).tmp
 	  mv $$($1_DST).tmp $$($1_DST)
         endif
--- a/make/gensrc/GensrcCharsetCoder.gmk	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/gensrc/GensrcCharsetCoder.gmk	Wed Jan 02 12:59:26 2019 +0100
@@ -36,7 +36,7 @@
 $(GENSRC_CHARSETCODER_DST)/CharsetDecoder.java: $(GENSRC_CHARSETCODER_TEMPLATE)
 	$(call MakeTargetDir)
 	$(RM) $@.tmp
-	$(TOOL_SPP) < $< >$@.tmp \
+	$(TOOL_SPP) -i$< -o$@.tmp \
 	    -Kdecoder \
 	    -DA='A' \
 	    -Da='a' \
@@ -71,7 +71,7 @@
 $(GENSRC_CHARSETCODER_DST)/CharsetEncoder.java: $(GENSRC_CHARSETCODER_TEMPLATE)
 	$(call MakeTargetDir)
 	$(RM) $@.tmp
-	$(TOOL_SPP) < $< >$@.tmp \
+	$(TOOL_SPP) -i$< -o$@.tmp \
 	    -Kencoder \
 	    -DA='An' \
 	    -Da='an' \
--- a/make/gensrc/GensrcVarHandles.gmk	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/gensrc/GensrcVarHandles.gmk	Wed Jan 02 12:59:26 2019 +0100
@@ -59,8 +59,9 @@
 	  $$(eval $1_type := $$$$(shell $(TR) '[:upper:]' '[:lower:]' <<< $$$$($1_Type)))
         endif
 	$$(call MakeDir, $$(@D))
+	$(RM) $$@
 	$(TOOL_SPP) -nel -K$$($1_type) -Dtype=$$($1_type) -DType=$$($1_Type) \
-	    $$($1_ARGS) < $$< > $$@
+	    $$($1_ARGS) -i$$< -o$$@
 
   GENSRC_VARHANDLES += $$($1_FILENAME)
 endef
@@ -147,10 +148,11 @@
 
   $$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandleByteArrayView.java.template $(BUILD_TOOLS_JDK)
 	$$(call MakeDir, $$(@D))
+	$(RM) $$@
 	$(TOOL_SPP) -nel -K$$($1_type) \
 	    -Dtype=$$($1_type) -DType=$$($1_Type) -DBoxType=$$($1_BoxType) \
 	    -DrawType=$$($1_rawType) -DRawType=$$($1_RawType) -DRawBoxType=$$($1_RawBoxType) \
-	    $$($1_ARGS) < $$< > $$@
+	    $$($1_ARGS) -i$$< -o$$@
 
   GENSRC_VARHANDLES += $$($1_FILENAME)
 endef
--- a/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java	Wed Jan 02 12:59:26 2019 +0100
@@ -28,7 +28,9 @@
 import java.io.IOException;
 import java.io.FileNotFoundException;
 import java.io.DataOutputStream;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.InputStream;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
@@ -134,18 +136,43 @@
     private static String currenciesWithMinorUnitsUndefined;
 
     public static void main(String[] args) {
-
+        InputStream in = System.in;
         // Look for "-o outputfilename" option
-        if ( args.length == 2 && args[0].equals("-o") ) {
-            try {
-                out = new DataOutputStream(new FileOutputStream(args[1]));
-            } catch ( FileNotFoundException e ) {
-                System.err.println("Error: " + e.getMessage());
-                e.printStackTrace(System.err);
+        for (int n = 0; n < args.length; ++n) {
+            if (args[n].equals("-o")) {
+                ++n;
+                if (n >= args.length) {
+                    System.err.println("Error: Invalid argument format");
+                    System.exit(1);
+                }
+                try {
+                    out = new DataOutputStream(new FileOutputStream(args[n]));
+                } catch ( FileNotFoundException e ) {
+                    System.err.println("Error: " + e.getMessage());
+                    e.printStackTrace(System.err);
+                    System.exit(1);
+                }
+            } else if (args[n].equals("-i")) {
+                ++n;
+                if (n >= args.length) {
+                    System.err.println("Error: Invalid argument format");
+                    System.exit(1);
+                }
+                try {
+                    in = new FileInputStream(args[n]);
+                } catch ( FileNotFoundException e ) {
+                    System.err.println("Error: " + e.getMessage());
+                    e.printStackTrace(System.err);
+                    System.exit(1);
+                }
+            } else {
+                System.err.println("Error: Invalid argument " + args[n]);
                 System.exit(1);
             }
-        } else {
-            System.err.println("Error: Illegal arg count");
+        }
+
+        if (out == null) {
+            System.err.println("Error: Invalid argument format");
             System.exit(1);
         }
 
@@ -154,7 +181,7 @@
         format.setLenient(false);
 
         try {
-            readInput();
+            readInput(in);
             buildMainAndSpecialCaseTables();
             buildOtherTables();
             writeOutput();
@@ -167,9 +194,9 @@
         }
     }
 
-    private static void readInput() throws IOException {
+    private static void readInput(InputStream in) throws IOException {
         currencyData = new Properties();
-        currencyData.load(System.in);
+        currencyData.load(in);
 
         // initialize other lookup strings
         formatVersion = (String) currencyData.get("formatVersion");
--- a/make/jdk/src/classes/build/tools/spp/Spp.java	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/jdk/src/classes/build/tools/spp/Spp.java	Wed Jan 02 12:59:26 2019 +0100
@@ -25,6 +25,8 @@
 
 package build.tools.spp;
 
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.util.*;
 import java.util.regex.*;
 
@@ -69,6 +71,8 @@
         Set<String> keys = new HashSet<>();
         boolean be = false;
         boolean el = true;
+        String inputFile = null;
+        String outputFile = null;
 
         for (String arg:args) {
             if (arg.startsWith("-D")) {
@@ -76,6 +80,10 @@
                 vars.put(arg.substring(2, i),arg.substring(i+1));
             } else if (arg.startsWith("-K")) {
                 keys.add(arg.substring(2));
+            } else if (arg.startsWith("-i")) {
+                inputFile = arg.substring(2);
+            } else if (arg.startsWith("-o")) {
+                outputFile = arg.substring(2);
             } else if ("-be".equals(arg)) {
                 be = true;
             } else if ("-nel".equals(arg)) {
@@ -87,11 +95,11 @@
         }
 
         StringBuffer out = new StringBuffer();
-        new Spp().spp(new Scanner(System.in),
+        new Spp().spp(new Scanner(new FileInputStream(inputFile)),
                       out, "",
                       keys, vars, be, el,
                       false);
-        System.out.print(out.toString());
+        new FileOutputStream(outputFile, true).write(out.toString().getBytes());
     }
 
     static final String LNSEP = System.getProperty("line.separator");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/scripts/windowsShortName.bat	Wed Jan 02 12:59:26 2019 +0100
@@ -0,0 +1,24 @@
+@echo off
+REM
+REM Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+REM or visit www.oracle.com if you need additional information or have any
+REM questions.
+REM
+if '%1' NEQ '' echo %~s1
--- a/make/src/native/fixpath.c	Tue Jan 01 20:09:02 2019 -0500
+++ b/make/src/native/fixpath.c	Wed Jan 02 12:59:26 2019 +0100
@@ -24,6 +24,7 @@
  */
 
 #include <Windows.h>
+#include <stdbool.h>
 #include <io.h>
 #include <stdio.h>
 #include <string.h>
@@ -53,25 +54,16 @@
 }
 
 /*
- * Test if pos points to /cygdrive/_/ where _ can
+ * Test if pos points to /prefix/_/ where _ can
  * be any character.
  */
-int is_cygdrive_here(int pos, char const *in, int len)
+int is_prefix_here(int pos, char const *in, int len, const char* prefix)
 {
-  // Length of /cygdrive/c/ is 12
-  if (pos+12 > len) return 0;
-  if (in[pos+11]=='/' &&
-      in[pos+9]=='/' &&
-      in[pos+8]=='e' &&
-      in[pos+7]=='v' &&
-      in[pos+6]=='i' &&
-      in[pos+5]=='r' &&
-      in[pos+4]=='d' &&
-      in[pos+3]=='g' &&
-      in[pos+2]=='y' &&
-      in[pos+1]=='c' &&
-      in[pos+0]=='/') {
-    return 1;
+  // Length of c/ is 2
+  int prefix_size = strlen(prefix);
+  if (pos+prefix_size+2 > len) return 0;
+  if (in[pos+prefix_size+1]=='/') {
+    return strncmp(in + pos, prefix, prefix_size) == 0;
   }
   return 0;
 }
@@ -93,7 +85,7 @@
   }
 
   for (i = 0, j = 0; i<len;) {
-    if (is_cygdrive_here(i, in, len)) {
+    if (is_prefix_here(i, in, len, "/cygdrive/")) {
       out[j++] = in[i+10];
       out[j++] = ':';
       i+=11;
@@ -196,7 +188,39 @@
   return str;
 }
 
+/*
+ * Replace /mnt/_/ with _:/
+ * Works in place since drive letter is always
+ * shorter than /mnt/
+ */
+char *replace_cygdrive_wsl(char const *in)
+{
+  size_t len = strlen(in);
+  char *out = (char*) malloc(len+1);
+  int i,j;
+
+  if (len < 7) {
+    memmove(out, in, len + 1);
+    return out;
+  }
+
+  for (i = 0, j = 0; i<len;) {
+    if (is_prefix_here(i, in, len, "/mnt/")) {
+      out[j++] = in[i+5];
+      out[j++] = ':';
+      i+=6;
+    } else {
+      out[j] = in[i];
+      i++;
+      j++;
+    }
+  }
+  out[j] = '\0';
+  return out;
+}
+
 char*(*replace_cygdrive)(char const *in) = NULL;
+bool debug_fixpath = false;
 
 char *files_to_delete[1024];
 int num_files_to_delete = 0;
@@ -250,11 +274,11 @@
     append(&buffer, &buflen, &used, block, blocklen);
   }
   buffer[used] = 0;
-  if (getenv("DEBUG_FIXPATH") != NULL) {
+  if (debug_fixpath) {
     fprintf(stderr, "fixpath input from @-file %s: %s\n", &in[1], buffer);
   }
   fixed = replace_cygdrive(buffer);
-  if (getenv("DEBUG_FIXPATH") != NULL) {
+  if (debug_fixpath) {
     fprintf(stderr, "fixpath converted to @-file %s is: %s\n", name, fixed);
   }
   fwrite(fixed, strlen(fixed), 1, atout);
@@ -362,28 +386,36 @@
     DWORD processFlags = 0;
     BOOL processInheritHandles = TRUE;
     BOOL waitForChild = TRUE;
+    char* fixpathPath;
 
-    if (argc<2 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm')) {
-        fprintf(stderr, "Usage: fixpath -c|m<path@path@...> [--detach] /cygdrive/c/WINDOWS/notepad.exe [/cygdrive/c/x/test.txt|@/cygdrive/c/x/atfile]\n");
+    debug_fixpath = (getenv("DEBUG_FIXPATH") != NULL);
+
+    if (argc<2 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm' && argv[1][1] != 'w')) {
+        fprintf(stderr, "Usage: fixpath -c|m|w<path@path@...> [--detach] /cygdrive/c/WINDOWS/notepad.exe [/cygdrive/c/x/test.txt|@/cygdrive/c/x/atfile]\n");
         exit(0);
     }
 
-    if (getenv("DEBUG_FIXPATH") != NULL) {
+    if (debug_fixpath) {
       char const * cmdline = GetCommandLine();
       fprintf(stderr, "fixpath input line >%s<\n", strstr(cmdline, argv[1]));
     }
 
     if (argv[1][1] == 'c' && argv[1][2] == '\0') {
-      if (getenv("DEBUG_FIXPATH") != NULL) {
+      if (debug_fixpath) {
         fprintf(stderr, "fixpath using cygwin mode\n");
       }
       replace_cygdrive = replace_cygdrive_cygwin;
     } else if (argv[1][1] == 'm') {
-      if (getenv("DEBUG_FIXPATH") != NULL) {
+      if (debug_fixpath) {
         fprintf(stderr, "fixpath using msys mode, with path list: %s\n", &argv[1][2]);
       }
       setup_msys_path_list(argv[1]);
       replace_cygdrive = replace_cygdrive_msys;
+    } else if (argv[1][1] == 'w') {
+      if (debug_fixpath) {
+        fprintf(stderr, "fixpath using wsl mode, with path list: %s\n", &argv[1][2]);
+      }
+      replace_cygdrive = replace_cygdrive_wsl;
     } else {
       fprintf(stderr, "fixpath Unknown mode: %s\n", argv[1]);
       exit(-1);
@@ -391,7 +423,7 @@
 
     if (argv[2][0] == '-') {
       if (strcmp(argv[2], "--detach") == 0) {
-        if (getenv("DEBUG_FIXPATH") != NULL) {
+        if (debug_fixpath) {
           fprintf(stderr, "fixpath in detached mode\n");
         }
         processFlags |= DETACHED_PROCESS;
@@ -417,7 +449,7 @@
         var[var_len - 1] = '\0';
         strupr(var);
 
-        if (getenv("DEBUG_FIXPATH") != NULL) {
+        if (debug_fixpath) {
           fprintf(stderr, "fixpath setting var >%s< to >%s<\n", var, val);
         }
 
@@ -480,15 +512,15 @@
     }
     *current = '\0';
 
-    if (getenv("DEBUG_FIXPATH") != NULL) {
+    if (debug_fixpath) {
       fprintf(stderr, "fixpath converted line >%s<\n", line);
     }
 
     if (cmd == argc) {
-       if (getenv("DEBUG_FIXPATH") != NULL) {
-         fprintf(stderr, "fixpath no command provided!\n");
-       }
-       exit(0);
+      if (debug_fixpath) {
+        fprintf(stderr, "fixpath no command provided!\n");
+      }
+      exit(0);
     }
 
     ZeroMemory(&si, sizeof(si));
@@ -498,6 +530,23 @@
     fflush(stderr);
     fflush(stdout);
 
+    fixpathPath = calloc(32767, sizeof(char));
+    rc = GetEnvironmentVariable("FIXPATH_PATH", fixpathPath, 32767);
+    if (rc) {
+      if (debug_fixpath) {
+        fprintf(stderr, "Setting Path to FIXPATH_PATH: %s\n", fixpathPath);
+      }
+      rc = SetEnvironmentVariable("Path", fixpathPath);
+      if (!rc) {
+        // Could not set Path for some reason.  Try to report why.
+        const int msg_len = 80 + strlen(fixpathPath);
+        char * msg = (char *)alloca(msg_len);
+        _snprintf_s(msg, msg_len, _TRUNCATE, "Could not set environment variable [Path=%s]", fixpathPath);
+        report_error(msg);
+        exit(1);
+      }
+    }
+
     rc = CreateProcess(NULL,
                        line,
                        0,
@@ -518,7 +567,7 @@
       WaitForSingleObject(pi.hProcess, INFINITE);
       GetExitCodeProcess(pi.hProcess, &exitCode);
 
-      if (getenv("DEBUG_FIXPATH") != NULL) {
+      if (debug_fixpath) {
         for (i=0; i<num_files_to_delete; ++i) {
           fprintf(stderr, "fixpath Not deleting temporary file %s\n",
                   files_to_delete[i]);
@@ -530,13 +579,13 @@
       }
 
       if (exitCode != 0) {
-        if (getenv("DEBUG_FIXPATH") != NULL) {
+        if (debug_fixpath) {
           fprintf(stderr, "fixpath exit code %d\n",
                   exitCode);
         }
       }
     } else {
-      if (getenv("DEBUG_FIXPATH") != NULL) {
+      if (debug_fixpath) {
         fprintf(stderr, "fixpath Not waiting for child process");
       }
     }