diff --git a/tools/build/src/engine/config_toolset.bat b/tools/build/src/engine/config_toolset.bat
index b0bdfbb6f5..b0e3baa9e5 100644
--- a/tools/build/src/engine/config_toolset.bat
+++ b/tools/build/src/engine/config_toolset.bat
@@ -184,7 +184,7 @@ set "_known_=1"
 :Skip_VC141
 if NOT "_%BOOST_JAM_TOOLSET%_" == "_borland_" goto Skip_BORLAND
 if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
-    call :Test_Path bcc32.exe )
+    call guess_toolset.bat test_path bcc32.exe )
 if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
     if not errorlevel 1 (
         set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\"
@@ -192,7 +192,7 @@ if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
 if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
     set "PATH=%BOOST_JAM_TOOLSET_ROOT%Bin;%PATH%"
     )
-set "BOOST_JAM_CC=bcc32 -WC -w- -q -I%BOOST_JAM_TOOLSET_ROOT%Include -L%BOOST_JAM_TOOLSET_ROOT%Lib /DNT -nbootstrap"
+set "BOOST_JAM_CC=bcc32 -WC -w- -q -I"%BOOST_JAM_TOOLSET_ROOT%Include" -L"%BOOST_JAM_TOOLSET_ROOT%Lib" -Nd /DNT -nbootstrap"
 set "BOOST_JAM_OPT_JAM=-ejam0"
 set "BOOST_JAM_OPT_MKJAMBASE=-emkjambasejam0"
 set "BOOST_JAM_OPT_YYACC=-eyyacc0"

diff --git a/tools/build/src/engine/vswhere_usability_wrapper.cmd b/tools/build/src/engine/vswhere_usability_wrapper.cmd
index eb7c537bc3..5f68b60730 100644
--- a/tools/build/src/engine/vswhere_usability_wrapper.cmd
+++ b/tools/build/src/engine/vswhere_usability_wrapper.cmd
@@ -1,7 +1,8 @@
 :: Copyright 2017 - Refael Ackermann
+:: Copyright 2019 - Thomas Kent
 :: Distributed under MIT style license
 :: See accompanying file LICENSE at https://github.com/node4good/windows-autoconf
-:: version: 1.15.4
+:: Forked from version: 1.15.4
 
 @if not defined DEBUG_HELPER @ECHO OFF
 setlocal
@@ -14,19 +15,44 @@ where vswhere 2> nul > nul
 if errorlevel 1 goto :no-vswhere
 set VSWHERE_REQ=-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64
 set VSWHERE_PRP=-property installationPath
+
+REM Visual Studio 2017 (15.X, toolset 14.1)
 set VSWHERE_LMT=-version "[15.0,16.0)"
-vswhere -prerelease > nul
-if "%~1"=="prerelase" set VSWHERE_WITH_PRERELASE=1
-if not errorlevel 1 if "%VSWHERE_WITH_PRERELASE%"=="1" set "VSWHERE_LMT=%VSWHERE_LMT% -prerelease"
 SET VSWHERE_ARGS=-latest -products * %VSWHERE_REQ% %VSWHERE_PRP% %VSWHERE_LMT%
 for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do (
     endlocal
+	echo Found with vswhere %%i
     @rem comment out setting VCINSTALLDIR for Boost.build
     @rem set "VCINSTALLDIR=%%i\VC\"
     set "VS150COMNTOOLS=%%i\Common7\Tools\"
     exit /B 0
 )
 
+REM Visual Studio 2019 (16.X, toolset 14.2)
+set VSWHERE_LMT=-version "[16.0,17.0)"
+SET VSWHERE_ARGS=-latest -products * %VSWHERE_REQ% %VSWHERE_PRP% %VSWHERE_LMT%
+for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do (
+    endlocal
+	echo Found with vswhere %%i
+    @rem comment out setting VCINSTALLDIR for Boost.build
+    @rem set "VCINSTALLDIR=%%i\VC\"
+    set "VS160COMNTOOLS=%%i\Common7\Tools\"
+    exit /B 0
+)
+
+REM Visual Studio Next (17.X, toolset 14.3???)
+set VSWHERE_LMT=-version "[17.0,18.0)"
+set VSWHERE_PRERELEASE=-prerelease
+SET VSWHERE_ARGS=-latest -products * %VSWHERE_REQ% %VSWHERE_PRP% %VSWHERE_LMT% %VSWHERE_PRERELEASE%
+for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do (
+    endlocal
+	echo Found with vswhere %%i
+    @rem comment out setting VCINSTALLDIR for Boost.build
+    @rem set "VCINSTALLDIR=%%i\VC\"
+    set "VS170COMNTOOLS=%%i\Common7\Tools\"
+    exit /B 0
+)
+
 :no-vswhere
 endlocal
 echo could not find "vswhere"

diff --git a/tools/build/src/engine/vswhere_usability_wrapper.cmd b/tools/build/src/engine/vswhere_usability_wrapper.cmd
index 5f68b60730..d642a578ef 100644
--- a/tools/build/src/engine/vswhere_usability_wrapper.cmd
+++ b/tools/build/src/engine/vswhere_usability_wrapper.cmd
@@ -40,8 +40,8 @@ for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do (
     exit /B 0
 )
 
-REM Visual Studio Next (17.X, toolset 14.3???)
-set VSWHERE_LMT=-version "[17.0,18.0)"
+REM Visual Studio Unknown Version, Beyond 2019
+set VSWHERE_LMT=-version "[17.0)"
 set VSWHERE_PRERELEASE=-prerelease
 SET VSWHERE_ARGS=-latest -products * %VSWHERE_REQ% %VSWHERE_PRP% %VSWHERE_LMT% %VSWHERE_PRERELEASE%
 for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do (
@@ -49,7 +49,7 @@ for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do (
 	echo Found with vswhere %%i
     @rem comment out setting VCINSTALLDIR for Boost.build
     @rem set "VCINSTALLDIR=%%i\VC\"
-    set "VS170COMNTOOLS=%%i\Common7\Tools\"
+    set "VSUNKCOMNTOOLS=%%i\Common7\Tools\"
     exit /B 0
 )

diff --git a/tools/build/src/engine/build.jam b/tools/build/src/engine/build.jam
index 0a67d14bb9..de567ddb5a 100644
--- a/tools/build/src/engine/build.jam
+++ b/tools/build/src/engine/build.jam
@@ -408,6 +408,13 @@ toolset vc141 cl : /Fe /Fe /Fd /Fo : -D
     [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ]
     -I$(--python-include) -I$(--extra-include)
     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
+## Microsoft Visual C++ 2019
+toolset vc142 cl : /Fe /Fe /Fd /Fo : -D
+    : /nologo
+    [ opt --release : /GL /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ]
+    [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ]
+    -I$(--python-include) -I$(--extra-include)
+    : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
 ## VMS/OpenVMS DEC C
 toolset vmsdecc cc : /OBJECT= : "/DEFINES=(" "," ")"
     : /STANDARD=VAXC /PREFIX_LIBRARY_ENTRIES=(ALL_ENTRIES)

diff --git a/tools/build/src/engine/config_toolset.bat b/tools/build/src/engine/config_toolset.bat
index b0e3baa9e5..9da024e41a 100644
--- a/tools/build/src/engine/config_toolset.bat
+++ b/tools/build/src/engine/config_toolset.bat
@@ -182,6 +182,50 @@ set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
 set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
 set "_known_=1"
 :Skip_VC141
+if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc142_" goto Skip_VC142
+call vswhere_usability_wrapper.cmd
+REM Reset ERRORLEVEL since from now on it's all based on ENV vars
+ver > nul 2> nul
+if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
+    if NOT "_%VS160COMNTOOLS%_" == "__" (
+        set "BOOST_JAM_TOOLSET_ROOT=%VS160COMNTOOLS%..\..\VC\"
+    ))
+
+if "_%BOOST_JAM_ARCH%_" == "__" set BOOST_JAM_ARCH=x86
+set BOOST_JAM_ARGS=%BOOST_JAM_ARGS% %BOOST_JAM_ARCH%
+
+REM return to current directory as vsdevcmd_end.bat switches to %USERPROFILE%\Source if it exists.
+pushd %CD%
+if "_%VSINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%Auxiliary\Build\vcvarsall.bat" %BOOST_JAM_ARGS%
+popd
+set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib"
+set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
+set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
+set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
+set "_known_=1"
+:Skip_VC142
+if NOT "_%BOOST_JAM_TOOLSET%_" == "_vcunk_" goto Skip_VCUNK
+call vswhere_usability_wrapper.cmd
+REM Reset ERRORLEVEL since from now on it's all based on ENV vars
+ver > nul 2> nul
+if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
+    if NOT "_%VSUNKCOMNTOOLS%_" == "__" (
+        set "BOOST_JAM_TOOLSET_ROOT=%VSUNKCOMNTOOLS%..\..\VC\"
+    ))
+
+if "_%BOOST_JAM_ARCH%_" == "__" set BOOST_JAM_ARCH=x86
+set BOOST_JAM_ARGS=%BOOST_JAM_ARGS% %BOOST_JAM_ARCH%
+
+REM return to current directory as vsdevcmd_end.bat switches to %USERPROFILE%\Source if it exists.
+pushd %CD%
+if "_%VSINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%Auxiliary\Build\vcvarsall.bat" %BOOST_JAM_ARGS%
+popd
+set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib"
+set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
+set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
+set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
+set "_known_=1"
+:Skip_VCUNK
 if NOT "_%BOOST_JAM_TOOLSET%_" == "_borland_" goto Skip_BORLAND
 if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
     call guess_toolset.bat test_path bcc32.exe )

diff --git a/tools/build/src/tools/msvc.jam b/tools/build/src/tools/msvc.jam
index e6c0b60358..cbde9eb136 100644
--- a/tools/build/src/tools/msvc.jam
+++ b/tools/build/src/tools/msvc.jam
@@ -21,6 +21,7 @@ http://msdn.microsoft.com/visualc/[Microsoft Visual C++] command-line
 tools on Microsoft Windows. The supported products and versions of
 command line tools are listed below:
 
+* Visual Studio 2019-14.2
 * Visual Studio 2017—14.1
 * Visual Studio 2015—14.0
 * Visual Studio 2013—12.0
@@ -37,7 +38,7 @@ equal to `msvc-[version number]` for example to build with Visual Studio
 2017 one could run:
 
 ----
-.\b2 toolset=msvc-14.1 target
+.\b2 toolset=msvc-14.2 target
 ----
 
 The `msvc` module is initialized using the following syntax:
@@ -1015,7 +1016,15 @@ local rule generate-setup-cmd ( version : command : parent : options * : cpu : g
         }
         else
         {
-            if [ MATCH "(14.1)" : $(version) ]
+            if [ MATCH "(14.2)" : $(version) ]
+            {
+                if $(.debug-configuration)
+                {
+                    ECHO 'notice\: "[generate-setup-cmd]" $(version) is 14.2' ;
+                }
+                parent = [ path.native [ path.join  $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ;
+            }
+            else if [ MATCH "(14.1)" : $(version) ]
             {
                 if $(.debug-configuration)
                 {
@@ -1173,9 +1182,9 @@ local rule configure-really ( version ? : options * )
 
         local command = [ feature.get-values <command> : $(options) ] ;
 
-        # For 14.1 we need the exact version as MS is planning rolling updates
+        # For 14.1+ we need the exact version as MS is planning rolling updates
         # that will cause our `setup-cmd` to become invalid
-        exact-version = [ MATCH "(14\.10\.[0-9\.]+)" : $(command) ] ;
+        exact-version = [ MATCH "(14\.[1-9][0-9]\.[0-9\.]+)" : $(command) ] ;
 
         # If version is specified, we try to search first in default paths, and
         # only then in PATH.
@@ -1204,7 +1213,11 @@ local rule configure-really ( version ? : options * )
             # version from the path.
             # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
             # 9.0express as 9.0 here.
-            if [ MATCH "(MSVC\\14.1)" : $(command) ]
+            if [ MATCH "(MSVC\\14.2)" : $(command) ]
+            {
+                version = 14.2 ;
+            }
+            else if [ MATCH "(MSVC\\14.1)" : $(command) ]
             {
                 version = 14.1 ;
             }
@@ -1533,8 +1546,26 @@ local rule default-path ( version )
     else
     {
         # try to use vswhere
-        local pseudo_env_VS150 ;
-        if $(version) = 14.1 || $(version) = "default"
+        local pseudo_env_VSCOMNTOOLS ;
+        if $(version) = 14.2 || $(version) = "default"
+        {
+            local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ;
+            local prop = "-property installationPath" ;
+            local limit = "-version \"[16.0,17.0)\"" ;
+            local root = [ os.environ "ProgramFiles(x86)" ] ;
+            if ( ! $(root) )
+            {
+                root = [ os.environ "ProgramFiles" ] ;
+            }
+            local vswhere = "$(root)\\Microsoft Visual Studio\\Installer\\vswhere.exe" ;
+            if ( [ path.exists $(vswhere) ] )
+            {
+                local vmwhere_cmd = "\"$(vswhere)\" -latest -products * $(req) $(prop) $(limit)" ;
+                local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vmwhere_cmd) ] : "\n" ] ;
+                pseudo_env_VSCOMNTOOLS = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
+            }
+        }
+        else if $(version) = 14.1
         {
             local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ;
             local prop = "-property installationPath" ;
@@ -1549,7 +1580,7 @@ local rule default-path ( version )
             {
                 local vmwhere_cmd = "\"$(vswhere)\" -latest -products * $(req) $(prop) $(limit)" ;
                 local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vmwhere_cmd) ] : "\n" ] ;
-                pseudo_env_VS150 = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
+                pseudo_env_VSCOMNTOOLS = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
             }
         }
 
@@ -1557,9 +1588,9 @@ local rule default-path ( version )
         for local env in $(.version-$(version)-env)
         {
             local env-path ;
-            if ( $(pseudo_env_VS150) && [ path.exists $(pseudo_env_VS150) ] )
+            if ( $(pseudo_env_VSCOMNTOOLS) && [ path.exists $(pseudo_env_VSCOMNTOOLS) ] )
             {
-                env-path = $(pseudo_env_VS150) ;
+                env-path = $(pseudo_env_VSCOMNTOOLS) ;
             }
             else
             {
@@ -1956,7 +1987,7 @@ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
                      armv7 armv7s ;
 
 # Known toolset versions, in order of preference.
-.known-versions = 14.1 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1
+.known-versions = 14.2 14.1 14.0 12.0 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1
     7.1toolkit 7.0 6.0 ;
 
 # Version aliases.
@@ -1970,6 +2001,7 @@ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
 .version-alias-12 = 12.0 ;
 .version-alias-14 = 14.0 ;
 .version-alias-14.1 = 14.1 ;
+.version-alias-14.2 = 14.2 ;
 
 # Names of registry keys containing the Visual C++ installation path (relative
 # to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
@@ -1999,6 +2031,11 @@ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
     "Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*"
     ;
 .version-14.1-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ;
+.version-14.2-path =
+    "../../VC/Tools/MSVC/*/bin/Host*/*"
+    "Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*"
+    ;
+.version-14.2-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ;
 
 # Auto-detect all the available msvc installations on the system.
 auto-detect-toolset-versions ;

diff --git a/tools/build/src/tools/msvc.jam b/tools/build/src/tools/msvc.jam
index cbde9eb136..185f5f2a1b 100644
--- a/tools/build/src/tools/msvc.jam
+++ b/tools/build/src/tools/msvc.jam
@@ -223,6 +223,7 @@ import project ;
 import property ;
 import property-set ;
 import rc ;
+import sequence ;
 import set ;
 import toolset ;
 import type ;
@@ -1547,55 +1548,46 @@ local rule default-path ( version )
     {
         # try to use vswhere
         local pseudo_env_VSCOMNTOOLS ;
-        if $(version) = 14.2 || $(version) = "default"
+        local all-env-paths ;
+        local root = [ os.environ "ProgramFiles(x86)" ] ;
+        if ( ! $(root) )
         {
-            local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ;
-            local prop = "-property installationPath" ;
-            local limit = "-version \"[16.0,17.0)\"" ;
-            local root = [ os.environ "ProgramFiles(x86)" ] ;
-            if ( ! $(root) )
-            {
-                root = [ os.environ "ProgramFiles" ] ;
-            }
-            local vswhere = "$(root)\\Microsoft Visual Studio\\Installer\\vswhere.exe" ;
-            if ( [ path.exists $(vswhere) ] )
-            {
-                local vmwhere_cmd = "\"$(vswhere)\" -latest -products * $(req) $(prop) $(limit)" ;
-                local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vmwhere_cmd) ] : "\n" ] ;
-                pseudo_env_VSCOMNTOOLS = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
-            }
+            root = [ os.environ "ProgramFiles" ] ;
         }
-        else if $(version) = 14.1
+        local vswhere = "$(root)\\Microsoft Visual Studio\\Installer\\vswhere.exe" ;
+        if $(version) in 14.1 14.2 default && [ path.exists $(vswhere) ]
         {
             local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ;
             local prop = "-property installationPath" ;
-            local limit = "-version \"[15.0,16.0)\"" ;
-            local root = [ os.environ "ProgramFiles(x86)" ] ;
-            if ( ! $(root) )
+            local limit ;
+
+            if $(version) = 14.2 || $(version) = "default"
             {
-                root = [ os.environ "ProgramFiles" ] ;
+                limit = "-version \"[16.0,17.0)\"" ;
             }
-            local vswhere = "$(root)\\Microsoft Visual Studio\\Installer\\vswhere.exe" ;
-            if ( [ path.exists $(vswhere) ] )
+            else if $(version) = 14.1
+            {
+                limit = "-version \"[15.0,16.0)\"" ;
+            }
+
+            local vswhere_cmd = "\"$(vswhere)\" -latest -products * $(req) $(prop) $(limit)" ;
+            local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vswhere_cmd) ] : "\n" ] ;
+            pseudo_env_VSCOMNTOOLS = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
+            if ! [ path.exists $(pseudo_env_VSCOMNTOOLS) ]
             {
-                local vmwhere_cmd = "\"$(vswhere)\" -latest -products * $(req) $(prop) $(limit)" ;
-                local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vmwhere_cmd) ] : "\n" ] ;
-                pseudo_env_VSCOMNTOOLS = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ;
+                return ; # Not found.  If we have vswhere, assume that it works.
             }
+            all-env-paths = $(pseudo_env_VSCOMNTOOLS) ;
+        }
+        else
+        {
+            all-env-paths = [ sequence.transform os.environ
+                : $(.version-$(version)-env) ] ;
         }
 
         # Check environment or previous path_VS150
-        for local env in $(.version-$(version)-env)
+        for local env-path in $(all-env-paths)
         {
-            local env-path ;
-            if ( $(pseudo_env_VSCOMNTOOLS) && [ path.exists $(pseudo_env_VSCOMNTOOLS) ] )
-            {
-                env-path = $(pseudo_env_VSCOMNTOOLS) ;
-            }
-            else
-            {
-                env-path = [ os.environ $(env) ] ;
-            }
             if $(env-path) && $(.version-$(version)-path)
             {
                 for local bin-path in $(.version-$(version)-path)
@@ -2033,9 +2025,9 @@ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
 .version-14.1-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ;
 .version-14.2-path =
     "../../VC/Tools/MSVC/*/bin/Host*/*"
-    "Microsoft Visual Studio/2017/*/VC/Tools/MSVC/*/bin/Host*/*"
+    "Microsoft Visual Studio/2019/*/VC/Tools/MSVC/*/bin/Host*/*"
     ;
-.version-14.2-env = VS150COMNTOOLS ProgramFiles ProgramFiles(x86) ;
+.version-14.2-env = VS160COMNTOOLS ProgramFiles ProgramFiles(x86) ;
 
 # Auto-detect all the available msvc installations on the system.
 auto-detect-toolset-versions ;

From 1691e6194c470e237ddf595bdbd9fb4e0a3320c3 Mon Sep 17 00:00:00 2001
From: Tom Kent <tom@teeks99.com>
Date: Tue, 5 Mar 2019 06:53:19 -0600
Subject: [PATCH 31/37] If the vswhere lookup fails, keep searching for others

---
 src/engine/vswhere_usability_wrapper.cmd | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/build/src/engine/vswhere_usability_wrapper.cmd b/tools/build/src/engine/vswhere_usability_wrapper.cmd
index d642a578ef..6b43e1eab7 100644
--- a/tools/build/src/engine/vswhere_usability_wrapper.cmd
+++ b/tools/build/src/engine/vswhere_usability_wrapper.cmd
@@ -56,4 +56,4 @@ for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do (
 :no-vswhere
 endlocal
 echo could not find "vswhere"
-exit /B 1
\ No newline at end of file
+exit /B 0
\ No newline at end of file

diff --git a/tools/build/src/engine/vswhere_usability_wrapper.cmd b/tools/build/src/engine/vswhere_usability_wrapper.cmd
index 6b43e1eab7..d642a578ef 100644
--- a/tools/build/src/engine/vswhere_usability_wrapper.cmd
+++ b/tools/build/src/engine/vswhere_usability_wrapper.cmd
@@ -56,4 +56,4 @@ for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do (
 :no-vswhere
 endlocal
 echo could not find "vswhere"
-exit /B 0
\ No newline at end of file
+exit /B 1
\ No newline at end of file

diff --git a/tools/build/src/tools/msvc.jam b/tools/build/src/tools/msvc.jam
index 185f5f2a1b..dda22b4c5f 100644
--- a/tools/build/src/tools/msvc.jam
+++ b/tools/build/src/tools/msvc.jam
@@ -1126,12 +1126,15 @@ local rule set-setup-command ( targets * : properties * )
 #
 local rule configure-really ( version ? : options * )
 {
-    local v = $(version) ;
+    local command = [ feature.get-values <command> : $(options) ] ;
 
-    # Decide what the 'default' version is.
-    if ! $(v)
+    if ! $(version) && ! $(command)
     {
+        # We were given neither a command, nor a version.
         # Take the best registered (i.e. auto-detected) version.
+        # FIXME: consider whether an explicitly specified setup script
+        # should disable this logic.  We already won't get here if
+        # there is a user specified command.
         version = [ $(.versions).all ] ;
         for local known in $(.known-versions)
         {
@@ -1141,59 +1144,31 @@ local rule configure-really ( version ? : options * )
                 break ;
             }
         }
+        # version might still have multiple elements if no versions
+        # were auto-detected, but an unknown version was configured
+        # manually.
         version = $(version[1]) ;
-        v = $(version) ;
-
-        # Note: 'version' can still be empty at this point if no versions have
-        # been auto-detected.
-        version ?= "default" ;
     }
 
-    # Version alias -> real version number.
-    version = [ resolve-possible-msvc-version-alias $(version) ] ;
-
-    # Check whether the selected configuration is already in use.
-    if $(version) in [ $(.versions).used ]
+    # Handle a user-provided command, and deduce the version if necessary.
+    # If the user-requested version was not autodetected and no command
+    # was given, attempt to find it in PATH
+    if $(command) || ! ( $(version:E=default) in [ $(.versions).all ] )
     {
-        # Allow multiple 'toolset.using' calls for the same configuration if the
-        # identical sets of options are used.
-        if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
+        local found-command = [ common.get-invocation-command-nodefault msvc : cl.exe : $(command) ] ;
+
+        if $(found-command)
         {
-            import errors ;
-            errors.error "MSVC toolset configuration: Toolset version"
-                "'$(version)' already configured." ;
+            command = $(found-command) ;
+            if ! $(command:D)
+            {
+                local path = [ common.get-absolute-tool-path $(command) ] ;
+                command = $(command:R=$(path)) ;
+            }
         }
-    }
-    else
-    {
-        # Register a new configuration.
-        $(.versions).register $(version) ;
-
-        # Add user-supplied to auto-detected options.
-        options = [ $(.versions).get $(version) : options ] $(options) ;
-
-        # Mark the configuration as 'used'.
-        $(.versions).use $(version) ;
-
-        # Generate conditions and save them.
-        local conditions = [ common.check-init-parameters msvc : version $(v) ]
-            ;
-
-        $(.versions).set $(version) : conditions : $(conditions) ;
-
-        local command = [ feature.get-values <command> : $(options) ] ;
-
-        # For 14.1+ we need the exact version as MS is planning rolling updates
-        # that will cause our `setup-cmd` to become invalid
-        exact-version = [ MATCH "(14\.[1-9][0-9]\.[0-9\.]+)" : $(command) ] ;
-
-        # If version is specified, we try to search first in default paths, and
-        # only then in PATH.
-        command = [ common.get-invocation-command msvc : cl.exe : $(command) :
-            [ default-paths $(version) ] : $(version) ] ;
-
-        if ( ! $(version) || $(version) = "default" ) && ! $(command:D)
+        else
         {
+            # If we still failed to find cl.exe, bail out.
             ECHO ;
             ECHO warning\:
                 "Did not find command for MSVC toolset."
@@ -1204,21 +1179,20 @@ local rule configure-really ( version ? : options * )
                 "build from the 'Visual Studio Command Prompt for VS 2017'."
                 ;
             ECHO ;
+            command ?= cl.exe ;
         }
 
-        common.handle-options msvc : $(conditions) : $(command) : $(options) ;
-
         if ! $(version)
         {
             # Even if version is not explicitly specified, try to detect the
             # version from the path.
             # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
             # 9.0express as 9.0 here.
-            if [ MATCH "(MSVC\\14.2)" : $(command) ]
+            if [ MATCH "(MSVC\\\\14.2)" : $(command) ]
             {
                 version = 14.2 ;
             }
-            else if [ MATCH "(MSVC\\14.1)" : $(command) ]
+            else if [ MATCH "(MSVC\\\\14.1)" : $(command) ]
             {
                 version = 14.1 ;
             }
@@ -1264,6 +1238,44 @@ local rule configure-really ( version ? : options * )
                 version = 6.0 ;
             }
         }
+    }
+
+    # Version alias -> real version number.
+    version = [ resolve-possible-msvc-version-alias $(version) ] ;
+
+    # Check whether the selected configuration is already in use.
+    if $(version) in [ $(.versions).used ]
+    {
+        # Allow multiple 'toolset.using' calls for the same configuration if the
+        # identical sets of options are used.
+        if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
+        {
+            import errors ;
+            errors.user-error "MSVC toolset configuration: Toolset version"
+                "'$(version)' already configured." ;
+        }
+    }
+    else
+    {
+        # Register a new configuration.
+        $(.versions).register $(version) ;
+        $(.versions).set $(version) : options : $(options) ;
+
+        # Mark the configuration as 'used'.
+        $(.versions).use $(version) ;
+
+        # Generate conditions and save them.
+        local conditions = [ common.check-init-parameters msvc : version $(version) ] ;
+
+        $(.versions).set $(version) : conditions : $(conditions) ;
+
+        command ?= [ $(.versions).get $(version) : default-command ] ;
+
+        # For 14.1+ we need the exact version as MS is planning rolling updates
+        # that will cause our `setup-cmd` to become invalid
+        exact-version = [ MATCH "(14\.[1-9][0-9]\.[0-9\.]+)" : $(command) ] ;
+
+        common.handle-options msvc : $(conditions) : $(command) : $(options) ;
 
         # Generate and register setup command.
 
@@ -1458,7 +1470,7 @@ local rule configure-really ( version ? : options * )
             {
                 for local cpu-condition in $(cpu-conditions)
                 {
-                    ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ;
+                    ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c):J= )'" ;
                 }
             }
 
@@ -1536,15 +1548,7 @@ local rule configure-really ( version ? : options * )
 #
 local rule default-path ( version )
 {
-    # Use auto-detected path if possible.
-    local result = [ feature.get-values <command> : [ $(.versions).get $(version)
-        : options ] ] ;
-
-    if $(result)
-    {
-        result = $(result:D) ;
-    }
-    else
+    local result ;
     {
         # try to use vswhere
         local pseudo_env_VSCOMNTOOLS ;
@@ -1611,28 +1615,6 @@ local rule default-path ( version )
 }
 
 
-# Returns either the default installation path (if 'version' is not empty) or
-# list of all known default paths (if no version is given)
-#
-local rule default-paths ( version ? )
-{
-    local possible-paths ;
-
-    if $(version)
-    {
-        possible-paths += [ default-path $(version) ] ;
-    }
-    else
-    {
-        for local i in $(.known-versions)
-        {
-            possible-paths += [ default-path $(i) ] ;
-        }
-    }
-
-    return $(possible-paths) ;
-}
-
 
 rule get-rspline ( target : lang-opt )
 {
@@ -1908,7 +1890,7 @@ local rule register-configuration ( version : path ? )
             }
 
             $(.versions).register $(version) ;
-            $(.versions).set $(version) : options : <command>$(command) ;
+            $(.versions).set $(version) : default-command : $(command) ;
         }
     }
 }
@@ -1992,8 +1974,6 @@ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
 .version-alias-11 = 11.0 ;
 .version-alias-12 = 12.0 ;
 .version-alias-14 = 14.0 ;
-.version-alias-14.1 = 14.1 ;
-.version-alias-14.2 = 14.2 ;
 
 # Names of registry keys containing the Visual C++ installation path (relative
 # to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
