Skip to content

Commit a4af309

Browse files
committed
[GR-52996] Improve VS detection and related error messages.
PullRequest: graal/17427
2 parents d7f4612 + cb73caa commit a4af309

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/WindowsBuildEnvironmentUtil.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
* This utility helps set up a build environment for Windows users automatically.
4141
*/
4242
class WindowsBuildEnvironmentUtil {
43+
private static final String PROGRAM_FILES_x86_ENV_KEY = "ProgramFiles(x86)";
4344
private static final String VCVARSALL = "vcvarsall.bat";
45+
private static final String VSWHERE = "vswhere.exe";
4446
private static final Path VCVARSALL_SUBPATH = Paths.get("VC", "Auxiliary", "Build", VCVARSALL);
4547
// Use another static field for minimum required version because CCompilerInvoker is hosted only
4648
private static final String VISUAL_STUDIO_MINIMUM_REQUIRED_VERSION = CCompilerInvoker.VISUAL_STUDIO_MINIMUM_REQUIRED_VERSION;
@@ -50,17 +52,13 @@ static void propagateEnv(Map<String, String> environment) {
5052
if (isCCompilerOnPath()) {
5153
return; // nothing to do, build environment initialized by user
5254
}
53-
Path vcVarsAllLocation = findVCVarsallWithVSWhere();
54-
if (vcVarsAllLocation == null) {
55-
throw fail(String.format("Failed to find '%s' in a Visual Studio installation.", VCVARSALL));
56-
}
55+
Path vcVarsAllLocation = findVCVarsallWithVSWhereOrFail();
5756
Map<String, String> originalEnv = new HashMap<>();
5857
int numSeenOutputSeparators = 0;
5958
String outputSeparator = "!NEXTCOMMAND!";
6059
try {
6160
// call `set`, then `vcvarsall.bat`, and then `set` again with separators in between
62-
String commandSequence = String.format("cmd.exe /c set && echo %s && \"%s\" x64 && echo %s && set",
63-
outputSeparator, vcVarsAllLocation, outputSeparator);
61+
String commandSequence = "cmd.exe /c set && echo %s && \"%s\" x64 && echo %s && set".formatted(outputSeparator, vcVarsAllLocation, outputSeparator);
6462
Process p = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", commandSequence});
6563
try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
6664
String line;
@@ -90,37 +88,41 @@ static void propagateEnv(Map<String, String> environment) {
9088
}
9189
}
9290

93-
private static Path findVCVarsallWithVSWhere() {
94-
String programFilesX86 = System.getenv("ProgramFiles(x86)");
91+
private static Path findVCVarsallWithVSWhereOrFail() {
92+
String programFilesX86 = System.getenv(PROGRAM_FILES_x86_ENV_KEY);
9593
if (programFilesX86 == null) {
96-
return null;
94+
throw fail("Variable '%s' is not defined in the system environment.".formatted(PROGRAM_FILES_x86_ENV_KEY));
9795
}
9896
/*
9997
* vswhere is included with the installer as of Visual Studio 2017 version 15.2 and later,
10098
* and can be found at the following location: `%ProgramFiles(x86)%\Microsoft Visual
10199
* Studio\Installer\vswhere.exe` (see:
102100
* https://github.com/microsoft/vswhere/blob/2717133/README.md).
103101
*/
104-
Path vsWhereExe = Paths.get(programFilesX86, "Microsoft Visual Studio", "Installer", "vswhere.exe");
102+
Path vsWhereExe = Paths.get(programFilesX86, "Microsoft Visual Studio", "Installer", VSWHERE);
105103
if (!Files.exists(vsWhereExe)) {
106-
return null;
104+
throw fail("Failed to find '%s' for locating Visual Studio installations.".formatted(VSWHERE));
107105
}
108106
try {
109107
Process p = Runtime.getRuntime().exec(new String[]{vsWhereExe.toAbsolutePath().toString(),
110108
"-version", VISUAL_STUDIO_MINIMUM_REQUIRED_VERSION,
109+
"-products", "*", /* https://github.com/microsoft/vswhere/issues/22 */
111110
"-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
112111
"-property", "installationPath"});
113112
try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
114-
Path installationPath = Paths.get(reader.readLine());
115-
Path possibleLocation = installationPath.resolve(VCVARSALL_SUBPATH);
116-
if (isRegularReadableFile(possibleLocation)) {
117-
return possibleLocation;
113+
String installationPathLine = reader.readLine();
114+
if (installationPathLine != null) {
115+
Path installationPath = Paths.get(installationPathLine);
116+
Path possibleLocation = installationPath.resolve(VCVARSALL_SUBPATH);
117+
if (isRegularReadableFile(possibleLocation)) {
118+
return possibleLocation;
119+
}
118120
}
119121
}
120122
} catch (IOException e) {
121-
throw fail("Failed to process vswhere.exe output.", e);
123+
throw fail("Failed to process output of '%s'.".formatted(VSWHERE), e);
122124
}
123-
throw fail("Failed to find suitable version of Visual Studio with vswhere.exe.");
125+
throw fail("Failed to find a suitable version of Visual Studio with '%s'.".formatted(VSWHERE));
124126
}
125127

126128
private static boolean isCCompilerOnPath() {

0 commit comments

Comments
 (0)