From 43929db9eb630b6f62f17f80c37a8e5a8d273e5d Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 26 Jun 2024 12:30:07 +0200 Subject: [PATCH 01/27] Support for --jvm option in Enso launcher --- .../src/main/java/org/enso/runner/Main.java | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/engine/runner/src/main/java/org/enso/runner/Main.java b/engine/runner/src/main/java/org/enso/runner/Main.java index 7e2dd587a1f7..3f31b307aa44 100644 --- a/engine/runner/src/main/java/org/enso/runner/Main.java +++ b/engine/runner/src/main/java/org/enso/runner/Main.java @@ -8,6 +8,7 @@ import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -53,6 +54,7 @@ /** The main CLI entry point class. */ public final class Main { + private static final String JVM_OPTION = "jvm"; private static final String RUN_OPTION = "run"; private static final String INSPECT_OPTION = "inspect"; private static final String DUMP_GRAPHS_OPTION = "dump-graphs"; @@ -127,6 +129,15 @@ private static Options buildOptions() { .longOpt(RUN_OPTION) .desc("Runs a specified Enso file.") .build(); + var jvm = + cliOptionBuilder() + .hasArg(true) + .numberOfArgs(1) + .optionalArg(true) + .argName("jvm") + .longOpt(JVM_OPTION) + .desc("Specifies whether to run JVM mode and optionally selects a JVM to run with.") + .build(); var inspect = cliOptionBuilder() .longOpt(INSPECT_OPTION) @@ -451,6 +462,7 @@ private static Options buildOptions() { options .addOption(help) .addOption(repl) + .addOption(jvm) .addOption(run) .addOption(inspect) .addOption(dumpGraphs) @@ -966,7 +978,7 @@ private URI parseUri(String string) { * * @param args the command line arguments */ - public static void main(String[] args) throws IOException { + public static void main(String[] args) throws Exception { new Main().launch(args); } @@ -1294,9 +1306,67 @@ private void println(String msg) { System.out.println(msg); } - private void launch(String[] args) { + private void launch(String[] args) throws IOException, InterruptedException, URISyntaxException { var options = buildOptions(); var line = preprocessArguments(options, args); + + if (line.hasOption(JVM_OPTION)) { + var jvm = line.getOptionValue(JVM_OPTION); + var current = System.getProperty("java.home"); + if (current == null || !current.equals(jvm)) { + println("Running with JVM: " + current); + println("Requested JVM: " + jvm); + var loc = Main.class.getProtectionDomain().getCodeSource().getLocation(); + println("Location: " + loc); + var commandAndArgs = new ArrayList(); + if (jvm == null) { + commandAndArgs.add("java"); + } else { + commandAndArgs.add(new File(new File(new File(jvm), "bin"), "java").getAbsolutePath()); + } + commandAndArgs.add("--add-opens=java.base/java.nio=ALL-UNNAMED"); + commandAndArgs.add("--module-path"); + var component = new File(loc.toURI().resolve("..")).getAbsoluteFile(); + if (!component.getName().equals("component")) { + component = new File(component, "component"); + } + if (!component.isDirectory()) { + throw new IOException("Cannot find " + component + " directory"); + } + commandAndArgs.add(component.getPath()); + commandAndArgs.add("-m"); + commandAndArgs.add("org.enso.runtime/org.enso.EngineRunnerBootLoader"); + var it = line.iterator(); + while (it.hasNext()) { + var op = it.next(); + if (JVM_OPTION.equals(op.getLongOpt())) { + continue; + } + var longName = op.getLongOpt(); + if (longName != null) { + commandAndArgs.add("--" + longName); + } else { + commandAndArgs.add("-" + op.getOpt()); + } + var values = op.getValuesList(); + if (values != null) { + commandAndArgs.addAll(values); + } + } + commandAndArgs.addAll(line.getArgList()); + var pb = new ProcessBuilder(); + pb.inheritIO(); + pb.command(commandAndArgs); + var p = pb.start(); + var exitCode = p.waitFor(); + if (exitCode == 0) { + throw exitSuccess(); + } else { + throw doExit(exitCode); + } + } + } + launch(options, line); } From 7d31eab7a2831faa7779e4e214d8be2db01f25f9 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 26 Jun 2024 14:03:45 +0200 Subject: [PATCH 02/27] Iterate installed GraalVM runtimes --- .../src/main/java/org/enso/runner/Main.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/engine/runner/src/main/java/org/enso/runner/Main.java b/engine/runner/src/main/java/org/enso/runner/Main.java index 3f31b307aa44..a2426c3cdedf 100644 --- a/engine/runner/src/main/java/org/enso/runner/Main.java +++ b/engine/runner/src/main/java/org/enso/runner/Main.java @@ -1314,12 +1314,23 @@ private void launch(String[] args) throws IOException, InterruptedException, URI var jvm = line.getOptionValue(JVM_OPTION); var current = System.getProperty("java.home"); if (current == null || !current.equals(jvm)) { - println("Running with JVM: " + current); - println("Requested JVM: " + jvm); var loc = Main.class.getProtectionDomain().getCodeSource().getLocation(); - println("Location: " + loc); var commandAndArgs = new ArrayList(); + JVM_FOUND: if (jvm == null) { + var env = new Environment() {}; + var dm = new DistributionManager(env); + var paths = dm.paths(); + var files = paths.runtimes().toFile().listFiles(); + if (files != null) { + for (var d : files) { + var java = new File(new File(d, "bin"), "java").getAbsoluteFile(); + if (java.exists()) { + commandAndArgs.add(java.getPath()); + break JVM_FOUND; + } + } + } commandAndArgs.add("java"); } else { commandAndArgs.add(new File(new File(new File(jvm), "bin"), "java").getAbsolutePath()); From 67f1632b1c20f23686c64770aea3ee6a38bf89c1 Mon Sep 17 00:00:00 2001 From: Dmitry Bushev Date: Wed, 26 Jun 2024 15:53:36 +0100 Subject: [PATCH 03/27] feat: engineDistributionRoot parameter --- build.sbt | 91 +++++++++++++++++++++------------------ project/NativeImage.scala | 1 + 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/build.sbt b/build.sbt index f563a3455610..a789d76d6971 100644 --- a/build.sbt +++ b/build.sbt @@ -2614,49 +2614,52 @@ lazy val `engine-runner` = project assembly := assembly .dependsOn(`runtime-fat-jar` / assembly) .value, - rebuildNativeImage := - NativeImage - .buildNativeImage( - "runner", - staticOnLinux = false, - additionalOptions = Seq( - "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog", - "-H:IncludeResources=.*Main.enso$", - "-H:+AddAllCharsets", - "-H:+IncludeAllLocales", - "-ea", - // useful perf & debug switches: - // "-g", - // "-H:+SourceLevelDebug", - // "-H:-DeleteLocalSymbols", - // you may need to set smallJdk := None to use following flags: - // "--trace-class-initialization=org.enso.syntax2.Parser", - "-Dnic=nic" - ), - mainClass = Some("org.enso.runner.Main"), - initializeAtRuntime = Seq( - "org.jline.nativ.JLineLibrary", - "org.jline.terminal.impl.jna", - "io.methvin.watchservice.jna.CarbonAPI", - "zio.internal.ZScheduler$$anon$4", - "org.enso.runner.Main$", - "sun.awt", - "sun.java2d", - "sun.font", - "java.awt", - "com.sun.imageio", - "com.sun.jna.internal.Cleaner", - "com.sun.jna.Structure$FFIType", - "akka.http" + rebuildNativeImage := Def + .taskDyn { + NativeImage + .buildNativeImage( + "runner", + engineDistributionRoot = engineDistributionRoot.value, + staticOnLinux = false, + additionalOptions = Seq( + "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog", + "-H:IncludeResources=.*Main.enso$", + "-H:+AddAllCharsets", + "-H:+IncludeAllLocales", + "-ea", + // useful perf & debug switches: + // "-g", + // "-H:+SourceLevelDebug", + // "-H:-DeleteLocalSymbols", + // you may need to set smallJdk := None to use following flags: + // "--trace-class-initialization=org.enso.syntax2.Parser", + "-Dnic=nic" + ), + mainClass = Some("org.enso.runner.Main"), + initializeAtRuntime = Seq( + "org.jline.nativ.JLineLibrary", + "org.jline.terminal.impl.jna", + "io.methvin.watchservice.jna.CarbonAPI", + "zio.internal.ZScheduler$$anon$4", + "org.enso.runner.Main$", + "sun.awt", + "sun.java2d", + "sun.font", + "java.awt", + "com.sun.imageio", + "com.sun.jna.internal.Cleaner", + "com.sun.jna.Structure$FFIType", + "akka.http" + ) ) - ) - .dependsOn(NativeImage.additionalCp) - .dependsOn(NativeImage.smallJdk) - .dependsOn(assembly) - .dependsOn( - buildEngineDistribution - ) - .value, + } + .dependsOn(NativeImage.additionalCp) + .dependsOn(NativeImage.smallJdk) + .dependsOn(assembly) + .dependsOn( + buildEngineDistribution + ) + .value, buildNativeImage := NativeImage .incrementalNativeImageBuild( rebuildNativeImage, @@ -3559,6 +3562,10 @@ ThisBuild / buildEngineDistribution := { buildEngineDistribution.result.value } +ThisBuild / engineDistributionRoot := { + engineDistributionRoot.value +} + lazy val buildEngineDistributionNoIndex = taskKey[Unit]("Builds the engine distribution without generating indexes") buildEngineDistributionNoIndex := { diff --git a/project/NativeImage.scala b/project/NativeImage.scala index a04697ebbb33..f2d4d649ceaa 100644 --- a/project/NativeImage.scala +++ b/project/NativeImage.scala @@ -85,6 +85,7 @@ object NativeImage { def buildNativeImage( artifactName: String, staticOnLinux: Boolean, + engineDistributionRoot: File = null, additionalOptions: Seq[String] = Seq.empty, buildMemoryLimitMegabytes: Option[Int] = Some(15608), runtimeThreadStackMegabytes: Option[Int] = Some(2), From e67cc8707d937c50bb386a7eed8b0d02d8f0ec4d Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 26 Jun 2024 19:17:39 +0200 Subject: [PATCH 04/27] Generate NI executable as ./built-distribution/enso-engine-0.0.0-dev-linux-amd64/enso-0.0.0-dev/bin/enso on Linux --- build.sbt | 20 +++++++++++--------- project/NativeImage.scala | 39 ++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/build.sbt b/build.sbt index a789d76d6971..90c898b9ef09 100644 --- a/build.sbt +++ b/build.sbt @@ -2618,9 +2618,9 @@ lazy val `engine-runner` = project .taskDyn { NativeImage .buildNativeImage( - "runner", - engineDistributionRoot = engineDistributionRoot.value, - staticOnLinux = false, + "enso", + targetDir = engineDistributionRoot.value / "bin", + staticOnLinux = false, additionalOptions = Seq( "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog", "-H:IncludeResources=.*Main.enso$", @@ -2660,12 +2660,14 @@ lazy val `engine-runner` = project buildEngineDistribution ) .value, - buildNativeImage := NativeImage - .incrementalNativeImageBuild( - rebuildNativeImage, - "runner" - ) - .value + buildNativeImage := Def.taskDyn { + NativeImage + .incrementalNativeImageBuild( + rebuildNativeImage, + "enso", + targetDir = engineDistributionRoot.value / "bin" + ) + }.value ) .dependsOn(`version-output`) .dependsOn(yaml) diff --git a/project/NativeImage.scala b/project/NativeImage.scala index f2d4d649ceaa..569ce692a661 100644 --- a/project/NativeImage.scala +++ b/project/NativeImage.scala @@ -83,9 +83,9 @@ object NativeImage { * @param verbose whether to print verbose output from the native image. */ def buildNativeImage( - artifactName: String, + name: String, staticOnLinux: Boolean, - engineDistributionRoot: File = null, + targetDir: File = null, additionalOptions: Seq[String] = Seq.empty, buildMemoryLimitMegabytes: Option[Int] = Some(15608), runtimeThreadStackMegabytes: Option[Int] = Some(2), @@ -96,7 +96,8 @@ object NativeImage { includeRuntime: Boolean = true ): Def.Initialize[Task[Unit]] = Def .task { - val log = state.value.log + val log = state.value.log + val targetFile = artifactFile(targetDir, name) def nativeImagePath(prefix: Path)(path: Path): Path = { val base = path.resolve(prefix) @@ -139,7 +140,7 @@ object NativeImage { } if (additionalOptions.contains("--language:java")) { log.warn( - s"Building ${artifactName} image with experimental Espresso support!" + s"Building ${targetFile} image with experimental Espresso support!" ) } @@ -230,7 +231,7 @@ object NativeImage { buildMemoryLimitOptions ++ runtimeMemoryOptions ++ additionalOptions ++ - Seq("-o", artifactName) + Seq("-o", targetFile.toString()) args = mainClass match { case Some(main) => @@ -241,8 +242,8 @@ object NativeImage { Seq("-jar", pathToJAR.toString) } - val targetDir = (Compile / target).value - val argFile = targetDir.toPath.resolve(NATIVE_IMAGE_ARG_FILE) + val td = (Compile / target).value + val argFile = td.toPath.resolve(NATIVE_IMAGE_ARG_FILE) IO.writeLines(argFile.toFile, args, append = false) val pathParts = pathExts ++ Option(System.getenv("PATH")).toSeq @@ -267,7 +268,7 @@ object NativeImage { sb.append(str + System.lineSeparator()) }) log.info( - s"Started building $artifactName native image. The output is captured." + s"Started building $targetFile native image. The output is captured." ) val retCode = process.!(processLogger) if (retCode != 0) { @@ -275,7 +276,7 @@ object NativeImage { println(sb.toString()) throw new RuntimeException("Native Image build failed") } - log.info(s"$artifactName native image build successful.") + log.info(s"$targetFile native image build successful.") } .dependsOn(Compile / compile) @@ -290,14 +291,15 @@ object NativeImage { */ def incrementalNativeImageBuild( actualBuild: TaskKey[Unit], - artifactName: String + name: String, + targetDir: File = null ): Def.Initialize[Task[Unit]] = Def.taskDyn { def rebuild(reason: String) = { streams.value.log.info( s"$reason, forcing a rebuild." ) - val artifact = artifactFile(artifactName) + val artifact = artifactFile(targetDir, name) if (artifact.exists()) { artifact.delete() } @@ -315,7 +317,7 @@ object NativeImage { sourcesDiff: ChangeReport[File] => if (sourcesDiff.modified.nonEmpty) rebuild(s"Native Image is not up to date") - else if (!artifactFile(artifactName).exists()) + else if (!artifactFile(targetDir, name).exists()) rebuild("Native Image does not exist") else Def.task { @@ -329,9 +331,16 @@ object NativeImage { /** [[File]] representing the artifact called `name` built with the Native * Image. */ - def artifactFile(name: String): File = - if (Platform.isWindows) file(name + ".exe") - else file(name) + def artifactFile(targetDir: File, name: String): File = { + val artifactName = + if (Platform.isWindows) name + ".exe" + else name + if (targetDir == null) { + new File(artifactName).getAbsoluteFile() + } else { + new File(targetDir, artifactName) + } + } private val muslBundleUrl = "https://github.com/gradinac/musl-bundle-example/releases/download/" + From 8f18b2f9e26ab2c539af279b171888f77fa96bc4 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 28 Jun 2024 17:24:44 +0200 Subject: [PATCH 05/27] Ignore --jvm when already in the right JVM --- engine/runner/src/main/java/org/enso/runner/Main.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engine/runner/src/main/java/org/enso/runner/Main.java b/engine/runner/src/main/java/org/enso/runner/Main.java index a2426c3cdedf..d587dd312260 100644 --- a/engine/runner/src/main/java/org/enso/runner/Main.java +++ b/engine/runner/src/main/java/org/enso/runner/Main.java @@ -1313,6 +1313,9 @@ private void launch(String[] args) throws IOException, InterruptedException, URI if (line.hasOption(JVM_OPTION)) { var jvm = line.getOptionValue(JVM_OPTION); var current = System.getProperty("java.home"); + if (jvm == null) { + jvm = current; + } if (current == null || !current.equals(jvm)) { var loc = Main.class.getProtectionDomain().getCodeSource().getLocation(); var commandAndArgs = new ArrayList(); From 54bb7d8bdd79f89439cfec7beb295ea6a2da1c03 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 28 Jun 2024 17:25:18 +0200 Subject: [PATCH 06/27] Recognize JAVA_OPTS environment variable and pass it to the JVM --- .../runner/src/main/java/org/enso/runner/Main.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/engine/runner/src/main/java/org/enso/runner/Main.java b/engine/runner/src/main/java/org/enso/runner/Main.java index d587dd312260..1ed72d122b78 100644 --- a/engine/runner/src/main/java/org/enso/runner/Main.java +++ b/engine/runner/src/main/java/org/enso/runner/Main.java @@ -1314,7 +1314,7 @@ private void launch(String[] args) throws IOException, InterruptedException, URI var jvm = line.getOptionValue(JVM_OPTION); var current = System.getProperty("java.home"); if (jvm == null) { - jvm = current; + jvm = current; } if (current == null || !current.equals(jvm)) { var loc = Main.class.getProtectionDomain().getCodeSource().getLocation(); @@ -1338,6 +1338,16 @@ private void launch(String[] args) throws IOException, InterruptedException, URI } else { commandAndArgs.add(new File(new File(new File(jvm), "bin"), "java").getAbsolutePath()); } + var jvmOptions = System.getenv("JAVA_OPTS"); + if (jvmOptions != null) { + for (var op : jvmOptions.split(" ")) { + if (op.isEmpty()) { + continue; + } + commandAndArgs.add(op); + } + } + commandAndArgs.add("--add-opens=java.base/java.nio=ALL-UNNAMED"); commandAndArgs.add("--module-path"); var component = new File(loc.toURI().resolve("..")).getAbsoluteFile(); From ec5151572498b88e90082eab3158297d702355d3 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 28 Jun 2024 19:36:51 +0200 Subject: [PATCH 07/27] Let EditionManager work with any EditionProvider, not just updating one --- .../scala/org/enso/editions/updater/EditionManager.scala | 4 +++- .../org/enso/editions/updater/UpdatingEditionProvider.scala | 6 +----- .../scala/org/enso/editions/provider/EditionProvider.scala | 2 +- .../enso/editions/provider/FileSystemEditionProvider.scala | 4 +++- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/EditionManager.scala b/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/EditionManager.scala index f4fccc1ad5ca..1f63c151c41a 100644 --- a/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/EditionManager.scala +++ b/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/EditionManager.scala @@ -10,7 +10,9 @@ import java.nio.file.Path import scala.util.Try /** A helper class for resolving editions. */ -class EditionManager private (editionProvider: UpdatingEditionProvider) { +class EditionManager private ( + editionProvider: editions.provider.EditionProvider +) { private val editionResolver = EditionResolver(editionProvider) private val engineVersionResolver = editions.EngineVersionResolver(editionProvider) diff --git a/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/UpdatingEditionProvider.scala b/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/UpdatingEditionProvider.scala index e7e9a2856a94..62e33c699314 100644 --- a/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/UpdatingEditionProvider.scala +++ b/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/UpdatingEditionProvider.scala @@ -38,12 +38,8 @@ class UpdatingEditionProvider( case Right(value) => Right(value) } - /** Finds all editions available on the [[searchPaths]]. */ - override def findAvailableEditions(): Seq[String] = - provider.findAvailableEditions() - /** Finds all available editions, performing an update if asked to. */ - def findAvailableEditions(update: Boolean): Seq[String] = { + override def findAvailableEditions(update: Boolean): Seq[String] = { if (update) { updater.updateEditions() } diff --git a/lib/scala/editions/src/main/scala/org/enso/editions/provider/EditionProvider.scala b/lib/scala/editions/src/main/scala/org/enso/editions/provider/EditionProvider.scala index 42ae8a156cac..b307bd96afa0 100644 --- a/lib/scala/editions/src/main/scala/org/enso/editions/provider/EditionProvider.scala +++ b/lib/scala/editions/src/main/scala/org/enso/editions/provider/EditionProvider.scala @@ -15,5 +15,5 @@ trait EditionProvider { ): Either[EditionLoadingError, Editions.Raw.Edition] /** Finds all editions that are currently available. */ - def findAvailableEditions(): Seq[String] + def findAvailableEditions(update: Boolean = false): Seq[String] } diff --git a/lib/scala/editions/src/main/scala/org/enso/editions/provider/FileSystemEditionProvider.scala b/lib/scala/editions/src/main/scala/org/enso/editions/provider/FileSystemEditionProvider.scala index dce23a1a1790..d9d502ec35ee 100644 --- a/lib/scala/editions/src/main/scala/org/enso/editions/provider/FileSystemEditionProvider.scala +++ b/lib/scala/editions/src/main/scala/org/enso/editions/provider/FileSystemEditionProvider.scala @@ -51,7 +51,9 @@ class FileSystemEditionProvider(searchPaths: List[Path]) } /** Finds all editions available on the [[searchPaths]]. */ - override def findAvailableEditions(): Seq[String] = + override def findAvailableEditions( + ignoreUpdateRequest: Boolean + ): Seq[String] = searchPaths.flatMap(findEditionsAt).distinct private def findEditionName(path: Path): Option[String] = From f1ad21b09c481bdb5f6f72d62cf48e4f740ccd45 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 28 Jun 2024 19:44:36 +0200 Subject: [PATCH 08/27] Don't use UpdatingEditionManager in regular execution --- .../enso/languageserver/boot/MainModule.scala | 6 +++- .../enso/runner/DependencyPreinstaller.scala | 3 +- .../editions/updater/EditionManager.scala | 30 ++++++++++++------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/engine/language-server/src/main/scala/org/enso/languageserver/boot/MainModule.scala b/engine/language-server/src/main/scala/org/enso/languageserver/boot/MainModule.scala index cb1b298228ba..441e64614801 100644 --- a/engine/language-server/src/main/scala/org/enso/languageserver/boot/MainModule.scala +++ b/engine/language-server/src/main/scala/org/enso/languageserver/boot/MainModule.scala @@ -158,7 +158,11 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: Level) { val distributionManager = new DistributionManager(environment) val editionProvider = - EditionManager.makeEditionProvider(distributionManager, Some(languageHome)) + EditionManager.makeEditionProvider( + distributionManager, + Some(languageHome), + false + ) val editionResolver = EditionResolver(editionProvider) val editionReferenceResolver = new EditionReferenceResolver( contentRoot.file, diff --git a/engine/runner/src/main/scala/org/enso/runner/DependencyPreinstaller.scala b/engine/runner/src/main/scala/org/enso/runner/DependencyPreinstaller.scala index f99b954afa7a..f42b2c54134d 100644 --- a/engine/runner/src/main/scala/org/enso/runner/DependencyPreinstaller.scala +++ b/engine/runner/src/main/scala/org/enso/runner/DependencyPreinstaller.scala @@ -43,7 +43,8 @@ object DependencyPreinstaller { val editionProvider = EditionManager.makeEditionProvider( distributionManager, - Some(languageHome) + Some(languageHome), + true ) val editionResolver = EditionResolver(editionProvider) val edition = editionResolver diff --git a/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/EditionManager.scala b/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/EditionManager.scala index 1f63c151c41a..ce82bca919e6 100644 --- a/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/EditionManager.scala +++ b/lib/scala/edition-updater/src/main/scala/org/enso/editions/updater/EditionManager.scala @@ -48,18 +48,26 @@ class EditionManager private ( object EditionManager { /** Create an [[EditionProvider]] that can locate editions from the - * distribution and the language home. + * distribution (if updating) and the language home. */ - def makeEditionProvider( + final def makeEditionProvider( distributionManager: DistributionManager, - languageHome: Option[LanguageHome] - ): UpdatingEditionProvider = { - val config = new GlobalConfigurationManager(distributionManager).getConfig - new UpdatingEditionProvider( - getSearchPaths(distributionManager, languageHome), - distributionManager.paths.cachedEditions, - config.editionProviders - ) + languageHome: Option[LanguageHome], + updating: Boolean + ): editions.provider.EditionProvider = { + val config = new GlobalConfigurationManager(distributionManager).getConfig + val searchPaths = getSearchPaths(distributionManager, languageHome) + val cachePath = distributionManager.paths.cachedEditions + if (updating) { + new UpdatingEditionProvider( + searchPaths, + cachePath, + config.editionProviders + ) + } else { + val actualSearchPaths = (searchPaths ++ List(cachePath)).distinct + new editions.provider.FileSystemEditionProvider(actualSearchPaths) + } } /** Get search paths associated with the distribution and language home. */ @@ -79,6 +87,6 @@ object EditionManager { distributionManager: DistributionManager, languageHome: Option[LanguageHome] = None ): EditionManager = new EditionManager( - makeEditionProvider(distributionManager, languageHome) + makeEditionProvider(distributionManager, languageHome, false) ) } From cfedcb6fda87f2c46a3d2266b8d8308f996ad259 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 29 Jun 2024 07:38:41 +0200 Subject: [PATCH 09/27] Derive languageHome from code location --- distribution/bin/enso | 2 +- distribution/bin/enso.bat | 2 +- .../org/enso/interpreter/OptionsHelper.java | 28 +++++++++++++++---- .../enso/interpreter/runtime/EnsoContext.java | 3 +- .../runtimeversionmanager/runner/Runner.scala | 5 +--- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/distribution/bin/enso b/distribution/bin/enso index 3638e0a7721d..81691b368715 100755 --- a/distribution/bin/enso +++ b/distribution/bin/enso @@ -8,5 +8,5 @@ for opt in "$@"; do done JAVA_OPTS="--add-opens=java.base/java.nio=ALL-UNNAMED $JAVA_OPTS" -exec java --module-path $COMP_PATH -Dorg.graalvm.language.enso.home=$COMP_PATH $EXTRA_OPTS $JAVA_OPTS -m org.enso.runtime/org.enso.EngineRunnerBootLoader "$@" +exec java --module-path $COMP_PATH $EXTRA_OPTS $JAVA_OPTS -m org.enso.runtime/org.enso.EngineRunnerBootLoader "$@" exit diff --git a/distribution/bin/enso.bat b/distribution/bin/enso.bat index 5387dd0073a0..65652caaf0e1 100644 --- a/distribution/bin/enso.bat +++ b/distribution/bin/enso.bat @@ -7,5 +7,5 @@ set EXTRA_OPTS=%EXTRA_OPTS% -Dgraal.Dump=Truffle:1 ) ) set JAVA_OPTS=%JAVA_OPTS% --add-opens=java.base/java.nio=ALL-UNNAMED -java --module-path %comp-dir% -Dorg.graalvm.language.enso.home=%comp-dir% -Dpolyglot.compiler.IterativePartialEscape=true %EXTRA_OPTS% %JAVA_OPTS% -m org.enso.runtime/org.enso.EngineRunnerBootLoader %* +java --module-path %comp-dir% -Dpolyglot.compiler.IterativePartialEscape=true %EXTRA_OPTS% %JAVA_OPTS% -m org.enso.runtime/org.enso.EngineRunnerBootLoader %* exit /B %errorlevel% diff --git a/engine/runtime/src/main/java/org/enso/interpreter/OptionsHelper.java b/engine/runtime/src/main/java/org/enso/interpreter/OptionsHelper.java index 0ef341a6ee76..01da0083b1d0 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/OptionsHelper.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/OptionsHelper.java @@ -2,10 +2,14 @@ import com.oracle.truffle.api.TruffleFile; import com.oracle.truffle.api.TruffleLanguage; +import java.io.File; +import java.net.URISyntaxException; import java.util.Optional; import org.enso.polyglot.RuntimeOptions; -public class OptionsHelper { +public final class OptionsHelper { + private OptionsHelper() {} + /** * Gets the location of the project that is the context of the current run. * @@ -22,17 +26,29 @@ public static Optional getProjectRoot(TruffleLanguage.Env env) { } /** - * Gets an optional override for the language home directory. + * Finds location of language home directory. It checks {@link + * RuntimeOptions#LANGUAGE_HOME_OVERRIDE} and uses it. If it is not specified, it derives the + * location from code source location of the JAR file. * *

This is used mostly for the runtime tests, as language home is not normally defined there. */ - public static Optional getLanguageHomeOverride(TruffleLanguage.Env env) { + public static Optional findLanguageHome(TruffleLanguage.Env env) { String option = env.getOptions().get(RuntimeOptions.LANGUAGE_HOME_OVERRIDE_KEY); - if (option.equals("")) { - return Optional.empty(); - } else { + if (!option.equals("")) { return Optional.of(option); } + try { + var cs = OptionsHelper.class.getProtectionDomain().getCodeSource(); + var runtimeJarUri = cs.getLocation().toURI(); + var runtimeJar = new File(runtimeJarUri); + var componentDir = runtimeJar.getParentFile(); + if (componentDir != null && componentDir.isDirectory()) { + return Optional.of(componentDir.getPath()); + } + } catch (IllegalStateException | URISyntaxException ex) { + // cannot derive the location + } + return Optional.empty(); } public static Optional getEditionOverride(TruffleLanguage.Env env) { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java index 0b962b357e75..ff674c43280c 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java @@ -174,8 +174,7 @@ public void initialize() { }, res -> res)); - Optional languageHome = - OptionsHelper.getLanguageHomeOverride(environment).or(() -> Optional.ofNullable(home)); + var languageHome = OptionsHelper.findLanguageHome(environment); var editionOverride = OptionsHelper.getEditionOverride(environment); var resourceManager = new org.enso.distribution.locking.ResourceManager(lockManager); diff --git a/lib/scala/runtime-version-manager/src/main/scala/org/enso/runtimeversionmanager/runner/Runner.scala b/lib/scala/runtime-version-manager/src/main/scala/org/enso/runtimeversionmanager/runner/Runner.scala index 0996182b4b4e..71dc607b3b6c 100644 --- a/lib/scala/runtime-version-manager/src/main/scala/org/enso/runtimeversionmanager/runner/Runner.scala +++ b/lib/scala/runtime-version-manager/src/main/scala/org/enso/runtimeversionmanager/runner/Runner.scala @@ -192,11 +192,8 @@ class Runner( val shouldInvokeViaModulePath = engine.graalRuntimeVersion.isUnchained val componentPath = engine.componentDirPath.toAbsolutePath.normalize - val langHomeOption = Seq( - s"-Dorg.graalvm.language.enso.home=$componentPath" - ) var jvmArguments = - manifestOptions ++ environmentOptions ++ commandLineOptions ++ langHomeOption + manifestOptions ++ environmentOptions ++ commandLineOptions if (shouldInvokeViaModulePath) { jvmArguments = jvmArguments :++ Seq( "--module-path", From 2f3e8325dbda0b7dc0a01bdcd11081dda7255266 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 29 Jun 2024 08:05:26 +0200 Subject: [PATCH 10/27] Search for the parser in component subdirectory --- .../generate-java/java/org/enso/syntax2/Parser.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/rust/parser/generate-java/java/org/enso/syntax2/Parser.java b/lib/rust/parser/generate-java/java/org/enso/syntax2/Parser.java index d2c8a75fef2f..beeafc03cad2 100644 --- a/lib/rust/parser/generate-java/java/org/enso/syntax2/Parser.java +++ b/lib/rust/parser/generate-java/java/org/enso/syntax2/Parser.java @@ -35,7 +35,7 @@ private static void initializeLibraries() { var d = root; File path = null; while (d != null) { - path = new File(d, name); + path = new File(new File(d, "component"), name); if (path.exists()) break; d = d.getParentFile(); } @@ -44,12 +44,13 @@ private static void initializeLibraries() { } System.load(path.getAbsolutePath()); } catch (NullPointerException | IllegalArgumentException | LinkageError e) { - if (!searchFromDirToTop(e, root, "target", "rust", "debug", name)) { - if (!searchFromDirToTop( - e, new File(".").getAbsoluteFile(), "target", "rust", "debug", name)) { - throw new IllegalStateException("Cannot load parser from " + root, e); - } + if (searchFromDirToTop(e, root, "target", "rust", "debug", name)) { + return; + } + if (searchFromDirToTop(e, new File(".").getAbsoluteFile(), "target", "rust", "debug", name)) { + return; } + throw new IllegalStateException("Cannot load parser from " + root, e); } } From 406291e42298401305658322a86da65ca32a4810 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 29 Jun 2024 08:24:22 +0200 Subject: [PATCH 11/27] Setup logging before processing --jvm option --- .../src/main/java/org/enso/runner/Main.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/engine/runner/src/main/java/org/enso/runner/Main.java b/engine/runner/src/main/java/org/enso/runner/Main.java index 1ed72d122b78..5d495fa1bbbf 100644 --- a/engine/runner/src/main/java/org/enso/runner/Main.java +++ b/engine/runner/src/main/java/org/enso/runner/Main.java @@ -520,17 +520,17 @@ private static void printHelp(Options options) { } /** Terminates the process with a failure exit code. */ - private RuntimeException exitFail() { + private static RuntimeException exitFail() { return doExit(1); } /** Terminates the process with a success exit code. */ - private RuntimeException exitSuccess() { + private static RuntimeException exitSuccess() { return doExit(0); } /** Shuts down the logging service and terminates the process. */ - private RuntimeException doExit(int exitCode) { + private static RuntimeException doExit(int exitCode) { RunnerLogging.tearDown(); System.exit(exitCode); return null; @@ -944,7 +944,7 @@ private void displayVersion(boolean useJson) { } /** Parses the log level option. */ - private Level parseLogLevel(String levelOption) { + private static Level parseLogLevel(String levelOption) { var name = levelOption.toLowerCase(); var found = Stream.of(Level.values()).filter(x -> name.equals(x.name().toLowerCase())).findFirst(); @@ -961,7 +961,7 @@ private Level parseLogLevel(String levelOption) { } /** Parses an URI that specifies the logging service connection. */ - private URI parseUri(String string) { + private static URI parseUri(String string) { try { return new URI(string); } catch (URISyntaxException ex) { @@ -1310,6 +1310,9 @@ private void launch(String[] args) throws IOException, InterruptedException, URI var options = buildOptions(); var line = preprocessArguments(options, args); + var logMasking = new boolean[1]; + var logLevel = setupLogging(options, line, logMasking); + if (line.hasOption(JVM_OPTION)) { var jvm = line.getOptionValue(JVM_OPTION); var current = System.getProperty("java.home"); @@ -1391,7 +1394,7 @@ private void launch(String[] args) throws IOException, InterruptedException, URI } } - launch(options, line); + launch(options, line, logLevel, logMasking[0]); } protected CommandLine preprocessArguments(Options options, String[] args) { @@ -1405,15 +1408,18 @@ protected CommandLine preprocessArguments(Options options, String[] args) { } } - protected void launch(Options options, CommandLine line) { + private static Level setupLogging(Options options, CommandLine line, boolean[] logMasking) { var logLevel = scala.Option.apply(line.getOptionValue(LOG_LEVEL)) - .map(this::parseLogLevel) + .map(Main::parseLogLevel) .getOrElse(() -> defaultLogLevel); - var connectionUri = scala.Option.apply(line.getOptionValue(LOGGER_CONNECT)).map(this::parseUri); - var logMasking = !line.hasOption(NO_LOG_MASKING); - RunnerLogging.setup(connectionUri, logLevel, logMasking); + var connectionUri = scala.Option.apply(line.getOptionValue(LOGGER_CONNECT)).map(Main::parseUri); + logMasking[0] = !line.hasOption(NO_LOG_MASKING); + RunnerLogging.setup(connectionUri, logLevel, logMasking[0]); + return logLevel; + } + private void launch(Options options, CommandLine line, Level logLevel, boolean logMasking) { if (line.hasOption(LANGUAGE_SERVER_OPTION)) { runLanguageServer(line, logLevel); } else { From cc48ec3f2379b99176249c69a84d261ee995f3ac Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 29 Jun 2024 08:32:40 +0200 Subject: [PATCH 12/27] Providing missing argument to makeEditionProvider --- .../enso/languageserver/websocket/json/BaseServerTest.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/BaseServerTest.scala b/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/BaseServerTest.scala index 8d6838c5e225..2a88021513fd 100644 --- a/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/BaseServerTest.scala +++ b/engine/language-server/src/test/scala/org/enso/languageserver/websocket/json/BaseServerTest.scala @@ -347,7 +347,8 @@ abstract class BaseServerTest val editionProvider = EditionManager.makeEditionProvider( distributionManager, - Some(languageHome) + Some(languageHome), + true ) val editionResolver = EditionResolver(editionProvider) val editionReferenceResolver = new EditionReferenceResolver( From 9c81fe549a95ad7769bb3f0b50c83f8cf3f4206c Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 29 Jun 2024 09:30:28 +0200 Subject: [PATCH 13/27] Adding update flag to FakeEditionProvider --- .../src/test/scala/org/enso/editions/EditionResolverSpec.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/scala/editions/src/test/scala/org/enso/editions/EditionResolverSpec.scala b/lib/scala/editions/src/test/scala/org/enso/editions/EditionResolverSpec.scala index 210dc84764b3..b0187a3e2416 100644 --- a/lib/scala/editions/src/test/scala/org/enso/editions/EditionResolverSpec.scala +++ b/lib/scala/editions/src/test/scala/org/enso/editions/EditionResolverSpec.scala @@ -54,7 +54,8 @@ class EditionResolverSpec ): Either[EditionLoadingError, Editions.Raw.Edition] = editions.get(name).toRight(EditionNotFound(name)) - override def findAvailableEditions(): Seq[String] = editions.keys.toSeq + override def findAvailableEditions(update: Boolean): Seq[String] = + editions.keys.toSeq } val resolver = EditionResolver(FakeEditionProvider) From eafa192524902b349d207f2af5fe75250254bfcf Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 29 Jun 2024 09:37:14 +0200 Subject: [PATCH 14/27] Change log entry --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af945c5d507a..db72bb350a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,12 @@ [10337]: https://github.com/enso-org/enso/pull/10337 [10340]: https://github.com/enso-org/enso/pull/10340 +#### Enso Language & Runtime + +- Support for [explicit --jvm option][10374] when launching `enso` CLI + +[10374]: https://github.com/enso-org/enso/pull/10374 + #### Enso Standard Library - [Added Statistic.Product][10122] From 5ea0814721a858fe2b8db41e05b781a82746fd15 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 29 Jun 2024 11:05:09 +0200 Subject: [PATCH 15/27] Benchmarks need to be executed in --jvm mode --- build/build/src/enso.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build/src/enso.rs b/build/build/src/enso.rs index 03e66565f83c..9cb59e98dece 100644 --- a/build/build/src/enso.rs +++ b/build/build/src/enso.rs @@ -74,7 +74,7 @@ impl BuiltEnso { pub async fn run_benchmarks(&self, opt: BenchmarkOptions) -> Result { self.cmd()? - .with_args(["--run", self.paths.repo_root.test.benchmarks.as_str()]) + .with_args(["--jvm", "--run", self.paths.repo_root.test.benchmarks.as_str()]) .set_env(ENSO_BENCHMARK_TEST_DRY_RUN, &Boolean::from(opt.dry_run))? .run_ok() .await From 13cb3d402d15fc97df573ac48e657b79cbc86804 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 3 Jul 2024 18:39:19 +0200 Subject: [PATCH 16/27] native-image needs location without .exe on Windows --- project/NativeImage.scala | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/project/NativeImage.scala b/project/NativeImage.scala index 569ce692a661..b45780e2485b 100644 --- a/project/NativeImage.scala +++ b/project/NativeImage.scala @@ -96,8 +96,8 @@ object NativeImage { includeRuntime: Boolean = true ): Def.Initialize[Task[Unit]] = Def .task { - val log = state.value.log - val targetFile = artifactFile(targetDir, name) + val log = state.value.log + val targetLoc = artifactFile(targetDir, name, false) def nativeImagePath(prefix: Path)(path: Path): Path = { val base = path.resolve(prefix) @@ -140,7 +140,7 @@ object NativeImage { } if (additionalOptions.contains("--language:java")) { log.warn( - s"Building ${targetFile} image with experimental Espresso support!" + s"Building ${targetLoc} image with experimental Espresso support!" ) } @@ -231,7 +231,7 @@ object NativeImage { buildMemoryLimitOptions ++ runtimeMemoryOptions ++ additionalOptions ++ - Seq("-o", targetFile.toString()) + Seq("-o", targetLoc.toString()) args = mainClass match { case Some(main) => @@ -268,15 +268,16 @@ object NativeImage { sb.append(str + System.lineSeparator()) }) log.info( - s"Started building $targetFile native image. The output is captured." + s"Started building $targetLoc native image. The output is captured." ) - val retCode = process.!(processLogger) - if (retCode != 0) { - log.error("Native Image build failed, with output: ") + val retCode = process.!(processLogger) + val targetFile = artifactFile(targetDir, name, true) + if (retCode != 0 || !targetFile.exists()) { + log.error("Native Image build of $targetFile failed, with output: ") println(sb.toString()) throw new RuntimeException("Native Image build failed") } - log.info(s"$targetFile native image build successful.") + log.info(s"$targetLoc native image build successful.") } .dependsOn(Compile / compile) @@ -331,9 +332,13 @@ object NativeImage { /** [[File]] representing the artifact called `name` built with the Native * Image. */ - def artifactFile(targetDir: File, name: String): File = { + def artifactFile( + targetDir: File, + name: String, + withExtension: Boolean = false + ): File = { val artifactName = - if (Platform.isWindows) name + ".exe" + if (withExtension && Platform.isWindows) name + ".exe" else name if (targetDir == null) { new File(artifactName).getAbsoluteFile() From 3fb6a1b98ca529aed5ed5ad74990e891cf928aa5 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 4 Jul 2024 09:19:02 +0200 Subject: [PATCH 17/27] There is no runner anymore --- build/build/paths.yaml | 1 - build/build/src/engine/context.rs | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/build/build/paths.yaml b/build/build/paths.yaml index e07d94cfe387..b6ff88b881ea 100644 --- a/build/build/paths.yaml +++ b/build/build/paths.yaml @@ -123,7 +123,6 @@ bench-report.xml: build.sbt: run: - runner: # The runner native image (Linux only). CHANGELOG.md: # Launcher Package diff --git a/build/build/src/engine/context.rs b/build/build/src/engine/context.rs index 3cd76ce446cd..f7b51c126fab 100644 --- a/build/build/src/engine/context.rs +++ b/build/build/src/engine/context.rs @@ -483,7 +483,15 @@ impl RunContext { if self.config.build_native_runner { debug!("Building and testing native engine runners"); runner_sanity_test(&self.repo_root, None).await?; - ide_ci::fs::remove_file_if_exists(&self.repo_root.runner)?; + let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".bat" } else { "" }); + let enso = self + .repo_root + .built_distribution + .enso_engine_triple + .engine_package + .bin + .join(filename); + ide_ci::fs::remove_file_if_exists(&enso)?; if self.config.build_espresso_runner { let enso_java = "espresso"; sbt.command()? @@ -636,7 +644,10 @@ pub async fn runner_sanity_test( // The engine package is necessary for running the native runner. ide_ci::fs::tokio::require_exist(engine_package).await?; if enso_java.is_none() { - let test_base = Command::new(&repo_root.runner) + let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".bat" } else { "" }); + let enso = + repo_root.built_distribution.enso_engine_triple.engine_package.bin.join(filename); + let test_base = Command::new(&enso) .args(["--run", repo_root.test.join("Base_Tests").as_str()]) .set_env_opt(ENSO_JAVA, enso_java)? .set_env(ENSO_DATA_DIRECTORY, engine_package)? From 8e4834e06cf5f0cecc3672eea826c1122bb4438d Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 5 Jul 2024 06:54:39 +0200 Subject: [PATCH 18/27] Use .exe in native runner tests --- build/build/src/engine/context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build/src/engine/context.rs b/build/build/src/engine/context.rs index f7b51c126fab..0dc48b7c4b46 100644 --- a/build/build/src/engine/context.rs +++ b/build/build/src/engine/context.rs @@ -483,7 +483,7 @@ impl RunContext { if self.config.build_native_runner { debug!("Building and testing native engine runners"); runner_sanity_test(&self.repo_root, None).await?; - let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".bat" } else { "" }); + let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".exe" } else { "" }); let enso = self .repo_root .built_distribution @@ -644,7 +644,7 @@ pub async fn runner_sanity_test( // The engine package is necessary for running the native runner. ide_ci::fs::tokio::require_exist(engine_package).await?; if enso_java.is_none() { - let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".bat" } else { "" }); + let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".exe" } else { "" }); let enso = repo_root.built_distribution.enso_engine_triple.engine_package.bin.join(filename); let test_base = Command::new(&enso) From 59f3087c9ea3f663896e487f062a8f36c0ce6dd3 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 5 Jul 2024 07:45:36 +0200 Subject: [PATCH 19/27] run_benchmarks without bash script wrapper --- build/build/src/enso.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/build/build/src/enso.rs b/build/build/src/enso.rs index 9cb59e98dece..709d6d9c2617 100644 --- a/build/build/src/enso.rs +++ b/build/build/src/enso.rs @@ -73,11 +73,21 @@ impl BuiltEnso { } pub async fn run_benchmarks(&self, opt: BenchmarkOptions) -> Result { - self.cmd()? - .with_args(["--jvm", "--run", self.paths.repo_root.test.benchmarks.as_str()]) + let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".exe" } else { "" }); + let enso = self + .paths + .repo_root + .built_distribution + .enso_engine_triple + .engine_package + .bin + .join(filename); + let benchmarks = Command::new(&enso) + .args(["--jvm", "--run", self.paths.repo_root.test.benchmarks.as_str()]) .set_env(ENSO_BENCHMARK_TEST_DRY_RUN, &Boolean::from(opt.dry_run))? .run_ok() - .await + .await; + Ok(benchmarks?) } pub fn run_test(&self, test_path: impl AsRef, ir_caches: IrCaches) -> Result { From 83f31be7b1914df83aee01221bab82aaf6b22cb5 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 5 Jul 2024 07:50:44 +0200 Subject: [PATCH 20/27] Supressing question mark operator is useless here warning --- build/build/src/enso.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/build/build/src/enso.rs b/build/build/src/enso.rs index 709d6d9c2617..2330ccfaa192 100644 --- a/build/build/src/enso.rs +++ b/build/build/src/enso.rs @@ -72,6 +72,7 @@ impl BuiltEnso { self.paths.repo_root.built_distribution.enso_engine_triple.engine_package.bin.join(filename) } + #[allow(clippy::needless_question_mark)] pub async fn run_benchmarks(&self, opt: BenchmarkOptions) -> Result { let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".exe" } else { "" }); let enso = self From 1ec943a91e56df2001209591a0707af036b2a7e0 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 6 Jul 2024 07:56:23 +0200 Subject: [PATCH 21/27] Updating documentation to new location of runner --- .gitignore | 1 - docs/infrastructure/native-image.md | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index f5da0aeb7242..84a8be89dfe6 100644 --- a/.gitignore +++ b/.gitignore @@ -133,7 +133,6 @@ build-cache/ ################## *.build_artifacts.txt -/runner ###################### ## Enso-Development ## diff --git a/docs/infrastructure/native-image.md b/docs/infrastructure/native-image.md index b1091285b21f..d99c3e357529 100644 --- a/docs/infrastructure/native-image.md +++ b/docs/infrastructure/native-image.md @@ -111,7 +111,7 @@ For example, to update settings for the Launcher: java -agentlib:native-image-agent=config-merge-dir=engine/launcher/src/main/resources/META-INF/native-image/org/enso/launcher -jar launcher.jar ``` -Note that for convenience, you can run the launcher/engine runner via +Note that for convenience, you can run the launcher/engine runtime via `bin/enso`, e.g. ```bash @@ -210,7 +210,7 @@ sbt> engine-runner/buildNativeImage and execute any program with that binary - for example `test/Base_Tests` ```bash -$ runner --run test/Base_Tests +$ ./built-distribution/enso-engine-*/enso-*/bin/enso --run test/Base_Tests ``` The task that generates the Native Image, along with all the necessary @@ -224,7 +224,7 @@ Since [PR-6966](https://github.com/enso-org/enso/pull/6966) there is an experimental support for including [Espresso Java interpreter](https://www.graalvm.org/jdk17/reference-manual/java-on-truffle/) to allow use of some library functions (like `IO.println`) in the _Native Image_ -built runner. +built runtime. The support can be enabled by setting environment variable `ENSO_JAVA=espresso` and making sure Espresso is installed in the Enso engine `component` directory: @@ -278,7 +278,7 @@ Espresso support works also with `ENSO_JAVA=espresso` is specified when building the `runner` executable: ```bash -enso$ rm runner +enso$ rm ./built-distribution/enso-engine-*/enso-*/bin/enso enso$ ENSO_JAVA=espresso sbt --java-home /graalvm sbt> engine-runner/buildNativeImage ``` @@ -288,7 +288,7 @@ build script detects presence of Espresso and automatically adds `--language:java` when creating the image. Then you can use ```bash -$ ENSO_JAVA=espresso ./runner --run hello.enso +$ ENSO_JAVA=espresso ./built-distribution/enso-engine-*/enso-*/bin/enso --run hello.enso ``` -to execute native image `runner` build of Enso together with Espresso. +to execute native image build of Enso together with Espresso. From 13c95186f57492cee0ae232231c6d81017c5d5eb Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 6 Jul 2024 07:58:37 +0200 Subject: [PATCH 22/27] Just return benchmarks Co-authored-by: Kaz Wesley --- build/build/src/enso.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build/src/enso.rs b/build/build/src/enso.rs index 2330ccfaa192..1d23ba16cdf7 100644 --- a/build/build/src/enso.rs +++ b/build/build/src/enso.rs @@ -88,7 +88,7 @@ impl BuiltEnso { .set_env(ENSO_BENCHMARK_TEST_DRY_RUN, &Boolean::from(opt.dry_run))? .run_ok() .await; - Ok(benchmarks?) + benchmarks } pub fn run_test(&self, test_path: impl AsRef, ir_caches: IrCaches) -> Result { From ffb2fb812aa49140a83faaa179d7dd336dfb1a00 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 6 Jul 2024 07:58:58 +0200 Subject: [PATCH 23/27] No need to disable linter Co-authored-by: Kaz Wesley --- build/build/src/enso.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/build/build/src/enso.rs b/build/build/src/enso.rs index 1d23ba16cdf7..656e40f7df44 100644 --- a/build/build/src/enso.rs +++ b/build/build/src/enso.rs @@ -72,7 +72,6 @@ impl BuiltEnso { self.paths.repo_root.built_distribution.enso_engine_triple.engine_package.bin.join(filename) } - #[allow(clippy::needless_question_mark)] pub async fn run_benchmarks(&self, opt: BenchmarkOptions) -> Result { let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".exe" } else { "" }); let enso = self From 60595badb2f59f749ce14bf15678ae9105306826 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 6 Jul 2024 07:59:27 +0200 Subject: [PATCH 24/27] Use with_executable_extension Co-authored-by: Kaz Wesley --- build/build/src/engine/context.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/build/src/engine/context.rs b/build/build/src/engine/context.rs index 0dc48b7c4b46..fc2e36bc8f1f 100644 --- a/build/build/src/engine/context.rs +++ b/build/build/src/engine/context.rs @@ -644,9 +644,8 @@ pub async fn runner_sanity_test( // The engine package is necessary for running the native runner. ide_ci::fs::tokio::require_exist(engine_package).await?; if enso_java.is_none() { - let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".exe" } else { "" }); let enso = - repo_root.built_distribution.enso_engine_triple.engine_package.bin.join(filename); + repo_root.built_distribution.enso_engine_triple.engine_package.bin.join("enso").with_executable_extension(); let test_base = Command::new(&enso) .args(["--run", repo_root.test.join("Base_Tests").as_str()]) .set_env_opt(ENSO_JAVA, enso_java)? From 49700cda0c4039ba9226d1466b8644e5214f9633 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 6 Jul 2024 07:59:51 +0200 Subject: [PATCH 25/27] Use with_executable_extension II Co-authored-by: Kaz Wesley --- build/build/src/engine/context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build/src/engine/context.rs b/build/build/src/engine/context.rs index fc2e36bc8f1f..333dfa68a72f 100644 --- a/build/build/src/engine/context.rs +++ b/build/build/src/engine/context.rs @@ -483,14 +483,14 @@ impl RunContext { if self.config.build_native_runner { debug!("Building and testing native engine runners"); runner_sanity_test(&self.repo_root, None).await?; - let filename = format!("enso{}", if TARGET_OS == OS::Windows { ".exe" } else { "" }); let enso = self .repo_root .built_distribution .enso_engine_triple .engine_package .bin - .join(filename); + .join("enso") + .with_executable_extension(); ide_ci::fs::remove_file_if_exists(&enso)?; if self.config.build_espresso_runner { let enso_java = "espresso"; From 2bd08b140951b2e35862399f6bcf72db661f9435 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 6 Jul 2024 08:04:05 +0200 Subject: [PATCH 26/27] cargo fmt --- build/build/src/engine/context.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/build/build/src/engine/context.rs b/build/build/src/engine/context.rs index 333dfa68a72f..ea7f13d92b9b 100644 --- a/build/build/src/engine/context.rs +++ b/build/build/src/engine/context.rs @@ -644,8 +644,13 @@ pub async fn runner_sanity_test( // The engine package is necessary for running the native runner. ide_ci::fs::tokio::require_exist(engine_package).await?; if enso_java.is_none() { - let enso = - repo_root.built_distribution.enso_engine_triple.engine_package.bin.join("enso").with_executable_extension(); + let enso = repo_root + .built_distribution + .enso_engine_triple + .engine_package + .bin + .join("enso") + .with_executable_extension(); let test_base = Command::new(&enso) .args(["--run", repo_root.test.join("Base_Tests").as_str()]) .set_env_opt(ENSO_JAVA, enso_java)? From bbbbf25b98d73cec9e69b18227adad7792b11599 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 6 Jul 2024 08:08:15 +0200 Subject: [PATCH 27/27] Using longer local variable name --- project/NativeImage.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/NativeImage.scala b/project/NativeImage.scala index b45780e2485b..e19fad98d93b 100644 --- a/project/NativeImage.scala +++ b/project/NativeImage.scala @@ -242,8 +242,8 @@ object NativeImage { Seq("-jar", pathToJAR.toString) } - val td = (Compile / target).value - val argFile = td.toPath.resolve(NATIVE_IMAGE_ARG_FILE) + val targetDirValue = (Compile / target).value + val argFile = targetDirValue.toPath.resolve(NATIVE_IMAGE_ARG_FILE) IO.writeLines(argFile.toFile, args, append = false) val pathParts = pathExts ++ Option(System.getenv("PATH")).toSeq