Start on the derivations section

This commit is contained in:
John Ericson 2022-03-21 13:13:55 -04:00 committed by Valentin Gagarin
parent e3a0209a9e
commit 678d75baea
2 changed files with 60 additions and 1 deletions

View file

@ -26,7 +26,7 @@
- [Input-Addressing](design/store/drvs/ia.md) - [Input-Addressing](design/store/drvs/ia.md)
- [Content-Addressing (Experimental)](design/store/drvs/ca.md) - [Content-Addressing (Experimental)](design/store/drvs/ca.md)
- [Building](design/store/building.md) - [Building](design/store/building.md)
- [Advanced Topic: store dir relocatability](design/store/relocatability.md) - [Advanced Topic: store entry relocatability](design/store/relocatability.md)
- [Package Management](package-management/package-management.md) - [Package Management](package-management/package-management.md)
- [Basic Package Management](package-management/basic-package-mgmt.md) - [Basic Package Management](package-management/basic-package-mgmt.md)
- [Profiles](package-management/profiles.md) - [Profiles](package-management/profiles.md)

View file

@ -0,0 +1,59 @@
# Derivations
Derivations are recipes to create store entries.
Derivations are the heart of Nix.
Other system (like Git or IPFS) also store and transfer immutable data, but they don't concern themselves with *how* that data was created.
This is where Nix comes in.
Derivations produce data by running arbitrary commands, like Make or Ninja rules.
Unlike those systems, derivations do not produce arbitrary files, but only specific store entries.
They cannot modify the store in any way, other than creating those store entries.
This rigid specification of what they do is what allows Nix's caching to be so simple and yet robust.
Based on the above, we can conceptually break derivations down into 3 parts:
1. What command will be run?
2. What existing store entries are needed as inputs?
3. What store entries will be produced as outputs?
## What command will be run?
The original core of Nix was very simple about this, in the mold of traditional Unix.
Commands consist of 3 parts:
1. Path to executable
2. Arguments (Excecpt for `argv[0]`, which is taken from the path in the usual way)
3. Environment variables.
## What existing store entries are needed as inputs?
The previous sub-section begs the question "how can we be sure the path to the executable points to what we think it does?"
It's a good questions!
## What store entries will be produced as outputs?
## Extra extensions
### `__structuredAttrs`
Historically speaking, most users of Nix made GNU Bash with a script the command run, regardless of what they were doing.
Bash variable are automatically created from env vars, but bash also supports array and string-keyed map variables in addition to string variables.
People also usually create derivations using language which also support these richer data types.
It was thus desired a way to get this data from the language "planning" the derivation to language to bash, the language evaluated at "run time".
`__structuredAttrs` does this by smuggling inside the core derivation format a map of named richer data.
At run time, this becomes two things:
1. A JSON file containing that map.
2. A bash script setting those variables.
The bash command can be passed a script which will "source" that Nix-created bash script, setting those variables with the richer data.
The outer script can then do whatever it likes with those richer variables as input.
However, since derivations can already contain arbitary input sources, the vast majority of `__structuredAttrs` can be handled by upper layers.
We might consider implementing `__structuredAttrs` in higher layers in the future, and simplifying the store layer.