# Best way to handle custom C-bindings in Shards

**URL:** <https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548>\
**Category:** Help & Support\
**Created:** [April 3, 2022, 2:20pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548 "2022-04-03T14:20:50Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![qequ](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/qequ/32/1605_2.png) [@qequ](https://forum.crystal-lang.org/u/qequ)\
**Post date:** [April 3, 2022, 2:20pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/1 "2022-04-03T14:20:50Z")

</div>

I’m currently working on a shard with some custom .c files and I wondered how should I handle the bindings in Crystal. In the examples that I have found Crystal uses the linker directly on object files. Is there any way to compile the .c files during the installation of the shard?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [April 3, 2022, 2:54pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/2 "2022-04-03T14:54:03Z")

</div>

Checkout the `postinstall` hook within [shards/shard.yml.adoc at master · crystal-lang/shards · GitHub](https://github.com/crystal-lang/shards/blob/master/docs/shard.yml.adoc#optional-attributes).

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 3, 2022, 4:08pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/3 "2022-04-03T16:08:12Z")

</div>

Here’s a shard doing that, in case you need a real world example: [myhtml/shard.yml at a4d1e8b8956731588752bc6e5164139cf8f29acb · kostya/myhtml · GitHub](https://github.com/kostya/myhtml/blob/a4d1e8b8956731588752bc6e5164139cf8f29acb/shard.yml#L8)

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [April 5, 2022, 10:39am UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/4 "2022-04-05T10:39:22Z")

</div>

I don’t think this is usually a good idea though. Distribution of source code and binary libraries should be separated. There are lots of issues with trying to build stuff automatically. You need a working toolchain for building the library. It won’t work if you’re cross compiling. Building the library from source is not as efficient as re-using a pre-built binary. …

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 5, 2022, 11:46am UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/5 "2022-04-05T11:46:34Z")

</div>

I don’t know if it’s the best way or not, but Ruby works exactly like that and I can’t remember people complaining about the way it works.

What alternative do you suggest?

---

<div class="post-metadata">

**Author:** ![mavu](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/mavu/32/213_2.png) [@mavu](https://forum.crystal-lang.org/u/mavu)\
**Post date:** [April 5, 2022, 12:10pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/6 "2022-04-05T12:10:44Z")

</div>

I was already once bitten by this. there is a youtube shard ([GitHub - iv-org/invidious: Invidious is an alternative front-end to YouTube](https://github.com/iv-org/invidious)) that i wanted to run on a Raspberry pi, only to notice that it ships a binary library that of course does not work on ARM.

So, yes, mixing code and binary in a repo is always a bad idea.  
I think a fresh language should have protability as an ideal. No need to repeat the errors of the past.

---

<div class="post-metadata">

**Author:** ![anon69898395](https://avatars.discourse-cdn.com/v4/letter/a/848f3c/32.png) [@anon69898395](https://forum.crystal-lang.org/u/anon69898395)\
**Post date:** [April 5, 2022, 1:46pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/7 "2022-04-05T13:46:43Z")

</div>

I don’t feel able to judge what’s the better way (or even the _right_ way) and what isn’t, as both ways have their ups and downs. But I would disagree that this is how it works in Ruby. If Ruby gems come with C code, they always compiled the C stuff during `gem install`…

Thinking about it - is it possible that this behaviour is depending on the platform? I think to remember that on Windows the gems came indeed already precompiled. But I have never seen it like that for OSX or Linux.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 5, 2022, 2:07pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/8 "2022-04-05T14:07:03Z")

</div>

> If Ruby gems come with C code, they always compiled the C stuff during `gem install`

That’s what happens with Crystal too. So how is that different than Ruby?

---

<div class="post-metadata">

**Author:** ![anon69898395](https://avatars.discourse-cdn.com/v4/letter/a/848f3c/32.png) [@anon69898395](https://forum.crystal-lang.org/u/anon69898395)\
**Post date:** [April 5, 2022, 2:22pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/9 "2022-04-05T14:22:37Z")

</div>

Oh my bad, sorry.  
In that case I obviously misunderstood you (or misunderstood the rest of this topic regarding how things happen in Crystal).

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [April 5, 2022, 5:32pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/10 "2022-04-05T17:32:57Z")

</div>

There’s a difference between

1. A gem/shard that has parts of its implementation written in C.
2. A gem/shard that provides bindings to an existing C library.

Case 1 is typical in Ruby for performance reasons. But it’s pretty uncommon in Crystal because you can write performant implementations directly in Crystal. The C code is an integral element of this specific project, and when it is installed, it needs to build its own C library.

Case 2 happens in both Ruby and Crystal for the purpose of reusing existing libraries. Here, the C code comes from somewhere else, and it’s usually easy to acquire pre-build binaries for the respective library. So there’s no need to worry about building it from the gem/shard itself.  
Instead, you can use whatever packaging mechanism that your system provides for installing binary packages.

---

<div class="post-metadata">

**Author:** ![qequ](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/qequ/32/1605_2.png) [@qequ](https://forum.crystal-lang.org/u/qequ)\
**Post date:** [April 6, 2022, 2:21pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/11 "2022-04-06T14:21:17Z")

</div>

> [@straight-shoota](#):
>
> But it’s pretty uncommon in Crystal because you can write performant implementations directly in Crystal.

Is Crystal performant enough to consider porting my C code to Crystal? I’m working mainly on random number generation

---

<div class="post-metadata">

**Author:** ![anon69898395](https://avatars.discourse-cdn.com/v4/letter/a/848f3c/32.png) [@anon69898395](https://forum.crystal-lang.org/u/anon69898395)\
**Post date:** [April 6, 2022, 2:49pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/12 "2022-04-06T14:49:50Z")

</div>

I don’t know how it’s regarding your specific use case (random number generation),  
but of the (very limited) things I have done with Crystal, the speed was incredible and would not justify to deal with any C code.

---

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [April 7, 2022, 5:46pm UTC](https://forum.crystal-lang.org/t/best-way-to-handle-custom-c-bindings-in-shards/4548/13 "2022-04-07T17:46:27Z")

</div>

Crystal’s performance is on par with C for a lot of things. If your code is exclusively CPU-bound (rather than, say, talking over a network) you might notice Crystal being _slightly_ slower, but not radically so. If you’re doing network I/O, the gap closes significantly.

As with all performance comparisons, though, the best way to answer the question is to try porting it over. Otherwise, the best we can do is speculate.
