Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importing (some of) Standard.Base works from NI runner #9866

Merged
merged 23 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
dbd5253
Adjust path to engine/runner
JaroslavTulach May 6, 2024
8cc1b2d
Regenerated with env JAVA_OPTS="-agentlib:native-image-agent=config-m…
JaroslavTulach May 6, 2024
a62f747
Include all Standard/Base JARs on classpath when building NI of engin…
JaroslavTulach May 6, 2024
b9f8fec
Importing from Standard.Base works in NI mode again
JaroslavTulach May 6, 2024
46b48d6
base-polyglot-root may not exist
JaroslavTulach May 7, 2024
2556a2c
Compute additional path at invocation of the buildNativeImage task
JaroslavTulach May 7, 2024
0d24b3e
Useful perf and debug switches
JaroslavTulach May 7, 2024
0d7a11b
Merging removal of java.desktop to this branch
JaroslavTulach May 8, 2024
9d75c72
Configuration for NI debugging of the runner
JaroslavTulach May 13, 2024
c507a47
NI is built from -cp - we need other method of detecting presence of …
JaroslavTulach May 13, 2024
2473812
Script to generate 'small JDK' with native-image in jdk directory
JaroslavTulach May 13, 2024
1933c77
Exclude Graal.js and Graal Python when using Espresso, as they don't …
JaroslavTulach May 14, 2024
593e9b0
Avoid special Graal.js settings
JaroslavTulach May 15, 2024
e20308b
Patching SnakeYaml to run without java.desktop
JaroslavTulach May 15, 2024
38fca73
Copy all JARs to polyglot/java directory in Espresso mode
JaroslavTulach May 15, 2024
87a15e0
Shelve SnakeYaml patches into a single project
JaroslavTulach May 15, 2024
d29c9a1
Build smalljdk before buildNativeImage
JaroslavTulach May 15, 2024
e4cb551
Merge remote-tracking branch 'origin/develop' into wip/jtulach/NIwith…
JaroslavTulach May 15, 2024
2e3b0ed
Hide access to various Pkgs constants
JaroslavTulach May 15, 2024
4d90834
Rewrite SBT support
hubertp May 16, 2024
9cf1543
fix NPE
hubertp May 16, 2024
c627c0f
Correctly detect new javaHome for NI
hubertp May 16, 2024
58ed0bc
nit
hubertp May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
"command": "npm run dev",
// "env": {"NODE_OPTIONS": "--inspect"},
"cwd": "${workspaceFolder}/app/gui2"
},
{
"type": "nativeimage",
"request": "launch",
"name": "Launch Native Image",
"nativeImagePath": "${workspaceFolder}/runner",
"args": "--help"
}
]
}
94 changes: 88 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import src.main.scala.licenses.{
import JPMSPlugin.autoImport._

import java.io.File
import java.nio.file.Paths

// ============================================================================
// === Global Configuration ===================================================
Expand Down Expand Up @@ -283,6 +284,7 @@ lazy val enso = (project in file("."))
`syntax-definition`,
`syntax-rust-definition`,
`text-buffer`,
yaml,
pkg,
cli,
`task-progress-notifications`,
Expand Down Expand Up @@ -693,6 +695,15 @@ lazy val `syntax-rust-definition` = project
Compile / javaSource := baseDirectory.value / "generate-java" / "java"
)

lazy val yaml = (project in file("lib/java/yaml"))
.settings(
frgaalJavaCompilerSetting,
version := "0.1",
libraryDependencies ++= Seq(
"io.circe" %% "circe-yaml" % circeYamlVersion % "provided"
)
)

lazy val pkg = (project in file("lib/scala/pkg"))
.settings(
Compile / run / mainClass := Some("org.enso.pkg.Main"),
Expand Down Expand Up @@ -1019,6 +1030,7 @@ lazy val `project-manager` = (project in file("lib/scala/project-manager"))
Test / javaOptions ++= testLogProviderOptions
)
.settings(
NativeImage.smallJdk := None,
rebuildNativeImage := NativeImage
.buildNativeImage(
"project-manager",
Expand Down Expand Up @@ -2246,6 +2258,9 @@ lazy val `runtime-fat-jar` =
MergeStrategy.concat
case PathList("module-info.class") =>
MergeStrategy.preferProject
// remove once https://github.com/snakeyaml/snakeyaml/pull/12 gets integrated
case PathList("org", "yaml", "snakeyaml", "introspector", xs @ _*) =>
MergeStrategy.preferProject
case PathList(xs @ _*) if xs.last.contains("module-info.class") =>
MergeStrategy.discard
case _ => MergeStrategy.first
Expand All @@ -2256,6 +2271,7 @@ lazy val `runtime-fat-jar` =
.dependsOn(`runtime-instrument-repl-debugger`)
.dependsOn(`runtime-instrument-runtime-server`)
.dependsOn(`runtime-language-epb`)
.dependsOn(yaml)
.dependsOn(LocalProject("runtime"))

/* Note [Unmanaged Classpath]
Expand Down Expand Up @@ -2311,6 +2327,9 @@ lazy val `engine-runner` = project
MergeStrategy.concat
case "reference.conf" =>
MergeStrategy.concat
// remove once https://github.com/snakeyaml/snakeyaml/pull/12 gets integrated
case PathList("org", "yaml", "snakeyaml", "introspector", xs @ _*) =>
MergeStrategy.preferProject
case PathList(xs @ _*) if xs.last.contains("module-info") =>
// runner.jar must not be a JPMS module
MergeStrategy.discard
Expand All @@ -2333,6 +2352,55 @@ lazy val `engine-runner` = project
run / connectInput := true
)
.settings(
NativeImage.smallJdk := Some(buildSmallJdk.value),
buildSmallJdk := {
val smallJdkDirectory = (target.value / "jdk").getAbsoluteFile()
val JS_MODULES =
"org.graalvm.nativeimage,org.graalvm.nativeimage.builder,org.graalvm.nativeimage.base,org.graalvm.nativeimage.driver,org.graalvm.nativeimage.librarysupport,org.graalvm.nativeimage.objectfile,org.graalvm.nativeimage.pointsto,com.oracle.graal.graal_enterprise,com.oracle.svm.svm_enterprise,jdk.compiler.graal,jdk.httpserver,java.naming,java.net.http"
val DEBUG_MODULES = "jdk.jdwp.agent"
val PYTHON_MODULES = "jdk.security.auth,java.naming"

val javaHome = Option(System.getProperty("java.home")).map(Paths.get(_))
val (jlink, modules, libDirs) = javaHome match {
case None =>
throw new RuntimeException("Missing java.home variable")
case Some(jh) =>
val exec = jh.resolve("bin").resolve("jlink")
val moduleJars = List(
"lib/svm/bin/../../graalvm/svm-driver.jar",
"lib/svm/bin/../builder/native-image-base.jar",
"lib/svm/bin/../builder/objectfile.jar",
"lib/svm/bin/../builder/pointsto.jar",
"lib/svm/bin/../builder/svm-enterprise.jar",
"lib/svm/bin/../builder/svm.jar",
"lib/svm/bin/../library-support.jar"
)
val targetLibDirs = List("graalvm", "svm", "static", "truffle")
(
exec,
moduleJars.map(jar => jh.resolve(jar).toString),
targetLibDirs.map(d => jh.resolve("lib").resolve("d"))
)
}

val exec =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exec in Scala! Amazing, thank you @hubertp!

s"$jlink --module-path ${modules.mkString(":")} --output $smallJdkDirectory --add-modules $JS_MODULES,$DEBUG_MODULES,$PYTHON_MODULES"
val exitCode = scala.sys.process.Process(exec).!
libDirs.foreach(libDir =>
IO.copyDirectory(
libDir.toFile,
smallJdkDirectory.toPath.resolve("lib").toFile
)
)
if (exitCode != 0) {
throw new RuntimeException(s"Cannot execute smalljdk.sh")
}
assert(
smallJdkDirectory.exists(),
"Directory of small JDK " + smallJdkDirectory + " is not present"
)
smallJdkDirectory
},
assembly := assembly
.dependsOn(`runtime-fat-jar` / assembly)
.value,
Expand All @@ -2344,16 +2412,21 @@ lazy val `engine-runner` = project
additionalOptions = Seq(
"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog",
"-H:IncludeResources=.*Main.enso$",
// useful perf & debug switches:
// "-g",
// "-H:+DashboardAll",
// "-H:DashboardDump=runner.bgv"
// "-H:+SourceLevelDebug",
// "-H:-DeleteLocalSymbols",
"-Dnic=nic"
),
mainClass = Some("org.enso.runner.Main"),
additionalCp = Seq(
"runtime.jar",
"runner.jar"
),
additionalCp = {
val core = Seq(
"runtime.jar",
"runner.jar"
)
val jars = `base-polyglot-root`.listFiles("*.jar")
JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
core ++ jars.map(_.getAbsolutePath())
},
initializeAtRuntime = Seq(
"org.jline.nativ.JLineLibrary",
"org.jline.terminal.impl.jna",
Expand All @@ -2371,7 +2444,11 @@ lazy val `engine-runner` = project
"akka.http"
)
)
.dependsOn(`std-base` / Compile / packageBin)
.dependsOn(assembly)
.dependsOn(
buildEngineDistribution
)
.value,
buildNativeImage := NativeImage
.incrementalNativeImageBuild(
Expand All @@ -2381,6 +2458,7 @@ lazy val `engine-runner` = project
.value
)
.dependsOn(`version-output`)
.dependsOn(yaml)
.dependsOn(pkg)
.dependsOn(cli)
.dependsOn(`library-manager`)
Expand All @@ -2390,6 +2468,9 @@ lazy val `engine-runner` = project
.dependsOn(`logging-service-logback` % Runtime)
.dependsOn(`polyglot-api`)

lazy val buildSmallJdk =
taskKey[File]("Build a minimal JDK used for native image generation")

lazy val launcher = project
.in(file("engine/launcher"))
.configs(Test)
Expand All @@ -2404,6 +2485,7 @@ lazy val launcher = project
)
)
.settings(
NativeImage.smallJdk := None,
rebuildNativeImage := NativeImage
.buildNativeImage(
"enso",
Expand Down
4 changes: 2 additions & 2 deletions docs/infrastructure/native-image.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Note that for convenience, you can run the launcher/engine runner via
`bin/enso`, e.g.

```bash
env JAVA_OPTS="-agentlib:native-image-agent=config-merge-dir=./engine/runner-native/src/main/resources/META-INF/native-image/org/enso/runner" ./built-distribution/enso-engine-0.0.0-dev-linux-amd64/enso-0.0.0-dev/bin/enso --run tmp.enso
env JAVA_OPTS="-agentlib:native-image-agent=config-merge-dir=./engine/runner/src/main/resources/META-INF/native-image/org/enso/runner" ./built-distribution/enso-engine-0.0.0-dev-linux-amd64/enso-0.0.0-dev/bin/enso --run tmp.enso
```

The command may need to be re-run with different arguments to ensure that all
Expand Down Expand Up @@ -210,7 +210,7 @@ sbt> engine-runner/buildNativeImage
and execute the binary on a sample factorial test program

```bash
> runner --run engine/runner-native/src/test/resources/Factorial.enso 6
> runner --run engine/runner/src/test/resources/Factorial.enso 6
```

The task that generates the Native Image, along with all the necessary
Expand Down
18 changes: 10 additions & 8 deletions engine/runner/src/main/java/org/enso/runner/ContextFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ PolyglotContext build() {
.options(options)
.option(RuntimeOptions.ENABLE_AUTO_PARALLELISM, Boolean.toString(enableAutoParallelism))
.option(RuntimeOptions.WARNINGS_LIMIT, Integer.toString(warningsLimit))
.option("js.foreign-object-prototype", "true")
JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
.out(out)
.in(in)
.serverTransport(
Expand Down Expand Up @@ -181,17 +180,13 @@ PolyglotContext build() {
}
if (ENGINE_HAS_JAVA) {
var javaHome = System.getProperty("java.home");
if (javaHome == null) {
javaHome = System.getenv("JAVA_HOME");
}
if (javaHome == null) {
throw new IllegalStateException("Specify JAVA_HOME environment property");
if (javaHome != null) {
builder.option("java.JavaHome", javaHome);
}
builder
.option("java.ExposeNativeJavaVM", "true")
.option("java.Polyglot", "true")
.option("java.UseBindingsLoader", "true")
.option("java.JavaHome", javaHome)
.allowCreateThread(true);
}
return new PolyglotContext(builder.build());
Expand All @@ -205,6 +200,13 @@ PolyglotContext build() {

static {
var modules = ModuleLayer.boot().modules().stream();
ENGINE_HAS_JAVA = modules.anyMatch(m -> "org.graalvm.espresso".equals(m.getName()));
var found = modules.anyMatch(m -> "org.graalvm.espresso".equals(m.getName()));
if (!found) {
var url =
ContextFactory.class.getResource(
"/META-INF/native-image/com.oracle.truffle.espresso/native-image.properties");
found = url != null;
}
ENGINE_HAS_JAVA = found;
}
}