nix-derivation

[!Derivation] A Derivation is a special Node in the Nix store, which tells Nix how to build one or more other Nodes.

/nix/store/ynzfmamryf6lrybjy1zqp1x190l5yiy5-demo.drv
  • Build instructions to construct Nodes
    • a “recipe” for building a package/module
  • When evaluating the Nix expression, Nix will create derivation .drv => recipe for building the package
  • Everything required to build this Derivation is explicitly listed in the file by path (you can see “hash” here, for example).
  • The derivation file (contents) is hashed to create a unique identifier for the package
  • The hash component of the Derivation’s path in the nix-store is essentially a hash of the contents of the file.

Derivation Definition

  • outputs: What nodes can this build?
  • inputDrvs: Other Derivations that must be built before this one
  • inputSrcs: Things already in the store on which this build depends
  • platform: Is this for macOS? Linux?
  • builder: What program gets run to do the build?
  • args: Arguments to pass to that program
  • env: Environment variables to set for that program

Nix expression to make a Derivation

with import <nixpkgs> {};

let
  # The ${...} is for string interpolation
  # The '' quotes are used for multi-line strings
  simplePackage = pkgs.writeShellScriptBin "whatIsMyIp" ''
    ${pkgs.curl}/bin/curl http://httpbin.org/get \
      | ${pkgs.jq}/bin/jq --raw-output .origin
  '';
in
stdenv.mkDerivation rec {
  name = "test-environment";

  buildInputs = [ simplePackage ];
}](<with import %3Cnixpkgs%3E {};

let
  emojify = let
    version = "2.0.0";
  in
    stdenv.mkDerivation {
      name = "emojify-${version}";

      # Using this build support function to fetch it from github
      src = fetchFromGitHub {
        owner = "mrowa44";
        repo = "emojify";
        # The git tag to fetch
        rev = "${version}";
        # Hashes must be specified so that the build is purely functional
        sha256 = "0zhbfxabgllpq3sy0pj5mm79l24vj1z10kyajc4n39yq8ibhq66j";
      };

      # We override the install phase, as the emojify project doesn't use make
      installPhase = ''
        # Make the output directory
        mkdir -p $out/bin

        # Copy the script there and make it executable
        cp emojify $out/bin/
        chmod +x $out/bin/emojify
      '';
    };
in
stdenv.mkDerivation {
  name = "emojify-environment";
  buildInputs = [ emojify ];
}>)

Output


# hash
bat /nix/store/zxkwzxslaa5pdscp0hsky7pw4ic0qcsm-python3.10-coverage-6.4.4.drv

# content of the hash
Derive([("dist","/nix/store/83bzp2dcqbiakfnyp6gajcbbmk8p4h10-python3.10-coverage-6.4.4-dist","",""),("out","/nix/store/n2d14c04kk8nk1naiyzc0a8g38c5cgds-python3.10-coverage-6.4.4","","")],[("/nix/store/09gvxfwqcmx0cs3yash79w0p4knfs9i6-python-namespaces-hook.sh.drv",["out"]),("/nix/store/5w5c
       │ i7i956nhy6wwx9z1hqbv7lh6lqj6-setuptools-setup-hook.drv",["out"]),("stdenv","/nix/store/g0jijpgcb4q54zbvz5p8yvxcnb6lshnk-stdenv-darwin"),("strictDeps","1"),("system","aarch64-darwin"),("version","6.4.4")])

Resources

  • https://www.sam.today/blog/derivations-102-learning-nix-pt-4/

Notes mentioning this note