DEV Community

Abhishek Pareek
Abhishek Pareek

Posted on

Build statically linked Rust binary with musl (and avoid a common pitfall)

Introduction

I was required to produce a x86-64 statically linked Rust binary for a containerized workload at work. This guide briefly outlines the process of doing so using musl, a lightweight C library. Unlike traditional compilation with glibc, musl eliminates dynamic dependencies, resulting in a single, external dependency-free executable.

A quick word on why musl is preferred over glibc

Even if a program is statically linked with glibc, it still requires to dynamically load the c library in order to satisfy loading of some NSS and iconv modules. ref

Steps

  • Create a new cargo project
  $ cargo new --bin static-rust-binary
Enter fullscreen mode Exit fullscreen mode
  • Build the default binary
  $ cd static-rust-binary
  $ cargo build 
Enter fullscreen mode Exit fullscreen mode
  • Check it is dynamically linked
  $ file ./target/debug/static-rust-binary 
./target/debug/static-rust-binary: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=774a033de72094a3ea8a7ac99261b57a86603173, for GNU/Linux 3.2.0, with debug_info, not stripped
Enter fullscreen mode Exit fullscreen mode
  • Change build target to musl and re-compile
  $ cargo build --release --target=x86_64-unknown-linux-musl
Enter fullscreen mode Exit fullscreen mode
  • Check if the binary is now statically linked
  $ file ./target/x86_64-unknown-linux-musl/release/static-rust-binary 
./target/x86_64-unknown-linux-musl/release/static-rust-binary: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), static-pie linked, BuildID[sha1]=e3880597fbf7adcb623d246b69c52d9aee6fe867, with debug_info, not stripped
Enter fullscreen mode Exit fullscreen mode

🎩✨ Voilà! ✨🎩
The statically linked rust binary is ready which can now be put in a scratch container to be run on #docker #kubernetes etc.


‼️ Attention! ‼️

In my experience I've run into trouble generating a statically linked binary if the project dependencies have implicitly or explicitly included openssl-sys crate. For example -

$ cargo build --release --target=x86_64-unknown-linux-musl
   ...
   Compiling openssl v0.10.63
   ...
   Compiling openssl-sys v0.9.99
error: failed to run custom build command for `openssl-sys v0.9.99`
Enter fullscreen mode Exit fullscreen mode

In this case the simplest way I've been able to fix the problem is to explicitly add the openssl crate (latest version) with the features = vendored conditional dependency to the Cargo.toml (Note: as of today "v0.10.63" is the latest version of openssl crate).

[dependencies]
...
openssl = { version = "0.10.63", features = ["vendored"] }
Enter fullscreen mode Exit fullscreen mode

Re-running the build compiles successfully.

$ cargo build --release --target=x86_64-unknown-linux-musl
   Compiling openssl v0.10.63
   ...
   Compiling openssl-sys v0.9.99
   ...
   Compiling static-rust-binary v0.1.0 (/home/abhishek.pareek/src/rust/simple-static-rust-binary)
Enter fullscreen mode Exit fullscreen mode

🤞 Hopeful this will help someone get unstuck in the future! 🌟 And don't hesitate to comment if this approach worked or not! 🚀

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay