Using mold as linker prevents libraries from being found

I installed mold using home-manager like this:

  home.packages = with pkgs; [
    mold
  ];

  home.file.".cargo/config.toml".text = ''
    [target.x86_64-unknown-linux-gnu]
    linker = "clang"
    rustflags = ["-C", "link-arg=-fuse-ld=${pkgs.mold}/bin/mold"]
  '';

This works fine as long as I’m building pure Rust projects. When I tried to build something that needed libpq, compilation failed saying libpq.so.5 not found.

The issue goes away if I remove the cargo/config.toml.

Any idea how to fix this?

2 Likes

This is probably the same issue lld has: LLD linker does not have required nixpkgs wrapper script and flags · Issue #24744 · NixOS/nixpkgs · GitHub

1 Like

Apparently we do have a wrapped lld now, but it’s not in pkgs.lld, it’s in pks.llvmPackages.bintools.

Let me restate the solution more clearly:

There are two packages that provide LLD in nixpkgs: pkgs.lld and pkgs.llvmPackages.bintools . The former is unwrapped, and doesn’t, eg, set rpath. The latter is wrapped, and just works. So, the following fixed the issue I was having with compiling Rust code:

matklad/config@440b1e2

Source: LLD linker does not have required nixpkgs wrapper script and flags · Issue #24744 · NixOS/nixpkgs · GitHub

I just found the same issue as the OP.

I managed to comeup with a fix: I’m not sure this is the best way to go, but it does make mold work. I’ve applied this in a small rust project: flake devShell: Use gcc12 and link using mold (4cd5ad13) · Commits · Roosemberth Palacios / mtt · GitLab

Basically, it consist of wrapping mold binaries with bintools-wrapper/ld-wrapper.sh:

    devShells = forAllSystems (pkgs: with pkgs; let
      bintools-wrapper = "${nixpkgs}/pkgs/build-support/bintools-wrapper";
      mold' = symlinkJoin {
        name = "mold";
        paths = [ mold ];
        nativeBuildInputs = [ pkgs.makeWrapper ];
        suffixSalt = lib.replaceStrings ["-" "."] ["_" "_"] targetPlatform.config;
        postBuild = ''
          for bin in ${mold}/bin/*; do
            rm $out/bin/"$(basename "$bin")"

            export prog="$bin"
            substituteAll "${bintools-wrapper}/ld-wrapper.sh" $out/bin/"$(basename "$bin")"
            chmod +x $out/bin/"$(basename "$bin")"

            mkdir -p $out/nix-support
            substituteAll "${bintools-wrapper}/add-flags.sh" $out/nix-support/add-flags.sh
            substituteAll "${bintools-wrapper}/add-hardening.sh" $out/nix-support/add-hardening.sh
            substituteAll "${bintools-wrapper}/../wrapper-common/utils.bash" $out/nix-support/utils.bash
          done
        '';
      };
    in {
      default = mkShell.override({ stdenv = gcc12Stdenv; }) {
        NIX_CFLAGS_LINK = "-fuse-ld=mold";
        packages = [ cargo clippy gdb rust-analyzer rustc rustfmt mold' ];
        inputsFrom = [ mtt ];
      };
    });
4 Likes

I added a useMoldLinker stdenv adapter stdenvAdapters: add useMoldLinker · NixOS/nixpkgs@299a7bd · GitHub

EDIT there’s now mold-wrapped

2 Likes

There’s also mold: wrap so it can find system libraries by dpc · Pull Request #257158 · NixOS/nixpkgs · GitHub

2 Likes