C lib bindings on different platforms

If I want to write a shards that binds a C library(gtk for example), how should I do to let it support different platforms?
There are, as far as I known, Three ways:

  • One is to bring pre-built libs together with the binding code, each lib for each platform. PIP is going this way, it packs wheels for every architecture and operatimg systems, so you can see numpy variants from linux-arm64 to windows-x86 to mac-amd64 and so on.
  • The other is to equip the language with a compiler toolchain, bring source code together with the binding code, and compile the lib locally.Gem is going this way.(but as a Windows user, I frequenty get stuck by errors beyond my level when compiling in the msys environment)
  • Or do neither of this. instead, you either re-write every required lib with native Crystal, or assume that the shards user already have the lib exactly as you want. Cargo seems like going this way.
    Which way does Crystal go on? and what should I do to have my bindings compatible to most platforms?

I’m not sure I follow… For example the standard library binds to libxml2. It doesn’t need to compile anything. It assumes you have libxml installed on your system. For gtk we can assume the user already has the require libraries in their system. If they don’t they get a linker error.

Am I missing something?

Note that unlike Rust, Crystal modules or files aren’t compiled independently.

Therefore I should download or install gtk, place it in CRYSTAL_LIBRARY_PATH,and add @[link("gtk")] on my lib declaration, get it.

Note that unlike Rust, Crystal modules or files aren’t compiled independently.

What does this mean? does it mean that I can’t compile a crystal code to a static lib, and link it to crystal core afterwards, but instead I must compile all the code into an executable in just one shot?

Exactly. There’s no way to compile some Crystal code and later link it with some other Crystal code. Crystal only supports going from an entire program to an executable, linking everything it finds along the way.

1 Like

@homodeluna the Link attribute has some options that integrated with pkg-config to lookup where the library files are located. If the library you use provides a .pc file and is registered in PKG_CONFIG_PATH then you need to match the lib name in the Link attribute.

See Link - Crystal 1.6.0

I never tried it on Windows, but it’s expected that who is trying to compile it to have it proper installed and available through pkg-config or in some default system specific path.