graalvm

Colin (fosskers) 2023-05-25T01:43:07.546489Z

Just adding a small echo that https://github.com/clj-easy/graal-docs/blob/master/doc/hello-world.md did in fact work

Colin (fosskers) 2023-05-25T01:57:35.339419Z

Now I'm on a quest to get static linking working.

Colin (fosskers) 2023-05-25T01:58:11.960149Z

Currently this far. It required a manual specification of --native-compiler-path on my particular OS.

Colin (fosskers) 2023-05-25T01:59:05.756969Z

Unfortunately...

/bin/ld: cannot find -lz: No such file or directory
collect2: error: ld returned 1 exit status
And https://docs.oracle.com/en/graalvm/enterprise/22/docs/reference-manual/native-image/guides/build-static-executables/ says I need the latest zlib, but I do indeed have that installed (via my system package manager) so I'm not sure what the problem is.

Colin (fosskers) 2023-05-25T02:15:17.295759Z

Definitely exists:

zlib /usr/
zlib /usr/include/
zlib /usr/include/zconf.h
zlib /usr/include/zlib.h
zlib /usr/lib/
zlib /usr/lib/libz.a
zlib /usr/lib/libz.so
zlib /usr/lib/libz.so.1
zlib /usr/lib/libz.so.1.2.13

Colin (fosskers) 2023-05-25T02:16:07.903019Z

LIBRARY_PATH looks good...

LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../:/lib/:/usr/lib/

Colin (fosskers) 2023-05-25T02:20:06.577189Z

--static              build statically linked executable (requires static libc and zlib)
but /usr/lib/libz.a is static think_beret

phronmophobic 2023-05-25T03:12:04.163099Z

You want libz to be static. I'm not sure if graalvm picks up LIBRARY_PATH. You can try explicitly putting libz on the path with an arg like:

--native-compiler-options='/usr/lib/libz.a'

phronmophobic 2023-05-25T03:13:55.789709Z

another try would be:

--native-compiler-options='-L' --native-compiler-options='/usr/lib/'

Colin (fosskers) 2023-05-25T03:18:56.587929Z

The LIBRARY_PATH I outputted above was from Graal's own output

phronmophobic 2023-05-25T03:33:59.853329Z

Did you try those compiler args?

Colin (fosskers) 2023-05-25T03:34:13.216309Z

Yes, they unfortunately didn't work

phronmophobic 2023-05-25T03:34:21.941179Z

You can also see how babashka sets up for musl, https://github.com/babashka/babashka/blob/236768cada33d6c570b36e199d3cbb26761574b2/script/setup-musl#L6

Colin (fosskers) 2023-05-25T03:35:56.944779Z

Cute

# Install libz.a in the correct place so ldd can find it
install -Dm644 "/usr/local/lib/libz.a" "/usr/lib/$arch-linux-musl/libz.a"

Colin (fosskers) 2023-05-25T03:38:12.838179Z

That did it!

🎉 1
Colin (fosskers) 2023-05-25T03:38:21.870389Z

The binary is actually smaller than before 🤔

Colin (fosskers) 2023-05-25T03:41:25.665659Z

In my case, it required symlinking a new /usr/lib/musl/lib/libz.a to the original /usr/lib/libz.a

Colin (fosskers) 2023-05-25T03:39:00.274219Z

Got it!

Colin (fosskers) 2023-05-25T03:39:16.061619Z

12mb statically linked binary of a Clojure program

Colin (fosskers) 2023-05-25T05:29:02.925479Z

Having some issues with bigger programs. Has anyone ever seen:

Exception in thread "main" java.lang.IllegalArgumentException: No matching ctor found for class org.eclipse.jetty.server.Server
when trying to run a statically linked binary that uses ring?

phronmophobic 2023-05-25T06:30:13.550889Z

Are you setting (set! *warn-on-reflection* true) and making sure you're not making any reflective calls? What library are you using? One tip is to use babashka libraries so you don't have to worry if they're graalvm compatible.

phronmophobic 2023-05-25T06:31:39.153419Z

Any java interop from clojure in graalvm will require either type hints or some config that tells graalvm to include reflection info for the classes you're interested in.

Colin (fosskers) 2023-05-25T06:35:42.518149Z

It was a very simple program; just a basic Ring server with a single handler.

Colin (fosskers) 2023-05-25T06:36:10.488429Z

It used ring-jetty-adapter as well

phronmophobic 2023-05-25T06:39:55.175429Z

Assuming it works under regular java17, I would check to see if any clojure code makes interop calls that require reflection

Colin (fosskers) 2023-05-25T06:40:48.489149Z

The stack trace was indeed showing a Reflector call

Colin (fosskers) 2023-05-25T06:41:23.044599Z

deeper down mind you, not in code I wrote

phronmophobic 2023-05-25T06:41:36.992949Z

I see ring/jetty under https://github.com/clj-easy/graalvm-clojure, but not sure if anyone has tried new versions.

phronmophobic 2023-05-25T06:42:16.060819Z

Not all clojure libraries are native-image compatible so if a library makes interop calls that require reflection, you either need to patch them or include extra config.

🤔 1
Colin (fosskers) 2023-05-25T06:43:03.091949Z

That example you just posted looks basically exactly the same as what I had

Colin (fosskers) 2023-05-25T06:43:14.932189Z

Perhaps something is just different in newer versions? that one was from 3 years ago

phronmophobic 2023-05-25T06:45:27.871759Z

Yea, I wouldn't be surprised. Having a bit of reflection used in java interop isn't a big deal for most clojure code, so it's easy to let them sneak in if you don't have an explicit check.

Colin (fosskers) 2023-05-25T07:16:18.554819Z

Thanks for your help

👍 1