From 2850cb73660db33ec3774fac4332b84a794cd3c8 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sat, 1 Mar 2025 12:14:14 +0100 Subject: [PATCH] nixVersions.nix_2_26: Use a multi-output derivation More or less https://github.com/NixOS/nix/pull/12582 and a few cleanups. (will upstream) --- .../nix/2_26/packaging/everything.nix | 329 ++++++++---------- 1 file changed, 148 insertions(+), 181 deletions(-) diff --git a/pkgs/tools/package-management/nix/2_26/packaging/everything.nix b/pkgs/tools/package-management/nix/2_26/packaging/everything.nix index 317eb6166a31..b1b53c4c885c 100644 --- a/pkgs/tools/package-management/nix/2_26/packaging/everything.nix +++ b/pkgs/tools/package-management/nix/2_26/packaging/everything.nix @@ -1,6 +1,7 @@ { lib, stdenv, + lndir, buildEnv, nix-util, @@ -38,7 +39,6 @@ nix-perl-bindings, testers, - runCommand, patchedSrc ? null, }: @@ -70,50 +70,6 @@ let ; }; - dev = stdenv.mkDerivation (finalAttrs: { - name = "nix-${nix-cli.version}-dev"; - pname = "nix"; - version = nix-cli.version; - dontUnpack = true; - dontBuild = true; - libs = map lib.getDev (lib.attrValues libs); - nix = nix-cli; - installPhase = '' - mkdir -p $out/nix-support - echo $libs >> $out/nix-support/propagated-build-inputs - echo $nix >> $out/nix-support/propagated-build-inputs - ''; - passthru = { - tests = { - pkg-config = testers.hasPkgConfigModules { - package = finalAttrs.finalPackage; - }; - }; - - # If we were to fully emulate output selection here, we'd confuse the Nix CLIs, - # because they rely on `drvPath`. - dev = finalAttrs.finalPackage.out; - - libs = throw "`nix.dev.libs` is not meant to be used; use `nix.libs` instead."; - }; - meta = { - mainProgram = "nix"; - pkgConfigModules = [ - "nix-cmd" - "nix-expr" - "nix-expr-c" - "nix-fetchers" - "nix-flake" - "nix-flake-c" - "nix-main" - "nix-main-c" - "nix-store" - "nix-store-c" - "nix-util" - "nix-util-c" - ]; - }; - }); devdoc = buildEnv { name = "nix-${nix-cli.version}-devdoc"; paths = [ @@ -122,147 +78,158 @@ let ]; }; - /** - Produce a set of derivation outputs that implement the multiple outputs interface. - - The multiple outputs interface was originally designed for derivations with - multiple outputs, but it can also be used for packages which do not correspond - 1:1 to a single derivation and whose outputs come from distinct derivations. - */ - makeOutputs = - { - outputs, - defaultOutput ? "out", - extraAttrs ? outputName: value: { }, - }: - - let - prepOutput = - outputName: value: - { - _type = "package"; - /** - For compatibility. The outputs of this package may not actually be implemented using a single derivation. - */ - type = "derivation"; - outputName = outputName; - outPath = value.outPath or value; - } - // extraAttrs outputName value; - - outputAttrs = lib.mapAttrs ( - outputName: value: { outputSpecified = true; } // prepOutput outputName value // commonAttrs - ) outputs; - - # This is without `outputSpecified`, but otherwise matches the `outputAttrs` above. - defaultOutputValue = prepOutput defaultOutput outputs.${defaultOutput} // commonAttrs; - - commonAttrs = { - outputs = builtins.attrNames outputs; - } // outputAttrs; - - in - defaultOutputValue; - in +stdenv.mkDerivation (finalAttrs: { + pname = "nix"; + version = nix-cli.version; -makeOutputs { - extraAttrs = outputName: drv: { - meta = drv.meta // { - description = "The Nix package manager"; - pkgConfigModules = dev.meta.pkgConfigModules; - outputsToInstall = [ - # man is symlinked - "out" + /** + This package uses a multi-output derivation, even though some outputs could + have been provided directly by the constituent component that provides it. + + This is because not all tooling handles packages composed of arbitrary + outputs yet. This includes nix itself, https://github.com/NixOS/nix/issues/6507. + + `devdoc` is also available, but not listed here, because this attribute is + not an output of the same derivation that provides `out`, `dev`, etc. + */ + outputs = [ + "out" + "dev" + "doc" + "man" + ]; + + /** + Unpacking is handled in this package's constituent components + */ + dontUnpack = true; + /** + Building is handled in this package's constituent components + */ + dontBuild = true; + + /** + `doCheck` controles whether tests are added as build gate for the combined package. + This includes both the unit tests and the functional tests, but not the + integration tests that run in CI (the flake's `hydraJobs` and some of the `checks`). + */ + doCheck = true; + + /** + `fixupPhase` currently doesn't understand that a symlink output isn't writable. + + We don't compile or link anything in this derivation, so fixups aren't needed. + */ + dontFixup = true; + + checkInputs = + [ + # Make sure the unit tests have passed + nix-util-tests.tests.run + nix-store-tests.tests.run + nix-expr-tests.tests.run + nix-fetchers-tests.tests.run + nix-flake-tests.tests.run + + # Make sure the functional tests have passed + nix-functional-tests + ] + ++ lib.optionals + (!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform) + [ + # Perl currently fails in static build + # TODO: Split out tests into a separate derivation? + nix-perl-bindings ]; - }; - internals = drv; - name = "nix"; - overrideAttrs = - _: - throw "The nix package does not support overrideAttrs, because it has been split into multiple derivations. Instead, you may call attributes such as overrideSource, appendPatches or overrideAllMesonComponents."; + + nativeBuildInputs = [ + lndir + ]; + + installPhase = + let + devPaths = lib.mapAttrsToList (_k: lib.getDev) finalAttrs.finalPackage.libs; + in + '' + mkdir -p $out $dev/nix-support $doc $man + + # Custom files + echo $libs >> $dev/nix-support/propagated-build-inputs + echo ${nix-cli} >> $dev/nix-support/propagated-build-inputs + + # Merged outputs + lndir ${nix-cli} $out + ( + libs=( ${lib.escapeShellArgs devPaths} ) + for lib in $libs; do + lndir $lib $dev + done + ) + + # Forwarded outputs + ln -s ${nix-manual} $doc + ln -s ${nix-manual.man} $man + ''; + + passthru = { inherit (nix-cli) version; - # Should not be required - inherit (drv) drvPath; - /** - The build platform's system string, used by Nix to dispatch derivations to the correct kinds of hosts. - - This particular attribute is _not_ used for that purpose, but it has the same value, and some other expressions expect it to be present. - */ - inherit (drv) system; - tests = drv.tests or { }; src = patchedSrc; + + /** + These are the libraries that are part of the Nix project. They are used + by the Nix CLI and other tools. + + If you need to use these libraries in your project, we recommend to use + the `-c` C API libraries exclusively, if possible. + + We also recommend that you build the complete package to ensure that the unit tests pass. + You could do this in CI, or by passing it in an unused environment variable. e.g in a `mkDerivation` call: + + ```nix + buildInputs = [ nix.libs.nix-util-c nix.libs.nix-store-c ]; + # Make sure the nix libs we use are ok + unusedInputsForTests = [ nix ]; + disallowedReferences = nix.all; + ``` + */ + inherit libs; + + /** + Developer documentation for `nix`, in `share/doc/nix/{internal,external}-api/`. + + This is not a proper output; see `outputs` for context. + */ + inherit devdoc; + + /** + Extra tests that test this package, but do not run as part of the build. + See + */ + tests = { + pkg-config = testers.hasPkgConfigModules { + package = finalAttrs.finalPackage; + }; + }; }; - outputs = { - inherit dev devdoc; - doc = nix-manual; - out = - (buildEnv { - name = "nix-${nix-cli.version}"; - paths = [ - nix-cli - nix-manual.man - ]; - meta.mainProgram = "nix"; - }).overrideAttrs - ( - finalAttrs: prevAttrs: { - doCheck = true; - doInstallCheck = true; - checkInputs = - [ - # Make sure the unit tests have passed - nix-util-tests.tests.run - nix-store-tests.tests.run - nix-expr-tests.tests.run - nix-fetchers-tests.tests.run - nix-flake-tests.tests.run - - # Make sure the functional tests have passed - nix-functional-tests - - # dev bundle is ok - # (checkInputs must be empty paths??) - (runCommand "check-pkg-config" { checked = dev.tests.pkg-config; } "mkdir $out") - ] - ++ lib.optionals - (!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform) - [ - # Perl currently fails in static build - # TODO: Split out tests into a separate derivation? - nix-perl-bindings - ]; - passthru = prevAttrs.passthru // { - inherit (nix-cli) version; - - /** - These are the libraries that are part of the Nix project. They are used - by the Nix CLI and other tools. - - If you need to use these libraries in your project, we recommend to use - the `-c` C API libraries exclusively, if possible. - - We also recommend that you build the complete package to ensure that the unit tests pass. - You could do this in CI, or by passing it in an unused environment variable. e.g in a `mkDerivation` call: - - ```nix - buildInputs = [ nix.libs.nix-util-c nix.libs.nix-store-c ]; - # Make sure the nix libs we use are ok - unusedInputsForTests = [ nix ]; - disallowedReferences = nix.all; - ``` - */ - inherit libs; - - tests = prevAttrs.passthru.tests or { } // { - # TODO: create a proper fixpoint and: - pkg-config = testers.hasPkgConfigModules { - package = finalAttrs.finalPackage; - }; - }; - }; - } - ); + meta = { + mainProgram = "nix"; + description = "The Nix package manager"; + pkgConfigModules = [ + "nix-cmd" + "nix-expr" + "nix-expr-c" + "nix-fetchers" + "nix-flake" + "nix-flake-c" + "nix-main" + "nix-main-c" + "nix-store" + "nix-store-c" + "nix-util" + "nix-util-c" + ]; }; -} + +})