Skip to content

Commit

Permalink
Fix build with --no-jlinking
Browse files Browse the repository at this point in the history
  • Loading branch information
jerboaa authored and zakkak committed Sep 13, 2023
1 parent eef7b54 commit 588ae3a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 24 deletions.
8 changes: 2 additions & 6 deletions sdk/mx.sdk/mx_sdk_vm_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2220,13 +2220,9 @@ def _get_extra_jvm_args():
extra_jvm_args = mx.list_to_cmd_line(image_config.extra_jvm_args)
if not _jlink_libraries():
if mx.is_windows():
extra_jvm_args = ' '.join([extra_jvm_args, r'--upgrade-module-path "%location%\..\..\jvmci\graal.jar"',
r'--add-modules org.graalvm.polyglot',
r'--module-path "%location%\..\..\truffle\truffle-api.jar:%location%\..\..\jvmci\polyglot.jar"'])
extra_jvm_args = ' '.join([extra_jvm_args, r'--upgrade-module-path "%location%\..\..\jvmci\graal.jar"'])
else:
extra_jvm_args = ' '.join([extra_jvm_args, '--upgrade-module-path "${location}/../../jvmci/graal.jar"',
'--add-modules org.graalvm.polyglot',
'--module-path "${location}/../../truffle/truffle-api.jar:${location}/../../jvmci/polyglot.jar"'])
extra_jvm_args = ' '.join([extra_jvm_args, '--upgrade-module-path "${location}/../../jvmci/graal.jar"'])
return extra_jvm_args

