Commit 2850cb73 authored by Robert Hensing's avatar Robert Hensing Committed by Jörg Thalheim
Browse files

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)
parent 0812c9a3
Loading
Loading
Loading
Loading
+142 −175
Original line number Diff line number Diff line
{
  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,93 +78,50 @@ let
    ];
  };

in
stdenv.mkDerivation (finalAttrs: {
  pname = "nix";
  version = nix-cli.version;

  /**
    Produce a set of derivation outputs that implement the multiple outputs interface.
    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.

    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.
    `devdoc` is also available, but not listed here, because this attribute is
    not an output of the same derivation that provides `out`, `dev`, etc.
  */
  makeOutputs =
    {
      outputs,
      defaultOutput ? "out",
      extraAttrs ? outputName: value: { },
    }:
  outputs = [
    "out"
    "dev"
    "doc"
    "man"
  ];

    let
      prepOutput =
        outputName: value:
        {
          _type = "package";
  /**
            For compatibility. The outputs of this package may not actually be implemented using a single derivation.
    Unpacking is handled in this package's constituent components
  */
          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;
  dontUnpack = true;
  /**
    Building is handled in this package's constituent components
  */
  dontBuild = true;

in
  /**
    `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;

makeOutputs {
  extraAttrs = outputName: drv: {
    meta = drv.meta // {
      description = "The Nix package manager";
      pkgConfigModules = dev.meta.pkgConfigModules;
      outputsToInstall = [
        # man is symlinked
        "out"
      ];
    };
    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.";
    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.
    `fixupPhase` currently doesn't understand that a symlink output isn't writable.

      This particular attribute is _not_ used for that purpose, but it has the same value, and some other expressions expect it to be present.
    We don't compile or link anything in this derivation, so fixups aren't needed.
  */
    inherit (drv) system;
    tests = drv.tests or { };
    src = patchedSrc;
  };
  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;
  dontFixup = true;

  checkInputs =
    [
@@ -221,10 +134,6 @@ makeOutputs {

      # 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)
@@ -233,8 +142,39 @@ makeOutputs {
        # TODO: Split out tests into a separate derivation?
        nix-perl-bindings
      ];
            passthru = prevAttrs.passthru // {

  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;
    src = patchedSrc;

    /**
      These are the libraries that are part of the Nix project. They are used
@@ -255,14 +195,41 @@ makeOutputs {
    */
    inherit libs;

              tests = prevAttrs.passthru.tests or { } // {
                # TODO: create a proper fixpoint and:
    /**
      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 <https://nixos.org/manual/nixpkgs/stable/index.html#var-passthru-tests>
    */
    tests = {
      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"
    ];
  };
}

})