Skip to content

Commit

Permalink
Build native images using GraalVM
Browse files Browse the repository at this point in the history
  • Loading branch information
ScalaWilliam committed Oct 19, 2018
1 parent 2aba0d6 commit b65a931
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cache:
- $HOME/.sbt
- $HOME/.m2
- $HOME/.ivy2
- $HOME/graalvm-ce-1.0.0-rc7

env:
global:
Expand All @@ -36,6 +37,18 @@ before_install:

before_script:
- curl -L --create-dirs -o $HOME/.sbt/launchers/1.2.6/sbt-launch.jar http://dl.bintray.com/sbt/maven-releases/org/scala-sbt/sbt-launch/1.2.6/sbt-launch.jar
# Make GraalVM `native-image` available and nothing else
- if [[ ! -d graalvm-ce-1.0.0-rc7 ]]; then
cd $HOME;
wget -O graalvm-ce-1.0.0-rc7-linux-amd64.tar.gz https://github.com/oracle/graal/releases/download/vm-1.0.0-rc7/graalvm-ce-1.0.0-rc7-linux-amd64.tar.gz;
tar zxf graalvm-ce-1.0.0-rc7-linux-amd64.tar.gz;
rm -f graalvm-ce-1.0.0-rc7-linux-amd64.tar.gz;
fi;
ls -lsa $HOME/graalvm-ce-1.0.0-rc7/bin/native-image;
mkdir -p $HOME/.bin;
ln -f -s $HOME/graalvm-ce-1.0.0-rc7/bin/native-image $HOME/.bin/native-image;
export PATH=$HOME/.bin:$PATH;
echo New path: ${PATH};

# job definitions

Expand All @@ -49,6 +62,8 @@ jobs:
script: sbt "^validateUniversal"
if: type = pull_request OR (type = push AND branch = master)
name: "scripted universal tests"
- script: sbt "^validateGraalVMNativeImage"
name: "scripted GraalVM native-image tests"
- script: sbt "^validateJar"
name: "scripted jar tests"
if: type = pull_request OR (type = push AND branch = master)
Expand Down
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ addCommandAlias("validateUniversal", "scripted universal/*")
addCommandAlias("validateJar", "scripted jar/*")
addCommandAlias("validateBash", "scripted bash/*")
addCommandAlias("validateAsh", "scripted ash/*")
addCommandAlias("validateGraalVMNativeImage", "scripted graalvm-native-image/*")
addCommandAlias("validateRpm", "scripted rpm/*")
addCommandAlias("validateDebian", "scripted debian/*")
addCommandAlias("validateDocker", "scripted docker/*")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.typesafe.sbt
package packager
package graalvmnativeimage

import sbt._

/**
* GraalVM settings
*/
trait GraalVMNativeImageKeys {
val graalVMNativeImageOptions =
SettingKey[Seq[String]]("graalvm-native-image-options", "GraalVM native-image options")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.typesafe.sbt.packager.graalvmnativeimage

import sbt._
import sbt.Keys._
import java.nio.charset.Charset

import com.typesafe.sbt.packager.SettingsHelper
import com.typesafe.sbt.packager.Keys._
import com.typesafe.sbt.packager.linux._
import com.typesafe.sbt.packager.Compat._
import com.typesafe.sbt.packager.validation._

/**
* Plugin to compile ahead-of-time native executables.
*
* @example Enable the plugin in the `build.sbt`
* {{{
* enablePlugins(GraalVMNativeImagePlugin)
* }}}
*/
object GraalVMNativeImagePlugin extends AutoPlugin {

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

private val GraalVMNativeImageCommand = "native-image"

import autoImport._

override def projectConfigurations: Seq[Configuration] = Seq(GraalVMNativeImage)

override lazy val projectSettings = Seq(
target in GraalVMNativeImage := target.value / "graalvm-native-image",
graalVMNativeImageOptions := Seq.empty,
packageBin in GraalVMNativeImage := {
val targetDirectory = (target in GraalVMNativeImage).value
targetDirectory.mkdirs()
val binaryName = name.value
val command = {
val nativeImageArguments = {
val className = (mainClass in Compile).value.getOrElse(sys.error("Could not find a main class."))
val classpathJars = Seq((packageBin in Compile).value) ++ (dependencyClasspath in Compile).value.map(_.data)
val classpath = classpathJars.mkString(":")
val extraOptions = graalVMNativeImageOptions.value
Seq("--class-path", classpath, s"-H:Name=$binaryName") ++ extraOptions ++ Seq(className)
}
Seq(GraalVMNativeImageCommand) ++ nativeImageArguments
}
sys.process.Process(command, targetDirectory) ! streams.value.log match {
case 0 => targetDirectory / binaryName
case x => sys.error(s"Failed to run $GraalVMNativeImageCommand, exit status: " + x)
}
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
enablePlugins(GraalVMNativeImagePlugin)

name := "simple-test"

version := "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Main {
def main(args: Array[String]): Unit = {
println("Hello world")
}
}
3 changes: 3 additions & 0 deletions src/sbt-test/graalvm-native-image/simple-native-image/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Generate the GraalVM native image
> show graalvm-native-image:packageBin
$ exists target/graalvm-native-image/simple-test
45 changes: 45 additions & 0 deletions src/sphinx/formats/graalvm-native-image.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.. _graalvm-native-image-plugin:

GraalVM Native Image Plugin
=============

GraalVM's ``native-image`` compiles Java programs AOT (ahead-of-time) into native binaries.

https://www.graalvm.org/docs/reference-manual/aot-compilation/ documents the AOT compilation of GraalVM.

Requirements
------------

You must have ``native-image`` of GraalVM in your ``PATH``.

Build
-----

.. code-block:: bash
sbt 'show graalvm-native-image:packageBin'
Required Settings
~~~~~~~~~~~~~~~~~

.. code-block:: scala
enablePlugins(GraalVMNativeImagePlugin)
Settings
--------

Publishing Settings
~~~~~~~~~~~~~~~~~~~

``graalVMNativeImageOptions``
Extra options that will be passed to the ``native-image`` command. By default, this includes the name of the main class.

Tasks
-----
The GraalVM Native Image plugin provides the following commands:

``graalvm-native-image:packageBin``
Generates a native image using GraalVM.

0 comments on commit b65a931

Please sign in to comment.