From 99ab2550e7ed83597c9b753a0adbc0b5e07cd65d Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 19 Mar 2026 21:43:39 +0800 Subject: [PATCH 1/2] appendOverlays: return spliced packages on empty overlay list `appendOverlays []` returned `self` (the unspliced inner fixpoint) while `import nixpkgs {}` returns `pkgs.__splicedPackages` (the spliced version). This caused `pkgs.makeWrapper` and similar spliced packages to lose their `__spliced` attribute after passing through `appendOverlays`, breaking cross-compilation in NixOS modules. The NixOS `nixpkgs.nix` module calls `cfg.pkgs.appendOverlays cfg.overlays`, and when no overlays are defined, the empty-list short-circuit returned unspliced packages. This meant `nativeBuildInputs = [ pkgs.makeWrapper ]` in NixOS modules would evaluate the host-platform makeWrapper (which throws in cross context) instead of being spliced to buildPackages.makeWrapper. Fix by returning `self.__splicedPackages` instead of `self` for the empty-list case. --- pkgs/top-level/stage.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index be333d3bddc1..e718bda745c5 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -264,7 +264,10 @@ let # in one go when calling Nixpkgs, for performance and simplicity. appendOverlays = extraOverlays: - if extraOverlays == [ ] then self else nixpkgsFun { overlays = args.overlays ++ extraOverlays; }; + if extraOverlays == [ ] then + self.__splicedPackages + else + nixpkgsFun { overlays = args.overlays ++ extraOverlays; }; # NOTE: each call to extend causes a full nixpkgs rebuild, adding ~130MB # of allocations. DO NOT USE THIS IN NIXPKGS. From 514529545bab291d6351935baeb409355c608207 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 19 Mar 2026 21:48:10 +0800 Subject: [PATCH 2/2] tests.top-level: add test for appendOverlays preserving splicing Ensures that appendOverlays with an empty list returns spliced packages, so that cross-compilation in NixOS modules works correctly. --- pkgs/test/top-level/default.nix | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkgs/test/top-level/default.nix b/pkgs/test/top-level/default.nix index e713b617f8dd..3946b363b764 100644 --- a/pkgs/test/top-level/default.nix +++ b/pkgs/test/top-level/default.nix @@ -64,4 +64,22 @@ lib.recurseIntoAttrs { assert lib.all (p: p.stdenv.buildPlatform == p.stdenv.hostPlatform) pkgsLocal; assert lib.all (p: p.stdenv.buildPlatform != p.stdenv.hostPlatform) pkgsCross; pkgs.emptyFile; + + # appendOverlays must preserve splicing so that cross-compilation + # works in NixOS modules (which go through appendOverlays via nixpkgs.nix). + appendOverlaysPreservesSplicing = + let + cross = nixpkgsFun { + localSystem = { + system = "x86_64-linux"; + }; + crossSystem = { + system = "aarch64-linux"; + }; + }; + appended = cross.appendOverlays [ ]; + in + assert cross.makeWrapper ? __spliced; + assert appended.makeWrapper ? __spliced; + pkgs.emptyFile; }