def _get_option_vars():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,10 +561,12 @@ public List<String> getBuilderJavaArgs() {
*/
public List<Path> getBuilderModulePath() {
List<Path> result = new ArrayList<>();
// Non-jlinked JDKs need truffle and graal-sdk on the module path since they
// don't have those modules as part of the JDK.
// Non-jlinked JDKs need truffle and word, collections, nativeimage on the
// module path since they don't have those modules as part of the JDK. Note
// that graal-sdk is now obsolete after the split in GR-43819 (#7171)
if (libJvmciDir != null) {
result.addAll(getJars(libJvmciDir, "graal-sdk", "enterprise-graal"));
result.addAll(getJars(libJvmciDir, "enterprise-graal"));
result.addAll(getJars(libJvmciDir, "word", "collections", "nativeimage"));
}
if (modulePathBuild) {
result.addAll(createTruffleBuilderModulePath());
Expand All @@ -574,19 +576,36 @@ public List<Path> getBuilderModulePath() {
}

private List<Path> createTruffleBuilderModulePath() {
List<Path> jars = getJars(rootDir.resolve(Paths.get("lib", "truffle")), "truffle-api", "truffle-runtime", "truffle-enterprise");
Path libTruffleDir = rootDir.resolve(Paths.get("lib", "truffle"));
List<Path> jars = getJars(libTruffleDir, "truffle-api", "truffle-runtime", "truffle-enterprise");
if (!jars.isEmpty()) {
/*
* If Truffle is installed as part of the JDK we always add the builder modules of
* Truffle to the builder module path. This is legacy support and should in the
* future no longer be needed.
*/
jars.addAll(getJars(rootDir.resolve(Paths.get("lib", "truffle")), "truffle-compiler"));
jars.addAll(getJars(libTruffleDir, "truffle-compiler"));
Path builderPath = rootDir.resolve(Paths.get("lib", "truffle", "builder"));
if (Files.exists(builderPath)) {
jars.addAll(getJars(builderPath, "truffle-runtime-svm", "truffle-enterprise-svm"));
if (libJvmciDir != null) {
// truffle-runtime-svm depends on polyglot, which is not part of non-jlinked
// JDKs
jars.addAll(getJars(libJvmciDir, "polyglot"));
}
}
if (libJvmciDir != null) {
// truffle-runtime depends on polyglot, which is not part of non-jlinked JDKs
jars.addAll(getJars(libTruffleDir, "jniutils"));
}
}
/*
* Non-Jlinked JDKs don't have truffle-compiler as part of the JDK, however the native
* image builder still needs it
*/
if (libJvmciDir != null) {
jars.addAll(getJars(libTruffleDir, "truffle-compiler"));
}

return jars;
}
Expand Down Expand Up @@ -1544,7 +1563,8 @@ protected int buildImage(List<String> javaArgs, LinkedHashSet<Path> cp, LinkedHa
Function<Path, Path> substituteModulePath = useBundle() ? bundleSupport::substituteModulePath : Function.identity();
List<Path> substitutedImageModulePath = imagemp.stream().map(substituteModulePath).toList();

Map<String, Path> modules = listModulesFromPath(javaExecutable, Stream.concat(mp.stream(), imagemp.stream()).distinct().toList());
List<String> mainClassArg = config.getGeneratorMainClass();
Map<String, Path> modules = listModulesFromPath(javaExecutable, javaArgs, mainClassArg, mp.stream().distinct().toList(), imagemp.stream().distinct().toList());
if (!addModules.isEmpty()) {

arguments.add("-D" + ModuleSupport.PROPERTY_IMAGE_EXPLICITLY_ADDED_MODULES + "=" +
Expand All @@ -1564,7 +1584,7 @@ protected int buildImage(List<String> javaArgs, LinkedHashSet<Path> cp, LinkedHa
}
}

arguments.addAll(config.getGeneratorMainClass());
arguments.addAll(mainClassArg);

if (IS_AOT && OS.getCurrent().hasProcFS) {
/*
Expand Down Expand Up @@ -1715,33 +1735,41 @@ protected int buildImage(List<String> javaArgs, LinkedHashSet<Path> cp, LinkedHa
/**
* Resolves and lists all modules given a module path.
*
* @see #callListModules(String, List)
* @see #callListModules(String, List, List, List, List)
*/
private Map<String, Path> listModulesFromPath(String javaExecutable, Collection<Path> modulePath) {
private Map<String, Path> listModulesFromPath(String javaExecutable, List<String> javaArgs, List<String> mainClassArg, List<Path> modulePath, List<Path> imagemp) {
if (modulePath.isEmpty() || !config.modulePathBuild) {
return Map.of();
}
String modulePathEntries = modulePath.stream()
.map(Path::toString)
.collect(Collectors.joining(File.pathSeparator));
return callListModules(javaExecutable, List.of("-p", modulePathEntries));
String imagePathEntries = imagemp.stream()
.map(Path::toString)
.collect(Collectors.joining(File.pathSeparator));
List<String> imagempArgs = List.of("-imagemp", imagePathEntries);
List<String> modulePathArgs = List.of("--module-path", modulePathEntries);
return callListModules(javaExecutable, javaArgs, mainClassArg, imagempArgs, modulePathArgs);
}

/**
* Calls <code>java $arguments --list-modules</code> to list all modules and parse the output.
* The output consists of a map with module name as key and {@link Path} to jar file if the
* module is not installed as part of the JDK. If the module is installed as part of the
* Calls the image generator's <code>--list-modules</code> to list all modules and parses the
* output. The output consists of a map with module name as key and {@link Path} to jar file if
* the module is not installed as part of the JDK. If the module is installed as part of the
* jdk/boot-layer then a <code>null</code> path will be returned.
* <p>
* This is a much more robust solution then trying to parse the JDK file structure manually.
*/
private static Map<String, Path> callListModules(String javaExecutable, List<String> arguments) {
private static Map<String, Path> callListModules(String javaExecutable, List<String> javaArgs, List<String> mainClassArg, List<String> imagempArgs, List<String> modulePathArgs) {
Process listModulesProcess = null;
Map<String, Path> result = new LinkedHashMap<>();
try {
var pb = new ProcessBuilder(javaExecutable);
pb.command().addAll(arguments);
pb.command().add("--list-modules");
pb.command().addAll(javaArgs);
pb.command().addAll(modulePathArgs);
pb.command().addAll(mainClassArg);
pb.command().addAll(imagempArgs);
pb.command().add("-H:+ListModules");
pb.environment().clear();
listModulesProcess = pb.start();

Expand All @@ -1758,8 +1786,10 @@ private static Map<String, Path> callListModules(String javaExecutable, List<Str
String[] splitModuleNameAndVersion = StringUtil.split(splitString[0], "@", 2);
Path externalPath = null;
if (splitString.length > 1) {
String pathURI = splitString[1]; // url: file://path/to/file
externalPath = Path.of(URI.create(pathURI)).toAbsolutePath();
String pathURI = splitString[1].trim(); // url: file://path/to/file
if (pathURI.startsWith("file://")) {
externalPath = Path.of(URI.create(pathURI)).toAbsolutePath();
}
}
result.put(splitModuleNameAndVersion[0], externalPath);
}
Expand Down

0 comments on commit 588ae3a

Please sign in to comment.