Hey there ๐ Is anybody here who could help me understand how graalvm and nix interact? I'm trying to build https://github.com/theiceshelf/firn/ from nix and it seems to succeed, but the resulting binary gives me an error when trying to execute it:
Error: Could not find or load main class firn.core
Caused by: java.lang.ClassNotFoundException: firn.core
i'd also gladyly use pre-built binaries, but executing any graalvm bin on nixos aborts with "file does not exist or is not an executable". if somebody knows how to fix that, that would be amazing as well
chmod +x <executable>?
Unfortunately it's not that simple
Meaning that I checked that already and I still get the same message
@arne-clojurians This is probably because the executable you build/use is glibc-linked
The exact error is
Failed to execute process '../firn-test/firn'. Reason:
The file '../firn-test/firn' does not exist or could not be executed.
It's not limited to firn though, when trying out bootleg I hit the same errorTry the babashka static binary, it probably works
It is statically linked against musl
The Error: Could not find or load main class firn.core is probably due to dynamic requires or so
The same thing happens with the most recent prebuilt babashka bin
There's a nixpkg I'm using though: https://github.com/NixOS/nixpkgs/blob/3b6c3bee9174dfe56fd0e586449457467abe7116/pkgs/development/interpreters/clojure/babashka.nix
@arne-clojurians The -> static <- pre-built bin?
Ah no, you're right ๐
Can I see how exactly that's built?
sure, babashka is open source.
Found the install
file already
Thanks!
And thanks for babashka of course
For static linking with musl, you also might want to read: https://github.com/lread/clj-graal-docs#static-linking-with-musl
Yes, that's exactly what I was looking for
Ah I see firn is already made to be compatible for graalvm
Yes, exactly. But the provided binary raises the error described above
Which I'm trying to wrap my head around
which one
the executable not found error I already explained: this is because it's linked against glibc
and glibc isn't in a standard location in nixos
but perhaps it would work if you build it locally though, hmm
perhaps @thiagokokada can help you, he also uses nixos
as does @ericdallo
I am trying to understand the exactly problem here? Is babashka static binary also having this issue of "file not found" :thinking_face: ?
BTW, if firn
is having this issue it is probably using dynamic link
You can use ldd
to check this
the bb static should work.
Graalvm non static binaries doesn't work on NixOS unless you compile the image on your machine
but if you build firn locally in nixos, wouldn't it work with glibc as well?
The bb static works fine for me and @thiagokokada on nixos
BTW
ldd firn
ldd: warning: you do not have execution permission for `./firn'
linux-vdso.so.1 (0x00007ffe6a9cb000)
libpthread.so.0 => /nix/store/ikl21vjfq900ccbqg1xasp83kadw6q8y-glibc-2.32-46/lib/libpthread.so.0 (0x00007f2fb26f4000)
libdl.so.2 => /nix/store/ikl21vjfq900ccbqg1xasp83kadw6q8y-glibc-2.32-46/lib/libdl.so.2 (0x00007f2fb26ef000)
libz.so.1 => not found
libc.so.6 => /nix/store/ikl21vjfq900ccbqg1xasp83kadw6q8y-glibc-2.32-46/lib/libc.so.6 (0x00007f2fb252e000)
/lib64/ld-linux-x86-64.so.2 => /nix/store/ikl21vjfq900ccbqg1xasp83kadw6q8y-glibc-2.32-46/lib64/ld-linux-x86-64.so.2 (0x00007f2fb63d2000)
> but if you build firn locally in nixos, wouldn't it work with glibc as well? It works as long the PATH to glibc doesn't change (but it changes frequently, for example, if any library that glibc depends is updated, the hash on the path is updated)
so, for graalvm works on nixos I always need to go into a shell with gcc, something like this should work:
nix-shell -p 'gcc'
and then graalvm native-image compile works
this is because the gcc
build input is missing from the graalvm nixpkgs derivation
> so, for graalvm works on nixos I always need to go into a shell with gcc, something like this should work: This may work with luck, but it is not necessary correct
Like I said, a rebuild on gcc may broke the binary
Anyway, the root cause of the issue seems to be the fact that firn
is not statically compiled
So maybe ask the maintainer if it could be static compiled :thinking_face: ? Or package it on nixpkgs
probably a PR which makes musl the default on linux is the easiest route
there's also this patch program for nixos right
to make it work with the local glibc
Yeah, patchelf
But looking at the ldd
, it is actually missing libz
$ ldd firn
ldd: warning: you do not have execution permission for `./firn'
linux-vdso.so.1 (0x00007ffe6a9cb000)
libpthread.so.0 => /nix/store/ikl21vjfq900ccbqg1xasp83kadw6q8y-glibc-2.32-46/lib/libpthread.so.0 (0x00007f2fb26f4000)
libdl.so.2 => /nix/store/ikl21vjfq900ccbqg1xasp83kadw6q8y-glibc-2.32-46/lib/libdl.so.2 (0x00007f2fb26ef000)
libz.so.1 => not found
libc.so.6 => /nix/store/ikl21vjfq900ccbqg1xasp83kadw6q8y-glibc-2.32-46/lib/libc.so.6 (0x00007f2fb252e000)
/lib64/ld-linux-x86-64.so.2 => /nix/store/ikl21vjfq900ccbqg1xasp83kadw6q8y-glibc-2.32-46/lib64/ld-linux-x86-64.so.2 (0x00007f2fb63d2000)
Only libz.so.1
is not found for firn
I found a working nix derivation https://github.com/Emiller88/dotfiles/blob/master/packages/firn.nix
nice
Thanks for helping everyone ๐ That was very informative
โฆ static compilation with musl would still make the resulting binary significantly smaller, i guess?
with babashka it's only a 5mb difference or so
ah yes, i mean vs using the patchelf'd version
are you talking about dynamically linked babashka vs statically linked against musl?
yes. you can see the binary sizes by going into the #babashka-circleci-buildss channel