1
0
Fork 0
mirror of https://github.com/NixOS/nix-pills synced 2024-09-19 04:00:13 -04:00

Format markdown with Prettier

This commit is contained in:
Noam Yorav-Raphael 2024-04-04 00:37:30 +03:00 committed by Jan Tojnar
parent d7c8d34649
commit b4eeb0cdfc
18 changed files with 102 additions and 102 deletions

View file

@ -26,7 +26,7 @@ Let's say you need an nginx service and also an nginx-openresty service. You hav
Or suppose that you want to run two different instances of mysql: 5.2 and 5.5. The same thing applies, plus you have to also make sure the two mysqlclient libraries do not collide.
This is not impossible but it *is* very inconvenient. If you want to install two whole stacks of software like GNOME 3.10 and GNOME 3.12, you can imagine the amount of work.
This is not impossible but it _is_ very inconvenient. If you want to install two whole stacks of software like GNOME 3.10 and GNOME 3.12, you can imagine the amount of work.
From an administrator's point of view: you can use containers. The typical solution nowadays is to create a container per service, especially when different versions are needed. That somewhat solves the problem, but at a different level and with other drawbacks. For example, needing orchestration tools, setting up a shared cache of packages, and new machines to monitor rather than simple services.
@ -36,7 +36,7 @@ And so on. Nix solves all this at the packaging level and solves it well. A sing
## Being purely functional
Nix makes no assumptions about the global state of the system. This has many advantages, but also some drawbacks of course. The core of a Nix system is the Nix store, usually installed under `/nix/store`, and some tools to manipulate the store. In Nix there is the notion of a *derivation* rather than a package. The difference can be subtle at the beginning, so I will often use the words interchangeably.
Nix makes no assumptions about the global state of the system. This has many advantages, but also some drawbacks of course. The core of a Nix system is the Nix store, usually installed under `/nix/store`, and some tools to manipulate the store. In Nix there is the notion of a _derivation_ rather than a package. The difference can be subtle at the beginning, so I will often use the words interchangeably.
Derivations/packages are stored in the Nix store as follows: `/nix/store/hash-name`, where the hash uniquely identifies the derivation (this isn't quite true, it's a little more complex), and the name is the name of the derivation.
@ -85,7 +85,7 @@ If there is a data format change, then migrating to the new data format remains
Nix lets you compose software at build time with maximum flexibility, and with builds being as reproducible as possible. Not only that, due to its nature deploying systems in the cloud is so easy, consistent, and reliable that in the Nix world all existing self-containment and orchestration tools are deprecated by [NixOps](http://nixos.org/nixops/).
It however *currently* falls short when working with dynamic composition at runtime or replacing low level libraries, due to the need to rebuild dependencies.
It however _currently_ falls short when working with dynamic composition at runtime or replacing low level libraries, due to the need to rebuild dependencies.
That may sound scary, however after running NixOS on both a server and a laptop desktop, I'm very satisfied so far. Some of the architectural problems just need some man-power, other design problems still need to be solved as a community.

View file

@ -8,7 +8,7 @@ For installation instructions, please refer to the Nix Reference Manual on [ Ins
## Installation
These articles are not a tutorial on *using* Nix. Instead, we're going to walk through the Nix system to understand the fundamentals.
These articles are not a tutorial on _using_ Nix. Instead, we're going to walk through the Nix system to understand the fundamentals.
The first thing to note: derivations in the Nix store refer to other derivations which are themselves in the Nix store. They don't use `libc` from our system or anywhere else. It's a self-contained store of all the software we need to bootstrap up to any particular package.
@ -50,7 +50,7 @@ Note: If this is the first time you're using Nix after the initial installation,
<div class="warning">
Important: Never change `/nix/store` manually. If you do, then it will no longer be in sync with the sqlite db, unless you *really* know what you are doing.
Important: Never change `/nix/store` manually. If you do, then it will no longer be in sync with the sqlite db, unless you _really_ know what you are doing.
</div>
@ -128,7 +128,7 @@ Keeping the store in `/nix` means we can grab the binary cache from nixos.org (j
- Thus bash would need to point to glibc under `/foo/store`, instead of under `/nix/store`
- So the binary cache can't help, because we need a *different* bash, and so we'd have to recompile everything ourselves.
- So the binary cache can't help, because we need a _different_ bash, and so we'd have to recompile everything ourselves.
After all `/nix` is a sensible place for the store.

View file

@ -135,7 +135,7 @@ A nicer view of the closure:
$ nix-store -q --tree `which man`
[...]
With the above command, you can find out exactly why a *runtime* dependency, be it direct or indirect, exists for a given derivation.
With the above command, you can find out exactly why a _runtime_ dependency, be it direct or indirect, exists for a given derivation.
The same applies to environments. As an exercise, run `nix-store -q --tree ~/.nix-profile`, and see that the first children are direct dependencies of the user environment: the installed derivations, and the `manifest.nix`.

View file

@ -110,7 +110,7 @@ Escaping `${...}` within double quoted strings is done with the backslash. Withi
## Lists
Lists are a sequence of expressions delimited by space (*not* comma):
Lists are a sequence of expressions delimited by space (_not_ comma):
nix-repl> [ 2 "foo" true (2+3) ]
[ 2 "foo" true 5 ]
@ -205,7 +205,7 @@ This kind of expression is something you rarely see in other languages. You can
nix-repl> with longName; a + b
7
That's it, it takes an attribute set and includes symbols from it in the scope of the inner expression. Of course, only valid identifiers from the keys of the set will be included. If a symbol exists in the outer scope and would also be introduced by the `with`, it will *not* be shadowed. You can however still refer to the attribute set:
That's it, it takes an attribute set and includes symbols from it in the scope of the inner expression. Of course, only valid identifiers from the keys of the set will be included. If a symbol exists in the outer scope and would also be introduced by the `with`, it will _not_ be shadowed. You can however still refer to the attribute set:
nix-repl> let a = 10; in with longName; a + b
14

View file

@ -230,4 +230,4 @@ This syntax only makes sense inside sets. There's no magic involved, it's simply
We will generalize the builder. You may have noticed that we wrote two separate `builder.sh` scripts in this post. We would like to have a generic builder script instead, especially since each build script goes in the nix store: a bit of a waste.
*Is it really that hard to package stuff in Nix? No*, here we're studying the fundamentals of Nix.
_Is it really that hard to package stuff in Nix? No_, here we're studying the fundamentals of Nix.

View file

@ -71,6 +71,7 @@ Darwin (i.e. macOS) builds typically use `clang` rather than `gcc` for a C compi
}
Later, we will show how Nix can automatically handle these differences. For now, please be just aware that changes similar to the above may be needed in what follows.
</div>
Now build it with `nix-build hello.nix` and you can launch `result/bin/hello`. Nothing easier, but do we have to create a builder.sh for each package? Do we always have to pass the dependencies to the `derivation` function?

View file

@ -63,7 +63,7 @@ How to use this file? Like our old builder. To test it, we enter a fake empty de
nix-shell$ buildPhase
...
*I unset `PATH` to further show that the `stdenv` is sufficiently self-contained to build autotools packages that have no other dependencies.*
_I unset `PATH` to further show that the `stdenv` is sufficiently self-contained to build autotools packages that have no other dependencies._
So we ran the `configurePhase` function and `buildPhase` function and they worked. These bash functions should be self-explanatory. You can read the code in the `setup` file.

View file

@ -188,11 +188,11 @@ We actually simplified the `findInputs` call site from before; `propagatedBuildI
findInputs $i
done
This demonstrates an important point. For the *current* package alone, it doesn't matter whether a dependency is propagated or not. It will be processed the same way: called with `findInputs` and `addToEnv`. (The packages discovered by `findInputs`, which are also accumulated in `pkgs` and passed to `addToEnv`, are also the same in both cases.) Downstream however, it certainly does matter because only the propagated immediate dependencies are put in the `$out/nix-support/propagated-build-inputs`.
This demonstrates an important point. For the _current_ package alone, it doesn't matter whether a dependency is propagated or not. It will be processed the same way: called with `findInputs` and `addToEnv`. (The packages discovered by `findInputs`, which are also accumulated in `pkgs` and passed to `addToEnv`, are also the same in both cases.) Downstream however, it certainly does matter because only the propagated immediate dependencies are put in the `$out/nix-support/propagated-build-inputs`.
## Setup Hooks
As we mentioned above, sometimes dependencies need to influence the packages that use them in ways other than just *being* a dependency. [^1] `propagatedBuildInputs` can actually be seen as an example of this: packages using that are effectively "injecting" those dependencies as extra `buildInputs` in their downstream dependents. But in general, a dependency might affect the packages it depends on in arbitrary ways. *Arbitrary* is the key word here. We could teach `setup.sh` things about upstream packages like `pkg/nix-support/propagated-build-inputs`, but not arbitrary interactions.
As we mentioned above, sometimes dependencies need to influence the packages that use them in ways other than just _being_ a dependency. [^1] `propagatedBuildInputs` can actually be seen as an example of this: packages using that are effectively "injecting" those dependencies as extra `buildInputs` in their downstream dependents. But in general, a dependency might affect the packages it depends on in arbitrary ways. _Arbitrary_ is the key word here. We could teach `setup.sh` things about upstream packages like `pkg/nix-support/propagated-build-inputs`, but not arbitrary interactions.
Setup hooks are the basic building block we have for this. In nixpkgs, a "hook" is basically a bash callback, and a setup hook is no exception. Let's look at the last part of `findInputs` we haven't covered:
@ -211,7 +211,7 @@ Setup hooks are the basic building block we have for this. In nixpkgs, a "hook"
If a package includes the path `pkg/nix-support/setup-hook`, it will be sourced by any stdenv-based build including that as a dependency.
This is strictly more general than any of the other mechanisms introduced in this chapter. For example, try writing a setup hook that has the same effect as a *propagatedBuildInputs* entry. One can almost think of this as an escape hatch around Nix's normal isolation guarantees, and the principle that dependencies are immutable and inert. We're not actually doing something unsafe or modifying dependencies, but we are allowing arbitrary ad-hoc behavior. For this reason, setup-hooks should only be used as a last resort.
This is strictly more general than any of the other mechanisms introduced in this chapter. For example, try writing a setup hook that has the same effect as a _propagatedBuildInputs_ entry. One can almost think of this as an escape hatch around Nix's normal isolation guarantees, and the principle that dependencies are immutable and inert. We're not actually doing something unsafe or modifying dependencies, but we are allowing arbitrary ad-hoc behavior. For this reason, setup-hooks should only be used as a last resort.
## Environment Hooks
@ -242,12 +242,11 @@ Functions listed in `envHooks` are applied to every package passed to `addToEnv`
envHooks+=(anEnvHook)
and if one dependency has that setup hook then all of them will be so `echo`ed. Allowing dependencies to learn about their *sibling* dependencies is exactly what compilers need.
and if one dependency has that setup hook then all of them will be so `echo`ed. Allowing dependencies to learn about their _sibling_ dependencies is exactly what compilers need.
## Next pill...
...I'm not sure! We could talk about the additional dependency types and hooks which cross compilation necessitates, building on our knowledge here to cover stdenv as it works today. We could talk about how nixpkgs is bootstrapped. Or we could talk about how `localSystem` and `crossSystem` are elaborated into the `buildPlatform`, `hostPlatform`, and `targetPlatform` each bootstrapping stage receives. Let us know which most interests you!
[^1]: We can now be precise and consider what `addToEnv` does alone the minimal treatment of a dependency: i.e. a package that is *just* a dependency would *only* have `addToEnv` applied to it.
[^1]: We can now be precise and consider what `addToEnv` does alone the minimal treatment of a dependency: i.e. a package that is _just_ a dependency would _only_ have `addToEnv` applied to it.
[^2]: It was called [GCC Wrapper](https://github.com/NixOS/nixpkgs/tree/6675f0a52c0962042a1000c7f20e887d0d26ae25/pkgs/build-support/gcc-wrapper) in the version of nixpkgs suggested for following along in this pill; Darwin and Clang support hadn't yet motivated the rename.