C headers not found with clang_13

I’m using nix on Darwin. I have this very simple nix shell:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
    buildInputs =
        with pkgs; [
            clang_13
            cmake
            ninja
        ] ++ lib.optionals stdenv.isDarwin [ darwin.DarwinTools ];
}

And I have this C file named test.c:

#include <stdio.h>
int main() {}

When I compile the file, I get this error:

test.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
         ^~~~~~~~~
1 error generated.

What do I have to do to make clang-13 find the standard library headers? I haven’t found a relevant issue on github.

Nix communicates store paths through environment variables:

echo $NIX_CFLAGS_COMPILE
-frandom-seed=s2xbdjx37r -isystem /nix/store/c9q5790qgzxxkbcdkmbd67icq1gqija2-libcxx-12.0.1-dev/include -isystem /nix/store/cp0m6qj9xysasirxixyfglcr1122x3ss-libcxxabi-12.0.1-dev/include -isystem /nix/store/jf5j1vybrzjr5fz6pv315m6w9qmbvi9f-compiler-rt-libc-12.0.1-dev/include -iframework /nix/store/48w7px4bh6bjhgfz3w74ij5s24j4mxxn-apple-framework-CoreFoundation-11.0.0/Library/Frameworks -isystem /nix/store/cirjwpbnqsnj0600x3k2643vll58aqf7-libobjc-11.0.0/include -isystem /nix/store/c9q5790qgzxxkbcdkmbd67icq1gqija2-libcxx-12.0.1-dev/include -isystem /nix/store/cp0m6qj9xysasirxixyfglcr1122x3ss-libcxxabi-12.0.1-dev/include -isystem /nix/store/jf5j1vybrzjr5fz6pv315m6w9qmbvi9f-compiler-rt-libc-12.0.1-dev/include -iframework /nix/store/48w7px4bh6bjhgfz3w74ij5s24j4mxxn-apple-framework-CoreFoundation-11.0.0/Library/Frameworks -isystem /nix/store/cirjwpbnqsnj0600x3k2643vll58aqf7-libobjc-11.0.0/include

But clang doesn’t recognize NIX_xxx flags, how does that work?

Wrapping. Clang (or gcc on linux) is just a script in stdenv, which is “nix aware”:

which clang
/nix/store/vyddzrn2mpf4r67hc9s2nzxa9ifvm9fi-clang-wrapper-12.0.1/bin/clang

What do I have to do to make clang-13 find the standard library headers? I haven’t found a relevant issue on github.

Dont reference clang_13 directly, you will get the unwrapped compiler which doesn’t know where libcxx resides. Instead, you want to use stdenv (or clangXXStdenv) instead. mkShell is just a modified version of stdenv, so it should work by default.

In short, remove clang_13 and it should work.

P.S. clang13Stdenv is available on master, but not on nixos-unstable at the time of writing, wait a few days, and it should be available.

Related video I made on compiling C programs with nix

Thank you. I think I got confused since the package for specific versions of gcc like gcc11 is the compiler wrapper, but specific versions of clang like clang_13 is not the wrapper.

I fixed my nix file like this:

{
    pkgs ? import <nixpkgs> {},
    stdenv ? pkgs.clang13Stdenv
}:
stdenv.mkDerivation {
    name = "nix-shell";
    phases = ["nobuildPhase"];
    buildInputs =
        with pkgs; [
            cmake
            ninja
        ] ++ lib.optionals stdenv.isDarwin [ darwin.DarwinTools ];

    nobuildPhase = ''
        echo
        echo "This derivation is not meant to be built, aborting";
        echo
        exit 1
    '';
}

Yea, sometimes nixpkgs is consistently inconsistent :). And once people take the time to deal with the additional complexity, it’s hard to force a “breaking change” to normalize the conventions.

1 Like