How to get path to an actual implementation of the c++ stdlib in build environment?

I’m working on a project where I’d like to nix-shell into an environment with a variable pointing to the source code directory of an implementation of the c++ stdlib. If I have a default.nix with just

with import <nixpkgs> {};
  stdenv.mkDerivation {
    inherit libstdcxx5;

then I get a variable $libstdcxx5 but it will only give me a directory with object files.

Adding as a dependency should do the trick, so:

with import <nixpkgs> {};

mkShell {
  buildInputs = [ ];

I’m looking for the actual source code, not object files. Is there any way to do that through Nixpkgs or will I have to go through fetchurl?

Normally, the source is unpacked in the sandbox when instantiating a derivation. If you want the source in the store, you could make a small derivation that copies the source into a store path. I am not sure if there is a trivial builder that does this for you, but it’s easy to hand-roll a derivation. E.g.:

with import <nixpkgs> {};
let libstdcpp =
  stdenv.mkDerivation {
    pname = "libstdcpp-src";
    version =;
    src =;

    phases = [ "unpackPhase" "installPhase" ];

    installPhase = ''
      mkdir -p $out
      cp -r . $out
in mkShell {
  MY_SOURCE_PATH = "${libstdcpp}/libstdc++-v3";

If you need to do this for more sources, you could factor this out to a small function (perhaps it already exists in nixpkgs). You could disable more phases e.g. if you do not want shebang patching, or provide a custom builder script.

Edit: updated with @lilyball 's suggestions.


Nitpick: This won’t copy files beginning with .. It might be better just to have the installPhase be cp -r . $out.

It might also be simpler to say phases = [ "unpack" "install" ] rather than disabling specific phases. This way you’ll also prevent fixup from running, which is probably a good thing.


Works beautifully, thanks!

Thanks for the nitpicks @lilyball. I have updated the example, in case someone needs/finds this in the future.