Nix does not trigger rebuild of coreutils

眉间皱痕 提交于 2019-12-11 18:42:55

问题


I am running Nix on top of Devuan GNU/Linux system (x86_64), with following ~/.nixpkgs/config.nix, as documented in Nix Pills:

{
  packageOverrides = pkgs: {
    coreutils = pkgs.coreutils.override {
      aclSupport = false;
      attrSupport = false;
      selinuxSupport = false;
    };
    coreutils2 = pkgs.coreutils.override {
      aclSupport = false;
      attrSupport = false;
      selinuxSupport = false;
    };
    w3m = pkgs.w3m.override {
      graphicsSupport = false;
      imlib2 = null;
      x11Support = false;
      mouseSupport = true;
    };
  };
}

But when I run nix-env -iA nixpkgs.coreutils, Nix installs stock version of coreutils, with optional features enabled:

$ nix-env -iA nixpkgs.coreutils
replacing old 'coreutils-8.31'
installing 'coreutils-8.31'
$ ldd /home/iu/.nix-profile/bin/ls |grep libattr
        libattr.so.1 => /nix/store/5xwmn6ai8c42j84k6gdzja0lnkdi3c60-attr-2.4.48/lib/libattr.so.1
(0x00007f0354e7f000)

But if I refer to same derivation (referential transparency) via other name:

$ nix-env -iA nixpkgs.coreutils2

Nix starts rebuild from source, which results in binaries, compiled without optional features, just as requested. What is even more mysterious, overriding build options for w3m works and do trigger rebuild.

Also, I noticed same strange behavior with gnutar. Is is somehow related to the fact that coreutils and gnutar are essential to Nix itself? How can I make coreutils in expected way?


回答1:


This happens because one final overlay is applied after your overlays. (You're using packageOverrides which becomes essentially the first user overlay)

To quote the commit:

The stdenvOverrides overlay is used to bring packages forward during bootstrapping via stdenv.overrides. These packages have already had the overlays applied to them in the previous boostrapping stage. If stdenvOverrides is not last in the overlays stack, all remaining overlays will windup being applied again to these packages.

gnutar is also set by this overlay.

$ nix repl '<nixpkgs>'
nix-repl> lib.attrNames (stdenv.overrides pkgs pkgs)
[ "acl" "attr" "bash" "binutils" "binutils-unwrapped" "bzip2" "coreutils" "diffutils" "findutils" "gawk" "gcc" "glibc" "gnugrep" "gnumake" "gnupatch" "gnused" "gnutar" "gzip" "patchelf" "pcre" "xz" "zlib" ]

The "good" news is you can use a normal overlay to configure the last overlay. It's convoluted but it works:

nix-repl> (import <nixpkgs> { overlays = [ (self: super: { stdenv = super.stdenv // { overrides = self2: super2: super.stdenv.overrides self2 super2 // { coreutils = "put your coreutils here"; }; }; }) ]; }).coreutils
"put your coreutils here"

I recommend using overlays instead of packageOverrides to make sure this happens in the last "user" overlay. So your overlay would be similar to:

_: super:
let
  coreutils = pkgs.coreutils.override {
    aclSupport = false;
    attrSupport = false;
    selinuxSupport = false;
  };
in
{
  # Overrides for stuff from stdenv go here. They're applied last
  # so we use the same stdenv for builds but a custom coreutils etc for
  # our system. This allows use to still use cache.nixos.org.
  stdenv = super.stdenv // {
    overrides = self2: super2: super.stdenv.overrides self2 super2 // {
      inherit coreutils;
    };
  };

  w3m = ...;
}


来源:https://stackoverflow.com/questions/58758367/nix-does-not-trigger-rebuild-of-coreutils

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!