NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.58k stars 13.73k forks source link

pkgsLLVM.llvmPackages.stdenv does not work: fatal error: 'cstdio' file not found #153759

Open trofi opened 2 years ago

trofi commented 2 years ago

pkgsLLVM should provide libc++ headers, but it does not. I initially observed it on pkgsLLVM.mold which uses llvmPackages_latest.stdenv.

Here is the one-liner reproducer:

good:

$ nix build --impure --expr 'with import ./. {}; llvmPackages.stdenv.mkDerivation { name = "d"; unpackPhase = "srcs=foo.cc; echo \"#include <cstdio>\" > $srcs"; buildPhase = "$CXX -c $srcs -o $out"; installPhase= " "; }' -L

d> unpacking sources
d> patching sources
d> configuring
d> no configure script, doing nothing
d> building
d> installing
d> post-installation fixup
d> shrinking RPATHs of ELF executables and libraries in /nix/store/dw557ng62rbvnhw5jmqll3xlkz4z79qq-d
d> shrinking /nix/store/dw557ng62rbvnhw5jmqll3xlkz4z79qq-d
d> patchelf: wrong ELF type
d> strip is /nix/store/185kz4r9brb1lay70w025287l11lb5y0-clang-wrapper-7.1.0/bin/strip
d> patching script interpreter paths in /nix/store/dw557ng62rbvnhw5jmqll3xlkz4z79qq-d
d> checking for references to /build/ in /nix/store/dw557ng62rbvnhw5jmqll3xlkz4z79qq-d...
d> patchelf: wrong ELF type

bad:

$ nix build --impure --expr 'with import ./. {}; pkgsLLVM.llvmPackages.stdenv.mkDerivation { name = "d"; unpackPhase = "srcs=foo.cc; echo \"#include <cstdio>\" > $srcs"; buildPhase = "$CXX -c $srcs -o $out"; installPhase= " "; }' -L

d-x86_64-unknown-linux-gnu> unpacking sources
d-x86_64-unknown-linux-gnu> patching sources
d-x86_64-unknown-linux-gnu> configuring
d-x86_64-unknown-linux-gnu> no configure script, doing nothing
d-x86_64-unknown-linux-gnu> building
d-x86_64-unknown-linux-gnu> foo.cc:1:10: fatal error: 'cstdio' file not found
d-x86_64-unknown-linux-gnu> #include <cstdio>
d-x86_64-unknown-linux-gnu>          ^~~~~~~~

Note: <cstdio> is not in the visible path.

sternenseemann commented 2 years ago

This seems to boil down to an issue in the llvmPackages bootstrapping logic, namely llvmPackages.clang picking the wrong wrapper for clang in this line:

https://github.com/NixOS/nixpkgs/blob/952aa6f820ce6ec717425c54b5817c81aac279c5/pkgs/development/compilers/llvm/7/default.nix#L99

The choice is made based on stdenv.cc, so for pkgsLLVM.llvmPackages.cc, we are looking at pkgsLLVM.buildPackages.stdenv.cc which is the C compiler used to build the package set used to build pkgsLLVM which turns out to be gcc.

The fix probably involves looking at targetPackages.stdenv.cc or similar to get a sense of what the default compiler of the current package set is supposed to be.

Another quite bizarre issue I can't yet explain is that pkgsLLVM.llvmPackages.stdenv.cc.bintools turns out to be GNU binutils when it clearly shouldn't.

jonringer commented 2 years ago

might be related: https://github.com/NixOS/nixpkgs/issues/147342

sternenseemann commented 2 years ago

Unrelated in a sense — the fix for this doesn't resolve #147342 unfortunately.

NickCao commented 2 years ago

The same for pkgsCross, reproducible with

{ nixpkgs ? builtins.getFlake "github:NixOS/nixpkgs/master" }:
let
  pkgs = import nixpkgs { system = "x86_64-linux"; };
in
# pkgs.stdenv.mkDerivation {
pkgs.pkgsCross.aarch64-multiplatform.llvmPackages.stdenv.mkDerivation {
  name = "test";
  src = builtins.toFile "test.cc" ''
    #include <cstdio>
    int main() {
      return 0;
    }
  '';
  dontUnpack = true;
  dontInstall = true;
  buildPhase = ''
    $CXX $src -o $out
  '';
}
sternenseemann commented 2 years ago

This is a different, but possibly related issue. aarch64-multiplatform should use gcc and libstdc++ by default and consequently the LLVM stdenv should also rely on libstdc++. Seems like something is going wrong there.

fstamour commented 1 year ago

ok, I thought I was going crazy