How to correctly populate a clang and llvm development environment using nix-shell?

Thanks to the discussion in OpenSSL dependency for Rust - #4 by danieldk I learned you can add pkgconfig to a shell.nix that needs to use openssl. (I also updated the wiki).

I then thought to try the same trick for a shell.nix used to compile a Rust project, olm-rs, that needs clang and llvm. I started with the following shell.nix:

# copied expressions from https://nixos.wiki/wiki/Rust
# and Mozilla's nix overlay README
# https://www.scala-native.org/en/latest/user/setup.html
let
  moz_overlay = import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz);
  pkgs = import <nixpkgs> { overlays = [ moz_overlay ]; };
in
  with pkgs;
  stdenv.mkDerivation {
    name = "clang-env-with-nightly-rust";
    buildInputs = [
      pkgs.latest.rustChannels.nightly.rust
      clang
      llvmPackages.libclang
      olm
    ];
    # why do we need to set the library path manually?
    shellHook = ''
      export LIBCLANG_PATH="${pkgs.llvmPackages.libclang}/lib";
    '';
  }

You’ll notice the ugly shellHook where I manually export the LIBCLANG_PATH.
When I remove the shellHook entirely and add pkgconfig to buildInputs, LIBCLANG_PATH is still not populated.

Am I specifying the wrong llvm and clang build inputs?
Or should I be doing something like what scala-native does?

1 Like

Yeah, clang does not provide pkgconfig files.

https://bugs.llvm.org/show_bug.cgi?id=9405

There are some other places it looks at:

https://crates.io/crates/clang-sys/0.8.0

You end up needing to set LIBCLANG_PATH no matter what here. It also looks for llvm-config, but we don’t put libclang there. So LIBCLANG_PATH is pretty much required. We could make this easier with a setup hook though.

PR here: LIBCLANG_PATH hook by matthewbauer · Pull Request #67725 · NixOS/nixpkgs · GitHub

1 Like

Wow, thanks for the quick answer and solution @matthewbauer!
Confirms that I wasn’t crazy trying to write the shell.nix that way.