Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mkShell: make it buildable #153194

Merged
merged 6 commits into from
Jan 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions doc/builders/special/mkshell.section.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
# pkgs.mkShell {#sec-pkgs-mkShell}

`pkgs.mkShell` is a special kind of derivation that is only useful when using
it combined with `nix-shell`. It will in fact fail to instantiate when invoked
with `nix-build`.
`pkgs.mkShell` is a specialized `stdenv.mkDerivation` that removes some
repetition when using it with `nix-shell` (or `nix develop`).

## Usage {#sec-pkgs-mkShell-usage}

Here is a common usage example:

```nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# specify which packages to add to the shell environment
packages = [ pkgs.gnumake ];
# add all the dependencies, of the given packages, to the shell environment
inputsFrom = with pkgs; [ hello gnutar ];

inputsFrom = [ pkgs.hello pkgs.gnutar ];

shellHook = ''
export DEBUG=1
'';
}
```

## Attributes

* `name` (default: `nix-shell`). Set the name of the derivation.
* `packages` (default: `[]`). Add executable packages to the `nix-shell` environment.
* `inputsFrom` (default: `[]`). Add build dependencies of the listed derivations to the `nix-shell` environment.
* `shellHook` (default: `""`). Bash statements that are executed by `nix-shell`.

... all the attributes of `stdenv.mkDerivation`.

## Building the shell

This derivation output will contain a text file that contains a reference to
all the build inputs. This is useful in CI where we want to make sure that
every derivation, and its dependencies, build properly. Or when creating a GC
root so that the build dependencies don't get garbage-collected.
27 changes: 16 additions & 11 deletions pkgs/build-support/mkshell/default.nix
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{ lib, stdenv }:
{ lib, stdenv, buildEnv }:

# A special kind of derivation that is only meant to be consumed by the
# nix-shell.
{
# a list of packages to add to the shell environment
{ name ? "nix-shell"
, # a list of packages to add to the shell environment
packages ? [ ]
, # propagate all the inputs from the given derivations
inputsFrom ? [ ]
Expand All @@ -15,10 +15,11 @@
}@attrs:
let
mergeInputs = name:
(attrs.${name} or []) ++
(attrs.${name} or [ ]) ++
(lib.subtractLists inputsFrom (lib.flatten (lib.catAttrs name inputsFrom)));

rest = builtins.removeAttrs attrs [
"name"
"packages"
"inputsFrom"
"buildInputs"
Expand All @@ -30,8 +31,7 @@ let
in

stdenv.mkDerivation ({
name = "nix-shell";
phases = [ "nobuildPhase" ];
inherit name;

buildInputs = mergeInputs "buildInputs";
nativeBuildInputs = packages ++ (mergeInputs "nativeBuildInputs");
Expand All @@ -41,10 +41,15 @@ stdenv.mkDerivation ({
shellHook = lib.concatStringsSep "\n" (lib.catAttrs "shellHook"
(lib.reverseList inputsFrom ++ [ attrs ]));

nobuildPhase = ''
echo
echo "This derivation is not meant to be built, aborting";
echo
exit 1
phases = [ "buildPhase" ];

buildPhase = ''
echo "------------------------------------------------------------" >>$out
echo " WARNING: the existence of this path is not guaranteed." >>$out
echo " It is an internal implementation detail for pkgs.mkShell." >>$out
echo "------------------------------------------------------------" >>$out
echo >> $out
# Record all build inputs as runtime dependencies
export >> $out
'';
} // rest)