Nix packaging Rust projects: combine fenix Rust 1.90, openssl, lld for fun and profit

wordy backstory

If your Rust project uses openssl from nixpkgs and has not been linked correctly you may see an error like error while loading shared libraries: libssl.so.3 when trying to execute it.

I saw this when upgrading to Rust 1.90 by way of fenix stable toolchain in my projects. Rust 1.90 rustc ships their own lld for a linker. (See the official release notes for more!)
I tried a bunch of tweaks to my nix expressions to correctly link and compile against openssl using the upstream provided rustc and ldd.

25 commits later. No working binary. :cry:

The Rust release notes point out you can configure rustc to use a provided lld.

I tried that. It worked! :sun_with_face:

step by step guide

Here is a guide to help you configure the Rust compiler to use nixpkgs lld and openssl.

  1. Modify your expression to pass the following code gen flag to rustc: -Clink-self-contained=-linker.
  2. Provide llvmPackages.bintools to your package build

Here is a concrete example package expression link-me.nix that puts those steps together:

{
  lib,
  rustPlatform,
  pkg-config,
  openssl,
  stdenv,
  fenix,
  llvmPackages,
}:

rustPlatform.buildRustPackage rec {
  pname = "link-me";
  version = "0.0.0";

  src = ./.;
  cargoHash = "sha256-iCQ0L2efC3x2yUi/jQ7rOQXDcAvxOpcGyICjpqBjxN4=";

  nativeBuildInputs = [
    pkg-config
    fenix.stable.rustc
    fenix.stable.cargo
    llvmPackages.bintools
  ];

  buildInputs = [
    openssl
  ];
  OPENSSL_NO_VENDOR = 1;
  RUSTFLAGS = "-Clink-self-contained=-linker";

  doCheck = false;
}

llvmPackages.bintools provides ld.lld.
Background explained towards end of that article the Wiki links (no pun intended) paragraph “Update”.

[bintools lld version] is wrapped into an rpath-setting shell script […] rpath (also known as RUNPATH) — this is more or less LD_LIBRARY_PATH , just hard-coded into the executable

1 Like