Build GraalVM native images with Clojure Deps and CLI tools
Clojure
279
43 commits
updated Aug 7, 2021
Build GraalVM native images using Clojure Deps and CLI tools.
This should be useful for creating lightweight, native CLI executables using Clojure and deps.edn.
See clj.native-cli for a starter project template.
This project depends on tools.deps.alpha and should be considered alpha itself.
NOTE: As of GraalVM 19.0.0, native-image is no longer included by default:
Native Image was extracted from the base GraalVM distribution. Currently it is available as an early adopter plugin. To install it, run:
gu install native-image. After this additional step, thenative-imageexecutable will be in thebindirectory, as for the previous releases.
➜ $GRAALVM_HOME/bin/gu install native-image
Downloading: Component catalog from www.graalvm.org
Processing component archive: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image licence files (org.graalvm.native-image, version 19.0.0)
Assuming a project structure like this:
.
├── deps.edn
└── src
└── core.clj
In your deps.edn specify an alias with a dependency on clj.native-image:
{:aliases {:native-image
{:main-opts ["-m" "clj.native-image" "core"
"--initialize-at-build-time"
;; optional native image name override
"-H:Name=core"]
:jvm-opts ["-Dclojure.compiler.direct-linking=true"]
:extra-deps
{clj.native-image/clj.native-image
{:git/url "https://github.com/taylorwood/clj.native-image.git"
:sha "7708e7fd4572459c81f6a6b8e44c96f41cdd92d4"}}}}}
Where core.clj is a class with -main entrypoint, for example:
(ns core
(:gen-class))
(defn -main [& args]
(println "Hello, World!"))
From your project directory, invoke clojure with the native-image alias, specifying the main namespace
(core in example above):
➜ clojure -A:native-image
Loading core
Compiling core
Building native image 'core' with classpath 'classes:src:etc.'
classlist: 1,944.26 ms
8<----------------------
[total]: 38,970.37 ms
Note: Either GRAALVM_HOME environment variable must be set, or GraalVM's native-image path must be passed as an argument,
and any additional arguments
will be passed to native-image e.g.:
➜ clojure -A:native-image --verbose
You can now execute the native image:
➜ ./core
Hello, World!
See this Gist for another example.
There are example deps.edn projects in the lein-native-image repo:
The --no-server flag is passed to native-image by default, to avoid creating orphaned build servers.
Also see caveats section of lein-native-image.
GraalVM Native Image AOT Compilation
This project was inspired by depstar.
You'll need Clojure CLI tooling and GraalVM installed to test locally.
Just change the source of the clj.native-image dependency to a :local/root instead of :git/url.
Issues, PRs, and suggestions are welcome!
Copyright © 2018 Taylor Wood.
Distributed under the MIT License.
Clojure
100.0%
Build GraalVM native images with Clojure Deps and CLI tools
Clojure
279
43 commits
updated Aug 7, 2021
Build GraalVM native images using Clojure Deps and CLI tools.
This should be useful for creating lightweight, native CLI executables using Clojure and deps.edn.
See clj.native-cli for a starter project template.
This project depends on tools.deps.alpha and should be considered alpha itself.
NOTE: As of GraalVM 19.0.0, native-image is no longer included by default:
Native Image was extracted from the base GraalVM distribution. Currently it is available as an early adopter plugin. To install it, run:
gu install native-image. After this additional step, thenative-imageexecutable will be in thebindirectory, as for the previous releases.
➜ $GRAALVM_HOME/bin/gu install native-image
Downloading: Component catalog from www.graalvm.org
Processing component archive: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image licence files (org.graalvm.native-image, version 19.0.0)
Assuming a project structure like this:
.
├── deps.edn
└── src
└── core.clj
In your deps.edn specify an alias with a dependency on clj.native-image:
{:aliases {:native-image
{:main-opts ["-m" "clj.native-image" "core"
"--initialize-at-build-time"
;; optional native image name override
"-H:Name=core"]
:jvm-opts ["-Dclojure.compiler.direct-linking=true"]
:extra-deps
{clj.native-image/clj.native-image
{:git/url "https://github.com/taylorwood/clj.native-image.git"
:sha "7708e7fd4572459c81f6a6b8e44c96f41cdd92d4"}}}}}
Where core.clj is a class with -main entrypoint, for example:
(ns core
(:gen-class))
(defn -main [& args]
(println "Hello, World!"))
From your project directory, invoke clojure with the native-image alias, specifying the main namespace
(core in example above):
➜ clojure -A:native-image
Loading core
Compiling core
Building native image 'core' with classpath 'classes:src:etc.'
classlist: 1,944.26 ms
8<----------------------
[total]: 38,970.37 ms
Note: Either GRAALVM_HOME environment variable must be set, or GraalVM's native-image path must be passed as an argument,
and any additional arguments
will be passed to native-image e.g.:
➜ clojure -A:native-image --verbose
You can now execute the native image:
➜ ./core
Hello, World!
See this Gist for another example.
There are example deps.edn projects in the lein-native-image repo:
The --no-server flag is passed to native-image by default, to avoid creating orphaned build servers.
Also see caveats section of lein-native-image.
GraalVM Native Image AOT Compilation
This project was inspired by depstar.
You'll need Clojure CLI tooling and GraalVM installed to test locally.
Just change the source of the clj.native-image dependency to a :local/root instead of :git/url.
Issues, PRs, and suggestions are welcome!
Copyright © 2018 Taylor Wood.
Distributed under the MIT License.
Clojure
100.0%