From a234fb2a5b48afdbe525465003929fa0e165c527 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 14 Jun 2022 20:12:45 +0200 Subject: [PATCH 1/6] nixos-generate-config: Add nixpkgs.system to hardware-config.nix --- nixos/modules/installer/tools/nixos-generate-config.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index b74ec838df42..5674bf348d10 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -84,6 +84,15 @@ sub debug { } +# nixpkgs.system +my ($status, @systemLines) = runCommand("nix-instantiate --impure --eval --expr builtins.currentSystem"); +if ($status != 0 || join("", @systemLines) =~ /error/) { + die "Failed to retrieve current system type from nix.\n"; +} +my $system = substr(@systemLines[0], 0, -1); +push @attrs, "nixpkgs.system = lib.mkDefault $system;"; + + my $cpuinfo = read_file "/proc/cpuinfo"; From 89b4bd8b24faa01db9b36f71e58804ed303a9816 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 15 Jun 2022 13:11:22 +0200 Subject: [PATCH 2/6] lib/options: Add showOptionWithDefLocs --- lib/default.nix | 3 ++- lib/options.nix | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/default.nix b/lib/default.nix index 070c2a67cf07..e2a93e63ac1f 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -131,7 +131,8 @@ let getValues getFiles optionAttrSetToDocList optionAttrSetToDocList' scrubOptionValue literalExpression literalExample literalDocBook - showOption showFiles unknownModule mkOption mkPackageOption + showOption showOptionWithDefLocs showFiles + unknownModule mkOption mkPackageOption mdDoc literalMD; inherit (self.types) isType setType defaultTypeMerge defaultFunctor isOptionType mkOptionType; diff --git a/lib/options.nix b/lib/options.nix index 50b19e483736..afae1769afdd 100644 --- a/lib/options.nix +++ b/lib/options.nix @@ -7,6 +7,7 @@ let collect concatLists concatMap + concatMapStringsSep elemAt filter foldl' @@ -340,6 +341,11 @@ rec { in "\n- In `${def.file}'${result}" ) defs; + showOptionWithDefLocs = opt: '' + ${showOption opt.loc}, with values defined in: + ${concatMapStringsSep "\n" (defFile: " - ${defFile}") opt.files} + ''; + unknownModule = ""; } From c9fea8c03cd76c841392feb69b7f6d37f527399e Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 14 Jun 2022 22:34:16 +0200 Subject: [PATCH 3/6] nixos: Add simplified nixpkgs.{hostSystem,buildSystem} --- nixos/modules/misc/nixpkgs.nix | 108 +++++++++++++++++++++++++--- nixos/modules/misc/nixpkgs/test.nix | 61 +++++++++++++++- 2 files changed, 158 insertions(+), 11 deletions(-) diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix index 866bb3516009..132a9b68ceb4 100644 --- a/nixos/modules/misc/nixpkgs.nix +++ b/nixos/modules/misc/nixpkgs.nix @@ -55,9 +55,46 @@ let check = builtins.isAttrs; }; - defaultPkgs = import ../../.. { - inherit (cfg) config overlays localSystem crossSystem; - }; + hasBuildPlatform = opt.buildPlatform.highestPrio < (mkOptionDefault {}).priority; + hasHostPlatform = opt.hostPlatform.isDefined; + hasPlatform = hasHostPlatform || hasBuildPlatform; + + # Context for messages + hostPlatformLine = optionalString hasHostPlatform "${showOptionWithDefLocs opt.hostPlatform}"; + buildPlatformLine = optionalString hasBuildPlatform "${showOptionWithDefLocs opt.buildPlatform}"; + platformLines = optionalString hasPlatform '' + Your system configuration configures nixpkgs with platform parameters: + ${hostPlatformLine + }${buildPlatformLine + }''; + + legacyOptionsDefined = + optional opt.system.isDefined opt.system + ++ (optional (opt.localSystem.highestPrio < (mkOptionDefault {}).priority) opt.localSystem) + ++ (optional (opt.crossSystem.highestPrio < (mkOptionDefault {}).priority) opt.crossSystem) + ; + + defaultPkgs = + if opt.hostPlatform.isDefined + then + let isCross = cfg.buildPlatform != cfg.hostPlatform; + systemArgs = + if isCross + then { + localSystem = cfg.buildPlatform; + crossSystem = cfg.hostPlatform; + } + else { + localSystem = cfg.hostPlatform; + }; + in + import ../../.. ({ + inherit (cfg) config overlays; + } // systemArgs) + else + import ../../.. { + inherit (cfg) config overlays localSystem crossSystem; + }; finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs; @@ -157,6 +194,46 @@ in ''; }; + hostPlatform = mkOption { + type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform + example = { system = "aarch64-linux"; config = "aarch64-unknown-linux-gnu"; }; + # Make sure that the final value has all fields for sake of other modules + # referring to this. TODO make `lib.systems` itself use the module system. + apply = lib.systems.elaborate; + defaultText = literalExpression + ''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform''; + description = '' + Specifies the platform where the NixOS configuration will run. + + To cross-compile, set also nixpkgs.buildPlatform. + + Ignored when nixpkgs.pkgs is set. + ''; + }; + + buildPlatform = mkOption { + type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform + default = cfg.hostPlatform; + example = { system = "x86_64-linux"; config = "x86_64-unknown-linux-gnu"; }; + # Make sure that the final value has all fields for sake of other modules + # referring to this. + apply = lib.systems.elaborate; + defaultText = literalExpression + ''config.nixpkgs.hostPlatform''; + description = '' + Specifies the platform on which NixOS should be built. + By default, NixOS is built on the system where it runs, but you can + change where it's built. Setting this option will cause NixOS to be + cross-compiled. + + For instance, if you're doing distributed multi-platform deployment, + or if you're building machines, you can set this to match your + development system and/or build farm. + + Ignored when nixpkgs.pkgs is set. + ''; + }; + localSystem = mkOption { type = types.attrs; # TODO utilize lib.systems.parsedPlatform default = { inherit (cfg) system; }; @@ -176,10 +253,13 @@ in deployment, or when building virtual machines. See its description in the Nixpkgs manual for more details. - Ignored when nixpkgs.pkgs is set. + Ignored when nixpkgs.pkgs or hostPlatform is set. ''; }; + # TODO deprecate. "crossSystem" is a nonsense identifier, because "cross" + # is a relation between at least 2 systems in the context of a + # specific build step, not a single system. crossSystem = mkOption { type = types.nullOr types.attrs; # TODO utilize lib.systems.parsedPlatform default = null; @@ -193,7 +273,7 @@ in should be set as null, the default. See its description in the Nixpkgs manual for more details. - Ignored when nixpkgs.pkgs is set. + Ignored when nixpkgs.pkgs or hostPlatform is set. ''; }; @@ -216,8 +296,7 @@ in See nixpkgs.localSystem for more information. - Ignored when nixpkgs.localSystem is set. - Ignored when nixpkgs.pkgs is set. + Ignored when nixpkgs.pkgs, nixpkgs.localSystem or nixpkgs.hostPlatform is set. ''; }; }; @@ -240,10 +319,23 @@ in else "nixpkgs.localSystem"; pkgsSystem = finalPkgs.stdenv.targetPlatform.system; in { - assertion = nixosExpectedSystem == pkgsSystem; + assertion = !hasPlatform -> nixosExpectedSystem == pkgsSystem; message = "The NixOS nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but NixOS was configured for system ${nixosExpectedSystem} via NixOS option ${nixosOption}. The NixOS system settings must match the Nixpkgs target system."; } ) + { + assertion = hasPlatform -> legacyOptionsDefined == []; + message = '' + Your system configures nixpkgs with the platform parameter${optionalString hasBuildPlatform "s"}: + ${hostPlatformLine + }${buildPlatformLine + } + However, it also defines the legacy options: + ${concatMapStrings showOptionWithDefLocs legacyOptionsDefined} + For a future proof system configuration, we recommend to remove + the legacy definitions. + ''; + } ]; }; diff --git a/nixos/modules/misc/nixpkgs/test.nix b/nixos/modules/misc/nixpkgs/test.nix index ec5fab9fb4a5..9e8851707f8f 100644 --- a/nixos/modules/misc/nixpkgs/test.nix +++ b/nixos/modules/misc/nixpkgs/test.nix @@ -1,8 +1,63 @@ { evalMinimalConfig, pkgs, lib, stdenv }: +let + eval = mod: evalMinimalConfig { + imports = [ ../nixpkgs.nix mod ]; + }; + withHost = eval { + nixpkgs.hostPlatform = "aarch64-linux"; + }; + withHostAndBuild = eval { + nixpkgs.hostPlatform = "aarch64-linux"; + nixpkgs.buildPlatform = "aarch64-darwin"; + }; + ambiguous = { + _file = "ambiguous.nix"; + nixpkgs.hostPlatform = "aarch64-linux"; + nixpkgs.buildPlatform = "aarch64-darwin"; + nixpkgs.system = "x86_64-linux"; + nixpkgs.localSystem.system = "x86_64-darwin"; + nixpkgs.crossSystem.system = "i686-linux"; + imports = [ + { _file = "repeat.nix"; + nixpkgs.hostPlatform = "aarch64-linux"; + } + ]; + }; + getErrors = module: + let + uncheckedEval = lib.evalModules { modules = [ ../nixpkgs.nix module ]; }; + in map (ass: ass.message) (lib.filter (ass: !ass.assertion) uncheckedEval.config.assertions); +in lib.recurseIntoAttrs { invokeNixpkgsSimple = - (evalMinimalConfig ({ config, modulesPath, ... }: { - imports = [ (modulesPath + "/misc/nixpkgs.nix") ]; + (eval { nixpkgs.system = stdenv.hostPlatform.system; - }))._module.args.pkgs.hello; + })._module.args.pkgs.hello; + assertions = + assert withHost._module.args.pkgs.stdenv.hostPlatform.system == "aarch64-linux"; + assert withHost._module.args.pkgs.stdenv.buildPlatform.system == "aarch64-linux"; + assert withHostAndBuild._module.args.pkgs.stdenv.hostPlatform.system == "aarch64-linux"; + assert withHostAndBuild._module.args.pkgs.stdenv.buildPlatform.system == "aarch64-darwin"; + assert builtins.trace (lib.head (getErrors ambiguous)) + getErrors ambiguous == + ['' + Your system configures nixpkgs with the platform parameters: + nixpkgs.hostPlatform, with values defined in: + - repeat.nix + - ambiguous.nix + nixpkgs.buildPlatform, with values defined in: + - ambiguous.nix + + However, it also defines the legacy options: + nixpkgs.system, with values defined in: + - ambiguous.nix + nixpkgs.localSystem, with values defined in: + - ambiguous.nix + nixpkgs.crossSystem, with values defined in: + - ambiguous.nix + + For a future proof system configuration, we recommend to remove + the legacy definitions. + '']; + pkgs.emptyFile; } From fc0971f4364fa7f8bfbae3bb789fb7e22128a7c7 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 15 Jun 2022 13:13:31 +0200 Subject: [PATCH 4/6] nixos-generate-config: nixpkgs.system -> nixpkgs.hostPlatform --- nixos/modules/installer/tools/nixos-generate-config.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index 5674bf348d10..65b5c0331f42 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -90,7 +90,7 @@ if ($status != 0 || join("", @systemLines) =~ /error/) { die "Failed to retrieve current system type from nix.\n"; } my $system = substr(@systemLines[0], 0, -1); -push @attrs, "nixpkgs.system = lib.mkDefault $system;"; +push @attrs, "nixpkgs.hostPlatform = lib.mkDefault $system;"; my $cpuinfo = read_file "/proc/cpuinfo"; From 1b4f4ddb5b566a4348880738f0489a19f7b05e57 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 16 Jun 2022 22:53:22 +0200 Subject: [PATCH 5/6] release-notes: Add nixpkgs.hostPlatform changes --- .../from_md/release-notes/rl-2211.section.xml | 59 +++++++++++++++++++ .../manual/release-notes/rl-2211.section.md | 27 +++++++++ 2 files changed, 86 insertions(+) diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index 2f5ae9fefe3a..f0e9ff0490a7 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -31,6 +31,65 @@ stdenv.buildPlatform.canExecute stdenv.hostPlatform. + + + The nixpkgs.hostPlatform and + nixpkgs.buildPlatform options have been + added. These cover and override the + nixpkgs.{system,localSystem,crossSystem} + options. + + + + + hostPlatform is the platform or + system string of the + NixOS system described by the configuration. + + + + + buildPlatform is the platform that is + responsible for building the NixOS configuration. It + defaults to the hostPlatform, for a + non-cross build configuration. To cross compile, set + buildPlatform to a different value. + + + + + The new options convey the same information, but with fewer + options, and following the Nixpkgs terminology. + + + The existing options + nixpkgs.{system,localSystem,crossSystem} + have not been formally deprecated, to allow for evaluation of + the change and to allow for a transition period so that in + time the ecosystem can switch without breaking compatibility + with any supported NixOS release. + + + + + nixos-generate-config now generates + configurations that can be built in pure mode. This is + achieved by setting the new + nixpkgs.hostPlatform option. + + + You may have to unset the system parameter + in lib.nixosSystem, or similarly remove + definitions of the + nixpkgs.{system,localSystem,crossSystem} + options. + + + Alternatively, you can remove the + hostPlatform line and use NixOS like you + would in NixOS 22.05 and earlier. + + PHP now defaults to PHP 8.1, updated from 8.0. diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index 8fd88e79a0fe..ecf8452057ce 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -17,6 +17,33 @@ In addition to numerous new and upgraded packages, this release has the followin built for `stdenv.hostPlatform` (i.e. produced by `stdenv.cc`) by evaluating `stdenv.buildPlatform.canExecute stdenv.hostPlatform`. +- The `nixpkgs.hostPlatform` and `nixpkgs.buildPlatform` options have been added. + These cover and override the `nixpkgs.{system,localSystem,crossSystem}` options. + + - `hostPlatform` is the platform or "`system`" string of the NixOS system + described by the configuration. + - `buildPlatform` is the platform that is responsible for building the NixOS + configuration. It defaults to the `hostPlatform`, for a non-cross + build configuration. To cross compile, set `buildPlatform` to a different + value. + + The new options convey the same information, but with fewer options, and + following the Nixpkgs terminology. + + The existing options `nixpkgs.{system,localSystem,crossSystem}` have not + been formally deprecated, to allow for evaluation of the change and to allow + for a transition period so that in time the ecosystem can switch without + breaking compatibility with any supported NixOS release. + +- `nixos-generate-config` now generates configurations that can be built in pure + mode. This is achieved by setting the new `nixpkgs.hostPlatform` option. + + You may have to unset the `system` parameter in `lib.nixosSystem`, or similarly + remove definitions of the `nixpkgs.{system,localSystem,crossSystem}` options. + + Alternatively, you can remove the `hostPlatform` line and use NixOS like you + would in NixOS 22.05 and earlier. + - PHP now defaults to PHP 8.1, updated from 8.0. - `hardware.nvidia` has a new option `open` that can be used to opt in the opensource version of NVIDIA kernel driver. Note that the driver's support for GeForce and Workstation GPUs is still alpha quality, see [NVIDIA Releases Open-Source GPU Kernel Modules](https://developer.nvidia.com/blog/nvidia-releases-open-source-gpu-kernel-modules/) for the official announcement. From 82da0794c28cf7eff6f0a3755fe8ec9d1cb8ed7f Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 21 Jun 2022 14:37:16 +0200 Subject: [PATCH 6/6] nixos-generate-config: Make robust against missing newline The substr solution assumed a newline to be present. The new solution will not remove the newline if it goes missing in the future. Apparently this is idiomatic perl. Thanks pennae for the suggestion! --- nixos/modules/installer/tools/nixos-generate-config.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index 65b5c0331f42..1935d8252607 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -89,7 +89,7 @@ my ($status, @systemLines) = runCommand("nix-instantiate --impure --eval --expr if ($status != 0 || join("", @systemLines) =~ /error/) { die "Failed to retrieve current system type from nix.\n"; } -my $system = substr(@systemLines[0], 0, -1); +chomp(my $system = @systemLines[0]); push @attrs, "nixpkgs.hostPlatform = lib.mkDefault $system;";