Skip to content

Commit

Permalink
Fix for native-image to work in Windows (#1312)
Browse files Browse the repository at this point in the history
* Fix for native-image to work in Windows

* The final native-image executable cannot be located in the file
  native-image.cmd unless the full path to native-image.cmd is
  given. Therefore, a new parameter is provided to the user to
  specify the native-image.cmd location.
* Picks the right CLASSPATH separator according to the OS
  instead of hardcoded to colon. Using Colon will fail in Windows
  build.
* Tested against GraalVM 20.0.0 and VS 2019.

* Update src/main/scala/com/typesafe/sbt/packager/graalvmnativeimage/GraalVMNativeImagePlugin.scala

Co-Authored-By: nigredo-tori <nigredo.tori@gmail.com>

* Exclude SettingKey from MIMA filter

* Adds info for graalVMNativeImageCommand setting key

* Workaround for MiMa exceptions

Co-authored-by: nigredo-tori <nigredo.tori@gmail.com>
  • Loading branch information
muuki88 and nigredo-tori committed Mar 5, 2020
1 parent c8c04fb commit 2d85875
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
5 changes: 2 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ mimaBinaryIssueFilters ++= {
ProblemFilters.exclude[ReversedMissingMethodProblem](
"com.typesafe.sbt.packager.docker.DockerKeys.dockerAutoremoveMultiStageIntermediateImages"
),
ProblemFilters.exclude[DirectMissingMethodProblem](
"com.typesafe.sbt.packager.docker.DockerPlugin.publishLocalDocker"
)
ProblemFilters
.exclude[DirectMissingMethodProblem]("com.typesafe.sbt.packager.docker.DockerPlugin.publishLocalDocker")
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ trait GraalVMNativeImageKeys {
"Version of GraalVM to build with. Setting this has the effect of generating a container build image to build the native image with this version of GraalVM."
)
}

trait GraalVMNativeImageKeysEx extends GraalVMNativeImageKeys {
val graalVMNativeImageCommand = settingKey[String]("GraalVM native-image executable command")
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ import com.typesafe.sbt.packager.universal.UniversalPlugin
*/
object GraalVMNativeImagePlugin extends AutoPlugin {

object autoImport extends GraalVMNativeImageKeys {
object autoImport extends GraalVMNativeImageKeysEx {
val GraalVMNativeImage: Configuration = config("graalvm-native-image")
}

import autoImport._

private val GraalVMBaseImage = "oracle/graalvm-ce"
private val NativeImageCommand = "native-image"

override def requires: Plugins = JavaAppPackaging

Expand All @@ -38,6 +37,7 @@ object GraalVMNativeImagePlugin extends AutoPlugin {
target in GraalVMNativeImage := target.value / "graalvm-native-image",
graalVMNativeImageOptions := Seq.empty,
graalVMNativeImageGraalVersion := None,
graalVMNativeImageCommand := "native-image",
resourceDirectory in GraalVMNativeImage := sourceDirectory.value / "graal",
mainClass in GraalVMNativeImage := (mainClass in Compile).value
) ++ inConfig(GraalVMNativeImage)(scopedSettings)
Expand All @@ -55,6 +55,7 @@ object GraalVMNativeImagePlugin extends AutoPlugin {
packageBin := {
val targetDirectory = target.value
val binaryName = name.value
val nativeImageCommand = graalVMNativeImageCommand.value
val className = mainClass.value.getOrElse(sys.error("Could not find a main class."))
val classpathJars = scriptClasspathOrdering.value
val extraOptions = graalVMNativeImageOptions.value
Expand All @@ -65,7 +66,15 @@ object GraalVMNativeImagePlugin extends AutoPlugin {

UniversalPlugin.autoImport.containerBuildImage.value match {
case None =>
buildLocal(targetDirectory, binaryName, className, classpathJars.map(_._1), extraOptions, streams.log)
buildLocal(
targetDirectory,
binaryName,
nativeImageCommand,
className,
classpathJars.map(_._1),
extraOptions,
streams.log
)

case Some(image) =>
val resourceMappings = MappingsHelper.relative(graalResources, graalResourceDirectories)
Expand All @@ -87,18 +96,20 @@ object GraalVMNativeImagePlugin extends AutoPlugin {

private def buildLocal(targetDirectory: File,
binaryName: String,
nativeImageCommand: String,
className: String,
classpathJars: Seq[File],
extraOptions: Seq[String],
log: ProcessLogger): File = {
targetDirectory.mkdirs()
val command = {
val nativeImageArguments = {
val classpath = classpathJars.mkString(":")
val classpath = classpathJars.mkString(java.io.File.pathSeparator)
Seq("--class-path", classpath, s"-H:Name=$binaryName") ++ extraOptions ++ Seq(className)
}
Seq(NativeImageCommand) ++ nativeImageArguments
Seq(nativeImageCommand) ++ nativeImageArguments
}

sys.process.Process(command, targetDirectory) ! log match {
case 0 => targetDirectory / binaryName
case x => sys.error(s"Failed to run $command, exit status: " + x)
Expand Down
13 changes: 13 additions & 0 deletions src/sphinx/formats/graalvm-native-image.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ Required Settings
Settings
--------

``native-image`` Executable Command (Pay attention if you are using Windows OS)
~~~~
Putting ``native-image`` in ``PATH`` does not work for Windows. ``native-image``is a batch file in Windows that calls another executable to compile the Java classes to a standalone executable. Therefore, the full path to the batch file e.g. ``C:\Program Files\Java\graalvm\bin\native-image.cmd`` must be provided. It is important to include ``.cmd``.

``graalVMNativeImageCommand``
Set this parameter to point to ``native-image`` or ``native-image.cmd``. For Linux, set this parameter if it is inconvenient to make ``native-image`` available in your ``PATH``.

For example:

.. code-block:: scala
graalVMNativeImageCommand := "C:/Program Files/Java/graalvm/bin/native-image.cmd"
Docker Image Build Settings
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down

0 comments on commit 2d85875

Please sign in to comment.