Fork me on GitHub
#announcements
<
2023-03-10
>
phronmophobic00:03:42

Initial release of https://github.com/phronmophobic/clj-graphviz Most (all?) graphviz libraries build on top of the dot command line tool. Instead, clj-graphviz wraps the underlying c libraries directly. The low-level c wrapper is complete, but the higher level clojure API is currently minimal.

🎉 68
❤️ 2
Huahai00:03:38

It would be nicer to bundle the native lib in the jar, as most JVM libraries using C libraries do

phronmophobic00:03:30

@U0A74MRCJ, I mostly agree. Do you know any good tools for building and deploying jars with native libs?

Huahai00:03:08

It’s a matter of putting them in the resource directory of the jar.

Huahai00:03:36

No extra tools necessary, as far as I can tell.

phronmophobic00:03:39

Right, but you also have to build the library for multiple architectures and platforms, right?

Huahai00:03:10

Right, that’s unavoidable. We all have to do that.

phronmophobic00:03:44

Is there an easy way to do that? My experience is that it's a pain.

Huahai00:03:53

I use a bunch of empty lein projects to do it, you may use clj build, or maven, or whatever

Huahai00:03:14

Depends on what build tool you are using already

phronmophobic00:03:44

Do you cross compile? or use some cloud CI service for the various platforms?

Huahai00:03:57

I use cloud CI

Huahai00:03:45

That’s the price to pay for using native library. It’s not a big deal. Once it’s setup, it’s not a problem.

Huahai00:03:16

You can’t expect your JVM users to do these themselves though, unless you don’t want people to use it.

phronmophobic00:03:32

That's what package managers are for.

phronmophobic00:03:53

I do agree that jar dependencies are easier though.

Huahai00:03:02

I don’t think package managers can do this for you, as native libraries are different, and platforms are numerous

Huahai00:03:40

Besides, you want to have control of the stack because your users will come to you

phronmophobic00:03:52

I tested clj-graphviz on mac and linux using the libs built by the system package managers.

Huahai00:03:40

You can’t expect users to install this and that, because your users are JVM users, they use Java to avoid the native dependency hell.

Huahai00:03:32

If possible, build your native libs statically even.

phronmophobic00:03:08

Can you load static libraries from the JVM?

phronmophobic00:03:28

I thought they had to be shared/dynamic libraries.

Huahai00:03:13

I think so

Huahai00:03:23

This only works for GraalVM though

Huahai00:03:51

For regular JVM, I don’t think so, as you are not going to build the VM.

👍 2
Huahai00:03:14

On GraalVM, static link only works for amd64 linux at the moment

Huahai00:03:32

But that’s what we are doing.

Huahai00:03:14

It’s a lot of work, for musl tool chain has to be used for static linking.

Huahai00:03:02

Anyways, as a library maintainer, that’s the work you have to do, because the users will come to you. You are responsible for the whole stack, from bottom to top. LOL

phronmophobic00:03:30

hmmm, I wonder if there's a way to automatically package native dependencies by just running the package manager script and putting that in a jar?

Huahai01:03:10

What package manager you are referring to? Apt? yum? They are providing for the OS. Putting the deps in the jar is the opposite of that: you are not using OS desp, you are providing deps of your own.

Huahai01:03:40

The reason to use JVM is because it is standalone, not OS dependent. That’s the whole Java story. Your users expect that story to stick, even your library depends on native things. That’s why we bundle .so, .dll, etc. in the jar.

Huahai01:03:43

Trying to use OS lib is more hustle than just compile your own and put them in the jar.

Huahai01:03:42

It’s much less work, trust me.

phronmophobic01:03:16

I do this work for my other library membrane, and it's a pain.

phronmophobic01:03:20

If there's an easier way, I'm definitely open to it. I also have wrappers for other c libraries like ffmpeg, chromium embedded framework, and libclang. It would be great to have an easy way to provide native deps for all these.

Huahai01:03:40

You are welcome to come up with something. Would love to see it.

phronmophobic01:03:31

Do you have any open source examples that show how easy it is?

Huahai01:03:44

This is what I do for datalevin: https://github.com/juji-io/dtlvnative

🙏 2
👍 2
Huahai01:03:09

just copy paste a bunch of files around

phronmophobic01:03:52

Thanks, I'll check it out.

borkdude15:03:44

Maybe it's an idea to decouple the native lib from the clojure code, as the underlying stuff (like compiled Java) often doesn't change as much and then you won't have to upload/download these binaries for every minor clojure change

💡 4
phronmophobic17:03:58

Yea, it’s pretty common to put the native lib in its own jar. It’s also common to use a different jar for each target platform and architecture so you can download only the deps that are actually required.

Ivar Refsdal18:03:56

Neat work @U7RJTCH6J ps maybe old news for you, but have you tried https://openjdk.org/jeps/434? (I've used it with some success myself...)

phronmophobic18:03:40

Not directly, but I have used https://github.com/IGJoshua/coffi which wraps it.

phronmophobic18:03:31

The c wrapper firsts generates a data representation of the c API by parsing the headers and then generates JNA code that does all the ffi. I would also like to have a code generator that uses panama. I really like the #coffi API, but there's some missing pieces for using structs by reference without fully serializing all the data (which I usually rely on).