summary refs log tree commit diff
path: root/pkgs/stdenv/generic/make-derivation.nix
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2017-07-05 17:56:53 -0400
committerJohn Ericson <John.Ericson@Obsidian.Systems>2017-07-07 12:16:51 -0400
commit4cf4d7180dfb7dba21e1dc832539daa5d31e2a23 (patch)
treecfc7bbb97962bb5e48d1491c108b599ccef5b189 /pkgs/stdenv/generic/make-derivation.nix
parente8e57452f4a35cfa5a20ede5dd6e0c6404f35903 (diff)
downloadnixlib-4cf4d7180dfb7dba21e1dc832539daa5d31e2a23.tar
nixlib-4cf4d7180dfb7dba21e1dc832539daa5d31e2a23.tar.gz
nixlib-4cf4d7180dfb7dba21e1dc832539daa5d31e2a23.tar.bz2
nixlib-4cf4d7180dfb7dba21e1dc832539daa5d31e2a23.tar.lz
nixlib-4cf4d7180dfb7dba21e1dc832539daa5d31e2a23.tar.xz
nixlib-4cf4d7180dfb7dba21e1dc832539daa5d31e2a23.tar.zst
nixlib-4cf4d7180dfb7dba21e1dc832539daa5d31e2a23.zip
stdenv: Conservatively move `mkDerivation` into it's own file
Diffstat (limited to 'pkgs/stdenv/generic/make-derivation.nix')
-rw-r--r--pkgs/stdenv/generic/make-derivation.nix155
1 files changed, 155 insertions, 0 deletions
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
new file mode 100644
index 000000000000..92d5d2a3d9d3
--- /dev/null
+++ b/pkgs/stdenv/generic/make-derivation.nix
@@ -0,0 +1,155 @@
+{ lib, config, stdenv
+
+# TODO(@Ericson2314): get off stdenv
+, extraBuildInputs
+, __extraImpureHostDeps
+, extraSandboxProfile
+, hostPlatform, targetPlatform
+}:
+
+rec {
+  # `mkDerivation` wraps the builtin `derivation` function to
+  # produce derivations that use this stdenv and its shell.
+  #
+  # See also:
+  #
+  # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv
+  #   Details on how to use this mkDerivation function
+  #
+  # * https://nixos.org/nix/manual/#ssec-derivation
+  #   Explanation about derivations in general
+  mkDerivation =
+    { nativeBuildInputs ? []
+    , buildInputs ? []
+
+    , propagatedNativeBuildInputs ? []
+    , propagatedBuildInputs ? []
+
+    , crossConfig ? null
+    , meta ? {}
+    , passthru ? {}
+    , pos ? # position used in error messages and for meta.position
+        (if attrs.meta.description or null != null
+          then builtins.unsafeGetAttrPos "description" attrs.meta
+          else builtins.unsafeGetAttrPos "name" attrs)
+    , separateDebugInfo ? false
+    , outputs ? [ "out" ]
+    , __impureHostDeps ? []
+    , __propagatedImpureHostDeps ? []
+    , sandboxProfile ? ""
+    , propagatedSandboxProfile ? ""
+    , ... } @ attrs:
+    let
+      dependencies = [
+        (map (drv: drv.nativeDrv or drv) nativeBuildInputs)
+        (map (drv: drv.crossDrv or drv) buildInputs)
+      ];
+      propagatedDependencies = [
+        (map (drv: drv.nativeDrv or drv) propagatedNativeBuildInputs)
+        (map (drv: drv.crossDrv or drv) propagatedBuildInputs)
+      ];
+    in let
+
+      outputs' =
+        outputs ++
+        (if separateDebugInfo then assert targetPlatform.isLinux; [ "debug" ] else []);
+
+      dependencies' = let
+          justMap = map lib.chooseDevOutputs dependencies;
+          nativeBuildInputs = lib.elemAt justMap 0
+            ++ lib.optional targetPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh;
+          buildInputs = lib.elemAt justMap 1
+               # TODO(@Ericson2314): Should instead also be appended to `nativeBuildInputs`.
+            ++ lib.optional separateDebugInfo ../../build-support/setup-hooks/separate-debug-info.sh;
+        in [ nativeBuildInputs buildInputs ];
+
+      propagatedDependencies' = map lib.chooseDevOutputs propagatedDependencies;
+
+      derivationArg =
+        (removeAttrs attrs
+          ["meta" "passthru" "crossAttrs" "pos"
+           "__impureHostDeps" "__propagatedImpureHostDeps"
+           "sandboxProfile" "propagatedSandboxProfile"])
+        // (let
+          # TODO(@Ericson2314): Reversing of dep lists is just temporary to avoid Darwin mass rebuild.
+          computedSandboxProfile =
+            lib.concatMap (input: input.__propagatedSandboxProfile or []) (extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies'));
+          computedPropagatedSandboxProfile =
+            lib.concatMap (input: input.__propagatedSandboxProfile or []) (lib.concatLists (lib.reverseList propagatedDependencies'));
+          computedImpureHostDeps =
+            lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies')));
+          computedPropagatedImpureHostDeps =
+            lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (lib.concatLists (lib.reverseList propagatedDependencies')));
+        in
+        {
+          builder = attrs.realBuilder or stdenv.shell;
+          args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)];
+          inherit stdenv;
+          system = stdenv.system; # TODO(@Ericson2314): be correct about cross compilation
+          userHook = config.stdenv.userHook or null;
+          __ignoreNulls = true;
+
+          nativeBuildInputs = lib.elemAt dependencies' 0;
+          buildInputs = lib.elemAt dependencies' 1;
+
+          propagatedNativeBuildInputs = lib.elemAt propagatedDependencies' 0;
+          propagatedBuildInputs = lib.elemAt propagatedDependencies' 1;
+        } // lib.optionalAttrs (hostPlatform.isDarwin) {
+          # TODO: remove lib.unique once nix has a list canonicalization primitive
+          __sandboxProfile =
+          let profiles = [ extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ];
+              final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles));
+          in final;
+          __propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]);
+          __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ __extraImpureHostDeps ++ [
+            "/dev/zero"
+            "/dev/random"
+            "/dev/urandom"
+            "/bin/sh"
+          ];
+          __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps;
+        } // (if outputs' != [ "out" ] then {
+          outputs = outputs';
+        } else { }));
+
+      # The meta attribute is passed in the resulting attribute set,
+      # but it's not part of the actual derivation, i.e., it's not
+      # passed to the builder and is not a dependency.  But since we
+      # include it in the result, it *is* available to nix-env for queries.
+      meta = { }
+          # If the packager hasn't specified `outputsToInstall`, choose a default,
+          # which is the name of `p.bin or p.out or p`;
+          # if he has specified it, it will be overridden below in `// meta`.
+          #   Note: This default probably shouldn't be globally configurable.
+          #   Services and users should specify outputs explicitly,
+          #   unless they are comfortable with this default.
+        // { outputsToInstall =
+          let
+            outs = outputs'; # the value passed to derivation primitive
+            hasOutput = out: builtins.elem out outs;
+          in [( lib.findFirst hasOutput null (["bin" "out"] ++ outs) )];
+        }
+        // attrs.meta or {}
+          # Fill `meta.position` to identify the source location of the package.
+        // lib.optionalAttrs (pos != null)
+          { position = pos.file + ":" + toString pos.line; }
+        ;
+
+    in
+
+      lib.addPassthru
+        (derivation (import ./check-meta.nix
+          {
+            inherit lib config meta derivationArg;
+            mkDerivationArg = attrs;
+            inherit (stdenv) system; # TODO: cross-compilation?
+          }))
+        ( {
+            overrideAttrs = f: mkDerivation (attrs // (f attrs));
+            inherit meta passthru;
+          } //
+          # Pass through extra attributes that are not inputs, but
+          # should be made available to Nix expressions using the
+          # derivation (e.g., in assertions).
+          passthru);
+}