Generate a library and load it

Hi guys, I have a question (for Linux).

How can I build a crystal library I wrote as a library (.so), and then load it from another crystal program ?

Because I start seriously to think to split my project in libraries, because I am starting to write too an init system (in Crystal as well)

To the best of my knowledge, the best documentation on this topic is here.
Please read Asterite’s comments and the replies to them.

Creating a C-ABI Shared Library in Crystal

crystal build sum.cr --single-module --link-flags="-shared" -o libsum.so
fun crystal_init : Void
  GC.init

  LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null)
end

fun sum(a : Int32, b : Int32): Int32
  puts "Calculate sum"
  a + b
end

This only works when there is only one shared library; with two or more, there will be a segmentation fault.

One approach would be to use a single libgc across all libraries while thoroughly mangling other symbols, but this is highly complex. Another idea—related to Ruby’s “external type definitions”—involves generating a type and ID translation table at compile time, though Crystal’s open classes and abstract types complicate things. Finally, there is a possibility that a dedicated shared library format for Crystal, rather than relying on the C ABI, could be devised (though exporting to WebAssembly might become more prevalent).

Since this issue is often discussed, I have written what I have heard so far and what can be inferred from it. Comments from those who know a little more about the issue are expected.

2 Likes

This is currently impossible.

It’s technically possible to create a library from crystal code, but every compilation of a Crystal program will generate the same symbols that will conflict with each other.

We don’t have the means to create a public external API while hiding the internal private symbols.