git.iko.soy/typeable/nix-pills-ru
on master help sign in
.gitignore+2−2
since splitsnapshots
unifiedsplit
@@ -1,5 +1,5 @@
1−nix.pdf
1+presentation.pdf
2−nix.html
2+presentation.html
3speaker-notes.md
3speaker-notes.md
4speaker-notes.html
4speaker-notes.html
5images/graphviz*
5images/graphviz*
Makefile+13−3
@@ -1,5 +1,15 @@
1−build: ; eval $$buildPhase
1+all: presentation.pdf presentation.html speaker-notes.html
2+.PHONY : all
3+
4+
5+.PHONY: autoreload
6+autoreload: ; while sleep 1; do make --no-print-directory -s; done
7+
8+
9+%.pdf: %.md; pandoc $< -t beamer --slide-level=2 --pdf-engine xelatex -F pandoc-filter-graphviz -o $@
10+%.html: %.md; pandoc $< -t slidy -F pandoc-filter-graphviz -o $@;
11+
12+
13+speaker-notes.md: presentation.md; sed -e "/<!--/,/-->/!d" nix.md | sed -e "s/<!--//" | sed -e "s/-->/\n\* \* \*/" > speaker-notes.md
2
14
3−autoreload: ; while inotifywait -qq nix.md; do eval $$buildPhase; done
4
15
5−all: build
README.mdnew file+13
@@ -0,0 +1,13 @@
1+# Nix pills in russian
2+
3+This repo contains a presentation about nix based on the wonderful [nix-pills](https://nixos.org/nixos/nix-pills).
4+
5+Markdown document is located [here](./presentation.md).
6+
7+PDF is located in the ["releases" tab in github repo](https://github.com/typeable/nix-pills-ru/releases).
8+
9+To enter an environment with all the needed packages, run `nix-shell`.
10+
11+To build PDF of the presentation and speaker's notes, run `make` (either after installing `pandoc`, `pandoc-filter-graphviz` and `graphviz` or from within the `nix-shell`).
12+
13+To start automatic regeneration of aforementioned files, run `make autoreload`.
default.nix−9
@@ -19,8 +19,6 @@ in stdenv.mkDerivation rec {
19 hack-font
19 hack-font
20 graphviz
20 graphviz
21 dot2tex
21 dot2tex
22−
23− inotify-tools
24 ];
22 ];
25
23
26 src = ./.;
24 src = ./.;
@@ -28,11 +26,4 @@ in stdenv.mkDerivation rec {
28 phases = [ "buildPhase" ];
26 phases = [ "buildPhase" ];
29
27
30 preferLocalBuild = true;
28 preferLocalBuild = true;
31−
32− buildPhase = ''
33− pandoc nix.md -t beamer --slide-level=2 --pdf-engine xelatex -F pandoc-filter-graphviz -o nix.pdf;
34− pandoc nix.md -t slidy -F pandoc-filter-graphviz -o nix.html;
35− sed -e "/<!--/,/-->/!d" nix.md | sed -e "s/<!--//" | sed -e "s/-->/\n\* \* \*/" > speaker-notes.md;
36− pandoc speaker-notes.md -o speaker-notes.html
37− '';
38}
29}
nix.md → presentation.mdrenamed+417−23
@@ -3,8 +3,8 @@ title: Nix
3subtitle: Язык, пакетный менеджер и экосистема
3subtitle: Язык, пакетный менеджер и экосистема
4author: Александр Бантьев @balsoft, typeable.io
4author: Александр Бантьев @balsoft, typeable.io
5description: |
5description: |
6− Вольный пересказ nix-pills на русском языке.
6+ Вольный пересказ nix-pills на русском языке.
7− https://nixos.org/nixos/nix-pills, автор Luca Bruno (aka Lethalman)
7+ https://nixos.org/nixos/nix-pills, автор Luca Bruno (aka Lethalman)
8theme: Boadilla
8theme: Boadilla
9colortheme: dolphin
9colortheme: dolphin
10mainfont: Roboto
10mainfont: Roboto
@@ -13,21 +13,20 @@ aspectratio: 169
13titlegraphic: images/nix.png
13titlegraphic: images/nix.png
14toc: true
14toc: true
15header-includes:
15header-includes:
16−- \usepackage[utf8]{inputenc}
16+ - \usepackage[utf8]{inputenc}
17−- \usepackage[russian]{babel}
17+ - \usepackage[russian]{babel}
18−- \uselanguage{Russian}
18+ - \uselanguage{Russian}
19−- \languagepath{Russian}
19+ - \languagepath{Russian}
20−- \usepackage{tikz}
20+ - \usepackage{tikz}
21---
21---
22
22
23+# Вступление
24+
23<!--
25<!--
24<meta charset="utf8" />
26<meta charset="utf8" />
25<title>Заметки выступающего</title>
27<title>Заметки выступающего</title>
26−# Заметки выступающего
27-->
28-->
28
29
29−# Вступление
30−
31Основано на <https://nixos.org/nixos/nix-pills> . Огромная благодарность @Lethalman и @grahamc за написание и поддержку этого материала!
30Основано на <https://nixos.org/nixos/nix-pills> . Огромная благодарность @Lethalman и @grahamc за написание и поддержку этого материала!
32
31
33Я хотел бы, чтобы к концу презентации всем стало понятно
32Я хотел бы, чтобы к концу презентации всем стало понятно
@@ -40,6 +39,8 @@ header-includes:
40
39
41Вы можете прекратить слушать после любой секции, и я надеюсь, что вы унесете какую-то полезную для себя информацию.
40Вы можете прекратить слушать после любой секции, и я надеюсь, что вы унесете какую-то полезную для себя информацию.
42
41
42+Исходники, собранный pdf и заметки докладчика для этой презентации находятся на <https://github.com/typeable/nix-pills-ru>
43+
43
44
44<!--
45<!--
45Как вы все скорее всего знаете, мы используем Nix для сборки и тестирования нашего кода. Я, Александр Бантьев (@balsoft) отвечаю за инфраструктуру сборки пакетов (Hydra, NixOps), а также за поддержание инструкций сборки в актуальном состоянии. Я бы хотел рассказать вам про nix с помощью вольного пересказа отличной серии статей ["Nix pills"](https://nixos.org/nixos/nix-pills)
46Как вы все скорее всего знаете, мы используем Nix для сборки и тестирования нашего кода. Я, Александр Бантьев (@balsoft) отвечаю за инфраструктуру сборки пакетов (Hydra, NixOps), а также за поддержание инструкций сборки в актуальном состоянии. Я бы хотел рассказать вам про nix с помощью вольного пересказа отличной серии статей ["Nix pills"](https://nixos.org/nixos/nix-pills)
@@ -53,13 +54,13 @@ header-includes:
53
54
54[Nix](https://nixos.org/nix) -- это
55[Nix](https://nixos.org/nix) -- это
55
56
56−#. Язык
57+1. Язык
57 + Декларативный
58 + Декларативный
58 + Функциональный
59 + Функциональный
59 + Чистый
60 + Чистый
60 + Ленивый
61 + Ленивый
61 + Динамически типизированный
62 + Динамически типизированный
62−#. Пакетный менеджер
63+2. Пакетный менеджер
63 + Атомарный
64 + Атомарный
64 + Повторяемый
65 + Повторяемый
65 + Source/Binary
66 + Source/Binary
@@ -91,7 +92,7 @@ digraph {
91}
92}
92```
93```
93
94
94−
95+
95# Nix как пакетный менеджер
96# Nix как пакетный менеджер
96
97
97> Nix is a powerful package manager for Linux and other Unix systems that makes package management reliable and reproducible. It provides atomic upgrades and rollbacks, side-by-side installation of multiple versions of a package, multi-user package management and easy setup of build environments.
98> Nix is a powerful package manager for Linux and other Unix systems that makes package management reliable and reproducible. It provides atomic upgrades and rollbacks, side-by-side installation of multiple versions of a package, multi-user package management and easy setup of build environments.
@@ -302,6 +303,22 @@ nix-repl> /home/balsoft/Документы
302error: path '/home/balsoft/' has a trailing slash
303error: path '/home/balsoft/' has a trailing slash
303```
304```
304
305
306+## `NIX_PATH` и `<nixpkgs>`
307+<!--
308+`NIX_PATH` -- переменная, очень похожая на `PATH` по синтаксису значений (значения разделены двоеточием), в которой nix ищет пути запрошенные через синтаксис `<path>`.
309+-->
310+```
311+$ NIX_PATH=home=$HOME nix repl
312+nix-repl> <home>
313+/home/balsoft
314+^D
315+$ NIX_PATH=/home nix repl
316+nix-repl> <balsoft>
317+/home/balsoft
318+$ nix repl
319+nix-repl> <nixpkgs>
320+/nix/store/zzjhgd7p1y879z0y9pz70vjd45yfi9iz-nixpkgs
321+```
305## Списки (lists)
322## Списки (lists)
306
323
307Списки в Nix иммутабельны и могут содержать значения любых типов вперемешку.
324Списки в Nix иммутабельны и могут содержать значения любых типов вперемешку.
@@ -326,6 +343,8 @@ nix-repl> [ import ./hello.nix {} ]
326## Множества аттрибутов (attribute sets, attrsets)
343## Множества аттрибутов (attribute sets, attrsets)
327```
344```
328nix-repl> s = { foo = "bar"; a-b = "baz"; "123" = "num"; }
345nix-repl> s = { foo = "bar"; a-b = "baz"; "123" = "num"; }
346+nix-repl> :t s
347+a set
329nix-repl> s
348nix-repl> s
330{ "123" = "num"; a-b = "baz"; foo = "bar"; }
349{ "123" = "num"; a-b = "baz"; foo = "bar"; }
331nix-repl> s.a-b
350nix-repl> s.a-b
@@ -334,6 +353,15 @@ nix-repl> s."123"
334"num"
353"num"
335nix-repl> s.${toString (122 + 1)}
354nix-repl> s.${toString (122 + 1)}
336"num"
355"num"
356+```
357+## Множества аттрибутов
358+```
359+nix-repl> s ? "123"
360+true
361+nix-repl> s ? a-b
362+true
363+nix-repl> s ? abc
364+false
337nix-repl> s.abc or "not found" # Note that `or` is a keyword
365nix-repl> s.abc or "not found" # Note that `or` is a keyword
338"not found"
366"not found"
339nix-repl> s // { a = 10; }
367nix-repl> s // { a = 10; }
@@ -652,7 +680,7 @@ graph [ dpi=200; ]
652```
680```
653set -e
681set -e
654unset PATH
682unset PATH
655−for p in $buildInputs; do
683+for p in $buildInputs $baseInputs; do
656 export PATH=$p/bin${PATH:+:}$PATH
684 export PATH=$p/bin${PATH:+:}$PATH
657done
685done
658tar -xf $src
686tar -xf $src
@@ -672,13 +700,379 @@ make install
672-->
700-->
673### `generic-builder.nix`
701### `generic-builder.nix`
674```
702```
675−{ buildInputs, pkgs, ... }@args:
703+pkgs: attrs:
676−with pkgs;
704+ with pkgs;
677−derivation (args // {
705+ let defaultAttrs = {
678− buildInputs = buildInputs
706+ builder = "${bash}/bin/bash";
707+ args = [ ./builder.sh ];
679− ++ [ gnutar gzip gnumake gcc binutils-unwrapped
708+ baseInputs = [ gnutar gzip gnumake gcc binutils-unwrapped
680− coreutils gawk gnused gnugrep ];
709+ coreutils gawk gnused gnugrep findutils ];
681− builder = "${bash}/bin/bash";
710+ buildInputs = [];
682− args = [ ./generic-builder.sh ];
711+ system = builtins.currentSystem;
683−})
712+ };
713+ in
714+derivation (defaultAttrs // attrs)
715+```
716+## `mkDerivation`: добавляем фазы
717+<!--
718+Создадим файл `setup.sh`, в котором определим стандартные "фазы" сборки, которые затем будем использовать в `builder.sh`.
719+-->
720+```
721+unset PATH
722+for p in $baseInputs $buildInputs; do
723+ export PATH=$p/bin${PATH:+:}$PATH
724+done
725+
726+function unpackPhase() {
727+ tar -xzf $src
728+
729+ for d in *; do
730+ if [ -d "$d" ]; then
731+ cd "$d"
732+ break
733+ fi
734+ done
735+}
736+```
737+***
738+```
739+function configurePhase() {
740+ ./configure --prefix=$out
741+}
742+function buildPhase() {
743+ make
744+}
745+function installPhase() {
746+ make install
747+}
748+function genericBuild() {
749+ unpackPhase
750+ configurePhase
751+ buildPhase
752+ installPhase
753+ fixupPhase
754+}
755+```
756+
757+***
758+
759+### `builder.sh`
760+```
761+set -e
762+source $setup
763+genericBuild
764+```
765+
766+***
767+
768+### `generic-builder.nix`
769+```
770+pkgs: attrs:
771+ with pkgs;
772+ let defaultAttrs = {
773+ builder = "${bash}/bin/bash";
774+ args = [ ./builder.sh ];
775+ setup = ./setup.sh;
776+ baseInputs = [ gnutar gzip gnumake gcc binutils-unwrapped
777+ coreutils gawk gnused gnugrep findutils ];
778+ buildInputs = [];
779+ system = builtins.currentSystem;
780+ };
781+ in
782+derivation (defaultAttrs // attrs)
783+```
784+## `mkDerivation`: воспользуемся нашей функцией!
785+<!--
786+Отлично! Наша функция умеет собирать autotools-проекты, при этом `builder.sh` получился очень простым благодаря `setup.nix`. Теперь если мы хотим собрать проект не на основе autotools, мы можем это легко сделать, пропустив некоторые фазы в builder.
787+-->
788+### `default.nix`
789+```
790+let
791+ pkgs = import <nixpkgs> {};
792+ mkDerivation = import ./generic-builder.nix pkgs;
793+in
794+mkDerivation {
795+ name = "hello";
796+ src = ./hello-2.10.tar.gz;
797+};
798+```
799+
800+## Пакеты как функции от зависимостей: паттерн inputs
801+<!--
802+Сделаем наш репозиторий ещё удобнее, вынеся определения пакетов в отдельные файлы. В каждом таком файле будет находиться функция, принимающая в качестве аргументов зависимости пакета и возвращающая деривацию (который мы будем создавать с помощью нашего `mkDerivation`)
803+-->
804+### `hello.nix`
805+```
806+{ mkDerivation }:
807+mkDerivation {
808+ name = "hello";
809+ src = ./hello-2.10.tar.gz;
810+}
811+```
812+
813+### `default.nix`
814+```
815+let
816+ pkgs = import <nixpkgs> {};
817+ mkDerivation = import ./generic-builder.nix pkgs;
818+in
819+{
820+ hello = import ./hello.nix { inherit mkDerivation };
821+}
822+```
823+
824+## Сборка с библиотеками: `NIX_CFLAGS_COMPILE`, `NIX_LDFLAGS`
825+<!--
826+Если мы хотим собирать пакеты, которые зависят от сторонних библиотек, нам понадобится ещё немного магии: нужно указать GCC и ld, где искать заголовочные и объектные файлы библиотек. Для этого существуют переменные `NIX CFLAGS COMPILE` и `NIX LDFLAGS`
827+-->
828+### `generic-builder.sh`
829+```
830+[...]
831+for p in $baseInputs $buildInputs; do
832+ [...]
833+ if [ -d $p/include ]; then
834+ export NIX_CFLAGS_COMPILE="-I $p/include${NIX_CFLAGS_COMPILE:+ }\
835+$NIX_CFLAGS_COMPILE"
836+ fi
837+ if [ -d $p/lib ]; then
838+ export NIX_LDFLAGS="-rpath $p/lib -L \
839+$p/lib${NIX_LDFLAGS:+ }$NIX_LDFLAGS"
840+ fi
841+done
842+[...]
684```
843```
844+***
845+### `graphviz.nix`
846+```
847+{ mkDerivation, gdSupport ? true, gd, fontconfig, libjpeg, bzip2 }:
848+
849+mkDerivation {
850+ name = "graphviz";
851+ src = ./graphviz-2.38.0.tar.gz;
852+ buildInputs = if gdSupport
853+ then [ gd fontconfig libjpeg bzip2 ]
854+ else [];
855+}
856+```
857+***
858+### `default.nix`
859+```
860+let
861+ pkgs = import <nixpkgs> {};
862+ mkDerivation = import ./generic-builder.nix pkgs;
863+in
864+{
865+ hello = import ./hello.nix { inherit mkDerivation };
866+ graphviz = import ./graphviz.nix { inherit mkDerivation
867+ gd fontconfig libjpeg bzip2; };
868+ graphvizCore = import ./graphviz.nix {
869+ inherit mkDerivation gd fontconfig libjpeg bzip2;
870+ gdSupport = false;
871+ };
872+}
873+```
874+
875+## Паттерн `callPackage`
876+<!--
877+Здорово! Мы сделали свой небольшой репозиторий с красивой файловой структурой, научились собирать пакеты с помощью autotools с возможностью легко перейти на другие системы сборки и даже собирать пакеты с библиотеками. Теперь пора уменьшить бойлерплейт. Можно заметить, что в корневом файле репозитория мы повторяем названия аргументов функции при её вызове. Это будет происходить постоянно при структуре репозитория, похожего на наш. Для того, чтобы исправить эту проблему, мы создадим функцию `callPackage`, которая будет вызывать функцию из указанного файла, автоматически передавая ей аргументы из указанного attrset. Например:
878+-->
879+### `default.nix`
880+```
881+let
882+ pkgs = import <nixpkgs> {};
883+ mkDerivation = import ./generic-builder.nix pkgs;
884+in
885+{
886+ hello = callPackage ./hello.nix { };
887+ graphviz = callPackage ./graphviz.nix { };
888+ graphvizCore = callPackage ./graphviz.nix { gdSupport = false; };
889+}
890+```
891+***
892+<!--
893+Для начала разберемся с тем, как же нам найти названия аргументов функции. В nix для этого существует встроенная функция `builins.functionArgs`. Она возвращает attrset, в котором названию аргументов соответствует наличие у них значения по-умолчанию.
894+-->
895+```
896+nix-repl> add = { a ? 3, b }: a+b
897+nix-repl> builtins.functionArgs add
898+{ a = true; b = false; }
899+```
900+<!--
901+Также в nix существует удобный builtin для "пересечения" двух attrset-ов. Он возвращает attrset, в котором имена аттрибутов -- пересечение имен аттрибутов его аргументов, а их значения берутся из второго аргумента. Например:
902+-->
903+```
904+nix-repl> values = { a = 3; b = 5; c = 10; }
905+nix-repl> builtins.intersectAttrs values (builtins.functionArgs add)
906+{ a = true; b = false; }
907+nix-repl> builtins.intersectAttrs (builtins.functionArgs add) values
908+{ a = 3; b = 5; }
909+```
910+## Простой вариант `callPackage`
911+<!--
912+Обладая этими знаниями, напишем простую реализацию нашего callPackage.
913+-->
914+```
915+nix-repl> callPackage = set: f:
916+ f (builtins.intersectAttrs
917+ (builtins.functionArgs f)
918+ set)
919+nix-repl> callPackage values add
920+8
921+nix-repl> with values; add { inherit a b; }
922+8
923+```
924+## `callPackage`: добавляем оверрайды
925+<!--
926+Добавим возможность перегружать значения с помощью последнего аргумента...
927+-->
928+```
929+nix-repl> callPackage = set: f: overrides:
930+ f ((builtins.intersectAttrs
931+ (builtins.functionArgs f)
932+ set)
933+ // overrides)
934+nix-repl> callPackage values add { }
935+8
936+nix-repl> callPackage values add { b = 12; }
937+15
938+```
939+## `callPackage`: используем!
940+```
941+let
942+ nixpkgs = import <nixpkgs> {};
943+ allPkgs = nixpkgs // pkgs;
944+ callPackage = path: overrides:
945+ let f = import path;
946+ in f ((builtins.intersectAttrs
947+ (builtins.functionArgs f)
948+ allPkgs)
949+ // overrides);
950+ pkgs = with nixpkgs; {
951+ mkDerivation = import ./generic-builder.nix nixpkgs;
952+ hello = callPackage ./hello.nix { };
953+ graphviz = callPackage ./graphviz.nix { };
954+ graphvizCore = callPackage ./graphviz.nix { gdSupport = false; };
955+ };
956+in pkgs
957+```
958+## Паттерн `override`
959+<!--
960+Nix -- это функциональный язык. Одна из идей функциональной парадигмы состоит в композиции функций. Это может быть очень удобно при работе с деривациями. Например, если мы хотим получить `graphviz`, собранный с нашей собственной версией библиотеки gd, на данный момент нам придется заново делать `callPackage ./graphviz.nix { gd = customgd; }` Это неудобно и добавляет бойлерплейт.
961+-->
962+```
963+mygraphviz = callPackage ./graphviz.nix { gd = customgd; }
964+
965+VS.
966+
967+mygraphviz = pkgs.graphviz.override { gd = customgd }
968+```
969+## Паттерн `override`: `makeOverridable`
970+<!--
971+Для реализации нашей затеи напишем функцию `mkOverridable`, которая будет принимать функцию, возвращающую attrset, и attrset (который будет являться "дефолтными" аргументами для данной функции). Вернет `makeOverridable` тот же attrset, что вернула бы данная функция, с добавлением аттрибута `override`, который является функцией, позволяющей нам "перегружать" стандартные аргументы.
972+-->
973+### `lib.nix`
974+```
975+rec {
976+ makeOverridable = f: origArgs:
977+ let
978+ origRes = f origArgs;
979+ in
980+ origRes // {
981+ override = newArgs:
982+ makeOverridable f (origArgs // newArgs);
983+ };
984+}
985+```
986+## Паттерн `override`: потестируем!
987+<!--
988+Работает! Теперь мы можем легко "перегружать" аргументы пакетов (которые, напомню, просто функции) в нашем репозитории. Нужно только не забыть вызывать все эти пакеты с makeOverridable.
989+-->
990+```
991+nix-repl> :l lib.nix
992+Added 1 variables.
993+nix-repl> f = { a, b }: { result = a+b; }
994+nix-repl> res = makeOverridable f { a = 3; b = 5; }
995+nix-repl> res2 = res.override { a = 10; }
996+nix-repl> res2
997+{ override = «lambda»; result = 15; }
998+nix-repl> res2.override { b = 20; }
999+{ override = «lambda»; result = 30; }
1000+```
1001+## Паттерн `override`: объединяем с `callPackage`
1002+### `lib.nix`
1003+```
1004+rec {
1005+ [...]
1006+ callPackage = pkgs: path: overrides:
1007+ let f = import path;
1008+ in makeOverridable
1009+ f ((builtins.intersectAttrs
1010+ (builtins.functionArgs f)
1011+ pkgs)
1012+ // overrides);
1013+}
1014+```
1015+## Паттерн `override`: репозиторий
1016+### `default.nix`
1017+```
1018+let
1019+ lib = import ./lib.nix;
1020+ nixpkgs = import <nixpkgs> {};
1021+ callPackage = lib.callPackage allPkgs;
1022+ allPkgs = nixpkgs // pkgs;
1023+ pkgs = with nixpkgs; rec {
1024+ mkDerivation = import ./generic-builder.nix nixpkgs;
1025+ hello = callPackage ./hello.nix { };
1026+ graphviz = callPackage ./graphviz.nix { };
1027+ graphvizCore = graphviz.override { gdSupport = false };
1028+ };
1029+in pkgs
1030+```
1031+## nixpkgs: краткая справка
1032+
1033+### Общая конфигурация для всех пакетов
1034+
1035+* `import <nixpkgs> { config = {...}; }`
1036+* `$NIXPKGS_CONFIG`
1037+* `~/.config/nixpkgs/config.nix`
1038+
1039+
1040+### Перегрузка пакетов
1041+
1042+```
1043+config.packageOverrides = oldPkgs: {
1044+ graphviz = oldPkgs.graphviz.override { gd = customgd; };
1045+}
1046+```
1047+
1048+### Оверлеи
1049+```
1050+nixpkgs.overlays = [ (self: super: {
1051+ graphviz = super.graphviz.override { gd = customgd; };
1052+} ) ];
1053+```
1054+
1055+## `stdenv.mkDerivation`: прокачиваем наш `mkDerivation`
1056+<!--
1057+Наша функция `mkDerivation`, без сомнения, прекарасна, но можно лучше! `stdenv.mkDerivation` из nixpkgs предоставляет интерфейс (т.е принимаемые и возвращаемые значения) очень похожие на наш `mkDerivation`, с несколькими отличиями:
1058+-->
1059+`stdenv.mkDerivation` может...
1060+
1061+* Изменять поведение фаз, например `{ buildPhase = "make"; }`
1062+* Изменять список фаз `{ phases = [ "buildPhase" ]; }`
1063+* Перегружать аргументы с помощью `overrideAttrs`
1064+* Автоматически добавлять хуки на проброс зависимостей с помощью `propogatedBuildInputs`
1065+
1066+
1067+## Что осталось за кадром в этом разделе
1068+
1069+<!--
1070+Нельзя объять необъятное -- а nixpkgs действительно необъятен, более 100МБ кода на данный момент -- и поэтому я оставлю изучение частностей на совести слушателя.
1071+-->
1072+
1073+* `stdenv`
1074+* `lib`
1075+* `fix`
1076+* ...
1077+<https://nixos.org/nixos/nix-pills> и <https://nixos.org/nixpkgs/manual> -- для тех, кому надо или интересно!
1078+