# Portable, dynamically linked packages on Linux

**URL:** <https://forum.crystal-lang.org/t/portable-dynamically-linked-packages-on-linux/7201>\
**Category:** Crystal Contrib\
**Created:** [September 23, 2024, 5:39pm UTC](https://forum.crystal-lang.org/t/portable-dynamically-linked-packages-on-linux/7201 "2024-09-23T17:39:41Z")\
**Posts on this page:** 4\
**Page:** 1

<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:** [September 23, 2024, 5:39pm UTC](https://forum.crystal-lang.org/t/portable-dynamically-linked-packages-on-linux/7201/1 "2024-09-23T17:39:41Z")

</div>

This article presents a very clever mechanism for dynamically linked executables to be fully portable, just like a statically linked one would be.

[https://brioche.dev/blog/portable-dynamically-linked-packages-on-linux/](https://brioche.dev/blog/portable-dynamically-linked-packages-on-linux/)

**TL;DR:** The executable needs to ship with all dynamically linked libraries and the necessary ELF-interpreter (`ld-linux.so`). The magic happens in a tiny, statically linked bootstrap program which exec’s the ELF-interpreter as userspace exec for a correct `/proc/self/exe` and with library path pointing to the bundled shared libraries. 💡

I figure this could be very useful for Crystal as it would allow us to ship portable builds of the interpreter. It needs to be dynamically linked for full support of loading libraries in the interpreter runtime (cf. [Shipping the interpreter](https://forum.crystal-lang.org/t/shipping-the-interpreter/4524)).

---

<div class="post-metadata">

**Author:** ![ralsina](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/ralsina/32/2139_2.png) [@ralsina](https://forum.crystal-lang.org/u/ralsina)\
**Post date:** [September 23, 2024, 7:43pm UTC](https://forum.crystal-lang.org/t/portable-dynamically-linked-packages-on-linux/7201/2 "2024-09-23T19:43:42Z")

</div>

A file that contains all that directory via baked\_file\_system then eutopexpands it into ~/.local/whatever and creates a shim in ~/.local/bin …

---

<div class="post-metadata">

**Author:** ![Sunrise](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/sunrise/32/2339_2.png) [@Sunrise](https://forum.crystal-lang.org/u/Sunrise)\
**Post date:** [September 24, 2024, 5:18am UTC](https://forum.crystal-lang.org/t/portable-dynamically-linked-packages-on-linux/7201/3 "2024-09-24T05:18:53Z")

</div>

What’s the advantages of packaging the entire dynamic linking runtime environment compared to directly distributing static-compiled programs?  
I think it is a project somewhat similar to conda, but I would prefer conda because it offers more packages, is more stable and mature (as Rust, Ruby, Clang, etc. have already done), provides more comprehensive platform support, and has lighter startup tools (such as micromamba, pixi, etc.).

---

<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:** [September 24, 2024, 8:09am UTC](https://forum.crystal-lang.org/t/portable-dynamically-linked-packages-on-linux/7201/4 "2024-09-24T08:09:42Z")

</div>

> [@Sunrise](#):
>
> What’s the advantages of packaging the entire dynamic linking runtime environment compared to directly distributing static-compiled programs?

One major reason is that some libraries are incredibly difficult to link fully statically. Glibc is an example for that. For that reason, statically linked programs usually use musl libc. That’s not generally bad, but there are differences between these libc implementations and some use cases may need glibc specifically.

The Crystal interpreter has a specific use case for `libdl`: it needs to be able to load dynamic libraries at runtime for handling `lib` bindings in interpreted code. `libdl` is simply not available as a static library. So it’s impossible to statically link a fully functional interpreter.  
See [Shipping the interpreter](https://forum.crystal-lang.org/t/shipping-the-interpreter/4524) for details.
