The state of dynamically linking Rust binaries

Firstly, I personally really like Rust. It's a fantastic language and it was the magnet that attracted me away from Golang. But it just might be handicapping itself.

What do I mean by this?

Dynamic linking is an absolute need since it allows for programs with many binaries to prefer Rust. Take a coreutils for example, imagine if the GNU coreutils were to be made in Rust. All the binaries statically linked, wouldn't be efficient or space effective :stuck_out_tongue:

A common reasoning is "Oh the average user does not have that many Rust binaries on their system", but this is harming Rust as a language since it implies that the average user will not have that many Rust binaries on their system, ever. This reasoning will generate a cycle of "The average user does not have that many Rust binaries on their system so there's not a need for dynamically linking" and "The average user does not have that many binaries on their system because the support of dynamically linking is very very immature."

Another common reasoning is "Oh a couple hundred megabytes never hurt anyone, did it? It's not the 80s anymore! Everyone has gigabytes of space!", but space will definitely be a problem if 2/3 of one's operating system is made using Rust. Imagine the amount of useless space it will take.

What this topic aims to do

This topic aims to bring attention and hopefully work on stable support for dynamic linking in the Rust programming language since it's one of the many key points that will allow it to massively scale.

The advantages and disadvantages of dynamic linking

The advantages of dynamic linking -

  • Smaller binary sizes
  • Allows Rust to scale massively and really increase it's user-base

The disadvantages of dynamic linking -

  • Increases complexity from Rust's side
  • Requires much more work on this.

What this topic aims to do

This topic aims to bring attention and hopefully work on stable support for dynamic linking in the Rust programming language since it's one of the many key points that will allow it to massively scale.

The conclusion

Now I know, I know. Dynamic linking is no piece of cake! It requires tons of work, but this posts aim was to bring attention to this topic and possibly make people contribute to this problem. That we, as a community could fix this problem.

Dynamic linking is tons of work, but it just might be really benefitial.

I do agree it would be nice to have dynamically linked stdlib, though it doesn't seems to be realistic in this stage as the libstd itself is steadily evolving. But I doubt some of your reasonings here are behind the trend.

On the performance wise, it will be equally or more efficient depends on the LTO is used. For the space, yes it's less efficient on the traditional use cases. But nowadays many applications(mainly servers but also clients) are distributed as a container image, which bundles the code and the entire environment besides the kernel, including the libc and the whole linux distribution. Glibc is popular to be suboptimal in this use case as its size is non-trivial. It's highly recommended to build applications with statically linked musl libc to reduce the size of the container image.

Mostly-unrelated side note: you can boot the debian with the Rust-based coreutils.

(post deleted by author)

@Hyeonu I agree that dynamic linking might not bring performance benefits but it is certainly one of the largest factors that go into making TRPL space effective.

Plus, I'm unsure on how containerized applications might be related to what I had said in this post :sweat_smile:

Containerized applications are usually found in applications that require a tedious or complex setup.

I can well imagine that dynamic linking produces smaller binaries. That sounds good because it saves space on disk and in RAM at run time.

But to know if this saving is significant, a pressing need, one would have to have some actual figures of the space savings achieved by having a dynamically linked system vs a statically linked one. If the difference is not huge then there is no hurry to go dynamic.

Do you have such hard figures?

I don't understand the part about "Allows Rust to scale massively and really increase it's user-base".

Your last bullet point sounds the same as the first only in different words.

As far as I can tell the point about "how containerized applications might be related to what I had said" is that in the modern world, where things are called out enormously across endless numbers of cores and machines, we find that a lot of it is run in virtual machines. Well, every VM instance carries with it it's own copies of shared libraries and likely only runs one application. Thus the space saving advantage of shared libraries is lost.

Similarly with containerised software. Every container gets its own copies of everything, except the kernel.

@ZiCog You yourself said that "it saves space on disk and in RAM at run time" but then continue to need a hard proof of it. :stuck_out_tongue:

Although, I totally agree. A hard proof of this topic will definitely support it and bring more attention if the difference is large enough.

I will research on this and carry it back to you in a few-ish hours?

Indeed I did say that. I also preceded it with "I can well imagine..." and "That sounds good...". Which are intended to indicate that I don't actually know for sure. I have never measured the space saving of dynamic linking. It is only something I have read on occasion and not really thought about much.

Back in the day we could boot Linux from a floppy disk and load the user space and application from another floppy disk. Since then our systems have grown from a couple of megabytes to gigabytes. Which suggests to me that the space is getting eaten up elsewhere and dynamic linking is not having an impact.

Hence my starting to want to know what the actual, real world, memory saving is. If any.

I really hate sounding critical here because I know you mean well, but this post feels like someone standing in front of a crowd and yelling "there's a problem and someone should do something about it". One bit of advice I was given when taking on leadership roles in volunteer organisations is that unless you can think of a person to actually do a task whenever you say "someone should do X", that "someone" is you.

Here are some prior conversations to help you read up on the history around dynamically linking Rust and learn who else feels strongly about the topic:

Also, this forum is mainly visited by end users of Rust. You might want to create a thread on the internal forums or ask the language team on Zulip.


I don't think this problem needs more advocacy. It needs work. There are hard problems blocking it from happening:

  • It depends on having a stable ABI.

    • This in turn requires research that confirms that the current ABI is good enough to stabilize. That's a lot of work — it touches lots of things, from algorithms for struct layout to internals of std's implementations. From C++ history we know ABI changes later are going to be painful, and freezing immature ABI can end up forcing suboptimal performance.
    • Probably requires new language features that help users guarantee ABI stability across releases (e.g. can I add a private field to a struct? It depends! Nothing will tell me currently what is going break due to such change). cargo semverver is incomplete and unstable.
  • It needs a solution for monomorphised generics. They way generics work is at odds with dynamic linking. AFAIK there's no silver bullet for this. Swift's solution turns zero-cost abstractions into very-high-cost abstractions.

    • MVP could simply ban generics (and inlining) across crate boundaries, but even that probably needs an RFC and some language features to control.
  • It may need a solution for (proc) macros that like generics generate code on the "wrong" side of the dynamic linking boundary.

  • Ability to distribute binaries with dynamically-linked std requires operating systems to ship std as part of the OS. That requires std to also stabilize, and have long-term stable redistributable version.