Bump GraalVM Version to 20.2.0 (#1094)

This commit is contained in:
Radosław Waśko 2020-08-28 13:03:09 +02:00 committed by GitHub
parent e64c0384b0
commit 125af6b7fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 310 additions and 111 deletions

View File

@ -58,10 +58,10 @@ Please list the reproduction steps for your bug. For example:
For example:
```
Enso Compiler and Runtime
Version: 0.0.1
Built with: scala-2.13.3 for GraalVM 20.1.0
Built from: main @ 919ffbdfacc44cc35a1b38f1bad5b573acdbe358
Running on: OpenJDK 64-Bit Server VM, GraalVM Community, JDK 11.0.7+10-jvmci-20.1-b02
Linux 4.15.0-108-generic (amd64)
Version: 0.1.0
Built with: scala-2.13.3 for GraalVM 20.2.0
Built from: main* @ 919ffbdfacc44cc35a1b38f1bad5b573acdbe358
Running on: OpenJDK 64-Bit Server VM, GraalVM Community, JDK 11.0.8+10-jvmci-20.2-b03
Linux 4.15.0-112-generic (amd64)
```
-->

View File

@ -11,7 +11,7 @@ on:
env:
# Please ensure that this is in sync with graalAPIVersion in build.sbt
graalVersion: 20.1.0
graalVersion: 20.2.0
javaVersion: java11
# Please ensure that this is in sync with project/build.properties
sbtVersion: 1.3.13

View File

@ -7,7 +7,7 @@ on:
env:
# Please ensure that this is in sync with graalVersion in build.sbt
graalVersion: 20.1.0
graalVersion: 20.2.0
# Please ensure that this is in sync with javaVersion in build.sbt
javaVersion: 11
# Please ensure that this is in sync with project/build.properties

View File

@ -29,19 +29,21 @@ jobs:
toolchain: ${{ env.rustToolchain }}
override: true
# Caches
- name: Cache Cargo Registry
uses: actions/cache@v2
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**Cargo.toml') }}
restore-keys: ${{ runner.os }}-cargo-registry
- name: Cache Cargo Test
uses: actions/cache@v2
with:
path: ./target/rust
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**Cargo.toml') }}
restore-keys: ${{ runner.os }}-cargo-build
# TODO [AA] at some point when the caching bug is fixed we will want to
# re-enable the caches
# # Caches
# - name: Cache Cargo Registry
# uses: actions/cache@v2
# with:
# path: ~/.cargo/registry
# key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**Cargo.toml') }}
# restore-keys: ${{ runner.os }}-cargo-registry
# - name: Cache Cargo Test
# uses: actions/cache@v2
# with:
# path: ./target/rust
# key: ${{ runner.os }}-cargo-build-${{ hashFiles('**Cargo.toml') }}
# restore-keys: ${{ runner.os }}-cargo-build
# Lint
- name: Check Code
@ -69,19 +71,19 @@ jobs:
- name: Install Clippy
run: rustup component add clippy
# Caches
- name: Cache Cargo Registry
uses: actions/cache@v2
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**Cargo.toml') }}
restore-keys: ${{ runner.os }}-cargo-registry
- name: Cache Cargo Test
uses: actions/cache@v2
with:
path: ./target/rust
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**Cargo.toml') }}
restore-keys: ${{ runner.os }}-cargo-build
# # Caches
# - name: Cache Cargo Registry
# uses: actions/cache@v2
# with:
# path: ~/.cargo/registry
# key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**Cargo.toml') }}
# restore-keys: ${{ runner.os }}-cargo-registry
# - name: Cache Cargo Test
# uses: actions/cache@v2
# with:
# path: ./target/rust
# key: ${{ runner.os }}-cargo-build-${{ hashFiles('**Cargo.toml') }}
# restore-keys: ${{ runner.os }}-cargo-build
# Lint
- name: Lint Code
@ -109,19 +111,19 @@ jobs:
toolchain: ${{ env.rustToolchain }}
override: true
# Caches
- name: Cache Cargo Registry
uses: actions/cache@v2
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**Cargo.toml') }}
restore-keys: ${{ runner.os }}-cargo-registry
- name: Cache Cargo Test
uses: actions/cache@v2
with:
path: ./target/rust
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**Cargo.toml') }}
restore-keys: ${{ runner.os }}-cargo-build
# # Caches
# - name: Cache Cargo Registry
# uses: actions/cache@v2
# with:
# path: ~/.cargo/registry
# key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**Cargo.toml') }}
# restore-keys: ${{ runner.os }}-cargo-registry
# - name: Cache Cargo Test
# uses: actions/cache@v2
# with:
# path: ./target/rust
# key: ${{ runner.os }}-cargo-build-${{ hashFiles('**Cargo.toml') }}
# restore-keys: ${{ runner.os }}-cargo-build
# Tests
- name: Test Native
@ -165,19 +167,19 @@ jobs:
mv $WASMPACKDIR/wasm-pack ~/.cargo/bin
rm -r $WASMPACKDIR
# Caches
- name: Cache Cargo Registry
uses: actions/cache@v2
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**Cargo.toml') }}
restore-keys: ${{ runner.os }}-cargo-registry
- name: Cache Cargo Test
uses: actions/cache@v2
with:
path: ./target/rust
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**Cargo.toml') }}
restore-keys: ${{ runner.os }}-cargo-build
# # Caches
# - name: Cache Cargo Registry
# uses: actions/cache@v2
# with:
# path: ~/.cargo/registry
# key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**Cargo.toml') }}
# restore-keys: ${{ runner.os }}-cargo-registry
# - name: Cache Cargo Test
# uses: actions/cache@v2
# with:
# path: ./target/rust
# key: ${{ runner.os }}-cargo-build-${{ hashFiles('**Cargo.toml') }}
# restore-keys: ${{ runner.os }}-cargo-build
# Tests
- name: Test WASM

View File

@ -8,7 +8,7 @@ on:
env:
# Please ensure that this is in sync with graalVersion in build.sbt
graalVersion: 20.1.0
graalVersion: 20.2.0
# Please ensure that this is in sync with javaVersion in build.sbt
javaVersion: 11
# Please ensure that this is in sync with project/build.properties
@ -100,6 +100,11 @@ jobs:
run: |
echo '::set-env name=CI_TEST_TIMEFACTOR::2'
echo '::set-env name=CI_TEST_FLAKY_ENABLE::true'
- name: Build the Launcher
run: |
sleep 1
sbt --no-colors launcher/buildNativeImage
echo '::set-env name=LAUNCHER_NATIVE_IMAGE_TEST_SKIP_BUILD::true'
- name: Test Enso
run: |
sleep 1

View File

@ -18,7 +18,7 @@ import com.typesafe.sbt.license.DepModuleInfo
val scalacVersion = "2.13.3"
val rustVersion = "1.40.0-nightly (b520af6fd 2019-11-03)"
val graalVersion = "20.1.0"
val graalVersion = "20.2.0"
val javaVersion = "11"
val ensoVersion = "0.1.0" // Note [Engine And Launcher Version]
@ -1002,7 +1002,11 @@ lazy val runner = project
)
.settings(
buildNativeImage := NativeImage
.buildNativeImage("enso", staticOnLinux = false)
.buildNativeImage(
"enso",
staticOnLinux = false,
Seq("-H:IncludeResources=.*Main.enso$")
)
.value
)
.settings(
@ -1036,10 +1040,13 @@ lazy val launcher = project
staticOnLinux = true,
Seq(
"--enable-all-security-services", // Note [HTTPS in the Launcher]
"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog"
"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog",
"-H:IncludeResources=.*Main.enso$"
)
)
.value,
// Note [Native Image Workaround for GraalVM 20.2]
libraryDependencies += "org.graalvm.nativeimage" % "svm" % "20.2.0" % "provided",
test in assembly := {},
assemblyOutputPath in assembly := file("launcher.jar")
)
@ -1069,3 +1076,23 @@ lazy val launcher = project
* `--enable-all-security-services` flag is used to ensure it is available in
* the built executable.
*/
/* Note [Native Image Workaround for GraalVM 20.2]
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* In GraalVM 20.2 the Native Image build of even simple Scala programs has
* started to fail on a call to `Statics.releaseFence`. It has been reported as
* a bug in the GraalVM repository: https://github.com/oracle/graal/issues/2770
*
* A proposed workaround for this bug is to substitute the original function
* with a different implementation that does not use the problematic
* MethodHandle. This is implemented in class
* `org.enso.launcher.workarounds.ReplacementStatics` using
* `org.enso.launcher.workarounds.Unsafe` which gives access to
* `sun.misc.Unsafe` which contains a low-level function corresponding to the
* required "release fence".
*
* To allow for that substitution, the launcher code requires annotations from
* the `svm` module and that is why this additional dependency is needed as long
* as that workaround is in-place. The dependency is marked as "provided"
* because it is included within the native-image build.
*/

