1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# Store Object
Nix organizes the data it manages into *store objects*.
A store object is the pair of
- a [file system object](#file-system-object)
- a set of [references](#reference) to store objects.
We call a store object's outermost file system object the *root*.
```haskell
data StoreOject = StoreObject {
root :: FileSystemObject
, references :: Set StoreObject
}
```
## File system object {#file-system-object}
The Nix store uses a simple file system model.
Every file system object is one of the following:
- File: an executable flag, and arbitrary data for contents
- Directory: mapping of names to child file system objects
- [Symbolic link](https://en.m.wikipedia.org/wiki/Symbolic_link): may point anywhere.
```haskell
data FileSystemObject
= File { isExecutable :: Bool, contents :: Bytes }
| Directory { entries :: Map FileName FileSystemObject }
| SymLink { target :: Path }
```
A bare file or symlink can be a root file system object.
Symlinks pointing outside of their own root, or to a store object without a matching reference, are allowed, but might not function as intended.
## Reference {#reference}
A store object can reference other store objects.
Nix stores have the *closure property*: for each store object in the store, all the store objects it references must also be in the store.
Building, copying and deleting store objects must be done in a way that obeys this property:
- We can only safely delete unreferenced objects.
- When copying, to maintain correctness, either the result must be "revealed" atomically to the destination store, or objects must be copied in reference-dependency order.
- Newly built store objects must only refer to store objects in the closure of the build inputs.
This ensures the purity of the build.
### Reference scanning
While references could be arbitrary paths, Nix requires them to be store paths to ensure correctness.
Anything outside a given store is not under control of Nix, and therefore cannot be guaranteed to be present when needed.
However, having references match store paths in files is not enforced by the data model:
Store objects could have excess or incomplete references with respect to store paths found in their file contents.
Scanning files therefore allows reliably capturing run time dependencies without declaring them explicitly.
Doing it at build time and persisting references in the store object avoids repeating this time-consuming operation.
|