This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-05-14
Channels
I'm looking at adding native-image support to pack. I know there is already clj.native-image, but it doesn't have a clojure tools (-T) usage, nor a tools.build-like API. Are there any complications/shortcuts/clever hacks that pack could help with? @borkdude I know you do a lot of scripting voodoo with native-image compilation, and it'd be great to port those to be defaults for the whole community using pack if possible.
Additionally, on the off chance anyone knows, I'd love to know the state of using svm-driver to build native-image without graalvm/native-image being installed. I've asked on the graal slack, but I'm not expecting an answer. The maven plugin briefly had support for it, but it was removed.
Seemingly it's not supported right now, due to certain patches in graalvm not being upstreamed yet. That means it's unreliable between versions. That's unfortunate.
My experience with including the svm driver in a project is not good. It makes it incompatible over different version of GraalVM
It is. The maven plugin used to do it. It's not documented. The maven plugin removed the functionality because it doesn't consistently work for all JDKs and svm versions because of patch upstreaming.
It is not that hard to just download GraalVM to a temp folder and use it. The convention that is used is GRAALVM_HOME
- I use that in all my compile scripts
I am considering doing that, yeah. I prefer the version of graal being pinned to the repo, rather than whatever version the user chooses, as it's got a higher reproducibility.
I mean, for the user it is not hard at all to grab a version of graalvm and use that for compilation
Because I want to use a specific version of graalvm and not be dependent on some tool doing that for me, I'm capable of doing that myself
If you are contributing to a new repo, which graal version does the maintainer want to make releases with?
usually the newest, but older ones work too. it's the same with Clojure, you don't usually specify the JVM version in your repo, and clj
doesn't magically grab a 1GB download from the internets
I don't think that comparison is analogous, it's more like specifying which version of the JDK you want your docker image to run with. Releases are a little different from development in terms of increasing consistency. Native image also seems more unstable than the standard JDK. It is also far more user-dependent due to a lack of distribution packaging because of the licensing. My perspective on instability could be inaccurate because I'm watching from afar.
Oh, so it isn't going yet. Good to know. I misunderstood. Still, people might get stuck on older versions.
I usually specify the graalvm version in documentation and people can also check in CI or a Dockerfile. If something is not working, I tell them to upgrade.
but I might not be the right audience for your tool, I don't think I would ever use a tool again which wraps native-image
My opinion is that having an uberjar tool is great, but from there on, just write a script to build with native image
Perhaps @UE21H2HHD has a different opinion :)
My humble opinions? So for the topic of svm… if I’ve understood… I recommend going with the flow and using Graal tooling.
Graal is complicated enough without introducing unsupported or uncommonly used configurations.
And… are you also talking about a build wrapper? I thinking rolling your own makes sense. It is not that complicated and also educates you, at least a bit, on the working of Graal. There are lots of levers and dials to fiddle with for Graal native-image. I personally want to be able to twiddle all that myself. https://github.com/clj-commons/rewrite-clj/blob/5ca373690efd8eb348f9a06eda7c4d32caeece3d/script/helper/graal.clj. I might reuse this on other projects, but only as a template that I would copy and paste.
It seems inefficient and exclusionary to have scripts which are copied around. At the least, a tool could handle locating the native image binary and perhaps give you a few of the boring arguments (eg -cp) to pass to native image. I'm certain there's a solution which both exposes the dials AND reduces the maintenance effort across everyone. Clojure always optimizes for power users first, but it still becomes easier over time.
For example, that version assertion is dope. The perfect function to expose in a library. You could even stick a simple range on it.
Yeah, I felt the temptation at one point too @dominicm! But Graal native-image is so early days and fiddly that I felt that it was not practical to generalize. That’s just me, though! Not at all saying you are wrong and I am right, just sharing.
> At the least, a tool could handle locating the native image binary
This is what the GRAALVM_HOME
environment variable convention is for.
The Github Action https://github.com/graalvm/setup-graalvm/ helps you with setting this up in CI, but doing it manually is trivial too (I've done it manually so far).
I also don't want to call native-image from within a JVM process since graalvm is very memory hungry and wasting extra memory on calling it from a JVM isn't something I want. Just a shell script will do.
If you leave more memory to native-image it will likely also be faster as it spends less time in GC.
That's a great tip, exactly the kind of thing I'm looking for. I know native image will always be highly configured, but I'd love to make the basic hello world fairly seamless.
I think it makes sense to always compile to an uberjar first and then use -jar foo.jar
It doesn't matter much, but I find it easier to reason about an uberjar. e.g you can test if java -jar foo.jar
works, if that doesn't work, then native image will fail as well
I've had some problems with long classpaths on Windows where an uberjar did work correctly
I also find myself wanting to publish an uberjar as an alternative to the native image anyways, so I would need both
And a good default is to allow arbitrary native image arguments on top of the defaults as every projects requires its own settings
You can read more info here: https://github.com/clj-easy/graal-docs