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