Skip to content

Commit

Permalink
Windows VS2017+: Enable AOT tooling to find correct linker path.
Browse files Browse the repository at this point in the history
    AOT tooling cannot find the correct linker path for Windows platforms
    using VS2017+.  This patch is a backport of an existing proposed
    solution found here:

    https://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2019-January/032282.html
    https://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2019-February/032652.html

    With adjustments to make it applicable to the OpenJDK11 code base.  In
    addition, a default path prefix is used in the event the expected
    environment variables are not found, which can be possible depending on
    the method of invocation (JTREG for example).
  • Loading branch information
sci-aws committed Feb 12, 2019
1 parent 4a5652e commit efadde1
Showing 1 changed file with 60 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -27,6 +27,10 @@
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Stream;

final class Linker {
Expand All @@ -44,9 +48,12 @@ String libFile() {
return libraryFileName;
}

private static Stream<String> getLines(InputStream stream) {
return new BufferedReader(new InputStreamReader(stream)).lines();
}

private static String getString(InputStream stream) {
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
Stream<String> lines = br.lines();
Stream<String> lines = getLines(stream);
StringBuilder sb = new StringBuilder();
lines.iterator().forEachRemaining(e -> sb.append(e));
return sb.toString();
Expand Down Expand Up @@ -147,9 +154,6 @@ void link() throws Exception {

}

/**
* Visual Studio supported versions Search Order is: VS2013, VS2015, VS2012
*/
public enum VSVERSIONS {
VS2013("VS120COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\link.exe"),
VS2015("VS140COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe"),
Expand All @@ -172,10 +176,59 @@ String WellKnownPath() {
}
}

private static Path getVC141AndNewerLinker() throws Exception {
String programFilesX86 = System.getenv("ProgramFiles(x86)");
if (programFilesX86 == null) {
// A reasonable platform default if the environment variable isn't found
programFilesX86 = "C:\\Program Files (x86)";
}
Path vswhere = Paths.get(programFilesX86 + "\\Microsoft Visual Studio\\Installer\\vswhere.exe");
if (!Files.exists(vswhere)) {
return null;
}

ProcessBuilder processBuilder = new ProcessBuilder(vswhere.toString(), "-requires",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "-property", "installationPath", "-latest");
processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE);
processBuilder.redirectError(ProcessBuilder.Redirect.PIPE);
Process process = processBuilder.start();
final int exitCode = process.waitFor();
if (exitCode != 0) {
String errorMessage = getString(process.getErrorStream());
if (errorMessage.isEmpty()) {
errorMessage = getString(process.getInputStream());
}
throw new InternalError(errorMessage);
}

String installationPath = getLines(process.getInputStream()).findFirst().orElseThrow(() -> new InternalError("Unexpected empty output from vswhere"));
Path vcToolsVersionFilePath = Paths.get(installationPath, "VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt");
List<String> vcToolsVersionFileLines = Files.readAllLines(vcToolsVersionFilePath);
if (vcToolsVersionFileLines.isEmpty()) {
throw new InternalError(vcToolsVersionFilePath.toString() + " is empty");
}
String vcToolsVersion = vcToolsVersionFileLines.get(0);
Path linkPath = Paths.get(installationPath, "VC\\Tools\\MSVC", vcToolsVersion, "bin\\Hostx64\\x64\\link.exe");
if (!Files.exists(linkPath)) {
throw new InternalError("Linker at path " + linkPath.toString() + " does not exist");
}

return linkPath;
}

/**
* Search for Visual Studio link.exe Search Order is: VS2013, VS2015, VS2012
* Search for Visual Studio link.exe Search Order is: VS2017+, VS2013, VS2015, VS2012
*/
private static String getWindowsLinkPath() {
try {
Path vc141NewerLinker = getVC141AndNewerLinker();
if (vc141NewerLinker != null) {
return vc141NewerLinker.toString();
}
} catch (Exception e) {
e.printStackTrace();
}

String link = "\\VC\\bin\\amd64\\link.exe";

/**
Expand Down

0 comments on commit efadde1

Please sign in to comment.