View File

@ -149,6 +149,12 @@ In order to build and run Enso you will need the following tools:
- [Rustup](https://rustup.rs), the rust toolchain management utility.
- On MacOS and Linux, the `tar` command is required for running some tests. It
should be installed by default on most distributions.
- If you want to be able to build the Launcher Native Image, you will need a
native C compiler for your platform as described in the
[Native Image Prerequisites](https://www.graalvm.org/reference-manual/native-image/#prerequisites).
On Linux that will be `gcc`, on macOS you may need `xcode` and on Windows you
need to configure the Developer Command Prompt for Microsoft Visual C++ for
the x64 architecture.
Managing multiple JVM installations can be a pain, so some of the team use
[Jenv](http://www.jenv.be/): A useful tool for managing multiple JVMs.
@ -296,7 +302,7 @@ Native Image component is installed in your GraalVM distribution. To install it,
run:
```bash
gu install native-image
<path-to-graal-home>/bin/gu install native-image
```
Then, you can build the launcher using:

View File

@ -42,7 +42,7 @@ My_Package
│ ├── Helper.enso
│ └── Util.enso
└── visualization (optional)
└──
└── ...
```
### The `src` Directory

View File

@ -120,7 +120,7 @@ For example:
```yaml
minimum-launcher-version: 0.0.1
graal-vm-version: 20.1.0
graal-vm-version: 20.2.0
graal-java-version: 11
jvm-options:
- value: "-Dpolyglot.engine.IterativePartialEscape=true"

View File

@ -31,7 +31,7 @@ GraalVM. You can get the Community Edition pre-built distributions from
It is important to run Enso with exactly the version specified here. Given that
Graal is still a relatively young project, even the minor version changes
introduce breaking API changes. The current version of GraalVM required for Enso
is `20.1.0`, and it must be the Java 11 build.
is `20.2.0`, and it must be the Java 11 build.
Before running the Enso packages, make sure that the `JAVA_HOME` environment
variable points to the correct home location of the Graal distribution.
@ -64,8 +64,8 @@ This section lists the most common failures and their probable causes.
section. It should be similar to:
```
Running on: OpenJDK 64-Bit Server VM, GraalVM Community, JDK 11.0.7+10-jvmci-20.1-b02
Linux 4.15.0-106-generic (amd64)
Running on: OpenJDK 64-Bit Server VM, GraalVM Community, JDK 11.0.8+10-jvmci-20.2-b03
Linux 4.15.0-112-generic (amd64)
```
It could also be caused by not using the launcher scripts and trying to run

View File

@ -17,3 +17,6 @@ up as follows:
migration.
- [**Native Image:**](native-image.md) Description of the Native Image build
used for building the launcher native binary.
- [**Rust:**](rust.md) Description of integration of the Scala project with the
Rust components.
- [**Upgrading GraalVM:**](upgrading-graalvm.md)

View File

@ -28,7 +28,8 @@ Native Image is used for building the Launcher.
### Native Image Component
The Native Image component has to be installed within the used GraalVM
distribution. It can be installed by running `gu install native-image`.
distribution. It can be installed by running
`<path-to-graal-home>/bin/gu install native-image`.
### Additional Linux Dependencies
@ -41,13 +42,19 @@ suggested by Graal as an alternative. The sbt task automatically downloads a
bundle containing all requirements for a static build with `musl`. It only
requires a `tar` command to be available to extract the bundle.
Currently, to enable compiling with `musl`, `-H:UseMuslC=/path/to/musl/bundle`
option is added to the `native-image` command. In the future, the command may
use a different option for enabling `musl` or even enable it by default, so the
Native Image task may need updating with a newer Graal release. More information
may be found in
Currently, to use `musl`, the `--libc=musl` option has to be added to the build
and `gcc-musl` must be available in the system PATH for the native-image. In the
future it is possible that a different option will be used or that the bundle
will not be required anymore if it became prepackaged. This task may thus need
an update when moving to a newer version of Graal. More information may be found
in
[the Native Image documentation](https://github.com/oracle/graal/blob/master/substratevm/STATIC-IMAGES.md).
To make the bundle work correctly with GraalVM 20.2, a shell script called
`gcc-musl` which loads the bundle's configuration is created by the task and the
paths starting with `/build/bundle` in `musl-gcc.specs` are replaced with
absolute paths to the bundle location.
## Static Builds
The task is parametrized with `staticOnLinux` parameter which if set to `true`,

View File

@ -2,8 +2,8 @@
layout: developer-doc
title: Rust
category: infrastructure
tags: [infrastructure, build]
order: 1
tags: [infrastructure, build, rust]
order: 4
---
# Rust

View File

@ -0,0 +1,27 @@
---
layout: developer-doc
title: Upgrading GraalVM
category: infrastructure
tags: [infrastructure, build, graalvm, graal, jvm]
order: 5
---
# Upgrading GraalVM
After upgrading the project to a newer version of GraalVM, all developers must
take the following actions to be able to continue development after the upgrade:
1. Download the new JVM version and set it as the default for the project. If
you use IntelliJ, you will also need to update the JVM used for the project
in the project settings.
2. Re-run `sbt bootstrap` to get the updated Truffle JAR (if there are issues
updating, removing `engine/runtime/build-cache` directory may help).
3. Do a full clean (it may not _always_ be required, but not doing it often
leads to problems so it is much safer to do it) by running `enso/clean`.
4. To be able to build or run tests for the `launcher` project, Native Image for
the new GraalVM version has to be installed, as it is not included by
default. This can be done with
`<path-to-graal-home>/bin/gu install native-image`.
- If there are problems building the Native Image, removing
`engine/launcher/build-cache` (which contains the downloaded `musl`
package) may help.

View File

@ -0,0 +1,24 @@
package org.enso.launcher.workarounds;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
/**
* Uses Native Image substitution capability to substitute the
* {@link scala.runtime.Statics#releaseFence()} function which causes problems
* when building the Native Image on GraalVM 20.2.0.
*/
@TargetClass(className = "scala.runtime.Statics")
final class ReplacementStatics {
/**
* Implements a "release fence" without using an unsupported
* {@link java.lang.invoke.MethodHandle} like the original one.
*
* Instead, uses {@link sun.misc.Unsafe#storeFence()} under the hood.
*/
@Substitute
public static void releaseFence() {
Unsafe.unsafeInstance().storeFence();
}
}

View File

@ -253,8 +253,9 @@ case class Launcher(cliOptions: GlobalCLIOptions) {
val versionDescription = VersionDescription.make(
"Enso Launcher",
includeRuntimeJVMInfo = false,
additionalParameters = runtimeVersionParameter.toSeq
includeRuntimeJVMInfo = false,
enableNativeImageOSWorkaround = true,
additionalParameters = runtimeVersionParameter.toSeq
)
println(versionDescription.asString(useJSON))

View File

@ -0,0 +1,22 @@
package org.enso.launcher.workarounds
/**
* Gives access to an instance of [[sun.misc.Unsafe]] which contains low-level
* functions that are used to replace the ones that cause problems in the
* Native Image build.
*
* Workaround based on
* https://github.com/plokhotnyuk/jsoniter-scala/blob/master/jsoniter-scala-examples/src/main/scala-2.13/com/github/plokhotnyuk/jsoniter_scala/examples/UnsafeUtils.java
*/
object Unsafe {
/**
* Instance of the [[sun.misc.Unsafe]] acquired using reflection that allows
* to run the unsafe functions needed by the workaround.
*/
val unsafeInstance: sun.misc.Unsafe = {
val field = classOf[sun.misc.Unsafe].getDeclaredField("theUnsafe")
field.setAccessible(true)
field.get(null).asInstanceOf[sun.misc.Unsafe]
}
}

View File

@ -54,9 +54,7 @@ public abstract class LoopingCallOptimiserNode extends CallOptimiserNode {
* @param loopNode a cached instance of the loop node used by this node
* @return the result of executing {@code function} using {@code arguments}
*/
// TODO[MK]: Remove the guard when https://github.com/oracle/graal/pull/2567 is released.
// Probably 20.2.
@Specialization(guards = "true")
@Specialization
public Stateful dispatch(
Object function,
CallerInfo callerInfo,

View File

@ -39,6 +39,7 @@ object VersionDescription {
def make(
header: String,
includeRuntimeJVMInfo: Boolean,
enableNativeImageOSWorkaround: Boolean = false,
additionalParameters: Seq[VersionDescriptionParameter] = Seq.empty
): VersionDescription = {
val version = Info.ensoVersion
@ -63,8 +64,13 @@ object VersionDescription {
if (includeRuntimeJVMInfo)
s"""Running on: $vmName, $vmVendor, JDK $jreVersion
| $osName $osVersion ($osArch)""".stripMargin
else
s"Running on: $osName $osVersion ($osArch)"
else if (enableNativeImageOSWorkaround) {
// TODO [RW] Currently the `os.name` property seems to be set to the
// OS the program has been built on, instead of the OS that is
// currently running. A workaround should be implemented in #1100
// that will use other means to query the OS name and version.
s"Built on: $osName ($osArch)"
} else s"Running on: $osName $osVersion ($osArch)"
val dirtyStr = if (Info.isDirty) "*" else ""
val parameters =

View File

@ -51,18 +51,16 @@ object NativeImage {
}
val debugParameters =
if (includeDebugInfo) "-H:GenerateDebugInfo=1" else ""
if (includeDebugInfo) Seq("-H:GenerateDebugInfo=1") else Seq()
val staticParameters =
val (staticParameters, pathExts) =
if (staticOnLinux && isLinux) {
// Note [Static Build On Linux]
val buildCache =
subProjectRoot / "build-cache"
val path = ensureMuslIsInstalled(buildCache, log)
s"--static -H:UseMuslC=$path"
} else ""
val resourcesGlobOpt = "-H:IncludeResources=.*Main.enso$"
(Seq("--static", "--libc=musl"), Seq(path.toString))
} else (Seq(), Seq())
val configLocation =
subProjectRoot / "native-image-config"
@ -70,24 +68,30 @@ object NativeImage {
if (configLocation.exists()) {
val path = configLocation.toPath.toAbsolutePath
log.debug(s"Picking up Native Image configuration from `$path`.")
s"-H:ConfigurationFileDirectories=$path"
Seq(s"-H:ConfigurationFileDirectories=$path")
} else {
log.debug(
"No Native Image configuration found, proceeding without it."
)
""
Seq()
}
val cmd =
s"$nativeImagePath $staticParameters $debugParameters " +
s"$resourcesGlobOpt $configs " +
s"--no-fallback --initialize-at-build-time " +
s"${additionalOptions.mkString(" ")} " +
s"-cp $classPath ${(Compile / mainClass).value.get} enso"
Seq(nativeImagePath) ++
debugParameters ++ staticParameters ++ configs ++
Seq("--no-fallback", "--initialize-at-build-time", "--no-server") ++
additionalOptions ++
Seq("-cp", classPath, (Compile / mainClass).value.get, artifactName)
log.debug(cmd)
val pathParts = pathExts ++ Option(System.getenv("PATH")).toSeq
val newPath = pathParts.mkString(File.pathSeparator)
if (cmd.! != 0) {
log.debug(s"""PATH="$newPath" ${cmd.mkString(" ")}""")
val process =
Process(cmd, None, "PATH" -> newPath)
if (process.! != 0) {
log.error("Native Image build failed.")
throw new RuntimeException("Native Image build failed")
}
@ -127,7 +131,16 @@ object NativeImage {
streams.value.cacheStoreFactory.make("incremental_native_image")
Tracked.diffInputs(store, FileInfo.hash)(filesSet) {
sourcesDiff: ChangeReport[File] =>
if (sourcesDiff.modified.nonEmpty)
if (System.getenv("LAUNCHER_NATIVE_IMAGE_TEST_SKIP_BUILD") == "true")
Def.task {
streams.value.log.warn(
"LAUNCHER_NATIVE_IMAGE_TEST_SKIP_BUILD set to true, " +
"Native Image will not be rebuilt. Use with caution as using " +
"this override without building the launcher manually may " +
"lead to launcher tests failure."
)
}
else if (sourcesDiff.modified.nonEmpty)
rebuild("Native Image is not up to date")
else if (!artifactFile(artifactName).exists())
rebuild("Native Image does not exist")
@ -157,12 +170,16 @@ object NativeImage {
* Ensures that the `musl` bundle is installed.
*
* Checks for existence of its directory and if it does not exist, downloads
* and extracts the bundle. `musl` is needed for static builds on Linux.
* and extracts the bundle. After extracting it does the required
* initialization (renaming paths to be absolute and creating a shell script
* called `musl-gcc`).
*
* `musl` is needed for static builds on Linux.
*
* @param buildCache build-cache directory for the current project
* @param log a logger instance
* @return path to the `musl` bundle that can be passed to the Native Image
* as a parameter
* @return path to the `musl` bundle binary directory which should be added
* to PATH of the launched native-image
*/
private def ensureMuslIsInstalled(
buildCache: File,
@ -170,7 +187,11 @@ object NativeImage {
): Path = {
val muslRoot = buildCache / "musl-1.2.0"
val bundleLocation = muslRoot / "bundle"
if (!bundleLocation.exists()) {
val binaryLocation = bundleLocation / "bin"
val gccLocation = binaryLocation / "musl-gcc"
def isMuslInstalled =
gccLocation.exists() && gccLocation.isOwnerExecutable
if (!isMuslInstalled) {
log.info(
"`musl` is required for a static build, but it is not installed for " +
"this subproject."
@ -201,6 +222,12 @@ object NativeImage {
throw new RuntimeException(s"Cannot extract $bundle.")
}
replacePathsInSpecs(
bundleLocation / "lib" / "musl-gcc.specs",
bundleLocation
)
createGCCWrapper(bundleLocation)
log.info("Installed `musl`.")
} catch {
case e: Exception =>
@ -213,7 +240,39 @@ object NativeImage {
}
bundleLocation.toPath.toAbsolutePath
binaryLocation.toPath.toAbsolutePath.normalize
}
/**
* Replaces paths in `musl-gcc.specs` with absolute paths to the bundle.
*
* The paths in `musl-gcc.specs` start with `/build/bundle` which is not a
* valid path by default. Instead, these prefixes are replaced with an
* absolute path to the bundle.
*
* @param specs reference to `musl-gcc.specs` file
* @param bundleLocation location of the bundle root
*/
private def replacePathsInSpecs(specs: File, bundleLocation: File): Unit = {
val content = IO.read(specs)
val bundlePath = bundleLocation.toPath.toAbsolutePath.normalize.toString
val replaced = content.replace("/build/bundle", bundlePath)
IO.write(specs, replaced)
}
/**
* Creates a simple shell script called `musl-gcc` which calls the original
* `gcc` and ensures the bundle's configuration (`musl-gcc.specs`) is loaded.
*/
private def createGCCWrapper(bundleLocation: File): Unit = {
val bundlePath = bundleLocation.toPath.toAbsolutePath.normalize.toString
val content =
s"""#!/bin/sh
|exec "$${REALGCC:-gcc}" "$$@" -specs "$bundlePath/lib/musl-gcc.specs"
|""".stripMargin
val wrapper = bundleLocation / "bin" / "musl-gcc"
IO.write(wrapper, content)
wrapper.setExecutable(true)
}
}
@ -226,10 +285,22 @@ object NativeImage {
* automatically downloads a bundle containing all requirements for a static
* build with `musl`.
*
* Currently, to use `musl`, the `-H:UseMuslC=/path/to/musl/bundle` option has
* to be added to the build. In the future, a `--libc=musl` option may be
* preferred instead, as described at
* https://github.com/oracle/graal/blob/master/substratevm/STATIC-IMAGES.md
* or even `musl` may be included by default. This task may thus need an update
* when moving to a newer version of Graal.
* The `musl` bundle that we use is not guaranteed to be maintained, so if in
* the future a new version of `musl` comes out and we need to upgrade, we may
* need to create our own infrastructure (a repository with CI jobs for creating
* such bundles). It is especially important to note that the libstdc++ that is
* included in this bundle should also be built using `musl` as otherwise linker
* errors may arise.
*
* Currently, to use `musl`, the `--libc=musl` option has to be added to the
* build and `gcc-musl` must be available in the system PATH for the
* native-image. In the future it is possible that a different option will be
* used or that the bundle will not be required anymore if it became
* prepackaged. This task may thus need an update when moving to a newer version
* of Graal.
*
* Currently to make the bundle work correctly with GraalVM 20.2, a shell script
* called `gcc-musl` which loads the bundle's configuration is created by the
* task and the paths starting with `/build/bundle` in `musl-gcc.specs` are
* replaced with absolute paths to the bundle location.
*/