【问题标题】:Nix does not trigger rebuild of coreutilsNix 不会触发 coreutils 的重建
【发布时间】:2019-11-07 23:32:17
【问题描述】:

我在 Devuan GNU/Linux 系统 (x86_64) 上运行 Nix,并遵循 ~/.nixpkgs/config.nix,如 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;
    };
  };
}

但是当我运行 nix-env -iA nixpkgs.coreutils 时,Nix 安装了原版的 coreutils,并启用了可选功能:

$ 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)

但如果我通过其他名称引用相同的派生(引用透明度):

$ nix-env -iA nixpkgs.coreutils2

Nix 从源代码开始重建,生成二进制文件,编译后没有可选功能,正如请求的那样。更神秘的是,w3m 的压倒一切的构建选项可以工作,并且 do 会触发重建。

另外,我注意到gnutar 有同样的奇怪行为。是否与coreutilsgnutar 对 Nix 本身至关重要这一事实有关?我怎样才能以预期的方式制作coreutils

【问题讨论】:

    标签: build nix


    【解决方案1】:

    这是因为 one final overlay 在您的叠加层之后应用。 (您使用的是packageOverrides,它基本上成为了第一个用户覆盖)

    引用commit

    stdenvOverrides 覆盖用于在 通过 stdenv.overrides 引导。这些包已经有了 在之前的助推阶段应用到它们的叠加层。如果 stdenvOverrides 不是覆盖堆栈中的最后一个,所有剩余的 叠加层将再次应用于这些包。

    gnutar 也由此覆盖设置。

    $ 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" ]
    

    “好”消息是您可以使用普通叠加层来配置最后一个叠加层。它很复杂,但很有效:

    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"
    

    我建议使用覆盖而不是packageOverrides 以确保这发生在最后一个“用户”覆盖中。 所以你的叠加层类似于:

    _: 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 = ...;
    }
    

    【讨论】:

    • 我猜你的意思是s/pkgs/super/(否则super 是未定义的)。但否则它会起作用。谢谢。
    • 等等,不。它无法重新编译perl。将提出新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 2012-03-05
    相关资源
    最近更新 更多