Import From Derivation

From NixOS Wiki
Revision as of 17:09, 7 February 2019 by imported>Grahamc (Start describing IFD)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Import From Derivation is where during a single Nix evaluation, the Nix expression:

  1. creates a derivation which will build a Nix expression
  2. imports that expression
  3. uses the results of the evaluation of the expression.

An example of IFD is:

let
  pkgs = import <nixpkgs> {};

  # Create a derivation which, when built, writes some Nix code to
  # its $out path.
  derivation-to-import = pkgs.writeText "example" ''
    pkgs: {
      ifd-example = pkgs.stdenv.mkDerivation rec {
        name = "hello-2.10-ifd-example";


        src = pkgs.fetchurl {
          url = "mirror://gnu/hello/2.10.tar.gz";
          sha256 = "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i";
        };
      };
    }
  '';

  # Import the derivation. This forces `derivation-to-import` to become
  # a string. This is normal behavior for Nix and Nixpkgs. The specific
  # difference here is the evaluation itself requires the result to be
  # built during the evaluation in order to continue evaluating.
  imported-derivation = import derivation-to-import;

  # Treat the imported-derivation variable as if we hadn't just created
  # its Nix expression inside this same evaluation.
  hello-package = (imported-derivation pkgs).ifd-example;
in hello-package

Building this looks familiar, but with an extra building ... line:

$ nix-build ./test.nix
building '/nix/store/8n001pyx2iqsnzd6niji1bvyjlg6x058-example.drv'... <- this build is forced at
                                                                         evaluation time

these derivations will be built:                                      <- now we're back to normal
                                                                         nix-build behavior
  /nix/store/3nm9rlv5smmvijcdifngjwl4v6zvll7k-hello-2.10-ifd-example.drv

building '/nix/store/3nm9rlv5smmvijcdifngjwl4v6zvll7k-hello-2.10-ifd-example.drv'...
[...snip...]

we'll see pretty similar output if we just evaluate it:

$ nix-instantiate ./test.nix
building '/nix/store/8n001pyx2iqsnzd6niji1bvyjlg6x058-example.drv'...

/nix/store/3nm9rlv5smmvijcdifngjwl4v6zvll7k-hello-2.10-ifd-example.drv

Some examples of IFD can be seen when using nixpkgs to fetch a specific version of nixpkgs, and then importing the source.