mirror of
https://github.com/NixOS/nix-pills
synced 2024-09-19 04:00:13 -04:00
Transform <xi:include> elements to include content
This commit is contained in:
parent
8291ca1677
commit
57dc8ac921
|
@ -157,7 +157,9 @@
|
|||
<para>
|
||||
In fact, there's no ldconfig cache either. So where does bash find libc?
|
||||
</para>
|
||||
<screen><xi:include href="./01/which-bash.txt" parse="text" /></screen>
|
||||
<screen>$ ldd `which bash`
|
||||
libc.so.6 => /nix/store/94n64qy99ja0vgbkf675nyk39g9b978n-glibc-2.19/lib/libc.so.6 (0x00007f0248cce000)
|
||||
</screen>
|
||||
<para>
|
||||
It turns out that when bash was built, it was built against that specific
|
||||
version of glibc in the Nix store, and at runtime it will require exactly that
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
$ ldd `which bash`
|
||||
libc.so.6 => /nix/store/94n64qy99ja0vgbkf675nyk39g9b978n-glibc-2.19/lib/libc.so.6 (0x00007f0248cce000)
|
|
@ -124,7 +124,11 @@
|
|||
xlink:href="https://nixos.org/manual/nix/stable/package-management/profiles.html">profile</link>:
|
||||
</para>
|
||||
|
||||
<xi:include href="./02/user-environment.xml" parse="xml" />
|
||||
<screen>creating /home/nix/.nix-profile
|
||||
installing 'nix-2.1.3'
|
||||
building path(s) `/nix/store/a7p1w3z2h8pl00ywvw6icr3g5l9vm5r7-<emphasis role="strong">user-environment</emphasis>'
|
||||
created 7 symlinks in user environment</screen>
|
||||
|
||||
|
||||
<para>
|
||||
A profile in Nix is a general and convenient concept for
|
||||
|
@ -144,7 +148,13 @@
|
|||
Let's take a closer look at our profile:
|
||||
</para>
|
||||
|
||||
<xi:include href="./02/profile.xml" parse="xml" />
|
||||
<screen>$ ls -l ~/.nix-profile/
|
||||
bin -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-<emphasis role="strong">nix-2.1.3</emphasis>/bin
|
||||
[...]
|
||||
manifest.nix -> /nix/store/q8b5238akq07lj9gfb3qb5ycq4dxxiwm-<emphasis role="strong">env-manifest.nix</emphasis>
|
||||
[...]
|
||||
share -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-<emphasis role="strong">nix-2.1.3</emphasis>/share</screen>
|
||||
|
||||
<para>
|
||||
That <package>nix-2.1.3</package> derivation in the Nix store is
|
||||
Nix itself, with binaries and libraries. The process of "installing"
|
||||
|
@ -188,8 +198,11 @@
|
|||
More output from the installer:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./02/nixpkgs-expressions.txt"
|
||||
parse="text" /></screen>
|
||||
<screen>downloading Nix expressions from `http://releases.nixos.org/nixpkgs/nixpkgs-14.10pre46060.a1a2851/nixexprs.tar.xz'...
|
||||
unpacking channels...
|
||||
created 2 symlinks in user environment
|
||||
modifying /home/nix/.profile...
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Nix expressions are written in the <link
|
||||
|
@ -260,7 +273,10 @@
|
|||
</para>
|
||||
|
||||
|
||||
<screen><xi:include href="./02/ldd-bash.txt" parse="text" /></screen>
|
||||
<screen>
|
||||
$ ldd /nix/store/*bash*/bin/bash
|
||||
[...]
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Keeping the store in <filename>/nix</filename> means we can grab
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
$ ldd /nix/store/*bash*/bin/bash
|
||||
[...]
|
|
@ -1,4 +0,0 @@
|
|||
downloading Nix expressions from `http://releases.nixos.org/nixpkgs/nixpkgs-14.10pre46060.a1a2851/nixexprs.tar.xz'...
|
||||
unpacking channels...
|
||||
created 2 symlinks in user environment
|
||||
modifying /home/nix/.profile...
|
|
@ -1,6 +0,0 @@
|
|||
<screen>$ ls -l ~/.nix-profile/
|
||||
bin -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-<emphasis role="strong">nix-2.1.3</emphasis>/bin
|
||||
[...]
|
||||
manifest.nix -> /nix/store/q8b5238akq07lj9gfb3qb5ycq4dxxiwm-<emphasis role="strong">env-manifest.nix</emphasis>
|
||||
[...]
|
||||
share -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-<emphasis role="strong">nix-2.1.3</emphasis>/share</screen>
|
|
@ -1,4 +0,0 @@
|
|||
<screen>creating /home/nix/.nix-profile
|
||||
installing 'nix-2.1.3'
|
||||
building path(s) `/nix/store/a7p1w3z2h8pl00ywvw6icr3g5l9vm5r7-<emphasis role="strong">user-environment</emphasis>'
|
||||
created 7 symlinks in user environment</screen>
|
|
@ -33,7 +33,8 @@
|
|||
If that's not the case:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/source-nix.txt" parse="text" /></screen>
|
||||
<screen>$ source ~/.nix-profile/etc/profile.d/nix.sh
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
To remind you, <literal>~/.nix-profile/etc</literal> points to the <literal>nix-2.1.3</literal>
|
||||
|
@ -55,7 +56,12 @@
|
|||
Back to the installation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/install-hello.txt" parse="text" /></screen>
|
||||
<screen>$ nix-env -i hello
|
||||
installing 'hello-2.10'
|
||||
[...]
|
||||
building '/nix/store/0vqw0ssmh6y5zj48yg34gc6macr883xk-user-environment.drv'...
|
||||
created 36 symlinks in user environment
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Now you can run <literal>hello</literal>. Things to notice:
|
||||
|
@ -92,13 +98,19 @@
|
|||
We can list generations without walking through the <filename>/nix</filename> hierarchy:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/list-generations.txt" parse="text" /></screen>
|
||||
<screen>$ nix-env --list-generations
|
||||
1 2014-07-24 09:23:30
|
||||
2 2014-07-25 08:45:01 (current)
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Listing installed derivations:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/list-installed-derivations.txt" parse="text" /></screen>
|
||||
<screen>$ nix-env -q
|
||||
nix-2.1.3
|
||||
hello-2.10
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
So, where did <literal>hello</literal> really get installed?
|
||||
|
@ -128,7 +140,11 @@
|
|||
a bit:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/ls-nix-profile.txt" parse="text" /></screen>
|
||||
<screen>$ ls -l ~/.nix-profile/
|
||||
dr-xr-xr-x 2 nix nix 4096 Jan 1 1970 bin
|
||||
lrwxrwxrwx 1 nix nix 55 Jan 1 1970 etc -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/etc
|
||||
[...]
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Now that's interesting. When only <literal>nix-2.1.3</literal> was installed, <filename>bin</filename> was a
|
||||
|
@ -136,7 +152,15 @@
|
|||
(<literal>man</literal>, <literal>hello</literal>), it's a real directory, not a symlink.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/ls-profile-bin.txt" parse="text" /></screen>
|
||||
<screen>$ ls -l ~/.nix-profile/bin/
|
||||
[...]
|
||||
man -> /nix/store/83cn9ing5sc6644h50dqzzfxcs07r2jn-man-1.6g/bin/man
|
||||
[...]
|
||||
nix-env -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin/nix-env
|
||||
[...]
|
||||
hello -> /nix/store/58r35bqb4f3lxbnbabq718svq9i2pda3-hello-2.10/bin/hello
|
||||
[...]
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Okay, that's clearer now. <literal>nix-env</literal> merged the paths from the installed derivations.
|
||||
|
@ -155,7 +179,9 @@
|
|||
old generation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/rollback.txt" parse="text" /></screen>
|
||||
<screen>$ nix-env --rollback
|
||||
switching from generation 3 to 2
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Now <command>nix-env -q</command> does not list <literal>man</literal> anymore.
|
||||
|
@ -166,7 +192,9 @@
|
|||
Enough with the rollback, let's go back to the most recent generation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/generation-3.txt" parse="text" /></screen>
|
||||
<screen>$ nix-env -G 3
|
||||
switching from generation 2 to 3
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
I invite you to read the manpage of <literal>nix-env</literal>. <literal>nix-env</literal> requires an operation
|
||||
|
@ -200,7 +228,10 @@
|
|||
To show the direct runtime dependencies of <literal>hello</literal>:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/references.txt" parse="text" /></screen>
|
||||
<screen>$ nix-store -q --references `which hello`
|
||||
/nix/store/fg4yq8i8wd08xg3fy58l6q73cjy8hjr2-glibc-2.27
|
||||
/nix/store/58r35bqb4f3lxbnbabq718svq9i2pda3-hello-2.10
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
The argument to <literal>nix-store</literal> can be anything as long as it points to the
|
||||
|
@ -212,7 +243,13 @@
|
|||
dependencies of <literal>hello</literal>:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/referrers.txt" parse="text" /></screen>
|
||||
<screen>$ nix-store -q --referrers `which hello`
|
||||
/nix/store/58r35bqb4f3lxbnbabq718svq9i2pda3-hello-2.10
|
||||
/nix/store/fhvy2550cpmjgcjcx5rzz328i0kfv3z3-env-manifest.nix
|
||||
/nix/store/yzdk0xvr0b8dcwhi2nns6d75k2ha5208-env-manifest.nix
|
||||
/nix/store/mp987abm20c70pl8p31ljw1r5by4xwfw-user-environment
|
||||
/nix/store/ppr3qbq7fk2m2pa49i2z3i32cvfhsv7p-user-environment
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Was it what you expected? It turns out that our environments depend upon <literal>hello</literal>.
|
||||
|
@ -241,7 +278,9 @@
|
|||
including absolutely everything necessary to use that derivation.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/nix-store.txt" parse="text" /></screen>
|
||||
<screen>$ nix-store -qR `which man`
|
||||
[...]
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Copying all those derivations to the Nix store of another machine makes
|
||||
|
@ -256,7 +295,9 @@
|
|||
A nicer view of the closure:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/nix-store-tree.txt" parse="text" /></screen>
|
||||
<screen>$ nix-store -q --tree `which man`
|
||||
[...]
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
With the above command, you can find out exactly why a
|
||||
|
@ -286,7 +327,11 @@
|
|||
<section>
|
||||
<title>Recovering the hard way</title>
|
||||
|
||||
<screen><xi:include href="./03/uninstall-all.txt" parse="text" /></screen>
|
||||
<screen>$ nix-env -e '*'
|
||||
uninstalling 'hello-2.10'
|
||||
uninstalling 'nix-2.1.3'
|
||||
[...]
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Oops, that uninstalled all derivations from the environment, including
|
||||
|
@ -308,13 +353,15 @@
|
|||
The first option is to rollback:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/nix-env-rollback.txt" parse="text" /></screen>
|
||||
<screen>$ /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin/nix-env --rollback
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
The second option is to install Nix, thus creating a new generation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/install.txt" parse="text" /></screen>
|
||||
<screen>$ /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin/nix-env -i /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin/nix-env
|
||||
</screen>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
@ -328,7 +375,9 @@
|
|||
<link xlink:href="https://nixos.org/manual/nix/stable/command-ref/nix-channel.html">nix-channel</link>.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/channel-list.txt" parse="text" /></screen>
|
||||
<screen>$ nix-channel --list
|
||||
nixpkgs http://nixos.org/channels/nixpkgs-unstable
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
If you're using NixOS, you may not see any output from the above command
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
$ nix-channel --list
|
||||
nixpkgs http://nixos.org/channels/nixpkgs-unstable
|
|
@ -1,2 +0,0 @@
|
|||
$ nix-env -G 3
|
||||
switching from generation 2 to 3
|
|
@ -1,5 +0,0 @@
|
|||
$ nix-env -i hello
|
||||
installing 'hello-2.10'
|
||||
[...]
|
||||
building '/nix/store/0vqw0ssmh6y5zj48yg34gc6macr883xk-user-environment.drv'...
|
||||
created 36 symlinks in user environment
|
|
@ -1 +0,0 @@
|
|||
$ /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin/nix-env -i /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin/nix-env
|
|
@ -1,3 +0,0 @@
|
|||
$ nix-env --list-generations
|
||||
1 2014-07-24 09:23:30
|
||||
2 2014-07-25 08:45:01 (current)
|
|
@ -1,3 +0,0 @@
|
|||
$ nix-env -q
|
||||
nix-2.1.3
|
||||
hello-2.10
|
|
@ -1,4 +0,0 @@
|
|||
$ ls -l ~/.nix-profile/
|
||||
dr-xr-xr-x 2 nix nix 4096 Jan 1 1970 bin
|
||||
lrwxrwxrwx 1 nix nix 55 Jan 1 1970 etc -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/etc
|
||||
[...]
|
|
@ -1,8 +0,0 @@
|
|||
$ ls -l ~/.nix-profile/bin/
|
||||
[...]
|
||||
man -> /nix/store/83cn9ing5sc6644h50dqzzfxcs07r2jn-man-1.6g/bin/man
|
||||
[...]
|
||||
nix-env -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin/nix-env
|
||||
[...]
|
||||
hello -> /nix/store/58r35bqb4f3lxbnbabq718svq9i2pda3-hello-2.10/bin/hello
|
||||
[...]
|
|
@ -1 +0,0 @@
|
|||
$ /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin/nix-env --rollback
|
|
@ -1,2 +0,0 @@
|
|||
$ nix-store -q --tree `which man`
|
||||
[...]
|
|
@ -1,2 +0,0 @@
|
|||
$ nix-store -qR `which man`
|
||||
[...]
|
|
@ -1,3 +0,0 @@
|
|||
$ nix-store -q --references `which hello`
|
||||
/nix/store/fg4yq8i8wd08xg3fy58l6q73cjy8hjr2-glibc-2.27
|
||||
/nix/store/58r35bqb4f3lxbnbabq718svq9i2pda3-hello-2.10
|
|
@ -1,6 +0,0 @@
|
|||
$ nix-store -q --referrers `which hello`
|
||||
/nix/store/58r35bqb4f3lxbnbabq718svq9i2pda3-hello-2.10
|
||||
/nix/store/fhvy2550cpmjgcjcx5rzz328i0kfv3z3-env-manifest.nix
|
||||
/nix/store/yzdk0xvr0b8dcwhi2nns6d75k2ha5208-env-manifest.nix
|
||||
/nix/store/mp987abm20c70pl8p31ljw1r5by4xwfw-user-environment
|
||||
/nix/store/ppr3qbq7fk2m2pa49i2z3i32cvfhsv7p-user-environment
|
|
@ -1,2 +0,0 @@
|
|||
$ nix-env --rollback
|
||||
switching from generation 3 to 2
|
|
@ -1 +0,0 @@
|
|||
$ source ~/.nix-profile/etc/profile.d/nix.sh
|
|
@ -1,4 +0,0 @@
|
|||
$ nix-env -e '*'
|
||||
uninstalling 'hello-2.10'
|
||||
uninstalling 'nix-2.1.3'
|
||||
[...]
|
|
@ -65,13 +65,23 @@
|
|||
Help is available through the <literal>:?</literal> command.)
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/basics.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> 1+3
|
||||
4
|
||||
|
||||
nix-repl> 7-4
|
||||
3
|
||||
|
||||
nix-repl> 3*2
|
||||
6
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Attempting to perform division in Nix can lead to some surprises.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/relative-path.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> 6/3
|
||||
/home/nix/6/3
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
What happened? Recall that Nix is not a general purpose language, it's a
|
||||
|
@ -83,7 +93,12 @@
|
|||
<literal>builtins.div</literal>.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/division.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> 6/ 3
|
||||
2
|
||||
|
||||
nix-repl> builtins.div 6 3
|
||||
2
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Other operators are <literal>||</literal>, <literal>&&</literal> and <literal>!</literal>
|
||||
|
@ -128,7 +143,11 @@
|
|||
convenient since many packages use dash in their names. In fact:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/dash.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> a-b
|
||||
error: undefined variable `a-b' at (string):1:1
|
||||
nix-repl> a - b
|
||||
error: undefined variable `a' at (string):1:1
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
As you can see, <literal>a-b</literal> is parsed as identifier, not as
|
||||
|
@ -145,7 +164,11 @@
|
|||
Strings are enclosed by double quotes (<literal>"</literal>), or two single quotes (<literal>''</literal>).
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/strings-basic.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> "foo"
|
||||
"foo"
|
||||
nix-repl> ''foo''
|
||||
"foo"
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
In other languages like Python you can also use single quotes for strings (e.g. <literal>'foo'</literal>),
|
||||
|
@ -159,7 +182,14 @@
|
|||
not <literal>$foo</literal> or <literal>{$foo}</literal> or anything else.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/interpolate.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> foo = "strval"
|
||||
nix-repl> "$foo"
|
||||
"$foo"
|
||||
nix-repl> "${foo}"
|
||||
"strval"
|
||||
nix-repl> "${2+3}"
|
||||
error: cannot coerce an integer to a string, at (string):1:2
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Note: ignore the <literal>foo = "strval"</literal> assignment, special syntax in <literal>nix repl</literal>.
|
||||
|
@ -175,14 +205,22 @@
|
|||
quotes inside strings without needing to escape them:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/double-quotes.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> ''test " test''
|
||||
"test \" test"
|
||||
nix-repl> ''${foo}''
|
||||
"strval"
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Escaping <literal>${...}</literal> within double quoted strings is done with the backslash.
|
||||
Within two single quotes, it's done with <literal>''</literal>:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/escaping.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> "\${foo}"
|
||||
"${foo}"
|
||||
nix-repl> ''test ''${foo} test''
|
||||
"test ${foo} test"
|
||||
</screen>
|
||||
|
||||
</section>
|
||||
|
||||
|
@ -193,7 +231,9 @@
|
|||
Lists are a sequence of expressions delimited by space (<emphasis>not</emphasis> comma):
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/lists.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> [ 2 "foo" true (2+3) ]
|
||||
[ 2 "foo" true 5 ]
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Lists, like everything else in Nix, are immutable. Adding or removing
|
||||
|
@ -210,7 +250,10 @@
|
|||
keys.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/set-basics.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> s = { foo = "bar"; a-b = "baz"; "123" = "num"; }
|
||||
nix-repl> s
|
||||
{ "123" = "num"; a-b = "baz"; foo = "bar"; }
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
For those reading Nix expressions from nixpkgs: do not confuse attribute sets with
|
||||
|
@ -221,7 +264,11 @@
|
|||
To access elements in the attribute set:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/set-access.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> s.a-b
|
||||
"baz"
|
||||
nix-repl> s."123"
|
||||
"num"
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Yes, you can use strings to address keys which aren't valid identifiers.
|
||||
|
@ -231,14 +278,18 @@
|
|||
Inside an attribute set you cannot normally refer to elements of the same attribute set:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/set-failed.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> { a = 3; b = a+4; }
|
||||
error: undefined variable `a' at (string):1:10
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
To do so, use
|
||||
<link xlink:href="https://nixos.org/manual/nix/stable/expressions/language-constructs.html#recursive-sets">recursive attribute sets</link>:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/set-recursive.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> rec { a = 3; b = a+4; }
|
||||
{ a = 3; b = 7; }
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
This is very convenient when defining packages, which tend to be recursive attribute sets.
|
||||
|
@ -252,7 +303,11 @@
|
|||
These are expressions, not statements.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/if.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> a = 3
|
||||
nix-repl> b = 4
|
||||
nix-repl> if a > b then "yes" else "no"
|
||||
"no"
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
You can't have only the <literal>then</literal> branch, you must specify also the <literal>else</literal>
|
||||
|
@ -268,7 +323,9 @@
|
|||
expressions.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/let-basic.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let a = "foo"; in a
|
||||
"foo"
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
The syntax is: first assign variables, then <literal>in</literal>, then an expression which can
|
||||
|
@ -276,33 +333,45 @@
|
|||
the value of the expression after the <literal>in</literal>.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/let-multiple.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let a = 3; b = 4; in a + b
|
||||
7
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Let's write two <literal>let</literal> expressions, one inside the other:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/let-nested.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let a = 3; in let b = 4; in a + b
|
||||
7
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
With <literal>let</literal> you cannot assign twice to the same variable. However, you can
|
||||
shadow outer variables:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/let-multiple-assign.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let a = 3; a = 8; in a
|
||||
error: attribute `a' at (string):1:12 already defined at (string):1:5
|
||||
nix-repl> let a = 3; in let a = 8; in a
|
||||
8
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
You cannot refer to variables in a <literal>let</literal> expression outside of it:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/let-scope.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let a = (let c = 3; in c); in c
|
||||
error: undefined variable `c' at (string):1:31
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
You can refer to variables in the <literal>let</literal> expression when assigning variables,
|
||||
like with recursive attribute sets:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/let-reference.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let a = 4; b = a + 5; in b
|
||||
9
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
So beware when you want to refer to a variable from the outer scope, but
|
||||
|
@ -321,7 +390,12 @@
|
|||
per-expression when to include symbols into the scope.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/with-basic.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> longName = { a = 3; b = 4; }
|
||||
nix-repl> longName.a + longName.b
|
||||
7
|
||||
nix-repl> with longName; a + b
|
||||
7
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
That's it, it takes an attribute set and includes symbols from it in the scope of the inner
|
||||
|
@ -331,7 +405,11 @@
|
|||
You can however still refer to the attribute set:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/with-scope.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let a = 10; in with longName; a + b
|
||||
14
|
||||
nix-repl> let a = 10; in with longName; longName.a + b
|
||||
7
|
||||
</screen>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
@ -342,7 +420,9 @@
|
|||
working with packages.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./04/lazy.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let a = builtins.div 4 0; b = 6; in b
|
||||
6
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Since <literal>a</literal> is not needed, there's no error about division by zero, because
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
nix-repl> 1+3
|
||||
4
|
||||
|
||||
nix-repl> 7-4
|
||||
3
|
||||
|
||||
nix-repl> 3*2
|
||||
6
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> a-b
|
||||
error: undefined variable `a-b' at (string):1:1
|
||||
nix-repl> a - b
|
||||
error: undefined variable `a' at (string):1:1
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> 6/ 3
|
||||
2
|
||||
|
||||
nix-repl> builtins.div 6 3
|
||||
2
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> ''test " test''
|
||||
"test \" test"
|
||||
nix-repl> ''${foo}''
|
||||
"strval"
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> "\${foo}"
|
||||
"${foo}"
|
||||
nix-repl> ''test ''${foo} test''
|
||||
"test ${foo} test"
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> a = 3
|
||||
nix-repl> b = 4
|
||||
nix-repl> if a > b then "yes" else "no"
|
||||
"no"
|
|
@ -1,7 +0,0 @@
|
|||
nix-repl> foo = "strval"
|
||||
nix-repl> "$foo"
|
||||
"$foo"
|
||||
nix-repl> "${foo}"
|
||||
"strval"
|
||||
nix-repl> "${2+3}"
|
||||
error: cannot coerce an integer to a string, at (string):1:2
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> let a = builtins.div 4 0; b = 6; in b
|
||||
6
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> let a = "foo"; in a
|
||||
"foo"
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> let a = 3; a = 8; in a
|
||||
error: attribute `a' at (string):1:12 already defined at (string):1:5
|
||||
nix-repl> let a = 3; in let a = 8; in a
|
||||
8
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> let a = 3; b = 4; in a + b
|
||||
7
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> let a = 3; in let b = 4; in a + b
|
||||
7
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> let a = 4; b = a + 5; in b
|
||||
9
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> let a = (let c = 3; in c); in c
|
||||
error: undefined variable `c' at (string):1:31
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> [ 2 "foo" true (2+3) ]
|
||||
[ 2 "foo" true 5 ]
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> 6/3
|
||||
/home/nix/6/3
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> s.a-b
|
||||
"baz"
|
||||
nix-repl> s."123"
|
||||
"num"
|
|
@ -1,3 +0,0 @@
|
|||
nix-repl> s = { foo = "bar"; a-b = "baz"; "123" = "num"; }
|
||||
nix-repl> s
|
||||
{ "123" = "num"; a-b = "baz"; foo = "bar"; }
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> { a = 3; b = a+4; }
|
||||
error: undefined variable `a' at (string):1:10
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> rec { a = 3; b = a+4; }
|
||||
{ a = 3; b = 7; }
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> "foo"
|
||||
"foo"
|
||||
nix-repl> ''foo''
|
||||
"foo"
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> longName = { a = 3; b = 4; }
|
||||
nix-repl> longName.a + longName.b
|
||||
7
|
||||
nix-repl> with longName; a + b
|
||||
7
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> let a = 10; in with longName; a + b
|
||||
14
|
||||
nix-repl> let a = 10; in with longName; longName.a + b
|
||||
7
|
|
@ -37,7 +37,8 @@ xml:id="functions-and-imports">
|
|||
then the body of the function.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/anon-function.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> x: x*2
|
||||
«lambda»</screen>
|
||||
|
||||
<para>
|
||||
So here we defined a function that takes a parameter
|
||||
|
@ -49,7 +50,11 @@ xml:id="functions-and-imports">
|
|||
We can store functions in variables.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/named-function.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> double = x: x*2
|
||||
nix-repl> double
|
||||
«lambda»
|
||||
nix-repl> double 3
|
||||
6</screen>
|
||||
|
||||
<para>
|
||||
As usual, please ignore the special syntax for assignments inside <literal>nix repl</literal>.
|
||||
|
@ -81,8 +86,13 @@ xml:id="functions-and-imports">
|
|||
it step by step.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/multi-argument-function.txt" parse="text"
|
||||
/></screen>
|
||||
<screen>nix-repl> mul = a: (b: a*b)
|
||||
nix-repl> mul
|
||||
«lambda»
|
||||
nix-repl> mul 3
|
||||
«lambda»
|
||||
nix-repl> (mul 3) 4
|
||||
12</screen>
|
||||
|
||||
<para>
|
||||
We defined a function that takes the parameter <code>a</code>, the body
|
||||
|
@ -97,7 +107,15 @@ xml:id="functions-and-imports">
|
|||
parsing the code:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/no-parenthesis.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> mul = a: b: a*b
|
||||
nix-repl> mul
|
||||
«lambda»
|
||||
nix-repl> mul 3
|
||||
«lambda»
|
||||
nix-repl> mul 3 4
|
||||
12
|
||||
nix-repl> mul (6+7) (8+9)
|
||||
221</screen>
|
||||
|
||||
<para>
|
||||
Much more readable, you don't even notice that functions only receive one
|
||||
|
@ -111,8 +129,11 @@ xml:id="functions-and-imports">
|
|||
<emphasis role="strong">partial application</emphasis>:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/partial-application.txt" parse="text"
|
||||
/></screen>
|
||||
<screen>nix-repl> foo = mul 3
|
||||
nix-repl> foo 4
|
||||
12
|
||||
nix-repl> foo 5
|
||||
15</screen>
|
||||
|
||||
<para>
|
||||
We stored the function returned by <code>mul 3</code> into a variable foo,
|
||||
|
@ -129,7 +150,12 @@ xml:id="functions-and-imports">
|
|||
a*b</code> first by using a set as argument, then using pattern matching.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/set-argument.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> mul = s: s.a*s.b
|
||||
nix-repl> mul { a = 3; b = 4; }
|
||||
12
|
||||
nix-repl> mul = { a, b }: a*b
|
||||
nix-repl> mul { a = 3; b = 4; }
|
||||
12</screen>
|
||||
|
||||
<para>
|
||||
In the first case we defined a function that accepts a single parameter. We
|
||||
|
@ -146,8 +172,11 @@ xml:id="functions-and-imports">
|
|||
<code>b</code> in the function body directly.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/argument-set-error.txt" parse="text"
|
||||
/></screen>
|
||||
<screen>nix-repl> mul = { a, b }: a*b
|
||||
nix-repl> mul { a = 3; b = 4; c = 6; }
|
||||
error: anonymous function at (string):1:2 called with unexpected argument `c', at (string):1:1
|
||||
nix-repl> mul { a = 3; }
|
||||
error: anonymous function at (string):1:2 called without required argument `b', at (string):1:1</screen>
|
||||
|
||||
<para>
|
||||
Only a set with exactly the attributes required by the function is accepted,
|
||||
|
@ -163,15 +192,19 @@ xml:id="functions-and-imports">
|
|||
of attributes in the argument set:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/default-values.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> mul = { a, b ? 2 }: a*b
|
||||
nix-repl> mul { a = 3; }
|
||||
6
|
||||
nix-repl> mul { a = 3; b = 4; }
|
||||
12</screen>
|
||||
|
||||
<para>
|
||||
Also you can allow passing more attributes (<emphasis
|
||||
role="strong">variadic</emphasis>) than the expected ones:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/variadic-arguments.txt" parse="text"
|
||||
/></screen>
|
||||
<screen>nix-repl> mul = { a, b, ... }: a*b
|
||||
nix-repl> mul { a = 3; b = 4; c = 2; }</screen>
|
||||
|
||||
<para>
|
||||
However, in the function body you cannot access the "c" attribute. The
|
||||
|
@ -179,8 +212,9 @@ xml:id="functions-and-imports">
|
|||
role="strong">@-pattern</emphasis>:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./05/named-set-argument.txt" parse="text"
|
||||
/></screen>
|
||||
<screen>nix-repl> mul = s@{ a, b, ... }: a*b*s.c
|
||||
nix-repl> mul { a = 3; b = 4; c = 2; }
|
||||
24</screen>
|
||||
|
||||
<para>
|
||||
That's it, you give a name to the whole parameter with name@ before the set
|
||||
|
@ -244,24 +278,25 @@ xml:id="functions-and-imports">
|
|||
<filename>a.nix</filename>:
|
||||
</para>
|
||||
|
||||
<programlisting><xi:include href="./05/a-nix.txt" parse="text"
|
||||
/></programlisting>
|
||||
<programlisting>3</programlisting>
|
||||
|
||||
<para>
|
||||
<filename>b.nix</filename>:
|
||||
</para>
|
||||
|
||||
<programlisting><xi:include href="./05/b-nix.txt" parse="text"
|
||||
/></programlisting>
|
||||
<programlisting>4</programlisting>
|
||||
|
||||
<para>
|
||||
<filename>mul.nix</filename>:
|
||||
</para>
|
||||
|
||||
<programlisting><xi:include href="./05/mul-nix.txt" parse="text"
|
||||
/></programlisting>
|
||||
<programlisting>a: b: a*b</programlisting>
|
||||
|
||||
<screen><xi:include href="./05/import.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> a = import ./a.nix
|
||||
nix-repl> b = import ./b.nix
|
||||
nix-repl> mul = import ./mul.nix
|
||||
nix-repl> mul a b
|
||||
12</screen>
|
||||
|
||||
<para>
|
||||
Yes it's really that simple. You import a file, and it gets parsed as an
|
||||
|
@ -273,10 +308,10 @@ xml:id="functions-and-imports">
|
|||
<filename>test.nix</filename>:
|
||||
</para>
|
||||
|
||||
<programlisting><xi:include href="./05/test-nix.txt" parse="text"
|
||||
/></programlisting>
|
||||
<programlisting>x</programlisting>
|
||||
|
||||
<screen><xi:include href="./05/test-import.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> let x = 5; in import ./test.nix
|
||||
error: undefined variable `x' at /home/lethal/test.nix:1:1</screen>
|
||||
|
||||
<para>
|
||||
So how do we pass information to the module? Use functions, like we did with
|
||||
|
@ -287,10 +322,16 @@ xml:id="functions-and-imports">
|
|||
<filename>test.nix</filename>:
|
||||
</para>
|
||||
|
||||
<programlisting><xi:include href="./05/test-nix-2.txt" parse="text"
|
||||
/></programlisting>
|
||||
<programlisting>{ a, b ? 3, trueMsg ? "yes", falseMsg ? "no" }:
|
||||
if a > b
|
||||
then builtins.trace trueMsg true
|
||||
else builtins.trace falseMsg false
|
||||
</programlisting>
|
||||
|
||||
<screen><xi:include href="./05/test-import-2.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> import ./test.nix { a = 5; trueMsg = "ok"; }
|
||||
trace: ok
|
||||
true
|
||||
</screen>
|
||||
|
||||
|
||||
<para>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
3
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> x: x*2
|
||||
«lambda»
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> mul = { a, b }: a*b
|
||||
nix-repl> mul { a = 3; b = 4; c = 6; }
|
||||
error: anonymous function at (string):1:2 called with unexpected argument `c', at (string):1:1
|
||||
nix-repl> mul { a = 3; }
|
||||
error: anonymous function at (string):1:2 called without required argument `b', at (string):1:1
|
|
@ -1 +0,0 @@
|
|||
4
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> mul = { a, b ? 2 }: a*b
|
||||
nix-repl> mul { a = 3; }
|
||||
6
|
||||
nix-repl> mul { a = 3; b = 4; }
|
||||
12
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> a = import ./a.nix
|
||||
nix-repl> b = import ./b.nix
|
||||
nix-repl> mul = import ./mul.nix
|
||||
nix-repl> mul a b
|
||||
12
|
|
@ -1 +0,0 @@
|
|||
a: b: a*b
|
|
@ -1,7 +0,0 @@
|
|||
nix-repl> mul = a: (b: a*b)
|
||||
nix-repl> mul
|
||||
«lambda»
|
||||
nix-repl> mul 3
|
||||
«lambda»
|
||||
nix-repl> (mul 3) 4
|
||||
12
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> double = x: x*2
|
||||
nix-repl> double
|
||||
«lambda»
|
||||
nix-repl> double 3
|
||||
6
|
|
@ -1,3 +0,0 @@
|
|||
nix-repl> mul = s@{ a, b, ... }: a*b*s.c
|
||||
nix-repl> mul { a = 3; b = 4; c = 2; }
|
||||
24
|
|
@ -1,9 +0,0 @@
|
|||
nix-repl> mul = a: b: a*b
|
||||
nix-repl> mul
|
||||
«lambda»
|
||||
nix-repl> mul 3
|
||||
«lambda»
|
||||
nix-repl> mul 3 4
|
||||
12
|
||||
nix-repl> mul (6+7) (8+9)
|
||||
221
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> foo = mul 3
|
||||
nix-repl> foo 4
|
||||
12
|
||||
nix-repl> foo 5
|
||||
15
|
|
@ -1,6 +0,0 @@
|
|||
nix-repl> mul = s: s.a*s.b
|
||||
nix-repl> mul { a = 3; b = 4; }
|
||||
12
|
||||
nix-repl> mul = { a, b }: a*b
|
||||
nix-repl> mul { a = 3; b = 4; }
|
||||
12
|
|
@ -1,3 +0,0 @@
|
|||
nix-repl> import ./test.nix { a = 5; trueMsg = "ok"; }
|
||||
trace: ok
|
||||
true
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> let x = 5; in import ./test.nix
|
||||
error: undefined variable `x' at /home/lethal/test.nix:1:1
|
|
@ -1,4 +0,0 @@
|
|||
{ a, b ? 3, trueMsg ? "yes", falseMsg ? "no" }:
|
||||
if a > b
|
||||
then builtins.trace trueMsg true
|
||||
else builtins.trace falseMsg false
|
|
@ -1 +0,0 @@
|
|||
x
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> mul = { a, b, ... }: a*b
|
||||
nix-repl> mul { a = 3; b = 4; c = 2; }
|
|
@ -70,13 +70,16 @@
|
|||
First of all, what's the name of our system as seen by nix?
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/current-system.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> builtins.currentSystem
|
||||
"x86_64-linux"</screen>
|
||||
|
||||
<para>
|
||||
Let's try to fake the name of the system:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/fake-system.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
|
||||
nix-repl> d
|
||||
«derivation /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv»</screen>
|
||||
|
||||
<para>
|
||||
Oh oh, what's that? Did it build the derivation? No it didn't, but it
|
||||
|
@ -131,7 +134,28 @@
|
|||
If your version of nix doesn't have <literal>nix derivation show</literal>, use <literal>nix show-derivation</literal> instead.
|
||||
</para></note>
|
||||
|
||||
<xi:include href="./06/show-derivation.xml" />
|
||||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>$ </prompt><userinput>nix derivation show /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-<emphasis>myname.drv</emphasis></userinput>
|
||||
<computeroutput>{
|
||||
"/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv": {
|
||||
"outputs": {
|
||||
"out": {
|
||||
"path": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
|
||||
}
|
||||
},
|
||||
"inputSrcs": [],
|
||||
"inputDrvs": {},
|
||||
"platform": "mysystem",
|
||||
"builder": "mybuilder",
|
||||
"args": [],
|
||||
"env": {
|
||||
"builder": "mybuilder",
|
||||
"name": "myname",
|
||||
"out": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname",
|
||||
"system": "mysystem"
|
||||
}
|
||||
}
|
||||
}</computeroutput></screen>
|
||||
|
||||
|
||||
<para>
|
||||
Ok, we can see there's an out path, but it does not exist yet. We never told
|
||||
|
@ -207,7 +231,13 @@
|
|||
Let's build our really fake derivation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/build-derivation.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
|
||||
nix-repl> :b d
|
||||
[...]
|
||||
these derivations will be built:
|
||||
/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
|
||||
building path(s) `/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname'
|
||||
error: a `mysystem' is required to build `/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv', but I am a `x86_64-linux'</screen>
|
||||
|
||||
<para>
|
||||
The <code>:b</code> is a <literal>nix repl</literal> specific command to build a derivation.
|
||||
|
@ -224,8 +254,7 @@
|
|||
<filename>.drv</filename> with:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/realise-derivation.txt" parse="text"
|
||||
/></screen>
|
||||
<screen>$ nix-store -r /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv</screen>
|
||||
|
||||
<para>
|
||||
You will get the same output as before.
|
||||
|
@ -235,7 +264,10 @@
|
|||
Let's fix the system attribute:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/fix-attribute.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = builtins.currentSystem; }
|
||||
nix-repl> :b d
|
||||
[...]
|
||||
build error: invalid file name `mybuilder'</screen>
|
||||
|
||||
<para>
|
||||
A step forward: of course, that <code>mybuilder</code> executable does not
|
||||
|
@ -252,7 +284,11 @@
|
|||
In this case, the returned value is a plain set:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/inspect-values.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
|
||||
nix-repl> builtins.isAttrs d
|
||||
true
|
||||
nix-repl> builtins.attrNames d
|
||||
[ "all" "builder" "drvAttrs" "drvPath" "name" "out" "outPath" "outputName" "system" "type" ]</screen>
|
||||
|
||||
<para>
|
||||
You can guess what <code>builtins.isAttrs</code> does; it returns true if
|
||||
|
@ -264,7 +300,8 @@
|
|||
Start from drvAttrs:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/drvattrs.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> d.drvAttrs
|
||||
{ builder = "mybuilder"; name = "myname"; system = "mysystem"; }</screen>
|
||||
|
||||
<para>
|
||||
That's basically the input we gave to the derivation function. Also the
|
||||
|
@ -272,7 +309,8 @@
|
|||
attributes are exactly the ones we gave as input.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/check-drvattrs.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> (d == d.out)
|
||||
true</screen>
|
||||
|
||||
<para>
|
||||
So out is just the derivation itself, it seems weird but the reason is that
|
||||
|
@ -293,7 +331,8 @@
|
|||
yourself a set with that type, it's a simple set:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/type-derivation.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> { type = "derivation"; }
|
||||
«derivation ???»</screen>
|
||||
|
||||
<para>
|
||||
Of course it has no other information, so Nix doesn't know what to say :-)
|
||||
|
@ -325,7 +364,10 @@
|
|||
Nix is able to do a conversion from a derivation set to a string.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/outpath.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> d.outPath
|
||||
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
|
||||
nix-repl> builtins.toString d
|
||||
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"</screen>
|
||||
|
||||
<para>
|
||||
Nix does the "set to string conversion" as long as there is the
|
||||
|
@ -333,13 +375,21 @@
|
|||
languages):
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/tostring.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> builtins.toString { outPath = "foo"; }
|
||||
"foo"
|
||||
nix-repl> builtins.toString { a = "b"; }
|
||||
error: cannot coerce a set to a string, at (string):1:1</screen>
|
||||
|
||||
<para>
|
||||
Say we want to use binaries from coreutils (ignore the nixpkgs etc.):
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/coreutils.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> :l <nixpkgs>
|
||||
Added 3950 variables.
|
||||
nix-repl> coreutils
|
||||
«derivation /nix/store/1zcs1y4n27lqs0gw4v038i303pb89rw6-coreutils-8.21.drv»
|
||||
nix-repl> builtins.toString coreutils
|
||||
"/nix/store/8w4cbiy7wqvaqsnsnb3zvabq1cp2zhyz-coreutils-8.21"</screen>
|
||||
|
||||
<para>
|
||||
Apart from the nixpkgs stuff, just think we added to the scope a series of
|
||||
|
@ -350,7 +400,8 @@
|
|||
</para>
|
||||
|
||||
|
||||
<screen><xi:include href="./06/list-coreutils.txt" parse="text" /></screen>
|
||||
<screen>$ ls /nix/store/*coreutils*/bin
|
||||
[...]</screen>
|
||||
|
||||
<para>
|
||||
I remind you, inside strings it's possible to interpolate Nix expressions
|
||||
|
@ -358,7 +409,10 @@
|
|||
</para>
|
||||
|
||||
|
||||
<screen><xi:include href="./06/interpolate.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> "${d}"
|
||||
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
|
||||
nix-repl> "${coreutils}"
|
||||
"/nix/store/8w4cbiy7wqvaqsnsnb3zvabq1cp2zhyz-coreutils-8.21"</screen>
|
||||
|
||||
<para>
|
||||
That's very convenient, because then we could refer to e.g. the bin/true
|
||||
|
@ -366,7 +420,8 @@
|
|||
</para>
|
||||
|
||||
|
||||
<screen><xi:include href="./06/reference.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> "${coreutils}/bin/true"
|
||||
"/nix/store/8w4cbiy7wqvaqsnsnb3zvabq1cp2zhyz-coreutils-8.21/bin/true"</screen>
|
||||
|
||||
</section>
|
||||
<section>
|
||||
|
@ -378,7 +433,12 @@
|
|||
exits with 0 (success).
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./06/test-build.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> :l <nixpkgs>
|
||||
nix-repl> d = derivation { name = "myname"; builder = "${coreutils}/bin/true"; system = builtins.currentSystem; }
|
||||
nix-repl> :b d
|
||||
[...]
|
||||
builder for `/nix/store/qyfrcd53wmc0v22ymhhd5r6sz5xmdc8a-myname.drv' failed to produce output path `/nix/store/ly2k1vswbfmswr33hw0kf0ccilrpisnk-myname'
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Another step forward, it executed the builder (bin/true), but the builder
|
||||
|
@ -396,7 +456,32 @@
|
|||
another derivation:
|
||||
</para>
|
||||
|
||||
<xi:include href="./06/examine-build.xml" />
|
||||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>$ </prompt><userinput>nix derivation show /nix/store/qyfrcd53wmc0v22ymhhd5r6sz5xmdc8a-<emphasis>myname.drv</emphasis></userinput>
|
||||
<computeroutput>{
|
||||
"/nix/store/qyfrcd53wmc0v22ymhhd5r6sz5xmdc8a-myname.drv": {
|
||||
"outputs": {
|
||||
"out": {
|
||||
"path": "/nix/store/ly2k1vswbfmswr33hw0kf0ccilrpisnk-myname"
|
||||
}
|
||||
},
|
||||
"inputSrcs": [],
|
||||
"inputDrvs": {
|
||||
"/nix/store/hixdnzz2wp75x1jy65cysq06yl74vx7q-coreutils-8.29.drv": [
|
||||
"out"
|
||||
]
|
||||
},
|
||||
"platform": "x86_64-linux",
|
||||
"builder": "/nix/store/qrxs7sabhqcr3j9ai0j0cp58zfnny0jz-coreutils-8.29/bin/true",
|
||||
"args": [],
|
||||
"env": {
|
||||
"builder": "/nix/store/qrxs7sabhqcr3j9ai0j0cp58zfnny0jz-coreutils-8.29/bin/true",
|
||||
"name": "myname",
|
||||
"out": "/nix/store/ly2k1vswbfmswr33hw0kf0ccilrpisnk-myname",
|
||||
"system": "x86_64-linux"
|
||||
}
|
||||
}
|
||||
}</computeroutput></screen>
|
||||
|
||||
|
||||
<para>
|
||||
Aha! Nix added a dependency to our myname.drv, it's the coreutils.drv.
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
|
||||
nix-repl> :b d
|
||||
[...]
|
||||
these derivations will be built:
|
||||
/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
|
||||
building path(s) `/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname'
|
||||
error: a `mysystem' is required to build `/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv', but I am a `x86_64-linux'
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> (d == d.out)
|
||||
true
|
|
@ -1,6 +0,0 @@
|
|||
nix-repl> :l <nixpkgs>
|
||||
Added 3950 variables.
|
||||
nix-repl> coreutils
|
||||
«derivation /nix/store/1zcs1y4n27lqs0gw4v038i303pb89rw6-coreutils-8.21.drv»
|
||||
nix-repl> builtins.toString coreutils
|
||||
"/nix/store/8w4cbiy7wqvaqsnsnb3zvabq1cp2zhyz-coreutils-8.21"
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> builtins.currentSystem
|
||||
"x86_64-linux"
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> d.drvAttrs
|
||||
{ builder = "mybuilder"; name = "myname"; system = "mysystem"; }
|
|
@ -1,25 +0,0 @@
|
|||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>$ </prompt><userinput>nix derivation show /nix/store/qyfrcd53wmc0v22ymhhd5r6sz5xmdc8a-<emphasis>myname.drv</emphasis></userinput>
|
||||
<computeroutput>{
|
||||
"/nix/store/qyfrcd53wmc0v22ymhhd5r6sz5xmdc8a-myname.drv": {
|
||||
"outputs": {
|
||||
"out": {
|
||||
"path": "/nix/store/ly2k1vswbfmswr33hw0kf0ccilrpisnk-myname"
|
||||
}
|
||||
},
|
||||
"inputSrcs": [],
|
||||
"inputDrvs": {
|
||||
"/nix/store/hixdnzz2wp75x1jy65cysq06yl74vx7q-coreutils-8.29.drv": [
|
||||
"out"
|
||||
]
|
||||
},
|
||||
"platform": "x86_64-linux",
|
||||
"builder": "/nix/store/qrxs7sabhqcr3j9ai0j0cp58zfnny0jz-coreutils-8.29/bin/true",
|
||||
"args": [],
|
||||
"env": {
|
||||
"builder": "/nix/store/qrxs7sabhqcr3j9ai0j0cp58zfnny0jz-coreutils-8.29/bin/true",
|
||||
"name": "myname",
|
||||
"out": "/nix/store/ly2k1vswbfmswr33hw0kf0ccilrpisnk-myname",
|
||||
"system": "x86_64-linux"
|
||||
}
|
||||
}
|
||||
}</computeroutput></screen>
|
|
@ -1,3 +0,0 @@
|
|||
nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
|
||||
nix-repl> d
|
||||
«derivation /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv»
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = builtins.currentSystem; }
|
||||
nix-repl> :b d
|
||||
[...]
|
||||
build error: invalid file name `mybuilder'
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
|
||||
nix-repl> builtins.isAttrs d
|
||||
true
|
||||
nix-repl> builtins.attrNames d
|
||||
[ "all" "builder" "drvAttrs" "drvPath" "name" "out" "outPath" "outputName" "system" "type" ]
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> "${d}"
|
||||
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
|
||||
nix-repl> "${coreutils}"
|
||||
"/nix/store/8w4cbiy7wqvaqsnsnb3zvabq1cp2zhyz-coreutils-8.21"
|
|
@ -1,2 +0,0 @@
|
|||
$ ls /nix/store/*coreutils*/bin
|
||||
[...]
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> d.outPath
|
||||
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
|
||||
nix-repl> builtins.toString d
|
||||
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
|
|
@ -1 +0,0 @@
|
|||
$ nix-store -r /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> "${coreutils}/bin/true"
|
||||
"/nix/store/8w4cbiy7wqvaqsnsnb3zvabq1cp2zhyz-coreutils-8.21/bin/true"
|
|
@ -1,21 +0,0 @@
|
|||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>$ </prompt><userinput>nix derivation show /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-<emphasis>myname.drv</emphasis></userinput>
|
||||
<computeroutput>{
|
||||
"/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv": {
|
||||
"outputs": {
|
||||
"out": {
|
||||
"path": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
|
||||
}
|
||||
},
|
||||
"inputSrcs": [],
|
||||
"inputDrvs": {},
|
||||
"platform": "mysystem",
|
||||
"builder": "mybuilder",
|
||||
"args": [],
|
||||
"env": {
|
||||
"builder": "mybuilder",
|
||||
"name": "myname",
|
||||
"out": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname",
|
||||
"system": "mysystem"
|
||||
}
|
||||
}
|
||||
}</computeroutput></screen>
|
|
@ -1,5 +0,0 @@
|
|||
nix-repl> :l <nixpkgs>
|
||||
nix-repl> d = derivation { name = "myname"; builder = "${coreutils}/bin/true"; system = builtins.currentSystem; }
|
||||
nix-repl> :b d
|
||||
[...]
|
||||
builder for `/nix/store/qyfrcd53wmc0v22ymhhd5r6sz5xmdc8a-myname.drv' failed to produce output path `/nix/store/ly2k1vswbfmswr33hw0kf0ccilrpisnk-myname'
|
|
@ -1,4 +0,0 @@
|
|||
nix-repl> builtins.toString { outPath = "foo"; }
|
||||
"foo"
|
||||
nix-repl> builtins.toString { a = "b"; }
|
||||
error: cannot coerce a set to a string, at (string):1:1
|
|
@ -1,2 +0,0 @@
|
|||
nix-repl> { type = "derivation"; }
|
||||
«derivation ???»
|
|
@ -63,7 +63,9 @@
|
|||
First of all, let's write our <filename>builder.sh</filename> in the
|
||||
current directory:
|
||||
|
||||
<programlisting><xi:include href="./07/builder.sh.txt" parse="text" /></programlisting>
|
||||
<programlisting>declare -xp
|
||||
echo foo > $out
|
||||
</programlisting>
|
||||
|
||||
The command <literal>declare -xp</literal>
|
||||
lists exported variables
|
||||
|
@ -91,12 +93,23 @@
|
|||
Like for coreutils in the previous pill, we get a blessed bash for free
|
||||
from our magic nixpkgs stuff:
|
||||
|
||||
<xi:include href="./07/bash.xml" />
|
||||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>nix-repl> </prompt><userinput>:l &lt;nixpkgs></userinput>
|
||||
<computeroutput>Added 3950 variables.</computeroutput>
|
||||
<prompt>nix-repl> </prompt><userinput>"${bash}"</userinput>
|
||||
<computeroutput>"/nix/store/ihmkc7z2wqk3bbipfnlh0yjrlfkkgnv6-<emphasis>bash-4.2-p45</emphasis>"</computeroutput>
|
||||
</screen>
|
||||
|
||||
|
||||
So with the usual trick, we can refer to
|
||||
<application>bin/bash</application> and create our derivation:
|
||||
|
||||
<xi:include href="./07/simple-derivation.xml" />
|
||||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>nix-repl> </prompt><userinput>d = derivation { name = "foo"; builder = "${bash}/bin/bash"; args = [ ./builder.sh ]; system = builtins.currentSystem; }</userinput>
|
||||
<prompt>nix-repl> </prompt><userinput>:b d</userinput>
|
||||
<computeroutput>[1 built, 0.0 MiB DL]
|
||||
|
||||
this derivation produced the following outputs:
|
||||
out -> /nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-<emphasis>foo</emphasis></computeroutput></screen>
|
||||
|
||||
|
||||
We did it! The contents of
|
||||
<filename>/nix/store/w024zci0x1hh1wj6gjq0jagkc1sgrf5r-<emphasis>foo</emphasis></filename>
|
||||
|
@ -117,7 +130,25 @@
|
|||
<para>
|
||||
We can use <command>nix-store --read-log</command> to see the logs our
|
||||
builder produced:
|
||||
<xi:include href="./07/read-log.xml" />
|
||||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>$ </prompt><userinput>nix-store --read-log /nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-<emphasis>foo</emphasis></userinput>
|
||||
<computeroutput>declare -x HOME="/homeless-shelter"
|
||||
declare -x NIX_BUILD_CORES="4"
|
||||
declare -x NIX_BUILD_TOP="/tmp/nix-build-foo.drv-0"
|
||||
declare -x NIX_LOG_FD="2"
|
||||
declare -x NIX_STORE="/nix/store"
|
||||
declare -x OLDPWD
|
||||
declare -x PATH="/path-not-set"
|
||||
declare -x PWD="/tmp/nix-build-foo.drv-0"
|
||||
declare -x SHLVL="1"
|
||||
declare -x TEMP="/tmp/nix-build-foo.drv-0"
|
||||
declare -x TEMPDIR="/tmp/nix-build-foo.drv-0"
|
||||
declare -x TMP="/tmp/nix-build-foo.drv-0"
|
||||
declare -x TMPDIR="/tmp/nix-build-foo.drv-0"
|
||||
declare -x builder="/nix/store/q1g0rl8zfmz7r371fp5p42p4acmv297d-bash-4.4-p19/bin/bash"
|
||||
declare -x name="foo"
|
||||
declare -x out="/nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-foo"
|
||||
declare -x system="x86_64-linux"</computeroutput></screen>
|
||||
|
||||
</para>
|
||||
<para>
|
||||
Let's inspect those environment variables printed during the build process.
|
||||
|
@ -169,7 +200,36 @@
|
|||
<para>
|
||||
We added something else to the derivation this time: the args attribute.
|
||||
Let's see how this changed the .drv compared to the previous pill:
|
||||
<xi:include href="./07/foo.drv.xml" />
|
||||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>$ </prompt><userinput>nix derivation show /nix/store/i76pr1cz0za3i9r6xq518bqqvd2raspw-<emphasis>foo.drv</emphasis></userinput>
|
||||
<computeroutput>{
|
||||
"/nix/store/i76pr1cz0za3i9r6xq518bqqvd2raspw-foo.drv": {
|
||||
"outputs": {
|
||||
"out": {
|
||||
"path": "/nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-foo"
|
||||
}
|
||||
},
|
||||
"inputSrcs": [
|
||||
"/nix/store/lb0n38r2b20r8rl1k45a7s4pj6ny22f7-builder.sh"
|
||||
],
|
||||
"inputDrvs": {
|
||||
"/nix/store/hcgwbx42mcxr7ksnv0i1fg7kw6jvxshb-bash-4.4-p19.drv": [
|
||||
"out"
|
||||
]
|
||||
},
|
||||
"platform": "x86_64-linux",
|
||||
"builder": "/nix/store/q1g0rl8zfmz7r371fp5p42p4acmv297d-bash-4.4-p19/bin/bash",
|
||||
"args": [
|
||||
"/nix/store/lb0n38r2b20r8rl1k45a7s4pj6ny22f7-builder.sh"
|
||||
],
|
||||
"env": {
|
||||
"builder": "/nix/store/q1g0rl8zfmz7r371fp5p42p4acmv297d-bash-4.4-p19/bin/bash",
|
||||
"name": "foo",
|
||||
"out": "/nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-foo",
|
||||
"system": "x86_64-linux"
|
||||
}
|
||||
}
|
||||
}</computeroutput></screen>
|
||||
|
||||
|
||||
Much like the usual .drv, except that there's a list of arguments in there
|
||||
passed to the builder (<application>bash</application>) with
|
||||
|
@ -192,16 +252,29 @@
|
|||
<para>
|
||||
Start off by writing a simple C program called <filename>simple.c</filename>:
|
||||
|
||||
<programlisting><xi:include href="./07/simple.c.txt" parse="text" /></programlisting>
|
||||
<programlisting>void main() {
|
||||
puts("Simple!");
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
And its <filename>simple_builder.sh</filename>:
|
||||
|
||||
<programlisting><xi:include href="./07/simple_builder.sh.txt" parse="text" /></programlisting>
|
||||
<programlisting>export PATH="$coreutils/bin:$gcc/bin"
|
||||
mkdir $out
|
||||
gcc -o $out/simple $src
|
||||
</programlisting>
|
||||
|
||||
Don't worry too much about where those variables come from yet; let's
|
||||
write the derivation and build it:
|
||||
|
||||
<xi:include href="./07/c-program-derivation.xml" />
|
||||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>nix-repl> </prompt><userinput>:l &lt;nixpkgs></userinput>
|
||||
<prompt>nix-repl> </prompt><userinput>simple = derivation { name = "simple"; builder = "${bash}/bin/bash"; args = [ ./simple_builder.sh ]; gcc = gcc; coreutils = coreutils; src = ./simple.c; system = builtins.currentSystem; }</userinput>
|
||||
<prompt>nix-repl> </prompt><userinput>:b simple</userinput>
|
||||
<computeroutput>this derivation produced the following outputs:
|
||||
|
||||
out -> /nix/store/ni66p4jfqksbmsl616llx3fbs1d232d4-simple
|
||||
</computeroutput></screen>
|
||||
|
||||
|
||||
Now you can run
|
||||
<filename>/nix/store/ni66p4jfqksbmsl616llx3fbs1d232d4-simple/simple</filename>
|
||||
|
@ -261,7 +334,19 @@
|
|||
Drop out of <application>nix repl</application> and write a file
|
||||
<filename>simple.nix</filename>:
|
||||
|
||||
<programlisting><xi:include href="./07/simple.txt" parse="text" /></programlisting>
|
||||
<programlisting>let
|
||||
pkgs = import <nixpkgs> { };
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "simple";
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./simple_builder.sh ];
|
||||
gcc = pkgs.gcc;
|
||||
coreutils = pkgs.coreutils;
|
||||
src = ./simple.c;
|
||||
system = builtins.currentSystem;
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
Now you can build it with <command>nix-build simple.nix</command>. This
|
||||
will create a symlink <filename>result</filename> in the current
|
||||
|
@ -311,7 +396,18 @@
|
|||
<para>
|
||||
Below is a revised version of the <filename>simple.nix</filename> file, using the <code>inherit</code> keyword:
|
||||
|
||||
<programlisting><xi:include href="./07/simple_inherit.txt" parse="text" /></programlisting>
|
||||
<programlisting>let
|
||||
pkgs = import <nixpkgs> { };
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "simple";
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./simple_builder.sh ];
|
||||
inherit (pkgs) gcc coreutils;
|
||||
src = ./simple.c;
|
||||
system = builtins.currentSystem;
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
Here we also take the opportunity to introduce the
|
||||
<link xlink:href="https://nixos.org/manual/nix/stable/expressions/language-constructs.html#inheriting-attributes"><code>inherit</code> keyword</link>.
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>nix-repl> </prompt><userinput>:l <nixpkgs></userinput>
|
||||
<computeroutput>Added 3950 variables.</computeroutput>
|
||||
<prompt>nix-repl> </prompt><userinput>"${bash}"</userinput>
|
||||
<computeroutput>"/nix/store/ihmkc7z2wqk3bbipfnlh0yjrlfkkgnv6-<emphasis>bash-4.2-p45</emphasis>"</computeroutput>
|
||||
</screen>
|
|
@ -1,2 +0,0 @@
|
|||
declare -xp
|
||||
echo foo > $out
|
|
@ -1,7 +0,0 @@
|
|||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>nix-repl> </prompt><userinput>:l <nixpkgs></userinput>
|
||||
<prompt>nix-repl> </prompt><userinput>simple = derivation { name = "simple"; builder = "${bash}/bin/bash"; args = [ ./simple_builder.sh ]; gcc = gcc; coreutils = coreutils; src = ./simple.c; system = builtins.currentSystem; }</userinput>
|
||||
<prompt>nix-repl> </prompt><userinput>:b simple</userinput>
|
||||
<computeroutput>this derivation produced the following outputs:
|
||||
|
||||
out -> /nix/store/ni66p4jfqksbmsl616llx3fbs1d232d4-simple
|
||||
</computeroutput></screen>
|
|
@ -1,29 +0,0 @@
|
|||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>$ </prompt><userinput>nix derivation show /nix/store/i76pr1cz0za3i9r6xq518bqqvd2raspw-<emphasis>foo.drv</emphasis></userinput>
|
||||
<computeroutput>{
|
||||
"/nix/store/i76pr1cz0za3i9r6xq518bqqvd2raspw-foo.drv": {
|
||||
"outputs": {
|
||||
"out": {
|
||||
"path": "/nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-foo"
|
||||
}
|
||||
},
|
||||
"inputSrcs": [
|
||||
"/nix/store/lb0n38r2b20r8rl1k45a7s4pj6ny22f7-builder.sh"
|
||||
],
|
||||
"inputDrvs": {
|
||||
"/nix/store/hcgwbx42mcxr7ksnv0i1fg7kw6jvxshb-bash-4.4-p19.drv": [
|
||||
"out"
|
||||
]
|
||||
},
|
||||
"platform": "x86_64-linux",
|
||||
"builder": "/nix/store/q1g0rl8zfmz7r371fp5p42p4acmv297d-bash-4.4-p19/bin/bash",
|
||||
"args": [
|
||||
"/nix/store/lb0n38r2b20r8rl1k45a7s4pj6ny22f7-builder.sh"
|
||||
],
|
||||
"env": {
|
||||
"builder": "/nix/store/q1g0rl8zfmz7r371fp5p42p4acmv297d-bash-4.4-p19/bin/bash",
|
||||
"name": "foo",
|
||||
"out": "/nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-foo",
|
||||
"system": "x86_64-linux"
|
||||
}
|
||||
}
|
||||
}</computeroutput></screen>
|
|
@ -1,18 +0,0 @@
|
|||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>$ </prompt><userinput>nix-store --read-log /nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-<emphasis>foo</emphasis></userinput>
|
||||
<computeroutput>declare -x HOME="/homeless-shelter"
|
||||
declare -x NIX_BUILD_CORES="4"
|
||||
declare -x NIX_BUILD_TOP="/tmp/nix-build-foo.drv-0"
|
||||
declare -x NIX_LOG_FD="2"
|
||||
declare -x NIX_STORE="/nix/store"
|
||||
declare -x OLDPWD
|
||||
declare -x PATH="/path-not-set"
|
||||
declare -x PWD="/tmp/nix-build-foo.drv-0"
|
||||
declare -x SHLVL="1"
|
||||
declare -x TEMP="/tmp/nix-build-foo.drv-0"
|
||||
declare -x TEMPDIR="/tmp/nix-build-foo.drv-0"
|
||||
declare -x TMP="/tmp/nix-build-foo.drv-0"
|
||||
declare -x TMPDIR="/tmp/nix-build-foo.drv-0"
|
||||
declare -x builder="/nix/store/q1g0rl8zfmz7r371fp5p42p4acmv297d-bash-4.4-p19/bin/bash"
|
||||
declare -x name="foo"
|
||||
declare -x out="/nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-foo"
|
||||
declare -x system="x86_64-linux"</computeroutput></screen>
|
|
@ -1,6 +0,0 @@
|
|||
<screen xmlns="http://docbook.org/ns/docbook"><prompt>nix-repl> </prompt><userinput>d = derivation { name = "foo"; builder = "${bash}/bin/bash"; args = [ ./builder.sh ]; system = builtins.currentSystem; }</userinput>
|
||||
<prompt>nix-repl> </prompt><userinput>:b d</userinput>
|
||||
<computeroutput>[1 built, 0.0 MiB DL]
|
||||
|
||||
this derivation produced the following outputs:
|
||||
out -> /nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-<emphasis>foo</emphasis></computeroutput></screen>
|
|
@ -1,3 +0,0 @@
|
|||
void main() {
|
||||
puts("Simple!");
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
let
|
||||
pkgs = import <nixpkgs> { };
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "simple";
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./simple_builder.sh ];
|
||||
gcc = pkgs.gcc;
|
||||
coreutils = pkgs.coreutils;
|
||||
src = ./simple.c;
|
||||
system = builtins.currentSystem;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export PATH="$coreutils/bin:$gcc/bin"
|
||||
mkdir $out
|
||||
gcc -o $out/simple $src
|
|
@ -1,11 +0,0 @@
|
|||
let
|
||||
pkgs = import <nixpkgs> { };
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "simple";
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./simple_builder.sh ];
|
||||
inherit (pkgs) gcc coreutils;
|
||||
src = ./simple.c;
|
||||
system = builtins.currentSystem;
|
||||
}
|
|
@ -41,17 +41,65 @@
|
|||
Let's create a builder script for GNU hello world, hello_builder.sh:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/hello-builder.txt" parse="text" /></screen>
|
||||
<screen>export PATH="$gnutar/bin:$gcc/bin:$gnumake/bin:$coreutils/bin:$gawk/bin:$gzip/bin:$gnugrep/bin:$gnused/bin:$bintools/bin"
|
||||
tar -xzf $src
|
||||
cd hello-2.12.1
|
||||
./configure --prefix=$out
|
||||
make
|
||||
make install
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
And the derivation hello.nix:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/hello-nix.txt" parse="text" /></screen>
|
||||
<screen>let
|
||||
pkgs = import <nixpkgs> { };
|
||||
in
|
||||
derivation {
|
||||
name = "hello";
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./hello_builder.sh ];
|
||||
inherit (pkgs)
|
||||
gnutar
|
||||
gzip
|
||||
gnumake
|
||||
gcc
|
||||
coreutils
|
||||
gawk
|
||||
gnused
|
||||
gnugrep
|
||||
;
|
||||
bintools = pkgs.binutils.bintools;
|
||||
src = ./hello-2.12.1.tar.gz;
|
||||
system = builtins.currentSystem;
|
||||
}
|
||||
</screen>
|
||||
<note><title>Nix on darwin</title>
|
||||
<para>Darwin (i.e. macOS) builds typically use <literal>clang</literal> rather than <literal>gcc</literal> for a C compiler.
|
||||
We can adapt this early example for darwin by using this modified version of <filename>hello.nix</filename>:
|
||||
<screen><xi:include href="./08/hello-nix-darwin.txt" parse="text" /></screen>
|
||||
<screen>let
|
||||
pkgs = import <nixpkgs> { };
|
||||
in
|
||||
derivation {
|
||||
name = "hello";
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./hello_builder.sh ];
|
||||
inherit (pkgs)
|
||||
gnutar
|
||||
gzip
|
||||
gnumake
|
||||
coreutils
|
||||
gawk
|
||||
gnused
|
||||
gnugrep
|
||||
;
|
||||
gcc = pkgs.clang;
|
||||
bintools = pkgs.clang.bintools.bintools_bin;
|
||||
src = ./hello-2.12.1.tar.gz;
|
||||
system = builtins.currentSystem;
|
||||
}
|
||||
</screen>
|
||||
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.
|
||||
</para>
|
||||
|
@ -78,7 +126,25 @@
|
|||
projects:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/generic-builder.txt" parse="text" /></screen>
|
||||
<screen>set -e
|
||||
unset PATH
|
||||
for p in $buildInputs; do
|
||||
export PATH=$p/bin${PATH:+:}$PATH
|
||||
done
|
||||
|
||||
tar -xf $src
|
||||
|
||||
for d in *; do
|
||||
if [ -d "$d" ]; then
|
||||
cd "$d"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
./configure --prefix=$out
|
||||
make
|
||||
make install
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
What do we do here?
|
||||
|
@ -130,7 +196,28 @@
|
|||
Now let's rewrite <filename>hello.nix</filename>:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/hello-nix-rev-1.txt" parse="text" /></screen>
|
||||
<screen>let
|
||||
pkgs = import <nixpkgs> { };
|
||||
in
|
||||
derivation {
|
||||
name = "hello";
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./builder.sh ];
|
||||
buildInputs = with pkgs; [
|
||||
gnutar
|
||||
gzip
|
||||
gnumake
|
||||
gcc
|
||||
coreutils
|
||||
gawk
|
||||
gnused
|
||||
gnugrep
|
||||
binutils.bintools
|
||||
];
|
||||
src = ./hello-2.12.1.tar.gz;
|
||||
system = builtins.currentSystem;
|
||||
}
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
All clear, except that buildInputs. However it's easier than any black
|
||||
|
@ -142,13 +229,23 @@
|
|||
to strings, and then concatenates them separated by a space:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/to-string.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> builtins.toString 123
|
||||
"123"
|
||||
nix-repl> builtins.toString [ 123 456 ]
|
||||
"123 456"
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Recall that derivations can be converted to a string, hence:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/to-string-nixpkgs.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> :l <nixpkgs>
|
||||
Added 3950 variables.
|
||||
nix-repl> builtins.toString gnugrep
|
||||
"/nix/store/g5gdylclfh6d224kqh9sja290pk186xd-gnugrep-2.14"
|
||||
nix-repl> builtins.toString [ gnugrep gnused ]
|
||||
"/nix/store/g5gdylclfh6d224kqh9sja290pk186xd-gnugrep-2.14 /nix/store/krgdc4sknzpw8iyk9p20lhqfd52kjmg0-gnused-4.2.2"
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Simple! The buildInputs variable is a string with out paths separated by
|
||||
|
@ -176,7 +273,28 @@
|
|||
Create <filename>autotools.nix</filename>:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/autotools-nix.txt" parse="text" /></screen>
|
||||
<screen>pkgs: attrs:
|
||||
let
|
||||
defaultAttrs = {
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./builder.sh ];
|
||||
baseInputs = with pkgs; [
|
||||
gnutar
|
||||
gzip
|
||||
gnumake
|
||||
gcc
|
||||
coreutils
|
||||
gawk
|
||||
gnused
|
||||
gnugrep
|
||||
binutils.bintools
|
||||
];
|
||||
buildInputs = [ ];
|
||||
system = builtins.currentSystem;
|
||||
};
|
||||
in
|
||||
derivation (defaultAttrs // attrs)
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Ok now we have to remember a little about
|
||||
|
@ -230,7 +348,11 @@
|
|||
operator:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/set-union.txt" parse="text" /></screen>
|
||||
<screen>nix-repl> { a = "b"; } // { c = "d"; }
|
||||
{ a = "b"; c = "d"; }
|
||||
nix-repl> { a = "b"; } // { a = "c"; }
|
||||
{ a = "c"; }
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
<emphasis role="bold">Exercise:</emphasis>
|
||||
|
@ -246,7 +368,15 @@
|
|||
Then we rewrite <filename>hello.nix</filename> as follows:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./08/hello-nix-rev-2.txt" parse="text" /></screen>
|
||||
<screen>let
|
||||
pkgs = import <nixpkgs> { };
|
||||
mkDerivation = import ./autotools.nix pkgs;
|
||||
in
|
||||
mkDerivation {
|
||||
name = "hello";
|
||||
src = ./hello-2.12.1.tar.gz;
|
||||
}
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Finally! We got a very simple description of a package! Below are a
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
pkgs: attrs:
|
||||
let
|
||||
defaultAttrs = {
|
||||
builder = "${pkgs.bash}/bin/bash";
|
||||
args = [ ./builder.sh ];
|
||||
baseInputs = with pkgs; [
|
||||
gnutar
|
||||
gzip
|
||||
gnumake
|
||||
gcc
|
||||
coreutils
|
||||
gawk
|
||||
gnused
|
||||
gnugrep
|
||||
binutils.bintools
|
||||
];
|
||||
buildInputs = [ ];
|
||||
system = builtins.currentSystem;
|
||||
};
|
||||
in
|
||||
derivation (defaultAttrs // attrs)
|
|
@ -1,18 +0,0 @@
|
|||
set -e
|
||||
unset PATH
|
||||
for p in $buildInputs; do
|
||||
export PATH=$p/bin${PATH:+:}$PATH
|
||||
done
|
||||
|
||||
tar -xf $src
|
||||
|
||||
for d in *; do
|
||||
if [ -d "$d" ]; then
|
||||
cd "$d"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
./configure --prefix=$out
|
||||
make
|
||||
make install
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue