From c331f126cd136f2c9b24d0e23376dbb72cee7309 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Sun, 29 Sep 2019 16:09:01 +0200 Subject: [PATCH] Improve using MSVC from within Cygwin (#480) * build: Support toolset=msvc even as Cygwin build. Fixes: https://github.com/boostorg/build/issues/459 * msvc.jam: Avoid segmentation fault if ProgramFiles env is missing. When we run in an 'env -i' session in Cygwin, which may not have the "ProgramFiles(x86)" or "ProgramFiles" environment variables set, we really should not end up in a segmentation fault. * msvc.jam: On Cygwin, query cygpath on missing ProgramFiles env. When we run in an 'env -i' session in Cygwin, which may not have the "ProgramFiles(x86)" or "ProgramFiles" environment variables set, we can try to query cygpath instead. --- src/tools/msvc.jam | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/tools/msvc.jam b/src/tools/msvc.jam index 807674493..9bc51d862 100644 --- a/src/tools/msvc.jam +++ b/src/tools/msvc.jam @@ -1563,8 +1563,25 @@ local rule default-path ( version ) { root = [ os.environ "ProgramFiles" ] ; } - local vswhere = "$(root)\\Microsoft Visual Studio\\Installer\\vswhere.exe" ; - if $(version) in 14.1 14.2 default && [ path.exists $(vswhere) ] + if ( ! $(root) ) && [ os.name ] in CYGWIN + { + # We probably are in an 'env -i' Cygwin session, where the user + # was unable restore the "ProgramFiles(x86)" environment variable, + # because it is an invalid environment variable name in Cygwin. + # However, we can try to query cygpath instead. + root = [ SHELL "cygpath -w -F 42" : strip-eol ] ; # CSIDL_PROGRAM_FILESX86 + if ( ! $(root) ) + { + root = [ SHELL "cygpath -w -F 38" : strip-eol ] ; # CSIDL_PROGRAM_FILES + } + } + # When we are a Cygwin build, [ SHELL ] does execute using "/bin/sh -c". + # When /bin/sh does find a forward slash, no PATH search is performed, + # causing [ SHELL "C:\\...\\Installer/vswhere.exe" ] to succeed. + # And fortunately, forward slashes do also work in native Windows. + local vswhere = "$(root)/Microsoft Visual Studio/Installer/vswhere.exe" ; + # The check for $(root) is to avoid a segmentation fault if not found. + if $(version) in 14.1 14.2 default && $(root) && [ path.exists $(vswhere) ] { local req = "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ; local prop = "-property installationPath" ; @@ -1579,8 +1596,10 @@ local rule default-path ( version ) 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" ] ; + # Quoting the "*" is for when we are a Cygwin build, to bypass /bin/sh. + local vswhere_cmd = "\"$(vswhere)\" -latest -products \"*\" $(req) $(prop) $(limit)" ; + # The split character "\r" is for when we are a Cygwin build. + local shell_ret = [ SPLIT_BY_CHARACTERS [ SHELL $(vswhere_cmd) ] : "\r\n" ] ; pseudo_env_VSCOMNTOOLS = [ path.native [ path.join $(shell_ret) "\\Common7\\Tools" ] ] ; if ! [ path.exists $(pseudo_env_VSCOMNTOOLS) ] {