(I am a nix newbie, mostly trying to setup my first project)
I am trying to ensure that all dependencies/buildInputs for my mkShell derivation (in a shell.nix) are built using a specific stdenv – in my case gcc10Stdenv. I can seem to create a new stdenv but I’m not sure how to use a named one like gcc10Stdenv, so I can take advantage of the binary cache.
I am currently using this: shell.nix
{ pkgs ? import <nixpkgs> {
overlays = [
(import ./nix/host-gcc10Stdenv.nix)
];
} }:
pkgs.mkShell {
buildInputs = [
pkgs.libxmlxx # I want this and its dependencies built with GCC10
# and so on ...
];
}
nix/host-gcc10Stdenv.nix
(self: super:
let
stdenv =
let stdenv = super.overrideCC super.stdenv super.gcc10;
in
stdenv.override { cc = super.stdenv.cc; };
in {
inherit stdenv;
}
)
This rebuilds a whole new stdenv with gcc10, how can I simply specify to use the gcc10Stdenv as stdenv, ideally directly in shell.nix? I’ve tried using pkgs.gcc10Stdenv.mkDerivation instead of mkShell, but it seems my buildInputs do not get compiled with that specified stdenv.
Instead of importing, you can just include the expression inline. You should also be able to override the stdenv directly:
{ pkgs ? import <nixpkgs> {
overlays = [
(final: prev: { stdenv = prev.gcc10Stdenv; })
];
} }:
pkgs.mkShell {
buildInputs = [
pkgs.libxmlxx # I want this and its dependencies built with GCC10
# and so on ...
];
}
Though I that should be basically the same as what you have – you will have to build everything yourself since we do not generally build stuff with other stdenvs except for some subsets of packages for selected ones.
@jtojnar When I try that (that was similar to my initial attempt to override stdenv via overlays), I get an infinite recursion error:
> nix-shell --pure --show-trace
error: while evaluating anonymous function at ./shell.nix:1:1, called from undefined position:
while evaluating anonymous function at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/impure.nix:15:1, called from ./shell.nix:1:10:
while evaluating anonymous function at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/default.nix:20:1, called from /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/impure.nix:84:1:
while evaluating anonymous function at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/stdenv/booter.nix:42:1, called from /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/default.nix:126:10:
while evaluating 'dfold' at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/stdenv/booter.nix:60:27, called from /Users/paulreimer/Development/nixos/nixpkgs/pkgs/stdenv/booter.nix:136:4:
while evaluating 'go' at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/stdenv/booter.nix:63:18, called from /Users/paulreimer/Development/nixos/nixpkgs/pkgs/stdenv/booter.nix:72:13:
while evaluating 'folder' at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/stdenv/booter.nix:89:33, called from /Users/paulreimer/Development/nixos/nixpkgs/pkgs/stdenv/booter.nix:68:18:
while evaluating 'allPackages' at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/default.nix:116:17, called from /Users/paulreimer/Development/nixos/nixpkgs/pkgs/stdenv/booter.nix:101:12:
while evaluating anonymous function at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/stage.nix:12:1, called from /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/default.nix:116:26:
while evaluating 'fix' at /Users/paulreimer/Development/nixos/nixpkgs/lib/fixed-points.nix:19:9, called from /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/stage.nix:252:3:
while evaluating 'extends' at /Users/paulreimer/Development/nixos/nixpkgs/lib/fixed-points.nix:69:24, called from /Users/paulreimer/Development/nixos/nixpkgs/lib/fixed-points.nix:19:20:
while evaluating 'stdenvOverrides' at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/stage.nix:130:27, called from /Users/paulreimer/Development/nixos/nixpkgs/lib/fixed-points.nix:69:67:
while evaluating the attribute 'stdenv.overrides' at ./shell.nix:3:21:
while evaluating the attribute 'gcc10Stdenv' at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/all-packages.nix:9014:3:
infinite recursion encountered, at /Users/paulreimer/Development/nixos/nixpkgs/pkgs/top-level/all-packages.nix:11:6
@abbec When I try that, I get a weird linker error [while compiling my application which depends on libxmlxx], which I think is because the packages listed in my shell.nixbuildInputs are not themselves built with the specified stdenv. I am currently using those lines you have suggested, but I also need this additional overlay hack on my dependencies to set their stdenv, too. (which I’m lucky only goes 2 levels deep so I can override them manually, as below), which I am trying to get rid of:
# ./nix/overlays/host-libxmlxx.nix (really wish I didn't need this file at all)
self: {pkgs, libxmlxx, ...}: {
libxmlxx = (
libxmlxx.override{ stdenv = pkgs.gcc10Stdenv; }
).overrideAttrs (oldAttrs: rec {
propagatedBuildInputs = [
pkgs.libxml2
(pkgs.glibmm.override{ stdenv = pkgs.gcc10Stdenv; })
];
});
}
So I think somehow the new stdenv is not being used by the dependencies, hence why this hack is required? [somehow the linker error only fires for C++ code using libxml++, so I don’t need to override stdenv on any C-only dependencies (like libxml2 above), but I think that’s just lazy luck and in theory I should be overriding stdenv on that one, too, in my overlay hack.]
I don’t know how to fix your issue, but the difference between the C and C++ dependency is probably due to ABI compatibility. C has a stable ABI while C++ has not, so it’s not just luck in this case. Good luck on fixing this issue!
I’m having an issue with this as well. Overriding stdenv = super.gcc9stdenv; in an overlay causes an infinite recursion error which I’m not sure how to resolve. Any clues? Here’s the script:
The drawback of this approach is that it’s a big hammer. It will rebuild all inputs recursively, even the ones that are only used at build time, i.e. nativeBuildInputs.
Thank you very much! I just gave it a try and it did all the inputs. The purpose was to avoid gcc. But, clang-wrapper ironically still relies on gcc. I tested with both llvmPackages_latest.{stdenv,libcxxStdenv}.
Oh, yea, on Linux I don’t think there’s a way to avoid bootstrapping with GCC. Once stdenv is built, nothing else will need to rely on previous stages though. Also FYI, pkgs.pkgsLLVM is a package set that uses clang for stdenv, but again it still gets bootstrapped via GCC.
I guess I don’t understand what you meant by this then? It depends on GCC in the sense that it’s needed for bootstrapping. But the same is true for pkgsLLVM. It also bootstraps llvm/clang with GCC.
key information was left out so there came to your confusion. To contextualize it, I’m using the following flake.nix for a project that requires some features from libc++. The is no problem with building the project. The problem is clangd always points to headers file during my daily editing job. Then, I found those unwanted header files come from gcc which results from stdenv.
Without using pkgs.pkgsLLVM, the clang dependency always searches at least from gcc’s c++/v1/include directory. And, this extra unwanted gcc causes a problem. Those gcc dependencies actually have no such an impact. I guess this ambiguity of different gcc dependencies caused confusion
Still I have no idea why config.replaceStdenv won’t solve the problem. And it’s not needed for my flake.nix; pkgs.pkgsLLVM suffices.