From 1a0bdc0de1bad45adb17f1706f34bda6c8abdf06 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 7 Jan 2023 03:16:56 -0800 Subject: [PATCH 1/4] stdenv: add rebootstrap parameter --- pkgs/stdenv/cross/default.nix | 3 +++ pkgs/stdenv/custom/default.nix | 3 +++ pkgs/stdenv/darwin/default.nix | 2 ++ pkgs/stdenv/default.nix | 7 +++++++ pkgs/stdenv/freebsd/default.nix | 3 +++ pkgs/stdenv/linux/default.nix | 32 ++++++++++++++++++++------------ pkgs/stdenv/native/default.nix | 2 ++ 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index bf410ec0a6841..ddafa3d2c9aeb 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -1,7 +1,10 @@ { lib , localSystem, crossSystem, config, overlays, crossOverlays ? [] +, rebootstrap ? false }: +assert rebootstrap -> throw "bootstrapping is irrelevant to stdenv/cross"; + let bootStages = import ../. { inherit lib localSystem overlays; diff --git a/pkgs/stdenv/custom/default.nix b/pkgs/stdenv/custom/default.nix index 4c7380118f7d5..9fc4a069f0c65 100644 --- a/pkgs/stdenv/custom/default.nix +++ b/pkgs/stdenv/custom/default.nix @@ -1,7 +1,10 @@ { lib , localSystem, crossSystem, config, overlays, crossOverlays ? [] +, rebootstrap ? false }: +assert rebootstrap -> throw "bootstrapping is not relevant to stdenv/custom"; + assert crossSystem == localSystem; let diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index 76c44870f4ad6..aad704f324d20 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -34,9 +34,11 @@ cpio = fetch { file = "cpio"; sha256 = "sha256-SWkwvLaFyV44kLKL2nx720SvcL4ej/p2V/bX3uqAGO0="; }; tarball = fetch { file = "bootstrap-tools.cpio.bz2"; sha256 = "sha256-kRC/bhCmlD4L7KAvJQgcukk7AinkMz4IwmG1rqlh5tA="; executable = false; }; } +, rebootstrap ? false }: assert crossSystem == localSystem; +assert rebootstrap -> throw "darwin does not yet support automatic rebootstrapping"; let inherit (localSystem) system; diff --git a/pkgs/stdenv/default.nix b/pkgs/stdenv/default.nix index 7a2ad665e09d7..ccee907f8bb60 100644 --- a/pkgs/stdenv/default.nix +++ b/pkgs/stdenv/default.nix @@ -8,6 +8,13 @@ lib # Args to pass on to the pkgset builder, too , localSystem, crossSystem, config, overlays, crossOverlays ? [] + +# If true, the bootstrapFiles will be rebuilt, resulting in a stdenv +# built by the same compiler as its bootstrap tools. Turning this +# feature on will considerably increase the rebuild cycle, but may +# help with troubleshooting the bootstrap. +, rebootstrap ? false + } @ args: let diff --git a/pkgs/stdenv/freebsd/default.nix b/pkgs/stdenv/freebsd/default.nix index de66085876052..3eafa152302c8 100644 --- a/pkgs/stdenv/freebsd/default.nix +++ b/pkgs/stdenv/freebsd/default.nix @@ -1,7 +1,10 @@ { lib , localSystem, crossSystem, config, overlays, crossOverlays ? [] +, rebootstrap ? false }: +assert rebootstrap -> throw "stdenv/freebsd does not yet support automatic rebootstrapping"; + assert crossSystem == localSystem; let inherit (localSystem) system; fetchURL = import ; diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index 870fb04c3883f..d1d8475d02277 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -58,7 +58,7 @@ # $ nix-tree --derivation $(nix-instantiate -A stdenv) { lib , localSystem, crossSystem, config, overlays, crossOverlays ? [] - +, rebootstrap ? false , bootstrapFiles ? let table = { glibc = { @@ -93,7 +93,7 @@ files = archLookupTable.${localSystem.system} or (if getCompatibleTools != null then getCompatibleTools else (abort "unsupported platform for the pure Linux stdenv")); in files -}: +} @args: assert crossSystem == localSystem; @@ -117,7 +117,7 @@ let # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...). - bootstrapTools = import (if localSystem.libc == "musl" then ./bootstrap-tools-musl else ./bootstrap-tools) { + unpackBootstrapTools = bootstrapFiles: import (if localSystem.libc == "musl" then ./bootstrap-tools-musl else ./bootstrap-tools) { inherit system bootstrapFiles; extraAttrs = lib.optionalAttrs config.contentAddressedByDefault @@ -135,10 +135,9 @@ let # the bootstrap. In all stages, we build an stdenv and the package # set that can be built with that stdenv. stageFun = prevStage: - { name, overrides ? (self: super: {}), extraNativeBuildInputs ? [] }: + { name, overrides ? (self: super: {}), extraNativeBuildInputs ? [], bootstrapTools ? prevStage.bootstrapTools }: let - thisStdenv = import ../generic { name = "${name}-stdenv-linux"; buildPlatform = localSystem; @@ -177,9 +176,11 @@ let stdenvNoCC = prevStage.ccWrapperStdenv; }; - overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; }; + overrides = self: super: (overrides self super) // { + fetchurl = thisStdenv.fetchurlBoot; + inherit bootstrapTools; + }; }; - in { inherit config overlays; stdenv = thisStdenv; @@ -187,15 +188,22 @@ let in -[ +# when rebootstrapping, we first prepend a copy of the stdenv stages +# that use the fetched bootstrapFiles: +lib.optionals rebootstrap (import ./. (args // { rebootstrap = false; })) ++ - ({}: { +[ + (prevStage: { __raw = true; - gcc-unwrapped = null; binutils = null; coreutils = null; gnugrep = null; + bootstrapTools = + unpackBootstrapTools + (if rebootstrap + then prevStage.freshBootstrapTools.bootstrapFiles + else bootstrapFiles); }) # Build a dummy stdenv with no GCC or working fetchurl. This is @@ -203,7 +211,7 @@ in # # resulting stage0 stdenv: # - coreutils, binutils, glibc, gcc: from bootstrapFiles - (prevStage: stageFun prevStage { + ({ bootstrapTools, ...}@prevStage: stageFun prevStage { name = "bootstrap-stage0"; overrides = self: super: { @@ -477,7 +485,7 @@ in # and the bootstrapTools-built, statically-linked # lib{mpfr,mpc,gmp,isl}.a which are linked into the final gcc # (see commit cfde88976ba4cddd01b1bb28b40afd12ea93a11d). - (prevStage: { + ({ bootstrapTools, ...}@prevStage: { inherit config overlays; stdenv = import ../generic rec { name = "stdenv-linux"; diff --git a/pkgs/stdenv/native/default.nix b/pkgs/stdenv/native/default.nix index 87862b84bc1b2..c50799db1e51d 100644 --- a/pkgs/stdenv/native/default.nix +++ b/pkgs/stdenv/native/default.nix @@ -1,8 +1,10 @@ { lib , localSystem, crossSystem, config, overlays, crossOverlays ? [] +, rebootstrap }: assert crossSystem == localSystem; +assert rebootstrap -> throw "stdenv/native does not yet support automatic rebootstrapping"; let inherit (localSystem) system; From 12408bcf9336f7817a10953e9f0b932031f1f297 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 7 Jan 2023 03:35:10 -0800 Subject: [PATCH 2/4] aarch64: enable rebootstrap, upgrade to gcc11 Incorporates changes from: - https://github.com/NixOS/nixpkgs/pull/209459 Should fix: - https://github.com/NixOS/nixpkgs/issues/108111 - https://github.com/NixOS/nixpkgs/issues/108305 - https://github.com/NixOS/nixpkgs/issues/201254 Alternative to: - https://github.com/NixOS/nixpkgs/pull/209063 --- pkgs/stdenv/linux/default.nix | 10 +++++++++- pkgs/top-level/all-packages.nix | 1 - 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index d1d8475d02277..eb7f97ac18a30 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -58,7 +58,15 @@ # $ nix-tree --derivation $(nix-instantiate -A stdenv) { lib , localSystem, crossSystem, config, overlays, crossOverlays ? [] -, rebootstrap ? false + +# ARMv8.0 backward compatibility (`-moutline-intrinsics`) currently +# requires regenerating bootstrapFiles; see: +# +# https://github.com/NixOS/nixpkgs/issues/108111 +# https://github.com/NixOS/nixpkgs/pull/108200 +# https://bugzilla.redhat.com/show_bug.cgi?id=1830472 +, rebootstrap ? localSystem.isAarch64 + , bootstrapFiles ? let table = { glibc = { diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index e4dc26675b41f..c49af2dfcb39b 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -14052,7 +14052,6 @@ with pkgs; inherit (let num = if (with stdenv.targetPlatform; isVc4 || libc == "relibc") then 6 - else if (stdenv.targetPlatform.isAarch64 && stdenv.isLinux) then 9 else 11; numS = toString num; in { From bc7725f9bac056a8622055f4655406a1a15b9447 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 7 Jan 2023 12:31:12 -0800 Subject: [PATCH 3/4] make-bootstrap-tools.nix: allow to override bootGCC and busyboxMinimal --- pkgs/stdenv/linux/make-bootstrap-tools.nix | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pkgs/stdenv/linux/make-bootstrap-tools.nix b/pkgs/stdenv/linux/make-bootstrap-tools.nix index c6112766781ee..ef8e525ff3e02 100644 --- a/pkgs/stdenv/linux/make-bootstrap-tools.nix +++ b/pkgs/stdenv/linux/make-bootstrap-tools.nix @@ -1,4 +1,20 @@ -{ pkgs ? import ../../.. {} }: +{ pkgs ? import ../../.. {} +, busyboxMinimal ? "${pkgs.busybox.override { + useMusl = !pkgs.stdenv.targetPlatform.isRiscV; + enableStatic = true; + enableMinimal = true; + extraConfig = '' + CONFIG_ASH y + CONFIG_ASH_ECHO y + CONFIG_ASH_TEST y + CONFIG_ASH_OPTIMIZE_FOR_SIZE y + CONFIG_MKDIR y + CONFIG_TAR y + CONFIG_UNXZ y + ''; + }}/bin/busybox" +, bootGCC ? pkgs.gcc.cc.override { enableLTO = false; } +}: let libc = pkgs.stdenv.cc.libc; @@ -15,22 +31,6 @@ in with pkgs; rec { tarMinimal = gnutar.override { acl = null; }; - busyboxMinimal = busybox.override { - useMusl = !stdenv.targetPlatform.isRiscV; - enableStatic = true; - enableMinimal = true; - extraConfig = '' - CONFIG_ASH y - CONFIG_ASH_ECHO y - CONFIG_ASH_TEST y - CONFIG_ASH_OPTIMIZE_FOR_SIZE y - CONFIG_MKDIR y - CONFIG_TAR y - CONFIG_UNXZ y - ''; - }; - - bootGCC = gcc.cc.override { enableLTO = false; }; bootBinutils = binutils.bintools.override { withAllTargets = false; # Don't need two linkers, disable whatever's not primary/default. @@ -196,7 +196,7 @@ in with pkgs; rec { mkdir $out/on-server XZ_OPT="-9 -e" tar cvJf $out/on-server/bootstrap-tools.tar.xz --hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 -C $out/pack . - cp ${busyboxMinimal}/bin/busybox $out/on-server + cp ${busyboxMinimal} $out/on-server/busybox chmod u+w $out/on-server/busybox nuke-refs $out/on-server/busybox ''; # */ From 3c29ce0d81d894b401700a9ad68ef4079d4522fb Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 7 Jan 2023 12:32:10 -0800 Subject: [PATCH 4/4] stdenv/linux: avoid unnecessary rebuilds when rebootstrapping --- pkgs/stdenv/linux/default.nix | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index eb7f97ac18a30..523acfe80f354 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -210,8 +210,15 @@ lib.optionals rebootstrap (import ./. (args // { rebootstrap = false; })) ++ bootstrapTools = unpackBootstrapTools (if rebootstrap - then prevStage.freshBootstrapTools.bootstrapFiles - else bootstrapFiles); + then (prevStage.freshBootstrapTools.override { + # Copy busybox from the original bootstrapFiles; it is + # safe to do this because it is statically linked. This + # avoids having to rebuild a musl-gcc compiler (glibc + # doesn't know how to do static linking). + busyboxMinimal = prevStage.stdenv.bootstrapFiles.busybox; + # don't rebuild a custom compiler + bootGCC = prevStage.gcc.cc; + }).bootstrapFiles else bootstrapFiles); }) # Build a dummy stdenv with no GCC or working fetchurl. This is @@ -520,7 +527,7 @@ lib.optionals rebootstrap (import ./. (args // { rebootstrap = false; })) ++ inherit (prevStage.stdenv) fetchurlBoot; extraAttrs = { - inherit bootstrapTools; + inherit bootstrapTools bootstrapFiles; shellPackage = prevStage.bash; };