mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-06 05:13:37 +00:00
Compare commits
478 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d231868990 | ||
|
|
5c5e904763 | ||
|
|
a8e92de019 | ||
|
|
70bab96717 | ||
|
|
9ac86f947e | ||
|
|
bd19f47b68 | ||
|
|
b0d9cb36de | ||
|
|
4a021a017d | ||
|
|
6465c790e2 | ||
|
|
38fca2124a | ||
|
|
5fa1475d12 | ||
|
|
0263e6efec | ||
|
|
65075167ce | ||
|
|
a2b526d41a | ||
|
|
daf0729f3a | ||
|
|
2d840dad4c | ||
|
|
2253d675d7 | ||
|
|
26ac90e6ad | ||
|
|
864b2d6aae | ||
|
|
2173c47506 | ||
|
|
792bbd380e | ||
|
|
5feeab1d57 | ||
|
|
556e1b892b | ||
|
|
33fe6ee6a6 | ||
|
|
77a465e98f | ||
|
|
b0f8e15376 | ||
|
|
4254bb9828 | ||
|
|
e59d4141c6 | ||
|
|
162556c9c6 | ||
|
|
d2e4593240 | ||
|
|
e8c74f4c61 | ||
|
|
32889165e0 | ||
|
|
7cf7ed166c | ||
|
|
23489b34c0 | ||
|
|
badecc4c42 | ||
|
|
7133dcdd28 | ||
|
|
6824d79c69 | ||
|
|
36107e6f03 | ||
|
|
5b83e496c8 | ||
|
|
24d68896e4 | ||
|
|
115cb2f780 | ||
|
|
e61b8b2294 | ||
|
|
79c3c16dcb | ||
|
|
8f9f2347d3 | ||
|
|
aeab34ccd2 | ||
|
|
8bd86b91d9 | ||
|
|
5b86bfc58d | ||
|
|
2aba37aaf0 | ||
|
|
ccc2c7c9e5 | ||
|
|
d665da8ea6 | ||
|
|
f3319286ff | ||
|
|
c1818c2963 | ||
|
|
bf65250cdb | ||
|
|
83d6492b02 | ||
|
|
12528e547f | ||
|
|
cc8278e186 | ||
|
|
2e7727f647 | ||
|
|
90748d0983 | ||
|
|
0432279805 | ||
|
|
6af1cd202d | ||
|
|
445e5c4ca5 | ||
|
|
60622584db | ||
|
|
6135eafe30 | ||
|
|
e19d01d6c6 | ||
|
|
c9f09d2b77 | ||
|
|
0f7088161a | ||
|
|
fcd16856b4 | ||
|
|
7f2dc5d3f6 | ||
|
|
2267e14d68 | ||
|
|
ac5f358c00 | ||
|
|
4ae5327664 | ||
|
|
3fd3be4408 | ||
|
|
f50a79045c | ||
|
|
1f379d95e4 | ||
|
|
a6f5f1efad | ||
|
|
20aa39d18d | ||
|
|
1d72ddad9d | ||
|
|
4e2f29507f | ||
|
|
979bef5356 | ||
|
|
d022dc9300 | ||
|
|
3a13d4707b | ||
|
|
713af5258f | ||
|
|
70a3a43ed8 | ||
|
|
caffe29c3e | ||
|
|
ddede54d49 | ||
|
|
1d05903577 | ||
|
|
e3def23b8f | ||
|
|
65f4afba5e | ||
|
|
191df96839 | ||
|
|
ad2acc8fcd | ||
|
|
ec561c6075 | ||
|
|
0f59068762 | ||
|
|
e32aabe4f1 | ||
|
|
d8fe0c9790 | ||
|
|
3816f98e0a | ||
|
|
15c7003f07 | ||
|
|
1ff2835e5a | ||
|
|
153fdba2c4 | ||
|
|
f45acd3831 | ||
|
|
e7ffa6c42e | ||
|
|
af551f2dea | ||
|
|
538d9b5d6d | ||
|
|
c5583a4540 | ||
|
|
f12e91f2c5 | ||
|
|
04e2196d82 | ||
|
|
7877e33af8 | ||
|
|
ee6a568a14 | ||
|
|
6dd99f177c | ||
|
|
2647742e02 | ||
|
|
64fd93763a | ||
|
|
4476d74db6 | ||
|
|
9b79dd6bf4 | ||
|
|
30745200d3 | ||
|
|
7bd9321c6d | ||
|
|
bb6d3c16d3 | ||
|
|
7e74fad881 | ||
|
|
471e755cc2 | ||
|
|
3e30c35937 | ||
|
|
5ce9f24ded | ||
|
|
9cb9a6b509 | ||
|
|
da25f05fc2 | ||
|
|
843d11b292 | ||
|
|
424d1aff43 | ||
|
|
e332f57678 | ||
|
|
6a45a297b9 | ||
|
|
207131488e | ||
|
|
ea8311a366 | ||
|
|
bd58129a12 | ||
|
|
bfece38f51 | ||
|
|
3af4a10350 | ||
|
|
076dd96812 | ||
|
|
939612898d | ||
|
|
7f7f3c1bc2 | ||
|
|
32f6c6be6b | ||
|
|
06416457c2 | ||
|
|
bc393f79eb | ||
|
|
e96ce2c60e | ||
|
|
be5b364581 | ||
|
|
06efe48e33 | ||
|
|
04c2762461 | ||
|
|
d6ac1e6d51 | ||
|
|
84fbe0d6d7 | ||
|
|
916531dfd1 | ||
|
|
3047988677 | ||
|
|
4562338552 | ||
|
|
6f10147e8c | ||
|
|
c110614936 | ||
|
|
cecc1e32db | ||
|
|
18fd4c1430 | ||
|
|
ab2ac03378 | ||
|
|
970b8ee8e7 | ||
|
|
e81ca34a6a | ||
|
|
5d391c49a9 | ||
|
|
5d24af631a | ||
|
|
c3fe7bed20 | ||
|
|
148b740a63 | ||
|
|
92f1827ea0 | ||
|
|
23730413fe | ||
|
|
efc7b847e3 | ||
|
|
49e5d4c507 | ||
|
|
67fee4b26e | ||
|
|
bf92ff9657 | ||
|
|
1695966348 | ||
|
|
13c0d0c86e | ||
|
|
cb69e43ad0 | ||
|
|
e86c38f9b3 | ||
|
|
e32412ae22 | ||
|
|
45f34ab410 | ||
|
|
c938ab4dc8 | ||
|
|
32f0c51ab7 | ||
|
|
523ce20887 | ||
|
|
d64126b0fe | ||
|
|
273cc85e69 | ||
|
|
5ea3dfcc6e | ||
|
|
0bac5850a2 | ||
|
|
6486138750 | ||
|
|
6df636feef | ||
|
|
3cac2c5fc5 | ||
|
|
9fb09319a3 | ||
|
|
b522266b77 | ||
|
|
4be705574a | ||
|
|
b314616134 | ||
|
|
4be870bad3 | ||
|
|
52604ad28d | ||
|
|
97a7b595ce | ||
|
|
99d1e66c4d | ||
|
|
76c266017d | ||
|
|
1a3edcdbda | ||
|
|
796efbab1c | ||
|
|
dc670e38fb | ||
|
|
6abce9522c | ||
|
|
9687ed9046 | ||
|
|
34455365b8 | ||
|
|
b5d47a8cfe | ||
|
|
26a5e637b7 | ||
|
|
58153f164d | ||
|
|
cb9f989b18 | ||
|
|
e81ee2be29 | ||
|
|
3ff6d0492a | ||
|
|
b8db5897c7 | ||
|
|
d1afa1b0d1 | ||
|
|
edca647059 | ||
|
|
257e0f78b0 | ||
|
|
ae5901f97c | ||
|
|
7a1b8a3bdf | ||
|
|
709a2fd0c5 | ||
|
|
0858ece1ad | ||
|
|
ac79602d7d | ||
|
|
80e93efbc9 | ||
|
|
fcb270e5f5 | ||
|
|
d664e30a14 | ||
|
|
531baf82ad | ||
|
|
77eaab7d6c | ||
|
|
ca6ac920ed | ||
|
|
4452a68425 | ||
|
|
723989b6c4 | ||
|
|
7e0c19c1a2 | ||
|
|
f115f87bb5 | ||
|
|
15761b0520 | ||
|
|
5d21d6a8a6 | ||
|
|
0e41e8bbf0 | ||
|
|
b4d6442660 | ||
|
|
637e3b0b43 | ||
|
|
5cdd170af6 | ||
|
|
d82e740f9b | ||
|
|
d5a73df00b | ||
|
|
e10b2fbfb5 | ||
|
|
c431588cd2 | ||
|
|
d1a8d192a5 | ||
|
|
b08b468c2b | ||
|
|
2e53a8dd7f | ||
|
|
a699a188b7 | ||
|
|
2f666306aa | ||
|
|
98c5bb1603 | ||
|
|
a33efc99b4 | ||
|
|
15d42c3605 | ||
|
|
2746f3a854 | ||
|
|
01f2389e2d | ||
|
|
8c2fa806b8 | ||
|
|
dc3073b52f | ||
|
|
12329a24de | ||
|
|
5c04d08990 | ||
|
|
4515fe3934 | ||
|
|
4b054488bd | ||
|
|
274a7cf7ee | ||
|
|
b7aadc752e | ||
|
|
6f4d27f60f | ||
|
|
5e3cbd4856 | ||
|
|
7dcc25befe | ||
|
|
a7fea3ef54 | ||
|
|
6334932eb7 | ||
|
|
bfec68ed10 | ||
|
|
5d47e25dc3 | ||
|
|
8f211997eb | ||
|
|
3c72d75922 | ||
|
|
d1b7c0ea70 | ||
|
|
51c88123b4 | ||
|
|
b79b512ef0 | ||
|
|
cc86145ed5 | ||
|
|
23445ad23e | ||
|
|
8e34256a80 | ||
|
|
e1bb0cdf4a | ||
|
|
5d98a082e5 | ||
|
|
8cd4e77209 | ||
|
|
c7eba63f29 | ||
|
|
0fd813b299 | ||
|
|
50a2e74991 | ||
|
|
34c3b3f27f | ||
|
|
8dfd8b83d4 | ||
|
|
413c01a0f8 | ||
|
|
7cec20c775 | ||
|
|
fe3d97ea6b | ||
|
|
c5e6538869 | ||
|
|
39a87f331c | ||
|
|
2e5f582da8 | ||
|
|
89284c21bc | ||
|
|
cbcfaaa006 | ||
|
|
9f75d283c1 | ||
|
|
eacd290c33 | ||
|
|
b07d941c8e | ||
|
|
a572a2f291 | ||
|
|
f79a9ca3c0 | ||
|
|
ef8bb2e6e5 | ||
|
|
5dc086df29 | ||
|
|
eaeb0d8073 | ||
|
|
684a291c66 | ||
|
|
28625e932f | ||
|
|
a0e49374df | ||
|
|
8be69850ab | ||
|
|
d1cd035a3b | ||
|
|
38b79d7686 | ||
|
|
d505f470d3 | ||
|
|
06115a3907 | ||
|
|
1a07877b5c | ||
|
|
cfc1b69bed | ||
|
|
014223bd00 | ||
|
|
26b6957daf | ||
|
|
fd4cdf183a | ||
|
|
8e11767d02 | ||
|
|
f6bec34f6f | ||
|
|
f95d5d0e86 | ||
|
|
d12bc4ffa1 | ||
|
|
9379081695 | ||
|
|
12c908ec5b | ||
|
|
baf7f98b45 | ||
|
|
00793f0756 | ||
|
|
3fb27d83ab | ||
|
|
c29ebc60f5 | ||
|
|
72a9c3c018 | ||
|
|
88a20de886 | ||
|
|
066d56507e | ||
|
|
2e4c131749 | ||
|
|
e4662de8c8 | ||
|
|
1010ced00c | ||
|
|
ac18b492d5 | ||
|
|
5f2226ddc7 | ||
|
|
4066f15504 | ||
|
|
d24e4eef6c | ||
|
|
fa4b560533 | ||
|
|
e3153cc3a5 | ||
|
|
0b5026fe95 | ||
|
|
848855a5ab | ||
|
|
448f8b0451 | ||
|
|
4d9f98face | ||
|
|
2d683367ed | ||
|
|
1f6b9b333d | ||
|
|
331e442eb7 | ||
|
|
7bcbf598ae | ||
|
|
fd3f80cf37 | ||
|
|
04e07c8db2 | ||
|
|
d9b70033a6 | ||
|
|
4b0fceda0f | ||
|
|
e2c85dc185 | ||
|
|
fc2a19eeb4 | ||
|
|
a2273f6125 | ||
|
|
8065ea839d | ||
|
|
fe5d858fe0 | ||
|
|
f960683794 | ||
|
|
a7c64d5df6 | ||
|
|
b992c1b19b | ||
|
|
8b39b045d8 | ||
|
|
84e8aa8105 | ||
|
|
7d734df56d | ||
|
|
42079b64d5 | ||
|
|
ae349e1d43 | ||
|
|
8df9058d46 | ||
|
|
fbf59749d3 | ||
|
|
d54510bb57 | ||
|
|
dbcb901036 | ||
|
|
5456a2d030 | ||
|
|
bb4f9c93dc | ||
|
|
207882e82f | ||
|
|
ad6fee913d | ||
|
|
11fc5010e4 | ||
|
|
f7eb5d7419 | ||
|
|
c4fc753068 | ||
|
|
a77785096c | ||
|
|
07b375e361 | ||
|
|
0c00ca14ed | ||
|
|
e9f847ea54 | ||
|
|
9bafea49ed | ||
|
|
a33faa6919 | ||
|
|
a3750f7803 | ||
|
|
fda621baec | ||
|
|
4807161a4d | ||
|
|
3f65ad28be | ||
|
|
856fa7f3f2 | ||
|
|
ac22e8344d | ||
|
|
43504afcb7 | ||
|
|
d9dbe89eb5 | ||
|
|
41dc4eca0c | ||
|
|
9f185a9669 | ||
|
|
a7ca3a4afb | ||
|
|
7ff8194989 | ||
|
|
147249a5e6 | ||
|
|
e00cbc0130 | ||
|
|
e64ae06426 | ||
|
|
751718af64 | ||
|
|
d5ca898035 | ||
|
|
ffb23b77e0 | ||
|
|
e1922e3103 | ||
|
|
8668905d22 | ||
|
|
80961187e0 | ||
|
|
a98d111d81 | ||
|
|
6ef4803b6d | ||
|
|
5e936719a0 | ||
|
|
a9b01de70d | ||
|
|
cb5f0fc64d | ||
|
|
15db5f4353 | ||
|
|
a56c4875dc | ||
|
|
c5b31675a8 | ||
|
|
3f7eee0c40 | ||
|
|
838702564f | ||
|
|
19c10d7347 | ||
|
|
8eba878ced | ||
|
|
2b240463bf | ||
|
|
d1df887b29 | ||
|
|
e1ce1fe14d | ||
|
|
36bad18d57 | ||
|
|
8c6cf0ca7c | ||
|
|
b13a486f24 | ||
|
|
9b544ab3cc | ||
|
|
797b5a2f1b | ||
|
|
c74e3fd3ae | ||
|
|
d41ac378b6 | ||
|
|
e8e8164f34 | ||
|
|
fb57ac55ff | ||
|
|
6fa68be9c2 | ||
|
|
6377a295a3 | ||
|
|
a039af10eb | ||
|
|
26833c5ecd | ||
|
|
33b0851d88 | ||
|
|
b28e618fb0 | ||
|
|
c82d282f06 | ||
|
|
34b06b4ba1 | ||
|
|
d005b64940 | ||
|
|
9c36de8cb2 | ||
|
|
2e324f2144 | ||
|
|
a0531e0394 | ||
|
|
5978790955 | ||
|
|
e696b60f38 | ||
|
|
aecf27fe92 | ||
|
|
4baa4995f3 | ||
|
|
e3613ab3ee | ||
|
|
55588d7acd | ||
|
|
440e2a757a | ||
|
|
2a36173043 | ||
|
|
db10d1bd21 | ||
|
|
69dbce32ce | ||
|
|
613dfd513c | ||
|
|
3a5a26e2ed | ||
|
|
89774f5b38 | ||
|
|
3356e5c033 | ||
|
|
bc6547a13f | ||
|
|
5b3c61ea5f | ||
|
|
927ce5ca71 | ||
|
|
50131497b7 | ||
|
|
b5a0c16f8f | ||
|
|
3b5ae362d9 | ||
|
|
1db66c9f47 | ||
|
|
1e634a6fcc | ||
|
|
0db38615dc | ||
|
|
58d901d16f | ||
|
|
3a3f336148 | ||
|
|
780dc0ad29 | ||
|
|
62c29a96be | ||
|
|
0cb416f51d | ||
|
|
181986627e | ||
|
|
f3ab45e5dc | ||
|
|
1e2ec46525 | ||
|
|
3d10bc8804 | ||
|
|
f7ac2e1b2e | ||
|
|
c9f73f8860 | ||
|
|
73435915ba | ||
|
|
2d6d111a3e | ||
|
|
89d9159353 | ||
|
|
ff28655321 | ||
|
|
31b5d57123 | ||
|
|
12d4f7abfb | ||
|
|
2068621b45 | ||
|
|
468a40bd89 | ||
|
|
a56d33a016 | ||
|
|
a49ba9c6fe | ||
|
|
b96e0c2c8c | ||
|
|
adb81add90 | ||
|
|
5440568fea | ||
|
|
a202c8027e | ||
|
|
746912a9ca | ||
|
|
503bb92245 | ||
|
|
6adae8e146 | ||
|
|
461ed7cc55 | ||
|
|
d07f940046 | ||
|
|
eef44f2495 | ||
|
|
f5351fec36 | ||
|
|
4025cb9e0c | ||
|
|
dc99ce8565 | ||
|
|
6ee0b0e335 | ||
|
|
74f22ff827 |
19
.github/CONTRIBUTING.md
vendored
19
.github/CONTRIBUTING.md
vendored
@@ -12,21 +12,4 @@ under the terms of [COPYING](../COPYING), which is an MIT-like license.
|
||||
|
||||
## Submitting changes
|
||||
|
||||
* Format the commits in the following way:
|
||||
|
||||
`(pkg-name | service-name): (from -> to | init at version | refactor | etc)`
|
||||
|
||||
Examples:
|
||||
|
||||
* nginx: init at 2.0.1
|
||||
* firefox: 3.0 -> 3.1.1
|
||||
* hydra service: add bazBaz option
|
||||
* nginx service: refactor config generation
|
||||
|
||||
* `meta.description` should:
|
||||
* Be capitalized
|
||||
* Not start with the package name
|
||||
* Not have a dot at the end
|
||||
|
||||
See the nixpkgs manual for more details on how to [Submit changes to nixpkgs](http://hydra.nixos.org/job/nixpkgs/trunk/manual/latest/download-by-type/doc/manual#chap-submitting-changes).
|
||||
|
||||
See the nixpkgs manual for details on how to [Submit changes to nixpkgs](http://hydra.nixos.org/job/nixpkgs/trunk/manual/latest/download-by-type/doc/manual#chap-submitting-changes).
|
||||
|
||||
20
.github/ISSUE_TEMPLATE.md
vendored
20
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,13 +1,17 @@
|
||||
## Issue description
|
||||
## Basic info
|
||||
|
||||
To make sure that we are on the same page:
|
||||
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
|
||||
|
||||
## Technical details
|
||||
|
||||
* Kernel: (run `uname -a`)
|
||||
* System: (NixOS: `nixos-version`, Ubuntu/Fedora: `lsb_release -a`, ...)
|
||||
* Nix version: (run `nix-env --version`)
|
||||
* Nixpkgs version: (run `nix-instantiate --eval '<nixpkgs>' -A lib.nixpkgsVersion`)
|
||||
|
||||
## Describe your issue here
|
||||
|
||||
### Expected result
|
||||
|
||||
### Actual result
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
|
||||
23
.github/PULL_REQUEST_TEMPLATE.md
vendored
23
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,19 +1,18 @@
|
||||
###### Motivation for this change
|
||||
###### Things done:
|
||||
|
||||
|
||||
###### Things done
|
||||
|
||||
- [ ] Tested using sandboxing
|
||||
([nix.useChroot](http://nixos.org/nixos/manual/options.html#opt-nix.useChroot) on NixOS,
|
||||
or option `build-use-chroot` in [`nix.conf`](http://nixos.org/nix/manual/#sec-conf-file)
|
||||
on non-NixOS)
|
||||
- Built on platform(s)
|
||||
- [ ] NixOS
|
||||
- [ ] OS X
|
||||
- [ ] Linux
|
||||
- [ ] Tested using sandboxing (`nix-build --option build-use-chroot true` or [nix.useChroot](http://nixos.org/nixos/manual/options.html#opt-nix.useChroot) on NixOS)
|
||||
- [ ] Built on platform(s): NixOS / OSX / Linux
|
||||
- [ ] Tested compilation of all pkgs that depend on this change using `nix-shell -p nox --run "nox-review wip"`
|
||||
- [ ] Tested execution of all binary files (usually in `./result/bin/`)
|
||||
- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md).
|
||||
|
||||
###### More
|
||||
|
||||
Fixes issue #<insert id>
|
||||
|
||||
cc @<maintainer>
|
||||
|
||||
|
||||
---
|
||||
|
||||
_Please note, that points are not mandatory, but rather desired._
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"userBlacklist": [
|
||||
"civodul",
|
||||
"jhasse"
|
||||
"civodul"
|
||||
]
|
||||
}
|
||||
|
||||
27
.travis.yml
27
.travis.yml
@@ -1,20 +1,7 @@
|
||||
language: nix
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
sudo: false
|
||||
script:
|
||||
- ./maintainers/scripts/travis-nox-review-pr.sh nixpkgs-verify nixpkgs-manual nixpkgs-tarball
|
||||
- ./maintainers/scripts/travis-nox-review-pr.sh nixos-options nixos-manual
|
||||
- os: linux
|
||||
sudo: required
|
||||
dist: trusty
|
||||
before_script:
|
||||
- sudo mount -o remount,exec,size=2G,mode=755 /run/user
|
||||
script: ./maintainers/scripts/travis-nox-review-pr.sh nox pr
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
script: ./maintainers/scripts/travis-nox-review-pr.sh nox pr
|
||||
env:
|
||||
global:
|
||||
- GITHUB_TOKEN=5edaaf1017f691ed34e7f80878f8f5fbd071603f
|
||||
language: python
|
||||
python: "3.4"
|
||||
sudo: required
|
||||
dist: trusty
|
||||
before_install: ./maintainers/scripts/travis-nox-review-pr.sh nix
|
||||
install: ./maintainers/scripts/travis-nox-review-pr.sh nox
|
||||
script: ./maintainers/scripts/travis-nox-review-pr.sh build
|
||||
|
||||
11
README.md
11
README.md
@@ -1,7 +1,6 @@
|
||||
[<img src="http://nixos.org/logo/nixos-hires.png" width="500px" alt="logo" />](https://nixos.org/nixos)
|
||||
|
||||
[](https://travis-ci.org/NixOS/nixpkgs)
|
||||
[](https://www.codetriage.com/nixos/nixpkgs)
|
||||
[](http://www.issuestats.com/github/nixos/nixpkgs)
|
||||
[](http://www.issuestats.com/github/nixos/nixpkgs)
|
||||
|
||||
@@ -15,12 +14,12 @@ build daemon as so-called channels. To get channel information via git, add
|
||||
```
|
||||
|
||||
For stability and maximum binary package support, it is recommended to maintain
|
||||
custom changes on top of one of the channels, e.g. `nixos-16.09` for the latest
|
||||
custom changes on top of one of the channels, e.g. `nixos-15.09` for the latest
|
||||
release and `nixos-unstable` for the latest successful build of master:
|
||||
|
||||
```
|
||||
% git remote update channels
|
||||
% git rebase channels/nixos-16.09
|
||||
% git rebase channels/nixos-15.09
|
||||
```
|
||||
|
||||
For pull-requests, please rebase onto nixpkgs `master`.
|
||||
@@ -32,11 +31,11 @@ For pull-requests, please rebase onto nixpkgs `master`.
|
||||
* [Documentation (Nix Expression Language chapter)](https://nixos.org/nix/manual/#ch-expression-language)
|
||||
* [Manual (How to write packages for Nix)](https://nixos.org/nixpkgs/manual/)
|
||||
* [Manual (NixOS)](https://nixos.org/nixos/manual/)
|
||||
* [Nix Wiki](https://nixos.org/wiki/) (deprecated, see milestone ["Move the Wiki!"](https://github.com/NixOS/nixpkgs/issues?q=is%3Aopen+is%3Aissue+milestone%3A%22Move+the+wiki%21%22))
|
||||
* [Nix Wiki](https://nixos.org/wiki/)
|
||||
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
|
||||
* [Continuous package builds for 16.09 release](https://hydra.nixos.org/jobset/nixos/release-16.09)
|
||||
* [Continuous package builds for 15.09 release](https://hydra.nixos.org/jobset/nixos/release-15.09)
|
||||
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
|
||||
* [Tests for 16.09 release](https://hydra.nixos.org/job/nixos/release-16.09/tested#tabs-constituents)
|
||||
* [Tests for 15.09 release](https://hydra.nixos.org/job/nixos/release-15.09/tested#tabs-constituents)
|
||||
|
||||
Communication:
|
||||
|
||||
|
||||
@@ -6,4 +6,4 @@ if ! builtins ? nixVersion || builtins.compareVersions requiredVersion builtins.
|
||||
|
||||
else
|
||||
|
||||
import ./pkgs/top-level/impure.nix
|
||||
import ./pkgs/top-level/all-packages.nix
|
||||
|
||||
@@ -251,13 +251,16 @@ bound to the variable name <varname>e2fsprogs</varname> in
|
||||
|
||||
<listitem><para>The version part of the <literal>name</literal>
|
||||
attribute <emphasis>must</emphasis> start with a digit (following a
|
||||
dash) — e.g., <literal>"hello-0.3.1rc2"</literal>.</para></listitem>
|
||||
dash) — e.g., <literal>"hello-0.3-pre-r3910"</literal> instead of
|
||||
<literal>"hello-svn-r3910"</literal>, as the latter would be seen as
|
||||
a package named <literal>hello-svn</literal> by
|
||||
<command>nix-env</command>.</para></listitem>
|
||||
|
||||
<listitem><para>If a package is not a release but a commit from a repository, then
|
||||
<listitem><para>If package is fetched from git's commit then
|
||||
the version part of the name <emphasis>must</emphasis> be the date of that
|
||||
(fetched) commit. The date must be in <literal>"YYYY-MM-DD"</literal> format.
|
||||
Also append <literal>"unstable"</literal> to the name - e.g.,
|
||||
<literal>"pkgname-unstable-2014-09-23"</literal>.</para></listitem>
|
||||
Also add <literal>"git"</literal> to the name - e.g.,
|
||||
<literal>"pkgname-git-2014-09-23"</literal>.</para></listitem>
|
||||
|
||||
<listitem><para>Dashes in the package name should be preserved
|
||||
in new variable names, rather than converted to underscores
|
||||
@@ -659,22 +662,4 @@ src = fetchFromGitHub {
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-patches"><title>Patches</title>
|
||||
<para>Only patches that are unique to <literal>nixpkgs</literal> should be
|
||||
included in <literal>nixpkgs</literal> source.</para>
|
||||
<para>Patches available online should be retrieved using
|
||||
<literal>fetchpatch</literal>.</para>
|
||||
<para>
|
||||
<programlisting>
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
name = "fix-check-for-using-shared-freetype-lib.patch";
|
||||
url = "http://git.ghostscript.com/?p=ghostpdl.git;a=patch;h=8f5d285";
|
||||
sha256 = "1f0k043rng7f0rfl9hhb89qzvvksqmkrikmm38p61yfx51l325xr";
|
||||
})
|
||||
];
|
||||
</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -46,10 +46,10 @@ $ export NIXPKGS_ALLOW_UNFREE=1
|
||||
allowUnfreePredicate = (pkg: ...);
|
||||
</programlisting>
|
||||
|
||||
Example to allow flash player and visual studio code only:
|
||||
Example to allow flash player only:
|
||||
|
||||
<programlisting>
|
||||
allowUnfreePredicate = with builtins; (pkg: elem (parseDrvName pkg.name).name [ "flashplayer" "vscode" ]);
|
||||
allowUnfreePredicate = (pkg: pkgs.lib.hasPrefix "flashplayer-" pkg.name);
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
with import ./.. { };
|
||||
with lib;
|
||||
let
|
||||
pkgs = import ./.. { };
|
||||
lib = pkgs.lib;
|
||||
sources = lib.sourceFilesBySuffices ./. [".xml"];
|
||||
sources = sourceFilesBySuffices ./. [".xml"];
|
||||
sources-langs = ./languages-frameworks;
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
stdenv.mkDerivation {
|
||||
name = "nixpkgs-manual";
|
||||
|
||||
|
||||
buildInputs = with pkgs; [ pandoc libxml2 libxslt zip ];
|
||||
buildInputs = [ pandoc libxml2 libxslt ];
|
||||
|
||||
xsltFlags = ''
|
||||
--param section.autolabel 1
|
||||
@@ -26,8 +26,7 @@ pkgs.stdenv.mkDerivation {
|
||||
extraHeader = ''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
|
||||
in ''
|
||||
{
|
||||
pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--chapters"} \
|
||||
--smart \
|
||||
pandoc '${inputFile}' -w docbook ${optionalString useChapters "--chapters"} \
|
||||
| sed -e 's|<ulink url=|<link xlink:href=|' \
|
||||
-e 's|</ulink>|</link>|' \
|
||||
-e 's|<sect. id=|<section xml:id=|' \
|
||||
@@ -49,51 +48,38 @@ pkgs.stdenv.mkDerivation {
|
||||
useChapters = true;
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ./languages-frameworks/python.md;
|
||||
outputFile = "./languages-frameworks/python.xml";
|
||||
inputFile = ./haskell-users-guide.md;
|
||||
outputFile = "haskell-users-guide.xml";
|
||||
useChapters = true;
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ./languages-frameworks/haskell.md;
|
||||
outputFile = "./languages-frameworks/haskell.xml";
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ../pkgs/development/idris-modules/README.md;
|
||||
inputFile = ./../pkgs/development/idris-modules/README.md;
|
||||
outputFile = "languages-frameworks/idris.xml";
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ../pkgs/development/r-modules/README.md;
|
||||
inputFile = ./../pkgs/development/r-modules/README.md;
|
||||
outputFile = "languages-frameworks/r.xml";
|
||||
}
|
||||
+ ''
|
||||
echo ${lib.nixpkgsVersion} > .version
|
||||
echo ${nixpkgsVersion} > .version
|
||||
|
||||
# validate against relaxng schema
|
||||
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
|
||||
${pkgs.jing}/bin/jing ${pkgs.docbook5}/xml/rng/docbook/docbook.rng manual-full.xml
|
||||
${jing}/bin/jing ${docbook5}/xml/rng/docbook/docbook.rng manual-full.xml
|
||||
|
||||
dst=$out/share/doc/nixpkgs
|
||||
mkdir -p $dst
|
||||
xsltproc $xsltFlags --nonet --xinclude \
|
||||
--output $dst/manual.html \
|
||||
${pkgs.docbook5_xsl}/xml/xsl/docbook/xhtml/docbook.xsl \
|
||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/docbook.xsl \
|
||||
./manual.xml
|
||||
|
||||
cp ${./style.css} $dst/style.css
|
||||
|
||||
mkdir -p $dst/images/callouts
|
||||
cp "${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/"*.gif $dst/images/callouts/
|
||||
cp "${docbook5_xsl}/xml/xsl/docbook/images/callouts/"*.gif $dst/images/callouts/
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "doc manual $dst manual.html" >> $out/nix-support/hydra-build-products
|
||||
|
||||
xsltproc $xsltFlags --nonet --xinclude \
|
||||
--output $dst/epub/ \
|
||||
${pkgs.docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl \
|
||||
./manual.xml
|
||||
|
||||
cp -r $dst/images $dst/epub/OEBPS
|
||||
echo "application/epub+zip" > mimetype
|
||||
zip -0Xq "$dst/Nixpkgs Contributors Guide - NixOS community.epub" mimetype
|
||||
zip -Xr9D "$dst/Nixpkgs Contributors Guide - NixOS community.epub" $dst/epub/*
|
||||
'';
|
||||
}
|
||||
|
||||
305
doc/erlang-users-guide.xml
Normal file
305
doc/erlang-users-guide.xml
Normal file
@@ -0,0 +1,305 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="users-guide-to-the-erlang-infrastructure">
|
||||
|
||||
<title>User's Guide to the Erlang Infrastructure</title>
|
||||
<section xml:id="build-tools">
|
||||
<title>Build Tools</title>
|
||||
<para>
|
||||
By default Rebar3 wants to manage it's own dependencies. In the
|
||||
normal non-Nix, this is perfectly acceptable. In the Nix world it
|
||||
is not. To support this we have created two versions of rebar3,
|
||||
<literal>rebar3</literal> and <literal>rebar3-open</literal>. The
|
||||
<literal>rebar3</literal> version has been patched to remove the
|
||||
ability to download anything from it. If you are not running it a
|
||||
nix-shell or a nix-build then its probably not going to work for
|
||||
you. <literal>rebar3-open</literal> is the normal, un-modified
|
||||
rebar3. It should work exactly as would any other version of
|
||||
rebar3. Any Erlang package should rely on
|
||||
<literal>rebar3</literal> and thats really what you should be
|
||||
using too.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="how-to-install-erlang-packages">
|
||||
<title>How to install Erlang packages</title>
|
||||
<para>
|
||||
Erlang packages are not registered in the top level simply because
|
||||
they are not relevant to the vast majority of Nix users. They are
|
||||
installable using the <literal>erlangPackages</literal> attribute set.
|
||||
|
||||
You can list the avialable packages in the
|
||||
<literal>erlangPackages</literal> with the following command:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A erlangPackages
|
||||
erlangPackages.esqlite esqlite-0.2.1
|
||||
erlangPackages.goldrush goldrush-0.1.7
|
||||
erlangPackages.ibrowse ibrowse-4.2.2
|
||||
erlangPackages.jiffy jiffy-0.14.5
|
||||
erlangPackages.lager lager-3.0.2
|
||||
erlangPackages.meck meck-0.8.3
|
||||
erlangPackages.rebar3-pc pc-1.1.0
|
||||
</programlisting>
|
||||
<para>
|
||||
To install any of those packages into your profile, refer to them by
|
||||
their attribute path (first column):
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-env -f "<nixpkgs>" -iA erlangPackages.ibrowse
|
||||
</programlisting>
|
||||
<para>
|
||||
The attribute path of any Erlang packages corresponds to the name
|
||||
of that particular package in Hex or its OTP Application/Release name.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="packaging-erlang-applications">
|
||||
<title>Packaging Erlang Applications</title>
|
||||
<section xml:id="rebar3-packages">
|
||||
<title>Rebar3 Packages</title>
|
||||
<para>
|
||||
There is a Nix functional called
|
||||
<literal>buildRebar3</literal>. We use this function to make a
|
||||
derivation that understands how to build the rebar3 project. For
|
||||
example, the epression we use to build the <link
|
||||
xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link>
|
||||
project follows.
|
||||
</para>
|
||||
<programlisting>
|
||||
{stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }:
|
||||
|
||||
buildRebar3 rec {
|
||||
name = "hex2nix";
|
||||
version = "0.0.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ericbmerritt";
|
||||
repo = "hex2nix";
|
||||
rev = "${version}";
|
||||
sha256 = "1w7xjidz1l5yjmhlplfx7kphmnpvqm67w99hd2m7kdixwdxq0zqg";
|
||||
};
|
||||
|
||||
erlangDeps = [ ibrowse jsx erlware_commons ];
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The only visible difference between this derivation and
|
||||
something like <literal>stdenv.mkDerivation</literal> is that we
|
||||
have added <literal>erlangDeps</literal> to the derivation. If
|
||||
you add your Erlang dependencies here they will be correctly
|
||||
handled by the system.
|
||||
</para>
|
||||
<para>
|
||||
If your package needs to compile native code via Rebar's port
|
||||
compilation mechenism. You should add <literal>compilePort =
|
||||
true;</literal> to the derivation.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="hex-packages">
|
||||
<title>Hex Packages</title>
|
||||
<para>
|
||||
Hex packages are based on Rebar packages. In fact, at the moment
|
||||
we can only compile Hex packages that are buildable with
|
||||
Rebar3. Packages that use Mix and other build systems are not
|
||||
supported. That being said, we know a lot more about Hex and can
|
||||
do more for you.
|
||||
</para>
|
||||
<programlisting>
|
||||
{ buildHex }:
|
||||
buildHex {
|
||||
name = "esqlite";
|
||||
version = "0.2.1";
|
||||
sha256 = "1296fn1lz4lz4zqzn4dwc3flgkh0i6n4sydg501faabfbv8d3wkr";
|
||||
compilePort = true;
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
For Hex packages you need to provide the name, the version, and
|
||||
the Sha 256 digest of the package and use
|
||||
<literal>buildHex</literal> to build it. Obviously, the package
|
||||
needs to have already been published to Hex.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="how-to-develop">
|
||||
<title>How to develop</title>
|
||||
<section xml:id="accessing-an-environment">
|
||||
<title>Accessing an Environment</title>
|
||||
<para>
|
||||
Often, all you want to do is be able to access a valid
|
||||
environment that contains a specific package and its
|
||||
dependencies. we can do that with the <literal>env</literal>
|
||||
part of a derivation. For example, lets say we want to access an
|
||||
erlang repl with ibrowse loaded up. We could do the following.
|
||||
</para>
|
||||
<programlisting>
|
||||
~/w/nixpkgs ❯❯❯ nix-shell -A erlangPackages.ibrowse.env --run "erl"
|
||||
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
|
||||
|
||||
Eshell V7.0 (abort with ^G)
|
||||
1> m(ibrowse).
|
||||
Module: ibrowse
|
||||
MD5: 3b3e0137d0cbb28070146978a3392945
|
||||
Compiled: January 10 2016, 23:34
|
||||
Object file: /nix/store/g1rlf65rdgjs4abbyj4grp37ry7ywivj-ibrowse-4.2.2/lib/erlang/lib/ibrowse-4.2.2/ebin/ibrowse.beam
|
||||
Compiler options: [{outdir,"/tmp/nix-build-ibrowse-4.2.2.drv-0/hex-source-ibrowse-4.2.2/_build/default/lib/ibrowse/ebin"},
|
||||
debug_info,debug_info,nowarn_shadow_vars,
|
||||
warn_unused_import,warn_unused_vars,warnings_as_errors,
|
||||
{i,"/tmp/nix-build-ibrowse-4.2.2.drv-0/hex-source-ibrowse-4.2.2/_build/default/lib/ibrowse/include"}]
|
||||
Exports:
|
||||
add_config/1 send_req_direct/7
|
||||
all_trace_off/0 set_dest/3
|
||||
code_change/3 set_max_attempts/3
|
||||
get_config_value/1 set_max_pipeline_size/3
|
||||
get_config_value/2 set_max_sessions/3
|
||||
get_metrics/0 show_dest_status/0
|
||||
get_metrics/2 show_dest_status/1
|
||||
handle_call/3 show_dest_status/2
|
||||
handle_cast/2 spawn_link_worker_process/1
|
||||
handle_info/2 spawn_link_worker_process/2
|
||||
init/1 spawn_worker_process/1
|
||||
module_info/0 spawn_worker_process/2
|
||||
module_info/1 start/0
|
||||
rescan_config/0 start_link/0
|
||||
rescan_config/1 stop/0
|
||||
send_req/3 stop_worker_process/1
|
||||
send_req/4 stream_close/1
|
||||
send_req/5 stream_next/1
|
||||
send_req/6 terminate/2
|
||||
send_req_direct/4 trace_off/0
|
||||
send_req_direct/5 trace_off/2
|
||||
send_req_direct/6 trace_on/0
|
||||
trace_on/2
|
||||
ok
|
||||
2>
|
||||
</programlisting>
|
||||
<para>
|
||||
Notice the <literal>-A erlangPackages.ibrowse.env</literal>.That
|
||||
is the key to this functionality.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="creating-a-shell">
|
||||
<title>Creating a Shell</title>
|
||||
<para>
|
||||
Getting access to an environment often isn't enough to do real
|
||||
development. Many times we need to create a
|
||||
<literal>shell.nix</literal> file and do our development inside
|
||||
of the environment specified by that file. This file looks a lot
|
||||
like the packageing described above. The main difference is that
|
||||
<literal>src</literal> points to project root and we call the
|
||||
package directly.
|
||||
</para>
|
||||
<programlisting>
|
||||
{ pkgs ? import "<nixpkgs"> {} }:
|
||||
|
||||
with pkgs;
|
||||
|
||||
let
|
||||
|
||||
f = { buildHex, ibrowse, jsx, erlware_commons }:
|
||||
buildHex {
|
||||
name = "hex2nix";
|
||||
version = "0.1.0";
|
||||
src = ./.;
|
||||
erlangDeps = [ ibrowse jsx erlware_commons ];
|
||||
};
|
||||
drv = erlangPackages.callPackage f {};
|
||||
|
||||
in
|
||||
drv
|
||||
</programlisting>
|
||||
<section xml:id="building-in-a-shell">
|
||||
<title>Building in a shell</title>
|
||||
<para>
|
||||
Unfortunatly for us users of Nix, Rebar isn't very cooperative
|
||||
with us from the standpoint of building a hermetic
|
||||
environment. When building the rebar3 support we had to do some
|
||||
sneaky things to get it not to go out and pull packages on its
|
||||
own. Also unfortunately, you have to do some of the same things
|
||||
when building a project inside of a Nix shell.
|
||||
|
||||
<orderedlist numeration="arabic">
|
||||
<listitem>
|
||||
<para>Run <literal>rebar3-nix-bootstrap</literal> every time
|
||||
dependencies change</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Set Home to the current directory.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
If you do these two things then Rebar will be happy with you. I
|
||||
codify these into a makefile. Forunately, rebar3-nix-bootstrap
|
||||
is idempotent and fairly quick. so you can run it as often as
|
||||
you like.
|
||||
</para>
|
||||
<programlisting>
|
||||
# =============================================================================
|
||||
# Rules
|
||||
# =============================================================================
|
||||
.PHONY= all test clean repl shell build test analyze bootstrap
|
||||
|
||||
all: test
|
||||
|
||||
clean:
|
||||
rm -rf _build
|
||||
rm -rf .cache
|
||||
|
||||
repl:
|
||||
nix-shell --run "erl"
|
||||
|
||||
shell:
|
||||
nix-shell --run "bash"
|
||||
|
||||
bootstrap:
|
||||
nix-shell --pure --run "rebar3-nix-bootstrap"
|
||||
|
||||
build: bootstrap
|
||||
nix-shell --pure --run "HOME=$(CURDIR) rebar3 compile"
|
||||
|
||||
analyze: bootstrap
|
||||
nix-shell --pure --run "HOME=$(CURDIR) rebar3 do compile,dialyzer"
|
||||
|
||||
test: bootstrap
|
||||
nix-shell --pure --run "HOME=$(CURDIR) rebar3 do compile,dialyzer,eunit"
|
||||
|
||||
</programlisting>
|
||||
<para>
|
||||
If you add the <literal>shell.nix</literal> as described and
|
||||
user rebar as follows things should simply work.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="generating-packages-from-hex-with-hex2nix">
|
||||
<title>Generating Packages from Hex with Hex2Nix</title>
|
||||
<para>
|
||||
Updating the Hex packages requires the use of the
|
||||
<literal>hex2nix</literal> tool. Given the path to the Erlang
|
||||
modules (usually
|
||||
<literal>pkgs/development/erlang-modules</literal>). It will
|
||||
happily dump a file called
|
||||
<literal>hex-packages.nix</literal>. That file will contain all
|
||||
the packages that use a recognized build system in Hex. However,
|
||||
it can't know whether or not all those packages are buildable.
|
||||
</para>
|
||||
<para>
|
||||
To make life easier for our users, it makes good sense to go
|
||||
ahead and attempt to build all those packages and remove the
|
||||
ones that don't build. To do that, simply run the command (in
|
||||
the root of your <literal>nixpkgs</literal> repository). that follows.
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-build -A erlangPackages
|
||||
</programlisting>
|
||||
<para>
|
||||
That will build every package in
|
||||
<literal>erlangPackages</literal>. Then you can go through and
|
||||
manually remove the ones that fail. Hopefully, someone will
|
||||
improve <literal>hex2nix</literal> in the future to automate
|
||||
that.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -89,27 +89,20 @@ in ...</programlisting>
|
||||
<title><pkg>.overrideDerivation</title>
|
||||
|
||||
<warning>
|
||||
<para>Do not use this function in Nixpkgs as it evaluates a Derivation
|
||||
before modifying it, which breaks package abstraction and removes
|
||||
error-checking of function arguments. In addition, this
|
||||
evaluation-per-function application incurs a performance penalty,
|
||||
which can become a problem if many overrides are used.
|
||||
It is only intended for ad-hoc customisation, such as in
|
||||
<filename>~/.nixpkgs/config.nix</filename>.
|
||||
</para>
|
||||
<para>Do not use this function in Nixpkgs. Because it breaks
|
||||
package abstraction and doesn’t provide error checking for
|
||||
function arguments, it is only intended for ad-hoc customisation
|
||||
(such as in <filename>~/.nixpkgs/config.nix</filename>).</para>
|
||||
</warning>
|
||||
|
||||
<para>
|
||||
The function <varname>overrideDerivation</varname> creates a new derivation
|
||||
based on an existing one by overriding the original's attributes with
|
||||
the attribute set produced by the specified function.
|
||||
This function is available on all
|
||||
derivations defined using the <varname>makeOverridable</varname> function.
|
||||
Most standard derivation-producing functions, such as
|
||||
<varname>stdenv.mkDerivation</varname>, are defined using this
|
||||
function, which means most packages in the nixpkgs expression,
|
||||
<varname>pkgs</varname>, have this function.
|
||||
The function <varname>overrideDerivation</varname> is usually available for all the
|
||||
derivations in the nixpkgs expression (<varname>pkgs</varname>).
|
||||
</para>
|
||||
<para>
|
||||
It is used to create a new derivation by overriding the attributes of
|
||||
the original derivation according to the given function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
@@ -125,9 +118,9 @@ in ...</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the above example, the <varname>name</varname>, <varname>src</varname>,
|
||||
and <varname>patches</varname> of the derivation will be overridden, while
|
||||
all other attributes will be retained from the original derivation.
|
||||
In the above example, the name, src and patches of the derivation
|
||||
will be overridden, while all other attributes will be retained from the
|
||||
original derivation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -135,20 +128,6 @@ in ...</programlisting>
|
||||
the original derivation.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
A package's attributes are evaluated *before* being modified by
|
||||
the <varname>overrideDerivation</varname> function.
|
||||
For example, the <varname>name</varname> attribute reference
|
||||
in <varname>url = "mirror://gnu/hello/${name}.tar.gz";</varname>
|
||||
is filled-in *before* the <varname>overrideDerivation</varname> function
|
||||
modifies the attribute set. This means that overriding the
|
||||
<varname>name</varname> attribute, in this example, *will not* change the
|
||||
value of the <varname>url</varname> attribute. Instead, we need to override
|
||||
both the <varname>name</varname> *and* <varname>url</varname> attributes.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-lib-makeOverridable">
|
||||
@@ -185,18 +164,42 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||
|
||||
|
||||
<section xml:id="sec-fhs-environments">
|
||||
<title>buildFHSUserEnv</title>
|
||||
<title>buildFHSChrootEnv/buildFHSUserEnv</title>
|
||||
|
||||
<para>
|
||||
<function>buildFHSUserEnv</function> provides a way to build and run
|
||||
FHS-compatible lightweight sandboxes. It creates an isolated root with
|
||||
bound <filename>/nix/store</filename>, so its footprint in terms of disk
|
||||
<function>buildFHSChrootEnv</function> and
|
||||
<function>buildFHSUserEnv</function> provide a way to build and run
|
||||
FHS-compatible lightweight sandboxes. They get their own isolated root with
|
||||
binded <filename>/nix/store</filename>, so their footprint in terms of disk
|
||||
space needed is quite small. This allows one to run software which is hard or
|
||||
unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions,
|
||||
games distributed as tarballs, software with integrity checking and/or external
|
||||
self-updated binaries. It uses Linux namespaces feature to create
|
||||
self-updated binaries.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>buildFHSChrootEnv</function> allows to create persistent
|
||||
environments, which can be constructed, deconstructed and entered by
|
||||
multiple users at once. A downside is that it requires
|
||||
<literal>root</literal> access for both those who create and destroy and
|
||||
those who enter it. It can be useful to create environments for daemons that
|
||||
one can enter and observe.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>buildFHSUserEnv</function> uses Linux namespaces feature to create
|
||||
temporary lightweight environments which are destroyed after all child
|
||||
processes exit, without root user rights requirement. Accepted arguments are:
|
||||
processes exit. It does not require root access, and can be useful to create
|
||||
sandboxes and wrap applications.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Those functions both rely on <function>buildFHSEnv</function>, which creates
|
||||
an actual directory structure given a list of necessary packages and extra
|
||||
build commands.
|
||||
<function>buildFHSChrootEnv</function> and <function>buildFHSUserEnv</function>
|
||||
both accept those arguments which are passed to
|
||||
<function>buildFHSEnv</function>:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
@@ -210,16 +213,14 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||
<term><literal>targetPkgs</literal></term>
|
||||
|
||||
<listitem><para>Packages to be installed for the main host's architecture
|
||||
(i.e. x86_64 on x86_64 installations). Along with libraries binaries are also
|
||||
installed.</para></listitem>
|
||||
(i.e. x86_64 on x86_64 installations).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>multiPkgs</literal></term>
|
||||
|
||||
<listitem><para>Packages to be installed for all architectures supported by
|
||||
a host (i.e. i686 and x86_64 on x86_64 installations). Only libraries are
|
||||
installed by default.</para></listitem>
|
||||
a host (i.e. i686 and x86_64 on x86_64 installations).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@@ -232,33 +233,29 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||
<varlistentry>
|
||||
<term><literal>extraBuildCommandsMulti</literal></term>
|
||||
|
||||
<listitem><para>Like <literal>extraBuildCommands</literal>, but
|
||||
<listitem><para>Like <literal>extraBuildCommandsMulti</literal>, but
|
||||
executed only on multilib architectures.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>extraOutputsToInstall</literal></term>
|
||||
|
||||
<listitem><para>Additional derivation outputs to be linked for both
|
||||
target and multi-architecture packages.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>extraInstallCommands</literal></term>
|
||||
|
||||
<listitem><para>Additional commands to be executed for finalizing the
|
||||
derivation with runner script.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>runScript</literal></term>
|
||||
|
||||
<listitem><para>A command that would be executed inside the sandbox and
|
||||
passed all the command line arguments. It defaults to
|
||||
<literal>bash</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
Additionally, <function>buildFHSUserEnv</function> accepts
|
||||
<literal>runScript</literal> parameter, which is a command that would be
|
||||
executed inside the sandbox and passed all the command line arguments. It
|
||||
default to <literal>bash</literal>.
|
||||
</para>
|
||||
<para>
|
||||
It also uses <literal>CHROOTENV_EXTRA_BINDS</literal> environment variable
|
||||
for binding extra directories in the sandbox to outside places. The format of
|
||||
the variable is <literal>/mnt=test-mnt:/data</literal>, where
|
||||
<literal>/mnt</literal> would be mounted as <literal>/test-mnt</literal>
|
||||
and <literal>/data</literal> would be mounted as <literal>/data</literal>.
|
||||
<literal>extraBindMounts</literal> array argument to
|
||||
<function>buildFHSUserEnv</function> function is prepended to this variable.
|
||||
Latter entries take priority if defined several times -- i.e. in case of
|
||||
<literal>/data=data1:/data=data2</literal> the actual bind path would be
|
||||
<literal>/data2</literal>.
|
||||
</para>
|
||||
<para>
|
||||
One can create a simple environment using a <literal>shell.nix</literal>
|
||||
like that:
|
||||
|
||||
784
doc/haskell-users-guide.md
Normal file
784
doc/haskell-users-guide.md
Normal file
@@ -0,0 +1,784 @@
|
||||
---
|
||||
title: User's Guide for Haskell in Nixpkgs
|
||||
author: Peter Simons
|
||||
date: 2015-06-01
|
||||
---
|
||||
# User's Guide to the Haskell Infrastructure
|
||||
|
||||
|
||||
## How to install Haskell packages
|
||||
|
||||
Nixpkgs distributes build instructions for all Haskell packages registered on
|
||||
[Hackage](http://hackage.haskell.org/), but strangely enough normal Nix package
|
||||
lookups don't seem to discover any of them, except for the default version of ghc, cabal-install, and stack:
|
||||
|
||||
$ nix-env -i alex
|
||||
error: selector ‘alex’ matches no derivations
|
||||
$ nix-env -qa ghc
|
||||
ghc-7.10.2
|
||||
|
||||
The Haskell package set is not registered in the top-level namespace because it
|
||||
is *huge*. If all Haskell packages were visible to these commands, then
|
||||
name-based search/install operations would be much slower than they are now. We
|
||||
avoided that by keeping all Haskell-related packages in a separate attribute
|
||||
set called `haskellPackages`, which the following command will list:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskellPackages
|
||||
haskellPackages.a50 a50-0.5
|
||||
haskellPackages.abacate haskell-abacate-0.0.0.0
|
||||
haskellPackages.abcBridge haskell-abcBridge-0.12
|
||||
haskellPackages.afv afv-0.1.1
|
||||
haskellPackages.alex alex-3.1.4
|
||||
haskellPackages.Allure Allure-0.4.101.1
|
||||
haskellPackages.alms alms-0.6.7
|
||||
[... some 8000 entries omitted ...]
|
||||
|
||||
To install any of those packages into your profile, refer to them by their
|
||||
attribute path (first column):
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -iA haskellPackages.Allure ...
|
||||
|
||||
The attribute path of any Haskell packages corresponds to the name of that
|
||||
particular package on Hackage: the package `cabal-install` has the attribute
|
||||
`haskellPackages.cabal-install`, and so on. (Actually, this convention causes
|
||||
trouble with packages like `3dmodels` and `4Blocks`, because these names are
|
||||
invalid identifiers in the Nix language. The issue of how to deal with these
|
||||
rare corner cases is currently unresolved.)
|
||||
|
||||
Haskell packages who's Nix name (second column) begins with a `haskell-` prefix
|
||||
are packages that provide a library whereas packages without that prefix
|
||||
provide just executables. Libraries may provide executables too, though: the
|
||||
package `haskell-pandoc`, for example, installs both a library and an
|
||||
application. You can install and use Haskell executables just like any other
|
||||
program in Nixpkgs, but using Haskell libraries for development is a bit
|
||||
trickier and we'll address that subject in great detail in section [How to
|
||||
create a development environment].
|
||||
|
||||
Attribute paths are deterministic inside of Nixpkgs, but the path necessary to
|
||||
reach Nixpkgs varies from system to system. We dodged that problem by giving
|
||||
`nix-env` an explicit `-f "<nixpkgs>"` parameter, but if you call `nix-env`
|
||||
without that flag, then chances are the invocation fails:
|
||||
|
||||
$ nix-env -iA haskellPackages.cabal-install
|
||||
error: attribute ‘haskellPackages’ in selection path
|
||||
‘haskellPackages.cabal-install’ not found
|
||||
|
||||
On NixOS, for example, Nixpkgs does *not* exist in the top-level namespace by
|
||||
default. To figure out the proper attribute path, it's easiest to query for the
|
||||
path of a well-known Nixpkgs package, i.e.:
|
||||
|
||||
$ nix-env -qaP coreutils
|
||||
nixos.coreutils coreutils-8.23
|
||||
|
||||
If your system responds like that (most NixOS installations will), then the
|
||||
attribute path to `haskellPackages` is `nixos.haskellPackages`. Thus, if you
|
||||
want to use `nix-env` without giving an explicit `-f` flag, then that's the way
|
||||
to do it:
|
||||
|
||||
$ nix-env -qaP -A nixos.haskellPackages
|
||||
$ nix-env -iA nixos.haskellPackages.cabal-install
|
||||
|
||||
Our current default compiler is GHC 7.10.x and the `haskellPackages` set
|
||||
contains packages built with that particular version. Nixpkgs contains the
|
||||
latest major release of every GHC since 6.10.4, however, and there is a whole
|
||||
family of package sets available that defines Hackage packages built with each
|
||||
of those compilers, too:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc6123
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc763
|
||||
|
||||
The name `haskellPackages` is really just a synonym for
|
||||
`haskell.packages.ghc7102`, because we prefer that package set internally and
|
||||
recommend it to our users as their default choice, but ultimately you are free
|
||||
to compile your Haskell packages with any GHC version you please. The following
|
||||
command displays the complete list of available compilers:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler
|
||||
haskell.compiler.ghc6104 ghc-6.10.4
|
||||
haskell.compiler.ghc6123 ghc-6.12.3
|
||||
haskell.compiler.ghc704 ghc-7.0.4
|
||||
haskell.compiler.ghc722 ghc-7.2.2
|
||||
haskell.compiler.ghc742 ghc-7.4.2
|
||||
haskell.compiler.ghc763 ghc-7.6.3
|
||||
haskell.compiler.ghc784 ghc-7.8.4
|
||||
haskell.compiler.ghc7102 ghc-7.10.2
|
||||
haskell.compiler.ghcHEAD ghc-7.11.20150402
|
||||
haskell.compiler.ghcNokinds ghc-nokinds-7.11.20150704
|
||||
haskell.compiler.ghcjs ghcjs-0.1.0
|
||||
haskell.compiler.jhc jhc-0.8.2
|
||||
haskell.compiler.uhc uhc-1.1.9.0
|
||||
|
||||
We have no package sets for `jhc` or `uhc` yet, unfortunately, but for every
|
||||
version of GHC listed above, there exists a package set based on that compiler.
|
||||
Also, the attributes `haskell.compiler.ghcXYC` and
|
||||
`haskell.packages.ghcXYC.ghc` are synonymous for the sake of convenience.
|
||||
|
||||
## How to create a development environment
|
||||
|
||||
### How to install a compiler
|
||||
|
||||
A simple development environment consists of a Haskell compiler and one or both
|
||||
of the tools `cabal-install` and `stack`. We saw in section
|
||||
[How to install Haskell packages] how you can install those programs into your
|
||||
user profile:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -iA haskellPackages.ghc haskellPackages.cabal-install
|
||||
|
||||
Instead of the default package set `haskellPackages`, you can also use the more
|
||||
precise name `haskell.compiler.ghc7102`, which has the advantage that it refers
|
||||
to the same GHC version regardless of what Nixpkgs considers "default" at any
|
||||
given time.
|
||||
|
||||
Once you've made those tools available in `$PATH`, it's possible to build
|
||||
Hackage packages the same way people without access to Nix do it all the time:
|
||||
|
||||
$ cabal get lens-4.11 && cd lens-4.11
|
||||
$ cabal install -j --dependencies-only
|
||||
$ cabal configure
|
||||
$ cabal build
|
||||
|
||||
If you enjoy working with Cabal sandboxes, then that's entirely possible too:
|
||||
just execute the command
|
||||
|
||||
$ cabal sandbox init
|
||||
|
||||
before installing the required dependencies.
|
||||
|
||||
The `nix-shell` utility makes it easy to switch to a different compiler
|
||||
version; just enter the Nix shell environment with the command
|
||||
|
||||
$ nix-shell -p haskell.compiler.ghc784
|
||||
|
||||
to bring GHC 7.8.4 into `$PATH`. Alternatively, you can use Stack instead of
|
||||
`nix-shell` directly to select compiler versions and other build tools
|
||||
per-project. It uses `nix-shell` under the hood when Nix support is turned on.
|
||||
See [How to build a Haskell project using Stack].
|
||||
|
||||
If you're using `cabal-install`, re-running `cabal configure` inside the spawned
|
||||
shell switches your build to use that compiler instead. If you're working on
|
||||
a project that doesn't depend on any additional system libraries outside of GHC,
|
||||
then it's even sufficient to just run the `cabal configure` command inside of
|
||||
the shell:
|
||||
|
||||
$ nix-shell -p haskell.compiler.ghc784 --command "cabal configure"
|
||||
|
||||
Afterwards, all other commands like `cabal build` work just fine in any shell
|
||||
environment, because the configure phase recorded the absolute paths to all
|
||||
required tools like GHC in its build configuration inside of the `dist/`
|
||||
directory. Please note, however, that `nix-collect-garbage` can break such an
|
||||
environment because the Nix store paths created by `nix-shell` aren't "alive"
|
||||
anymore once `nix-shell` has terminated. If you find that your Haskell builds
|
||||
no longer work after garbage collection, then you'll have to re-run `cabal
|
||||
configure` inside of a new `nix-shell` environment.
|
||||
|
||||
### How to install a compiler with libraries
|
||||
|
||||
GHC expects to find all installed libraries inside of its own `lib` directory.
|
||||
This approach works fine on traditional Unix systems, but it doesn't work for
|
||||
Nix, because GHC's store path is immutable once it's built. We cannot install
|
||||
additional libraries into that location. As a consequence, our copies of GHC
|
||||
don't know any packages except their own core libraries, like `base`,
|
||||
`containers`, `Cabal`, etc.
|
||||
|
||||
We can register additional libraries to GHC, however, using a special build
|
||||
function called `ghcWithPackages`. That function expects one argument: a
|
||||
function that maps from an attribute set of Haskell packages to a list of
|
||||
packages, which determines the libraries known to that particular version of
|
||||
GHC. For example, the Nix expression `ghcWithPackages (pkgs: [pkgs.mtl])`
|
||||
generates a copy of GHC that has the `mtl` library registered in addition to
|
||||
its normal core packages:
|
||||
|
||||
$ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"
|
||||
|
||||
[nix-shell:~]$ ghc-pkg list mtl
|
||||
/nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d:
|
||||
mtl-2.2.1
|
||||
|
||||
This function allows users to define their own development environment by means
|
||||
of an override. After adding the following snippet to `~/.nixpkgs/config.nix`,
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
|
||||
(haskellPackages: with haskellPackages; [
|
||||
# libraries
|
||||
arrows async cgi criterion
|
||||
# tools
|
||||
cabal-install haskintex
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
it's possible to install that compiler with `nix-env -f "<nixpkgs>" -iA
|
||||
myHaskellEnv`. If you'd like to switch that development environment to a
|
||||
different version of GHC, just replace the `ghc7102` bit in the previous
|
||||
definition with the appropriate name. Of course, it's also possible to define
|
||||
any number of these development environments! (You can't install two of them
|
||||
into the same profile at the same time, though, because that would result in
|
||||
file conflicts.)
|
||||
|
||||
The generated `ghc` program is a wrapper script that re-directs the real
|
||||
GHC executable to use a new `lib` directory --- one that we specifically
|
||||
constructed to contain all those packages the user requested:
|
||||
|
||||
$ cat $(type -p ghc)
|
||||
#! /nix/store/xlxj...-bash-4.3-p33/bin/bash -e
|
||||
export NIX_GHC=/nix/store/19sm...-ghc-7.10.2/bin/ghc
|
||||
export NIX_GHCPKG=/nix/store/19sm...-ghc-7.10.2/bin/ghc-pkg
|
||||
export NIX_GHC_DOCDIR=/nix/store/19sm...-ghc-7.10.2/share/doc/ghc/html
|
||||
export NIX_GHC_LIBDIR=/nix/store/19sm...-ghc-7.10.2/lib/ghc-7.10.2
|
||||
exec /nix/store/j50p...-ghc-7.10.2/bin/ghc "-B$NIX_GHC_LIBDIR" "$@"
|
||||
|
||||
The variables `$NIX_GHC`, `$NIX_GHCPKG`, etc. point to the *new* store path
|
||||
`ghcWithPackages` constructed specifically for this environment. The last line
|
||||
of the wrapper script then executes the real `ghc`, but passes the path to the
|
||||
new `lib` directory using GHC's `-B` flag.
|
||||
|
||||
The purpose of those environment variables is to work around an impurity in the
|
||||
popular [ghc-paths](http://hackage.haskell.org/package/ghc-paths) library. That
|
||||
library promises to give its users access to GHC's installation paths. Only,
|
||||
the library can't possible know that path when it's compiled, because the path
|
||||
GHC considers its own is determined only much later, when the user configures
|
||||
it through `ghcWithPackages`. So we [patched
|
||||
ghc-paths](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/patches/ghc-paths-nix.patch)
|
||||
to return the paths found in those environment variables at run-time rather
|
||||
than trying to guess them at compile-time.
|
||||
|
||||
To make sure that mechanism works properly all the time, we recommend that you
|
||||
set those variables to meaningful values in your shell environment, too, i.e.
|
||||
by adding the following code to your `~/.bashrc`:
|
||||
|
||||
if type >/dev/null 2>&1 -p ghc; then
|
||||
eval "$(egrep ^export "$(type -p ghc)")"
|
||||
fi
|
||||
|
||||
If you are certain that you'll use only one GHC environment which is located in
|
||||
your user profile, then you can use the following code, too, which has the
|
||||
advantage that it doesn't contain any paths from the Nix store, i.e. those
|
||||
settings always remain valid even if a `nix-env -u` operation updates the GHC
|
||||
environment in your profile:
|
||||
|
||||
if [ -e ~/.nix-profile/bin/ghc ]; then
|
||||
export NIX_GHC="$HOME/.nix-profile/bin/ghc"
|
||||
export NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg"
|
||||
export NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html"
|
||||
export NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$($NIX_GHC --numeric-version)"
|
||||
fi
|
||||
|
||||
### How to install a compiler with libraries, hoogle and documentation indexes
|
||||
|
||||
If you plan to use your environment for interactive programming, not just
|
||||
compiling random Haskell code, you might want to replace `ghcWithPackages` in
|
||||
all the listings above with `ghcWithHoogle`.
|
||||
|
||||
This environment generator not only produces an environment with GHC and all
|
||||
the specified libraries, but also generates a `hoogle` and `haddock` indexes
|
||||
for all the packages, and provides a wrapper script around `hoogle` binary that
|
||||
uses all those things. A precise name for this thing would be
|
||||
"`ghcWithPackagesAndHoogleAndDocumentationIndexes`", which is, regrettably, too
|
||||
long and scary.
|
||||
|
||||
For example, installing the following environment
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
myHaskellEnv = self.haskellPackages.ghcWithHoogle
|
||||
(haskellPackages: with haskellPackages; [
|
||||
# libraries
|
||||
arrows async cgi criterion
|
||||
# tools
|
||||
cabal-install haskintex
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
allows one to browse module documentation index [not too dissimilar to
|
||||
this](https://downloads.haskell.org/~ghc/latest/docs/html/libraries/index.html)
|
||||
for all the specified packages and their dependencies by directing a browser of
|
||||
choice to `~/.nix-profiles/share/doc/hoogle/index.html` (or
|
||||
`/run/current-system/sw/share/doc/hoogle/index.html` in case you put it in
|
||||
`environment.systemPackages` in NixOS).
|
||||
|
||||
After you've marveled enough at that try adding the following to your
|
||||
`~/.ghc/ghci.conf`
|
||||
|
||||
:def hoogle \s -> return $ ":! hoogle search -cl --count=15 \"" ++ s ++ "\""
|
||||
:def doc \s -> return $ ":! hoogle search -cl --info \"" ++ s ++ "\""
|
||||
|
||||
and test it by typing into `ghci`:
|
||||
|
||||
:hoogle a -> a
|
||||
:doc a -> a
|
||||
|
||||
Be sure to note the links to `haddock` files in the output. With any modern and
|
||||
properly configured terminal emulator you can just click those links to
|
||||
navigate there.
|
||||
|
||||
Finally, you can run
|
||||
|
||||
hoogle server -p 8080
|
||||
|
||||
and navigate to http://localhost:8080/ for your own local
|
||||
[Hoogle](https://www.haskell.org/hoogle/). Note, however, that Firefox and
|
||||
possibly other browsers disallow navigation from `http:` to `file:` URIs for
|
||||
security reasons, which might be quite an inconvenience. See [this
|
||||
page](http://kb.mozillazine.org/Links_to_local_pages_do_not_work) for
|
||||
workarounds.
|
||||
|
||||
### How to build a Haskell project using Stack
|
||||
|
||||
[Stack][http://haskellstack.org] is a popular build tool for Haskell projects.
|
||||
It has first-class support for Nix. Stack can optionally use Nix to
|
||||
automatically select the right version of GHC and other build tools to build,
|
||||
test and execute apps in an existing project downloaded from somewhere on the
|
||||
Internet. Pass the `--nix` flag to any `stack` command to do so, e.g.
|
||||
|
||||
$ git clone --recursive http://github.com/yesodweb/wai
|
||||
$ cd wai
|
||||
$ stack --nix build
|
||||
|
||||
If you want `stack` to use Nix by default, you can add a `nix` section to the
|
||||
`stack.yaml` file, as explained in the [Stack documentation][stack-nix-doc]. For
|
||||
example:
|
||||
|
||||
nix:
|
||||
enable: true
|
||||
packages: [pkgconfig zeromq zlib]
|
||||
|
||||
The example configuration snippet above tells Stack to create an ad hoc
|
||||
environment for `nix-shell` as in the below section, in which the `pkgconfig`,
|
||||
`zeromq` and `zlib` packages from Nixpkgs are available. All `stack` commands
|
||||
will implicitly be executed inside this ad hoc environment.
|
||||
|
||||
Some projects have more sophisticated needs. For examples, some ad hoc
|
||||
environments might need to expose Nixpkgs packages compiled in a certain way, or
|
||||
with extra environment variables. In these cases, you'll need a `shell` field
|
||||
instead of `packages`:
|
||||
|
||||
nix:
|
||||
enable: true
|
||||
shell-file: shell.nix
|
||||
|
||||
For more on how to write a `shell.nix` file see the below section. You'll need
|
||||
to express a derivation. Note that Nixpkgs ships with a convenience wrapper
|
||||
function around `mkDerivation` called `haskell.lib.buildStackProject` to help you
|
||||
create this derivation in exactly the way Stack expects. All of the same inputs
|
||||
as `mkDerivation` can be provided. For example, to build a Stack project that
|
||||
including packages that link against a version of the R library compiled with
|
||||
special options turned on:
|
||||
|
||||
with (import <nixpkgs> { });
|
||||
|
||||
let R = pkgs.R.override { enableStrictBarrier = true; };
|
||||
in
|
||||
haskell.lib.buildStackProject {
|
||||
name = "HaskellR";
|
||||
buildInputs = [ R zeromq zlib ];
|
||||
}
|
||||
|
||||
[stack-nix-doc]: http://docs.haskellstack.org/en/stable/nix_integration.html
|
||||
|
||||
### How to create ad hoc environments for `nix-shell`
|
||||
|
||||
The easiest way to create an ad hoc development environment is to run
|
||||
`nix-shell` with the appropriate GHC environment given on the command-line:
|
||||
|
||||
nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [mtl pandoc])"
|
||||
|
||||
For more sophisticated use-cases, however, it's more convenient to save the
|
||||
desired configuration in a file called `shell.nix` that looks like this:
|
||||
|
||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||
let
|
||||
inherit (nixpkgs) pkgs;
|
||||
ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
|
||||
monad-par mtl
|
||||
]);
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "my-haskell-env-0";
|
||||
buildInputs = [ ghc ];
|
||||
shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)";
|
||||
}
|
||||
|
||||
Now run `nix-shell` --- or even `nix-shell --pure` --- to enter a shell
|
||||
environment that has the appropriate compiler in `$PATH`. If you use `--pure`,
|
||||
then add all other packages that your development environment needs into the
|
||||
`buildInputs` attribute. If you'd like to switch to a different compiler
|
||||
version, then pass an appropriate `compiler` argument to the expression, i.e.
|
||||
`nix-shell --argstr compiler ghc784`.
|
||||
|
||||
If you need such an environment because you'd like to compile a Hackage package
|
||||
outside of Nix --- i.e. because you're hacking on the latest version from Git
|
||||
---, then the package set provides suitable nix-shell environments for you
|
||||
already! Every Haskell package has an `env` attribute that provides a shell
|
||||
environment suitable for compiling that particular package. If you'd like to
|
||||
hack the `lens` library, for example, then you just have to check out the
|
||||
source code and enter the appropriate environment:
|
||||
|
||||
$ cabal get lens-4.11 && cd lens-4.11
|
||||
Downloading lens-4.11...
|
||||
Unpacking to lens-4.11/
|
||||
|
||||
$ nix-shell "<nixpkgs>" -A haskellPackages.lens.env
|
||||
[nix-shell:/tmp/lens-4.11]$
|
||||
|
||||
At point, you can run `cabal configure`, `cabal build`, and all the other
|
||||
development commands. Note that you need `cabal-install` installed in your
|
||||
`$PATH` already to use it here --- the `nix-shell` environment does not provide
|
||||
it.
|
||||
|
||||
## How to create Nix builds for your own private Haskell packages
|
||||
|
||||
If your own Haskell packages have build instructions for Cabal, then you can
|
||||
convert those automatically into build instructions for Nix using the
|
||||
`cabal2nix` utility, which you can install into your profile by running
|
||||
`nix-env -i cabal2nix`.
|
||||
|
||||
### How to build a stand-alone project
|
||||
|
||||
For example, let's assume that you're working on a private project called
|
||||
`foo`. To generate a Nix build expression for it, change into the project's
|
||||
top-level directory and run the command:
|
||||
|
||||
$ cabal2nix . >foo.nix
|
||||
|
||||
Then write the following snippet into a file called `default.nix`:
|
||||
|
||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||
nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./foo.nix { }
|
||||
|
||||
Finally, store the following code in a file called `shell.nix`:
|
||||
|
||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||
(import ./default.nix { inherit nixpkgs compiler; }).env
|
||||
|
||||
At this point, you can run `nix-build` to have Nix compile your project and
|
||||
install it into a Nix store path. The local directory will contain a symlink
|
||||
called `result` after `nix-build` returns that points into that location. Of
|
||||
course, passing the flag `--argstr compiler ghc763` allows switching the build
|
||||
to any version of GHC currently supported.
|
||||
|
||||
Furthermore, you can call `nix-shell` to enter an interactive development
|
||||
environment in which you can use `cabal configure` and `cabal build` to develop
|
||||
your code. That environment will automatically contain a proper GHC derivation
|
||||
with all the required libraries registered as well as all the system-level
|
||||
libraries your package might need.
|
||||
|
||||
If your package does not depend on any system-level libraries, then it's
|
||||
sufficient to run
|
||||
|
||||
$ nix-shell --command "cabal configure"
|
||||
|
||||
once to set up your build. `cabal-install` determines the absolute paths to all
|
||||
resources required for the build and writes them into a config file in the
|
||||
`dist/` directory. Once that's done, you can run `cabal build` and any other
|
||||
command for that project even outside of the `nix-shell` environment. This
|
||||
feature is particularly nice for those of us who like to edit their code with
|
||||
an IDE, like Emacs' `haskell-mode`, because it's not necessary to start Emacs
|
||||
inside of nix-shell just to make it find out the necessary settings for
|
||||
building the project; `cabal-install` has already done that for us.
|
||||
|
||||
If you want to do some quick-and-dirty hacking and don't want to bother setting
|
||||
up a `default.nix` and `shell.nix` file manually, then you can use the
|
||||
`--shell` flag offered by `cabal2nix` to have it generate a stand-alone
|
||||
`nix-shell` environment for you. With that feature, running
|
||||
|
||||
$ cabal2nix --shell . >shell.nix
|
||||
$ nix-shell --command "cabal configure"
|
||||
|
||||
is usually enough to set up a build environment for any given Haskell package.
|
||||
You can even use that generated file to run `nix-build`, too:
|
||||
|
||||
$ nix-build shell.nix
|
||||
|
||||
### How to build projects that depend on each other
|
||||
|
||||
If you have multiple private Haskell packages that depend on each other, then
|
||||
you'll have to register those packages in the Nixpkgs set to make them visible
|
||||
for the dependency resolution performed by `callPackage`. First of all, change
|
||||
into each of your projects top-level directories and generate a `default.nix`
|
||||
file with `cabal2nix`:
|
||||
|
||||
$ cd ~/src/foo && cabal2nix . >default.nix
|
||||
$ cd ~/src/bar && cabal2nix . >default.nix
|
||||
|
||||
Then edit your `~/.nixpkgs/config.nix` file to register those builds in the
|
||||
default Haskell package set:
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
haskellPackages = super.haskellPackages.override {
|
||||
overrides = self: super: {
|
||||
foo = self.callPackage ../src/foo {};
|
||||
bar = self.callPackage ../src/bar {};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Once that's accomplished, `nix-env -f "<nixpkgs>" -qA haskellPackages` will
|
||||
show your packages like any other package from Hackage, and you can build them
|
||||
|
||||
$ nix-build "<nixpkgs>" -A haskellPackages.foo
|
||||
|
||||
or enter an interactive shell environment suitable for building them:
|
||||
|
||||
$ nix-shell "<nixpkgs>" -A haskellPackages.bar.env
|
||||
|
||||
## Miscellaneous Topics
|
||||
|
||||
### How to build with profiling enabled
|
||||
|
||||
Every Haskell package set takes a function called `overrides` that you can use
|
||||
to manipulate the package as much as you please. One useful application of this
|
||||
feature is to replace the default `mkDerivation` function with one that enables
|
||||
library profiling for all packages. To accomplish that, add configure the
|
||||
following snippet in your `~/.nixpkgs/config.nix` file:
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
profiledHaskellPackages = self.haskellPackages.override {
|
||||
overrides = self: super: {
|
||||
mkDerivation = args: super.mkDerivation (args // {
|
||||
enableLibraryProfiling = true;
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Then, replace instances of `haskellPackages` in the `cabal2nix`-generated
|
||||
`default.nix` or `shell.nix` files with `profiledHaskellPackages`.
|
||||
|
||||
### How to override package versions in a compiler-specific package set
|
||||
|
||||
Nixpkgs provides the latest version of
|
||||
[`ghc-events`](http://hackage.haskell.org/package/ghc-events), which is 0.4.4.0
|
||||
at the time of this writing. This is fine for users of GHC 7.10.x, but GHC
|
||||
7.8.4 cannot compile that binary. Now, one way to solve that problem is to
|
||||
register an older version of `ghc-events` in the 7.8.x-specific package set.
|
||||
The first step is to generate Nix build instructions with `cabal2nix`:
|
||||
|
||||
$ cabal2nix cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
|
||||
|
||||
Then add the override in `~/.nixpkgs/config.nix`:
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
haskell = super.haskell // {
|
||||
packages = super.haskell.packages // {
|
||||
ghc784 = super.haskell.packages.ghc784.override {
|
||||
overrides = self: super: {
|
||||
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
This code is a little crazy, no doubt, but it's necessary because the intuitive
|
||||
version
|
||||
|
||||
haskell.packages.ghc784 = super.haskell.packages.ghc784.override {
|
||||
overrides = self: super: {
|
||||
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
|
||||
};
|
||||
};
|
||||
|
||||
doesn't do what we want it to: that code replaces the `haskell` package set in
|
||||
Nixpkgs with one that contains only one entry,`packages`, which contains only
|
||||
one entry `ghc784`. This override loses the `haskell.compiler` set, and it
|
||||
loses the `haskell.packages.ghcXYZ` sets for all compilers but GHC 7.8.4. To
|
||||
avoid that problem, we have to perform the convoluted little dance from above,
|
||||
iterating over each step in hierarchy.
|
||||
|
||||
Once it's accomplished, however, we can install a variant of `ghc-events`
|
||||
that's compiled with GHC 7.8.4:
|
||||
|
||||
nix-env -f "<nixpkgs>" -iA haskell.packages.ghc784.ghc-events
|
||||
|
||||
Unfortunately, it turns out that this build fails again while executing the
|
||||
test suite! Apparently, the release archive on Hackage is missing some data
|
||||
files that the test suite requires, so we cannot run it. We accomplish that by
|
||||
re-generating the Nix expression with the `--no-check` flag:
|
||||
|
||||
$ cabal2nix --no-check cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
|
||||
|
||||
Now the builds succeeds.
|
||||
|
||||
Of course, in the concrete example of `ghc-events` this whole exercise is not
|
||||
an ideal solution, because `ghc-events` can analyze the output emitted by any
|
||||
version of GHC later than 6.12 regardless of the compiler version that was used
|
||||
to build the `ghc-events' executable, so strictly speaking there's no reason to
|
||||
prefer one built with GHC 7.8.x in the first place. However, for users who
|
||||
cannot use GHC 7.10.x at all for some reason, the approach of downgrading to an
|
||||
older version might be useful.
|
||||
|
||||
### How to recover from GHC's infamous non-deterministic library ID bug
|
||||
|
||||
GHC and distributed build farms don't get along well:
|
||||
|
||||
https://ghc.haskell.org/trac/ghc/ticket/4012
|
||||
|
||||
When you see an error like this one
|
||||
|
||||
package foo-0.7.1.0 is broken due to missing package
|
||||
text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
|
||||
|
||||
then you have to download and re-install `foo` and all its dependents from
|
||||
scratch:
|
||||
|
||||
# nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \
|
||||
| xargs -L 1 nix-store --repair-path --option binary-caches http://hydra.nixos.org
|
||||
|
||||
If you're using additional Hydra servers other than `hydra.nixos.org`, then it
|
||||
might be necessary to purge the local caches that store data from those
|
||||
machines to disable these binary channels for the duration of the previous
|
||||
command, i.e. by running:
|
||||
|
||||
rm /nix/var/nix/binary-cache-v3.sqlite
|
||||
rm /nix/var/nix/manifests/*
|
||||
rm /nix/var/nix/channel-cache/*
|
||||
|
||||
### Builds on Darwin fail with `math.h` not found
|
||||
|
||||
Users of GHC on Darwin have occasionally reported that builds fail, because the
|
||||
compiler complains about a missing include file:
|
||||
|
||||
fatal error: 'math.h' file not found
|
||||
|
||||
The issue has been discussed at length in [ticket
|
||||
6390](https://github.com/NixOS/nixpkgs/issues/6390), and so far no good
|
||||
solution has been proposed. As a work-around, users who run into this problem
|
||||
can configure the environment variables
|
||||
|
||||
export NIX_CFLAGS_COMPILE="-idirafter /usr/include"
|
||||
export NIX_CFLAGS_LINK="-L/usr/lib"
|
||||
|
||||
in their `~/.bashrc` file to avoid the compiler error.
|
||||
|
||||
### Builds using Stack complain about missing system libraries
|
||||
|
||||
-- While building package zlib-0.5.4.2 using:
|
||||
runhaskell -package=Cabal-1.22.4.0 -clear-package-db [... lots of flags ...]
|
||||
Process exited with code: ExitFailure 1
|
||||
Logs have been written to: /home/foo/src/stack-ide/.stack-work/logs/zlib-0.5.4.2.log
|
||||
|
||||
Configuring zlib-0.5.4.2...
|
||||
Setup.hs: Missing dependency on a foreign library:
|
||||
* Missing (or bad) header file: zlib.h
|
||||
This problem can usually be solved by installing the system package that
|
||||
provides this library (you may need the "-dev" version). If the library is
|
||||
already installed but in a non-standard location then you can use the flags
|
||||
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
|
||||
If the header file does exist, it may contain errors that are caught by the C
|
||||
compiler at the preprocessing stage. In this case you can re-run configure
|
||||
with the verbosity flag -v3 to see the error messages.
|
||||
|
||||
When you run the build inside of the nix-shell environment, the system
|
||||
is configured to find libz.so without any special flags -- the compiler
|
||||
and linker "just know" how to find it. Consequently, Cabal won't record
|
||||
any search paths for libz.so in the package description, which means
|
||||
that the package works fine inside of nix-shell, but once you leave the
|
||||
shell the shared object can no longer be found. That issue is by no
|
||||
means specific to Stack: you'll have that problem with any other
|
||||
Haskell package that's built inside of nix-shell but run outside of that
|
||||
environment.
|
||||
|
||||
You can remedy this issue in several ways. The easiest is to add a `nix` section
|
||||
to the `stack.yaml` like the following:
|
||||
|
||||
nix:
|
||||
enable: true
|
||||
packages: [ zlib ]
|
||||
|
||||
Stack's Nix support knows to add `${zlib}/lib` and `${zlib}/include` as an
|
||||
`--extra-lib-dirs` and `extra-include-dirs`, respectively. Alternatively, you
|
||||
can achieve the same effect by hand. First of all, run
|
||||
|
||||
$ nix-build --no-out-link "<nixpkgs>" -A zlib
|
||||
/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8
|
||||
|
||||
to find out the store path of the system's zlib library. Now, you can
|
||||
|
||||
1) add that path (plus a "/lib" suffix) to your $LD_LIBRARY_PATH
|
||||
environment variable to make sure your system linker finds libz.so
|
||||
automatically. It's no pretty solution, but it will work.
|
||||
|
||||
2) As a variant of (1), you can also install any number of system
|
||||
libraries into your user's profile (or some other profile) and point
|
||||
$LD_LIBRARY_PATH to that profile instead, so that you don't have to
|
||||
list dozens of those store paths all over the place.
|
||||
|
||||
3) The solution I prefer is to call stack with an appropriate
|
||||
--extra-lib-dirs flag like so:
|
||||
|
||||
$ stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build
|
||||
|
||||
Typically, you'll need --extra-include-dirs as well. It's possible
|
||||
to add those flag to the project's "stack.yaml" or your user's
|
||||
global "~/.stack/global/stack.yaml" file so that you don't have to
|
||||
specify them manually every time. But again, you're likely better off using
|
||||
Stack's Nix support instead.
|
||||
|
||||
The same thing applies to `cabal configure`, of course, if you're
|
||||
building with `cabal-install` instead of Stack.
|
||||
|
||||
### Creating statically linked binaries
|
||||
|
||||
There are two levels of static linking. The first option is to configure the
|
||||
build with the Cabal flag `--disable-executable-dynamic`. In Nix expressions,
|
||||
this can be achieved by setting the attribute:
|
||||
|
||||
enableSharedExecutables = false;
|
||||
|
||||
That gives you a binary with statically linked Haskell libraries and
|
||||
dynamically linked system libraries.
|
||||
|
||||
To link both Haskell libraries and system libraries statically, the additional
|
||||
flags `--ghc-option=-optl=-static --ghc-option=-optl=-pthread` need to be used.
|
||||
In Nix, this is accomplished with:
|
||||
|
||||
configureFlags = [ "--ghc-option=-optl=-static" "--ghc-option=-optl=-pthread" ];
|
||||
|
||||
It's important to realize, however, that most system libraries in Nix are built
|
||||
as shared libraries only, i.e. there is just no static library available that
|
||||
Cabal could link!
|
||||
|
||||
|
||||
## Other resources
|
||||
|
||||
- The Youtube video [Nix Loves Haskell](https://www.youtube.com/watch?v=BsBhi_r-OeE)
|
||||
provides an introduction into Haskell NG aimed at beginners. The slides are
|
||||
available at http://cryp.to/nixos-meetup-3-slides.pdf and also -- in a form
|
||||
ready for cut & paste -- at
|
||||
https://github.com/NixOS/cabal2nix/blob/master/doc/nixos-meetup-3-slides.md.
|
||||
|
||||
- Another Youtube video is [Escaping Cabal Hell with Nix](https://www.youtube.com/watch?v=mQd3s57n_2Y),
|
||||
which discusses the subject of Haskell development with Nix but also provides
|
||||
a basic introduction to Nix as well, i.e. it's suitable for viewers with
|
||||
almost no prior Nix experience.
|
||||
|
||||
- Oliver Charles wrote a very nice [Tutorial how to develop Haskell packages with Nix](http://wiki.ocharles.org.uk/Nix).
|
||||
|
||||
- The *Journey into the Haskell NG infrastructure* series of postings
|
||||
describe the new Haskell infrastructure in great detail:
|
||||
|
||||
- [Part 1](http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015591.html)
|
||||
explains the differences between the old and the new code and gives
|
||||
instructions how to migrate to the new setup.
|
||||
|
||||
- [Part 2](http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015608.html)
|
||||
looks in-depth at how to tweak and configure your setup by means of
|
||||
overrides.
|
||||
|
||||
- [Part 3](http://lists.science.uu.nl/pipermail/nix-dev/2015-April/016912.html)
|
||||
describes the infrastructure that keeps the Haskell package set in Nixpkgs
|
||||
up-to-date.
|
||||
@@ -6,14 +6,13 @@ date: 2015-11-25
|
||||
|
||||
# Introduction
|
||||
|
||||
The Nix Packages collection (Nixpkgs) is a set of thousands of packages for the
|
||||
[Nix package manager](http://nixos.org/nix/), released under a
|
||||
[permissive MIT/X11 license](https://github.com/NixOS/nixpkgs/blob/master/COPYING).
|
||||
Packages are available for several platforms, and can be used with the Nix
|
||||
package manager on most GNU/Linux distributions as well as NixOS.
|
||||
The Nix Packages collection (Nixpkgs) is a set of over 30,000 packages for the
|
||||
[Nix package manager](http://nixos.org/nix/), released under a [permissive MIT/X11 license](https://github.com/NixOS/nixpkgs/blob/master/COPYING).
|
||||
Packages are available for several architectures, and can be used with the Nix package manager
|
||||
on most GNU/Linux distributions as well as NixOS.
|
||||
|
||||
This manual primarily describes how to write packages for the Nix Packages collection
|
||||
(Nixpkgs). Thus it’s mainly for packagers and developers who want to add packages to
|
||||
This manual describes how to write packages for the Nix Packages collection
|
||||
(Nixpkgs). Thus it’s for packagers and developers who want to add packages to
|
||||
Nixpkgs. If you like to learn more about the Nix package manager and the Nix
|
||||
expression language, then you are kindly referred to the [Nix manual](http://nixos.org/nix/manual/).
|
||||
|
||||
@@ -21,33 +20,29 @@ expression language, then you are kindly referred to the [Nix manual](http://nix
|
||||
|
||||
Nix expressions describe how to build packages from source and are collected in
|
||||
the [nixpkgs repository](https://github.com/NixOS/nixpkgs). Also included in the
|
||||
collection are Nix expressions for
|
||||
[NixOS modules](http://nixos.org/nixos/manual/index.html#sec-writing-modules).
|
||||
With these expressions the Nix package manager can build binary packages.
|
||||
collection are Nix expressions for [NixOS modules](http://nixos.org/nixos/manual/index.html#sec-writing-modules). With
|
||||
these expressions the Nix package manager can build binary packages.
|
||||
|
||||
Packages, including the Nix packages collection, are distributed through
|
||||
[channels](http://nixos.org/nix/manual/#sec-channels). The collection is
|
||||
distributed for users of Nix on non-NixOS distributions through the channel
|
||||
`nixpkgs`. Users of NixOS generally use one of the `nixos-*` channels, e.g.
|
||||
`nixos-16.03`, which includes all packages and modules for the stable NixOS
|
||||
16.03. The purpose of stable NixOS releases are generally only given
|
||||
`nixos-15.09`, which includes all packages and modules for the stable NixOS
|
||||
15.09. The channels of the stable NixOS releases are generally only given
|
||||
security updates. More up to date packages and modules are available via the
|
||||
`nixos-unstable` channel.
|
||||
|
||||
Both `nixos-unstable` and `nixpkgs` follow the `master` branch of the Nixpkgs
|
||||
repository, although both do lag the `master` branch by generally
|
||||
[a couple of days](http://howoldis.herokuapp.com/). Updates to a channel are
|
||||
distributed as soon as all tests for that channel pass, e.g.
|
||||
[this table](http://hydra.nixos.org/job/nixpkgs/trunk/unstable#tabs-constituents)
|
||||
repository, although both do lag the `master` branch by generally [a couple of days](http://howoldis.herokuapp.com/). Updates to a channel are distributed as
|
||||
soon as all tests for that channel pass, e.g. [this table](http://hydra.nixos.org/job/nixpkgs/trunk/unstable#tabs-constituents)
|
||||
shows the status of tests for the `nixpkgs` channel.
|
||||
|
||||
The tests are conducted by a cluster called [Hydra](http://nixos.org/hydra/),
|
||||
which also builds binary packages from the Nix expressions in Nixpkgs for
|
||||
`x86_64-linux`, `i686-linux` and `x86_64-darwin`.
|
||||
The binaries are made available via a [binary cache](https://cache.nixos.org).
|
||||
which also builds binary packages from the Nix expressions in Nixpkgs. As soon
|
||||
as a channel is updated, the binaries are made available via a [binary cache](https://cache.nixos.org). Until the channel updates, binaries that have
|
||||
already been built, are available via [Hydra's binary cache](https://hydra.nixos.org).
|
||||
|
||||
The current Nix expressions of the channels are available in the
|
||||
[`nixpkgs-channels`](https://github.com/NixOS/nixpkgs-channels) repository,
|
||||
which has branches corresponding to the available channels. There is also the
|
||||
[Nixpkgs Monitor](http://monitor.nixos.org) which keeps track of updates
|
||||
and security vulnerabilities.
|
||||
Nixpkgs Monitor which keeps track of updates and security vulnerabilities.
|
||||
|
||||
@@ -1,376 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="sec-beam">
|
||||
|
||||
<title>Beam Languages (Erlang & Elixir)</title>
|
||||
<section xml:id="beam-introduction">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
In this document and related Nix expressions we use the term
|
||||
<emphasis>Beam</emphasis> to describe the environment. Beam is
|
||||
the name of the Erlang Virtial Machine and, as far as we know,
|
||||
from a packaging perspective all languages that run on Beam are
|
||||
interchangable. The things that do change, like the build
|
||||
system, are transperant to the users of the package. So we make
|
||||
no distinction.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="build-tools">
|
||||
<title>Build Tools</title>
|
||||
<section xml:id="build-tools-rebar3">
|
||||
<title>Rebar3</title>
|
||||
<para>
|
||||
By default Rebar3 wants to manage it's own dependencies. In the
|
||||
normal non-Nix, this is perfectly acceptable. In the Nix world it
|
||||
is not. To support this we have created two versions of rebar3,
|
||||
<literal>rebar3</literal> and <literal>rebar3-open</literal>. The
|
||||
<literal>rebar3</literal> version has been patched to remove the
|
||||
ability to download anything from it. If you are not running it a
|
||||
nix-shell or a nix-build then its probably not going to work for
|
||||
you. <literal>rebar3-open</literal> is the normal, un-modified
|
||||
rebar3. It should work exactly as would any other version of
|
||||
rebar3. Any Erlang package should rely on
|
||||
<literal>rebar3</literal> and thats really what you should be
|
||||
using too.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="build-tools-other">
|
||||
<title>Mix & Erlang.mk</title>
|
||||
<para>
|
||||
Both Mix and Erlang.mk work exactly as you would expect. There
|
||||
is a bootstrap process that needs to be run for both of
|
||||
them. However, that is supported by the
|
||||
<literal>buildMix</literal> and <literal>buildErlangMk</literal> derivations.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="how-to-install-beam-packages">
|
||||
<title>How to install Beam packages</title>
|
||||
<para>
|
||||
Beam packages are not registered in the top level simply because
|
||||
they are not relevant to the vast majority of Nix users. They are
|
||||
installable using the <literal>beamPackages</literal> attribute
|
||||
set.
|
||||
|
||||
You can list the avialable packages in the
|
||||
<literal>beamPackages</literal> with the following command:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A beamPackages
|
||||
beamPackages.esqlite esqlite-0.2.1
|
||||
beamPackages.goldrush goldrush-0.1.7
|
||||
beamPackages.ibrowse ibrowse-4.2.2
|
||||
beamPackages.jiffy jiffy-0.14.5
|
||||
beamPackages.lager lager-3.0.2
|
||||
beamPackages.meck meck-0.8.3
|
||||
beamPackages.rebar3-pc pc-1.1.0
|
||||
</programlisting>
|
||||
<para>
|
||||
To install any of those packages into your profile, refer to them by
|
||||
their attribute path (first column):
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse
|
||||
</programlisting>
|
||||
<para>
|
||||
The attribute path of any Beam packages corresponds to the name
|
||||
of that particular package in Hex or its OTP Application/Release name.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="packaging-beam-applications">
|
||||
<title>Packaging Beam Applications</title>
|
||||
<section xml:id="packaging-erlang-applications">
|
||||
<title>Erlang Applications</title>
|
||||
<section xml:id="rebar3-packages">
|
||||
<title>Rebar3 Packages</title>
|
||||
<para>
|
||||
There is a Nix functional called
|
||||
<literal>buildRebar3</literal>. We use this function to make a
|
||||
derivation that understands how to build the rebar3 project. For
|
||||
example, the epression we use to build the <link
|
||||
xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link>
|
||||
project follows.
|
||||
</para>
|
||||
<programlisting>
|
||||
{stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }:
|
||||
|
||||
buildRebar3 rec {
|
||||
name = "hex2nix";
|
||||
version = "0.0.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ericbmerritt";
|
||||
repo = "hex2nix";
|
||||
rev = "${version}";
|
||||
sha256 = "1w7xjidz1l5yjmhlplfx7kphmnpvqm67w99hd2m7kdixwdxq0zqg";
|
||||
};
|
||||
|
||||
beamDeps = [ ibrowse jsx erlware_commons ];
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The only visible difference between this derivation and
|
||||
something like <literal>stdenv.mkDerivation</literal> is that we
|
||||
have added <literal>erlangDeps</literal> to the derivation. If
|
||||
you add your Beam dependencies here they will be correctly
|
||||
handled by the system.
|
||||
</para>
|
||||
<para>
|
||||
If your package needs to compile native code via Rebar's port
|
||||
compilation mechenism. You should add <literal>compilePort =
|
||||
true;</literal> to the derivation.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="erlang-mk-packages">
|
||||
<title>Erlang.mk Packages</title>
|
||||
<para>
|
||||
Erlang.mk functions almost identically to Rebar. The only real
|
||||
difference is that <literal>buildErlangMk</literal> is called
|
||||
instead of <literal>buildRebar3</literal>
|
||||
</para>
|
||||
<programlisting>
|
||||
{ buildErlangMk, fetchHex, cowlib, ranch }:
|
||||
buildErlangMk {
|
||||
name = "cowboy";
|
||||
version = "1.0.4";
|
||||
src = fetchHex {
|
||||
pkg = "cowboy";
|
||||
version = "1.0.4";
|
||||
sha256 =
|
||||
"6a0edee96885fae3a8dd0ac1f333538a42e807db638a9453064ccfdaa6b9fdac";
|
||||
};
|
||||
beamDeps = [ cowlib ranch ];
|
||||
|
||||
meta = {
|
||||
description = ''Small, fast, modular HTTP server written in
|
||||
Erlang.'';
|
||||
license = stdenv.lib.licenses.isc;
|
||||
homepage = "https://github.com/ninenines/cowboy";
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
</section>
|
||||
<section xml:id="mix-packages">
|
||||
<title>Mix Packages</title>
|
||||
<para>
|
||||
Mix functions almost identically to Rebar. The only real
|
||||
difference is that <literal>buildMix</literal> is called
|
||||
instead of <literal>buildRebar3</literal>
|
||||
</para>
|
||||
<programlisting>
|
||||
{ buildMix, fetchHex, plug, absinthe }:
|
||||
buildMix {
|
||||
name = "absinthe_plug";
|
||||
version = "1.0.0";
|
||||
src = fetchHex {
|
||||
pkg = "absinthe_plug";
|
||||
version = "1.0.0";
|
||||
sha256 =
|
||||
"08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33";
|
||||
};
|
||||
beamDeps = [ plug absinthe];
|
||||
|
||||
meta = {
|
||||
description = ''A plug for Absinthe, an experimental GraphQL
|
||||
toolkit'';
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
homepage = "https://github.com/CargoSense/absinthe_plug";
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="how-to-develop">
|
||||
<title>How to develop</title>
|
||||
<section xml:id="accessing-an-environment">
|
||||
<title>Accessing an Environment</title>
|
||||
<para>
|
||||
Often, all you want to do is be able to access a valid
|
||||
environment that contains a specific package and its
|
||||
dependencies. we can do that with the <literal>env</literal>
|
||||
part of a derivation. For example, lets say we want to access an
|
||||
erlang repl with ibrowse loaded up. We could do the following.
|
||||
</para>
|
||||
<programlisting>
|
||||
~/w/nixpkgs ❯❯❯ nix-shell -A beamPackages.ibrowse.env --run "erl"
|
||||
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
|
||||
|
||||
Eshell V7.0 (abort with ^G)
|
||||
1> m(ibrowse).
|
||||
Module: ibrowse
|
||||
MD5: 3b3e0137d0cbb28070146978a3392945
|
||||
Compiled: January 10 2016, 23:34
|
||||
Object file: /nix/store/g1rlf65rdgjs4abbyj4grp37ry7ywivj-ibrowse-4.2.2/lib/erlang/lib/ibrowse-4.2.2/ebin/ibrowse.beam
|
||||
Compiler options: [{outdir,"/tmp/nix-build-ibrowse-4.2.2.drv-0/hex-source-ibrowse-4.2.2/_build/default/lib/ibrowse/ebin"},
|
||||
debug_info,debug_info,nowarn_shadow_vars,
|
||||
warn_unused_import,warn_unused_vars,warnings_as_errors,
|
||||
{i,"/tmp/nix-build-ibrowse-4.2.2.drv-0/hex-source-ibrowse-4.2.2/_build/default/lib/ibrowse/include"}]
|
||||
Exports:
|
||||
add_config/1 send_req_direct/7
|
||||
all_trace_off/0 set_dest/3
|
||||
code_change/3 set_max_attempts/3
|
||||
get_config_value/1 set_max_pipeline_size/3
|
||||
get_config_value/2 set_max_sessions/3
|
||||
get_metrics/0 show_dest_status/0
|
||||
get_metrics/2 show_dest_status/1
|
||||
handle_call/3 show_dest_status/2
|
||||
handle_cast/2 spawn_link_worker_process/1
|
||||
handle_info/2 spawn_link_worker_process/2
|
||||
init/1 spawn_worker_process/1
|
||||
module_info/0 spawn_worker_process/2
|
||||
module_info/1 start/0
|
||||
rescan_config/0 start_link/0
|
||||
rescan_config/1 stop/0
|
||||
send_req/3 stop_worker_process/1
|
||||
send_req/4 stream_close/1
|
||||
send_req/5 stream_next/1
|
||||
send_req/6 terminate/2
|
||||
send_req_direct/4 trace_off/0
|
||||
send_req_direct/5 trace_off/2
|
||||
send_req_direct/6 trace_on/0
|
||||
trace_on/2
|
||||
ok
|
||||
2>
|
||||
</programlisting>
|
||||
<para>
|
||||
Notice the <literal>-A beamPackages.ibrowse.env</literal>.That
|
||||
is the key to this functionality.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="creating-a-shell">
|
||||
<title>Creating a Shell</title>
|
||||
<para>
|
||||
Getting access to an environment often isn't enough to do real
|
||||
development. Many times we need to create a
|
||||
<literal>shell.nix</literal> file and do our development inside
|
||||
of the environment specified by that file. This file looks a lot
|
||||
like the packageing described above. The main difference is that
|
||||
<literal>src</literal> points to project root and we call the
|
||||
package directly.
|
||||
</para>
|
||||
<programlisting>
|
||||
{ pkgs ? import "<nixpkgs"> {} }:
|
||||
|
||||
with pkgs;
|
||||
|
||||
let
|
||||
|
||||
f = { buildRebar3, ibrowse, jsx, erlware_commons }:
|
||||
buildRebar3 {
|
||||
name = "hex2nix";
|
||||
version = "0.1.0";
|
||||
src = ./.;
|
||||
erlangDeps = [ ibrowse jsx erlware_commons ];
|
||||
};
|
||||
drv = beamPackages.callPackage f {};
|
||||
|
||||
in
|
||||
drv
|
||||
</programlisting>
|
||||
<section xml:id="building-in-a-shell">
|
||||
<title>Building in a shell</title>
|
||||
<para>
|
||||
We can leveral the support of the Derivation, regardless of
|
||||
which build Derivation is called by calling the commands themselv.s
|
||||
</para>
|
||||
<programlisting>
|
||||
# =============================================================================
|
||||
# Variables
|
||||
# =============================================================================
|
||||
|
||||
NIX_TEMPLATES := "$(CURDIR)/nix-templates"
|
||||
|
||||
TARGET := "$(PREFIX)"
|
||||
|
||||
PROJECT_NAME := thorndyke
|
||||
|
||||
NIXPKGS=../nixpkgs
|
||||
NIX_PATH=nixpkgs=$(NIXPKGS)
|
||||
NIX_SHELL=nix-shell -I "$(NIX_PATH)" --pure
|
||||
# =============================================================================
|
||||
# Rules
|
||||
# =============================================================================
|
||||
.PHONY= all test clean repl shell build test analyze configure install \
|
||||
test-nix-install publish plt analyze
|
||||
|
||||
all: build
|
||||
|
||||
guard-%:
|
||||
@ if [ "${${*}}" == "" ]; then \
|
||||
echo "Environment variable $* not set"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
rm -rf _build
|
||||
rm -rf .cache
|
||||
|
||||
repl:
|
||||
$(NIX_SHELL) --run "iex -pa './_build/prod/lib/*/ebin'"
|
||||
|
||||
shell:
|
||||
$(NIX_SHELL)
|
||||
|
||||
configure:
|
||||
$(NIX_SHELL) --command 'eval "$$configurePhase"'
|
||||
|
||||
build: configure
|
||||
$(NIX_SHELL) --command 'eval "$$buildPhase"'
|
||||
|
||||
install:
|
||||
$(NIX_SHELL) --command 'eval "$$installPhase"'
|
||||
|
||||
test:
|
||||
$(NIX_SHELL) --command 'mix test --no-start --no-deps-check'
|
||||
|
||||
plt:
|
||||
$(NIX_SHELL) --run "mix dialyzer.plt --no-deps-check"
|
||||
|
||||
analyze: build plt
|
||||
$(NIX_SHELL) --run "mix dialyzer --no-compile"
|
||||
|
||||
</programlisting>
|
||||
<para>
|
||||
If you add the <literal>shell.nix</literal> as described and
|
||||
user rebar as follows things should simply work. Aside from the
|
||||
<literal>test</literal>, <literal>plt</literal>, and
|
||||
<literal>analyze</literal> the talks work just fine for all of
|
||||
the build Derivations.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="generating-packages-from-hex-with-hex2nix">
|
||||
<title>Generating Packages from Hex with Hex2Nix</title>
|
||||
<para>
|
||||
Updating the Hex packages requires the use of the
|
||||
<literal>hex2nix</literal> tool. Given the path to the Erlang
|
||||
modules (usually
|
||||
<literal>pkgs/development/erlang-modules</literal>). It will
|
||||
happily dump a file called
|
||||
<literal>hex-packages.nix</literal>. That file will contain all
|
||||
the packages that use a recognized build system in Hex. However,
|
||||
it can't know whether or not all those packages are buildable.
|
||||
</para>
|
||||
<para>
|
||||
To make life easier for our users, it makes good sense to go
|
||||
ahead and attempt to build all those packages and remove the
|
||||
ones that don't build. To do that, simply run the command (in
|
||||
the root of your <literal>nixpkgs</literal> repository). that follows.
|
||||
</para>
|
||||
<programlisting>
|
||||
$ nix-build -A beamPackages
|
||||
</programlisting>
|
||||
<para>
|
||||
That will build every package in
|
||||
<literal>beamPackages</literal>. Then you can go through and
|
||||
manually remove the ones that fail. Hopefully, someone will
|
||||
improve <literal>hex2nix</literal> in the future to automate
|
||||
that.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
@@ -1,244 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="sec-bower">
|
||||
|
||||
<title>Bower</title>
|
||||
|
||||
<para>
|
||||
<link xlink:href="http://bower.io">Bower</link> is a package manager
|
||||
for web site front-end components. Bower packages (comprising of
|
||||
build artefacts and sometimes sources) are stored in
|
||||
<command>git</command> repositories, typically on Github. The
|
||||
package registry is run by the Bower team with package metadata
|
||||
coming from the <filename>bower.json</filename> file within each
|
||||
package.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The end result of running Bower is a
|
||||
<filename>bower_components</filename> directory which can be included
|
||||
in the web app's build process.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Bower can be run interactively, by installing
|
||||
<varname>nodePackages.bower</varname>. More interestingly, the Bower
|
||||
components can be declared in a Nix derivation, with the help of
|
||||
<varname>nodePackages.bower2nix</varname>.
|
||||
</para>
|
||||
|
||||
<section xml:id="ssec-bower2nix-usage">
|
||||
<title><command>bower2nix</command> usage</title>
|
||||
|
||||
<para>
|
||||
Suppose you have a <filename>bower.json</filename> with the following contents:
|
||||
|
||||
|
||||
<example xml:id="ex-bowerJson"><title><filename>bower.json</filename></title>
|
||||
<programlisting language="json">
|
||||
<![CDATA[{
|
||||
"name": "my-web-app",
|
||||
"dependencies": {
|
||||
"angular": "~1.5.0",
|
||||
"bootstrap": "~3.3.6"
|
||||
}
|
||||
}]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
|
||||
|
||||
<para>
|
||||
Running <command>bower2nix</command> will produce something like the
|
||||
following output:
|
||||
|
||||
<programlisting language="nix">
|
||||
<![CDATA[{ fetchbower, buildEnv }:
|
||||
buildEnv { name = "bower-env"; ignoreCollisions = true; paths = [
|
||||
(fetchbower "angular" "1.5.3" "~1.5.0" "1749xb0firxdra4rzadm4q9x90v6pzkbd7xmcyjk6qfza09ykk9y")
|
||||
(fetchbower "bootstrap" "3.3.6" "~3.3.6" "1vvqlpbfcy0k5pncfjaiskj3y6scwifxygfqnw393sjfxiviwmbv")
|
||||
(fetchbower "jquery" "2.2.2" "1.9.1 - 2" "10sp5h98sqwk90y4k6hbdviwqzvzwqf47r3r51pakch5ii2y7js1")
|
||||
]; }]]>
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
|
||||
<para>
|
||||
Using the <command>bower2nix</command> command line arguments, the
|
||||
output can be redirected to a file. A name like
|
||||
<filename>bower-packages.nix</filename> would be fine.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The resulting derivation is a union of all the downloaded Bower
|
||||
packages (and their dependencies). To use it, they still need to be
|
||||
linked together by Bower, which is where
|
||||
<varname>buildBowerComponents</varname> is useful.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-build-bower-components"><title><varname>buildBowerComponents</varname> function</title>
|
||||
|
||||
<para>
|
||||
The function is implemented in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/bower-modules/generic/default.nix">
|
||||
<filename>pkgs/development/bower-modules/generic/default.nix</filename></link>.
|
||||
Example usage:
|
||||
|
||||
<example xml:id="ex-buildBowerComponents"><title>buildBowerComponents</title>
|
||||
<programlisting language="nix">
|
||||
bowerComponents = buildBowerComponents {
|
||||
name = "my-web-app";
|
||||
generated = ./bower-packages.nix; <co xml:id="ex-buildBowerComponents-1" />
|
||||
src = myWebApp; <co xml:id="ex-buildBowerComponents-2" />
|
||||
};
|
||||
</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In <xref linkend="ex-buildBowerComponents" />, the following arguments
|
||||
are of special significance to the function:
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="ex-buildBowerComponents-1">
|
||||
<para>
|
||||
<varname>generated</varname> specifies the file which was created by <command>bower2nix</command>.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ex-buildBowerComponents-2">
|
||||
<para>
|
||||
<varname>src</varname> is your project's sources. It needs to
|
||||
contain a <filename>bower.json</filename> file.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<varname>buildBowerComponents</varname> will run Bower to link
|
||||
together the output of <command>bower2nix</command>, resulting in a
|
||||
<filename>bower_components</filename> directory which can be used.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here is an example of a web frontend build process using
|
||||
<command>gulp</command>. You might use <command>grunt</command>, or
|
||||
anything else.
|
||||
</para>
|
||||
|
||||
<example xml:id="ex-bowerGulpFile"><title>Example build script (<filename>gulpfile.js</filename>)</title>
|
||||
<programlisting language="javascript">
|
||||
<![CDATA[var gulp = require('gulp');
|
||||
|
||||
gulp.task('default', [], function () {
|
||||
gulp.start('build');
|
||||
});
|
||||
|
||||
gulp.task('build', [], function () {
|
||||
console.log("Just a dummy gulp build");
|
||||
gulp
|
||||
.src(["./bower_components/**/*"])
|
||||
.pipe(gulp.dest("./gulpdist/"));
|
||||
});]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<example xml:id="ex-buildBowerComponentsDefaultNix">
|
||||
<title>Full example — <filename>default.nix</filename></title>
|
||||
<programlisting language="nix">
|
||||
{ myWebApp ? { outPath = ./.; name = "myWebApp"; }
|
||||
, pkgs ? import <nixpkgs> {}
|
||||
}:
|
||||
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "my-web-app-frontend";
|
||||
src = myWebApp;
|
||||
|
||||
buildInputs = [ pkgs.nodePackages.gulp ];
|
||||
|
||||
bowerComponents = pkgs.buildBowerComponents { <co xml:id="ex-buildBowerComponentsDefault-1" />
|
||||
name = "my-web-app";
|
||||
generated = ./bower-packages.nix;
|
||||
src = myWebApp;
|
||||
};
|
||||
|
||||
buildPhase = ''
|
||||
cp --reflink=auto --no-preserve=mode -R $bowerComponents/bower_components . <co xml:id="ex-buildBowerComponentsDefault-2" />
|
||||
export HOME=$PWD <co xml:id="ex-buildBowerComponentsDefault-3" />
|
||||
${pkgs.nodePackages.gulp}/bin/gulp build <co xml:id="ex-buildBowerComponentsDefault-4" />
|
||||
'';
|
||||
|
||||
installPhase = "mv gulpdist $out";
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
A few notes about <xref linkend="ex-buildBowerComponentsDefaultNix" />:
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="ex-buildBowerComponentsDefault-1">
|
||||
<para>
|
||||
The result of <varname>buildBowerComponents</varname> is an
|
||||
input to the frontend build.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ex-buildBowerComponentsDefault-2">
|
||||
<para>
|
||||
Whether to symlink or copy the
|
||||
<filename>bower_components</filename> directory depends on the
|
||||
build tool in use. In this case a copy is used to avoid
|
||||
<command>gulp</command> silliness with permissions.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ex-buildBowerComponentsDefault-3">
|
||||
<para>
|
||||
<command>gulp</command> requires <varname>HOME</varname> to
|
||||
refer to a writeable directory.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ex-buildBowerComponentsDefault-4">
|
||||
<para>
|
||||
The actual build command. Other tools could be used.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-bower2nix-troubleshooting">
|
||||
<title>Troubleshooting</title>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>ENOCACHE</literal> errors from
|
||||
<varname>buildBowerComponents</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This means that Bower was looking for a package version which
|
||||
doesn't exist in the generated
|
||||
<filename>bower-packages.nix</filename>.
|
||||
</para>
|
||||
<para>
|
||||
If <filename>bower.json</filename> has been updated, then run
|
||||
<command>bower2nix</command> again.
|
||||
</para>
|
||||
<para>
|
||||
It could also be a bug in <command>bower2nix</command> or
|
||||
<command>fetchbower</command>. If possible, try reformulating
|
||||
the version specification in <filename>bower.json</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
@@ -5,29 +5,27 @@
|
||||
<title>Go</title>
|
||||
|
||||
<para>The function <varname>buildGoPackage</varname> builds
|
||||
standard Go programs.
|
||||
standard Go packages.
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-buildGoPackage'><title>buildGoPackage</title>
|
||||
<programlisting>
|
||||
deis = buildGoPackage rec {
|
||||
name = "deis-${version}";
|
||||
version = "1.13.0";
|
||||
|
||||
goPackagePath = "github.com/deis/deis"; <co xml:id='ex-buildGoPackage-1' />
|
||||
subPackages = [ "client" ]; <co xml:id='ex-buildGoPackage-2' />
|
||||
|
||||
net = buildGoPackage rec {
|
||||
name = "go.net-${rev}";
|
||||
goPackagePath = "golang.org/x/net"; <co xml:id='ex-buildGoPackage-1' />
|
||||
subPackages = [ "ipv4" "ipv6" ]; <co xml:id='ex-buildGoPackage-2' />
|
||||
rev = "e0403b4e005";
|
||||
src = fetchFromGitHub {
|
||||
owner = "deis";
|
||||
repo = "deis";
|
||||
rev = "v${version}";
|
||||
sha256 = "1qv9lxqx7m18029lj8cw3k7jngvxs4iciwrypdy0gd2nnghc68sw";
|
||||
inherit rev;
|
||||
owner = "golang";
|
||||
repo = "net";
|
||||
sha256 = "1g7cjzw4g4301a3yqpbk8n1d4s97sfby2aysl275x04g0zh8jxqp";
|
||||
};
|
||||
|
||||
goDeps = ./deps.nix; <co xml:id='ex-buildGoPackage-3' />
|
||||
|
||||
buildFlags = "--tags release"; <co xml:id='ex-buildGoPackage-4' />
|
||||
}
|
||||
goPackageAliases = [ "code.google.com/p/go.net" ]; <co xml:id='ex-buildGoPackage-3' />
|
||||
propagatedBuildInputs = [ goPackages.text ]; <co xml:id='ex-buildGoPackage-4' />
|
||||
buildFlags = "--tags release"; <co xml:id='ex-buildGoPackage-5' />
|
||||
disabled = isGo13;<co xml:id='ex-buildGoPackage-6' />
|
||||
};
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
@@ -49,80 +47,50 @@ the following arguments are of special significance to the function:
|
||||
packages will be built.
|
||||
</para>
|
||||
<para>
|
||||
In this example only <literal>github.com/deis/deis/client</literal> will be built.
|
||||
In this example only <literal>code.google.com/p/go.net/ipv4</literal> and
|
||||
<literal>code.google.com/p/go.net/ipv6</literal> will be built.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-buildGoPackage-3'>
|
||||
<para>
|
||||
<varname>goDeps</varname> is where the Go dependencies of a Go program are listed
|
||||
as a list of package source identified by Go import path.
|
||||
It could be imported as a separate <varname>deps.nix</varname> file for
|
||||
readability. The dependency data structure is described below.
|
||||
<varname>goPackageAliases</varname> is a list of alternative import paths
|
||||
that are valid for this library.
|
||||
Packages that depend on this library will automatically rename
|
||||
import paths that match any of the aliases to <literal>goPackagePath</literal>.
|
||||
</para>
|
||||
<para>
|
||||
In this example imports will be renamed from
|
||||
<literal>code.google.com/p/go.net</literal> to
|
||||
<literal>golang.org/x/net</literal> in every package that depend on the
|
||||
<literal>go.net</literal> library.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-buildGoPackage-4'>
|
||||
<para>
|
||||
<varname>propagatedBuildInputs</varname> is where the dependencies of a Go library are
|
||||
listed. Only libraries should list <varname>propagatedBuildInputs</varname>. If a standalone
|
||||
program is being built instead, use <varname>buildInputs</varname>. If a library's tests require
|
||||
additional dependencies that are not propagated, they should be listed in <varname>buildInputs</varname>.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-buildGoPackage-5'>
|
||||
<para>
|
||||
<varname>buildFlags</varname> is a list of flags passed to the go build command.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
</calloutlist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>The <varname>goDeps</varname> attribute can be imported from a separate
|
||||
<varname>nix</varname> file that defines which Go libraries are needed and should
|
||||
be included in <varname>GOPATH</varname> for <varname>buildPhase</varname>.
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-goDeps'><title>deps.nix</title>
|
||||
<programlisting>
|
||||
[ <co xml:id='ex-goDeps-1' />
|
||||
{
|
||||
goPackagePath = "gopkg.in/yaml.v2"; <co xml:id='ex-goDeps-2' />
|
||||
fetch = {
|
||||
type = "git"; <co xml:id='ex-goDeps-3' />
|
||||
url = "https://gopkg.in/yaml.v2";
|
||||
rev = "a83829b6f1293c91addabc89d0571c246397bbf4";
|
||||
sha256 = "1m4dsmk90sbi17571h6pld44zxz7jc4lrnl4f27dpd1l8g5xvjhh";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/docopt/docopt-go";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/docopt/docopt-go";
|
||||
rev = "784ddc588536785e7299f7272f39101f7faccc3f";
|
||||
sha256 = "0wwz48jl9fvl1iknvn9dqr4gfy1qs03gxaikrxxp9gry6773v3sj";
|
||||
};
|
||||
}
|
||||
]
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
|
||||
<calloutlist>
|
||||
|
||||
<callout arearefs='ex-goDeps-1'>
|
||||
<callout arearefs='ex-buildGoPackage-6'>
|
||||
<para>
|
||||
<varname>goDeps</varname> is a list of Go dependencies.
|
||||
If <varname>disabled</varname> is <literal>true</literal>,
|
||||
nix will refuse to build this package.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-goDeps-2'>
|
||||
<para>
|
||||
<varname>goPackagePath</varname> specifies Go package import path.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='ex-goDeps-3'>
|
||||
<para>
|
||||
<varname>fetch type</varname> that needs to be used to get package source. If <varname>git</varname>
|
||||
is used there should be <varname>url</varname>, <varname>rev</varname> and <varname>sha256</varname>
|
||||
defined next to it.
|
||||
In this example the package will not be built for go 1.3. The <literal>isGo13</literal>
|
||||
is an utility function that returns <literal>true</literal> if go used to build the
|
||||
package has version 1.3.x.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
@@ -131,21 +99,12 @@ the following arguments are of special significance to the function:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<varname>buildGoPackage</varname> produces <xref linkend='chap-multiple-output' xrefstyle="select: title" />
|
||||
where <varname>bin</varname> includes program binaries. You can test build a Go binary as follows:
|
||||
Reusable Go libraries may be found in the <varname>goPackages</varname> set. You can test
|
||||
build a Go package as follows:
|
||||
|
||||
<screen>
|
||||
$ nix-build -A deis.bin
|
||||
</screen>
|
||||
|
||||
or build all outputs with:
|
||||
|
||||
<screen>
|
||||
$ nix-build -A deis.all
|
||||
</screen>
|
||||
|
||||
<varname>bin</varname> output will be installed by default with <varname>nix-env -i</varname>
|
||||
or <varname>systemPackages</varname>.
|
||||
<screen>
|
||||
$ nix-build -A goPackages.net
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
@@ -160,7 +119,6 @@ done
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>To extract dependency information from a Go package in automated way use <link xlink:href="https://github.com/kamilchm/go2nix">go2nix</link>.
|
||||
It can produce complete derivation and <varname>goDeps</varname> file for Go programs.</para>
|
||||
<para>To extract dependency information from a Go package in automated way use <link xlink:href="https://github.com/cstrahan/go2nix">go2nix</link>.</para>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,825 +0,0 @@
|
||||
---
|
||||
title: User's Guide for Haskell in Nixpkgs
|
||||
author: Peter Simons
|
||||
date: 2015-06-01
|
||||
---
|
||||
# User's Guide to the Haskell Infrastructure
|
||||
|
||||
|
||||
## How to install Haskell packages
|
||||
|
||||
Nixpkgs distributes build instructions for all Haskell packages registered on
|
||||
[Hackage](http://hackage.haskell.org/), but strangely enough normal Nix package
|
||||
lookups don't seem to discover any of them, except for the default version of ghc, cabal-install, and stack:
|
||||
|
||||
$ nix-env -i alex
|
||||
error: selector ‘alex’ matches no derivations
|
||||
$ nix-env -qa ghc
|
||||
ghc-7.10.2
|
||||
|
||||
The Haskell package set is not registered in the top-level namespace because it
|
||||
is *huge*. If all Haskell packages were visible to these commands, then
|
||||
name-based search/install operations would be much slower than they are now. We
|
||||
avoided that by keeping all Haskell-related packages in a separate attribute
|
||||
set called `haskellPackages`, which the following command will list:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskellPackages
|
||||
haskellPackages.a50 a50-0.5
|
||||
haskellPackages.abacate haskell-abacate-0.0.0.0
|
||||
haskellPackages.abcBridge haskell-abcBridge-0.12
|
||||
haskellPackages.afv afv-0.1.1
|
||||
haskellPackages.alex alex-3.1.4
|
||||
haskellPackages.Allure Allure-0.4.101.1
|
||||
haskellPackages.alms alms-0.6.7
|
||||
[... some 8000 entries omitted ...]
|
||||
|
||||
To install any of those packages into your profile, refer to them by their
|
||||
attribute path (first column):
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -iA haskellPackages.Allure ...
|
||||
|
||||
The attribute path of any Haskell packages corresponds to the name of that
|
||||
particular package on Hackage: the package `cabal-install` has the attribute
|
||||
`haskellPackages.cabal-install`, and so on. (Actually, this convention causes
|
||||
trouble with packages like `3dmodels` and `4Blocks`, because these names are
|
||||
invalid identifiers in the Nix language. The issue of how to deal with these
|
||||
rare corner cases is currently unresolved.)
|
||||
|
||||
Haskell packages who's Nix name (second column) begins with a `haskell-` prefix
|
||||
are packages that provide a library whereas packages without that prefix
|
||||
provide just executables. Libraries may provide executables too, though: the
|
||||
package `haskell-pandoc`, for example, installs both a library and an
|
||||
application. You can install and use Haskell executables just like any other
|
||||
program in Nixpkgs, but using Haskell libraries for development is a bit
|
||||
trickier and we'll address that subject in great detail in section [How to
|
||||
create a development environment].
|
||||
|
||||
Attribute paths are deterministic inside of Nixpkgs, but the path necessary to
|
||||
reach Nixpkgs varies from system to system. We dodged that problem by giving
|
||||
`nix-env` an explicit `-f "<nixpkgs>"` parameter, but if you call `nix-env`
|
||||
without that flag, then chances are the invocation fails:
|
||||
|
||||
$ nix-env -iA haskellPackages.cabal-install
|
||||
error: attribute ‘haskellPackages’ in selection path
|
||||
‘haskellPackages.cabal-install’ not found
|
||||
|
||||
On NixOS, for example, Nixpkgs does *not* exist in the top-level namespace by
|
||||
default. To figure out the proper attribute path, it's easiest to query for the
|
||||
path of a well-known Nixpkgs package, i.e.:
|
||||
|
||||
$ nix-env -qaP coreutils
|
||||
nixos.coreutils coreutils-8.23
|
||||
|
||||
If your system responds like that (most NixOS installations will), then the
|
||||
attribute path to `haskellPackages` is `nixos.haskellPackages`. Thus, if you
|
||||
want to use `nix-env` without giving an explicit `-f` flag, then that's the way
|
||||
to do it:
|
||||
|
||||
$ nix-env -qaP -A nixos.haskellPackages
|
||||
$ nix-env -iA nixos.haskellPackages.cabal-install
|
||||
|
||||
Our current default compiler is GHC 7.10.x and the `haskellPackages` set
|
||||
contains packages built with that particular version. Nixpkgs contains the
|
||||
latest major release of every GHC since 6.10.4, however, and there is a whole
|
||||
family of package sets available that defines Hackage packages built with each
|
||||
of those compilers, too:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc6123
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc763
|
||||
|
||||
The name `haskellPackages` is really just a synonym for
|
||||
`haskell.packages.ghc7102`, because we prefer that package set internally and
|
||||
recommend it to our users as their default choice, but ultimately you are free
|
||||
to compile your Haskell packages with any GHC version you please. The following
|
||||
command displays the complete list of available compilers:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler
|
||||
haskell.compiler.ghc6104 ghc-6.10.4
|
||||
haskell.compiler.ghc6123 ghc-6.12.3
|
||||
haskell.compiler.ghc704 ghc-7.0.4
|
||||
haskell.compiler.ghc722 ghc-7.2.2
|
||||
haskell.compiler.ghc742 ghc-7.4.2
|
||||
haskell.compiler.ghc763 ghc-7.6.3
|
||||
haskell.compiler.ghc784 ghc-7.8.4
|
||||
haskell.compiler.ghc7102 ghc-7.10.2
|
||||
haskell.compiler.ghcHEAD ghc-7.11.20150402
|
||||
haskell.compiler.ghcNokinds ghc-nokinds-7.11.20150704
|
||||
haskell.compiler.ghcjs ghcjs-0.1.0
|
||||
haskell.compiler.jhc jhc-0.8.2
|
||||
haskell.compiler.uhc uhc-1.1.9.0
|
||||
|
||||
We have no package sets for `jhc` or `uhc` yet, unfortunately, but for every
|
||||
version of GHC listed above, there exists a package set based on that compiler.
|
||||
Also, the attributes `haskell.compiler.ghcXYC` and
|
||||
`haskell.packages.ghcXYC.ghc` are synonymous for the sake of convenience.
|
||||
|
||||
## How to create a development environment
|
||||
|
||||
### How to install a compiler
|
||||
|
||||
A simple development environment consists of a Haskell compiler and one or both
|
||||
of the tools `cabal-install` and `stack`. We saw in section
|
||||
[How to install Haskell packages] how you can install those programs into your
|
||||
user profile:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -iA haskellPackages.ghc haskellPackages.cabal-install
|
||||
|
||||
Instead of the default package set `haskellPackages`, you can also use the more
|
||||
precise name `haskell.compiler.ghc7102`, which has the advantage that it refers
|
||||
to the same GHC version regardless of what Nixpkgs considers "default" at any
|
||||
given time.
|
||||
|
||||
Once you've made those tools available in `$PATH`, it's possible to build
|
||||
Hackage packages the same way people without access to Nix do it all the time:
|
||||
|
||||
$ cabal get lens-4.11 && cd lens-4.11
|
||||
$ cabal install -j --dependencies-only
|
||||
$ cabal configure
|
||||
$ cabal build
|
||||
|
||||
If you enjoy working with Cabal sandboxes, then that's entirely possible too:
|
||||
just execute the command
|
||||
|
||||
$ cabal sandbox init
|
||||
|
||||
before installing the required dependencies.
|
||||
|
||||
The `nix-shell` utility makes it easy to switch to a different compiler
|
||||
version; just enter the Nix shell environment with the command
|
||||
|
||||
$ nix-shell -p haskell.compiler.ghc784
|
||||
|
||||
to bring GHC 7.8.4 into `$PATH`. Alternatively, you can use Stack instead of
|
||||
`nix-shell` directly to select compiler versions and other build tools
|
||||
per-project. It uses `nix-shell` under the hood when Nix support is turned on.
|
||||
See [How to build a Haskell project using Stack].
|
||||
|
||||
If you're using `cabal-install`, re-running `cabal configure` inside the spawned
|
||||
shell switches your build to use that compiler instead. If you're working on
|
||||
a project that doesn't depend on any additional system libraries outside of GHC,
|
||||
then it's even sufficient to just run the `cabal configure` command inside of
|
||||
the shell:
|
||||
|
||||
$ nix-shell -p haskell.compiler.ghc784 --command "cabal configure"
|
||||
|
||||
Afterwards, all other commands like `cabal build` work just fine in any shell
|
||||
environment, because the configure phase recorded the absolute paths to all
|
||||
required tools like GHC in its build configuration inside of the `dist/`
|
||||
directory. Please note, however, that `nix-collect-garbage` can break such an
|
||||
environment because the Nix store paths created by `nix-shell` aren't "alive"
|
||||
anymore once `nix-shell` has terminated. If you find that your Haskell builds
|
||||
no longer work after garbage collection, then you'll have to re-run `cabal
|
||||
configure` inside of a new `nix-shell` environment.
|
||||
|
||||
### How to install a compiler with libraries
|
||||
|
||||
GHC expects to find all installed libraries inside of its own `lib` directory.
|
||||
This approach works fine on traditional Unix systems, but it doesn't work for
|
||||
Nix, because GHC's store path is immutable once it's built. We cannot install
|
||||
additional libraries into that location. As a consequence, our copies of GHC
|
||||
don't know any packages except their own core libraries, like `base`,
|
||||
`containers`, `Cabal`, etc.
|
||||
|
||||
We can register additional libraries to GHC, however, using a special build
|
||||
function called `ghcWithPackages`. That function expects one argument: a
|
||||
function that maps from an attribute set of Haskell packages to a list of
|
||||
packages, which determines the libraries known to that particular version of
|
||||
GHC. For example, the Nix expression `ghcWithPackages (pkgs: [pkgs.mtl])`
|
||||
generates a copy of GHC that has the `mtl` library registered in addition to
|
||||
its normal core packages:
|
||||
|
||||
$ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"
|
||||
|
||||
[nix-shell:~]$ ghc-pkg list mtl
|
||||
/nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d:
|
||||
mtl-2.2.1
|
||||
|
||||
This function allows users to define their own development environment by means
|
||||
of an override. After adding the following snippet to `~/.nixpkgs/config.nix`,
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
|
||||
(haskellPackages: with haskellPackages; [
|
||||
# libraries
|
||||
arrows async cgi criterion
|
||||
# tools
|
||||
cabal-install haskintex
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
it's possible to install that compiler with `nix-env -f "<nixpkgs>" -iA
|
||||
myHaskellEnv`. If you'd like to switch that development environment to a
|
||||
different version of GHC, just replace the `ghc7102` bit in the previous
|
||||
definition with the appropriate name. Of course, it's also possible to define
|
||||
any number of these development environments! (You can't install two of them
|
||||
into the same profile at the same time, though, because that would result in
|
||||
file conflicts.)
|
||||
|
||||
The generated `ghc` program is a wrapper script that re-directs the real
|
||||
GHC executable to use a new `lib` directory --- one that we specifically
|
||||
constructed to contain all those packages the user requested:
|
||||
|
||||
$ cat $(type -p ghc)
|
||||
#! /nix/store/xlxj...-bash-4.3-p33/bin/bash -e
|
||||
export NIX_GHC=/nix/store/19sm...-ghc-7.10.2/bin/ghc
|
||||
export NIX_GHCPKG=/nix/store/19sm...-ghc-7.10.2/bin/ghc-pkg
|
||||
export NIX_GHC_DOCDIR=/nix/store/19sm...-ghc-7.10.2/share/doc/ghc/html
|
||||
export NIX_GHC_LIBDIR=/nix/store/19sm...-ghc-7.10.2/lib/ghc-7.10.2
|
||||
exec /nix/store/j50p...-ghc-7.10.2/bin/ghc "-B$NIX_GHC_LIBDIR" "$@"
|
||||
|
||||
The variables `$NIX_GHC`, `$NIX_GHCPKG`, etc. point to the *new* store path
|
||||
`ghcWithPackages` constructed specifically for this environment. The last line
|
||||
of the wrapper script then executes the real `ghc`, but passes the path to the
|
||||
new `lib` directory using GHC's `-B` flag.
|
||||
|
||||
The purpose of those environment variables is to work around an impurity in the
|
||||
popular [ghc-paths](http://hackage.haskell.org/package/ghc-paths) library. That
|
||||
library promises to give its users access to GHC's installation paths. Only,
|
||||
the library can't possible know that path when it's compiled, because the path
|
||||
GHC considers its own is determined only much later, when the user configures
|
||||
it through `ghcWithPackages`. So we [patched
|
||||
ghc-paths](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/patches/ghc-paths-nix.patch)
|
||||
to return the paths found in those environment variables at run-time rather
|
||||
than trying to guess them at compile-time.
|
||||
|
||||
To make sure that mechanism works properly all the time, we recommend that you
|
||||
set those variables to meaningful values in your shell environment, too, i.e.
|
||||
by adding the following code to your `~/.bashrc`:
|
||||
|
||||
if type >/dev/null 2>&1 -p ghc; then
|
||||
eval "$(egrep ^export "$(type -p ghc)")"
|
||||
fi
|
||||
|
||||
If you are certain that you'll use only one GHC environment which is located in
|
||||
your user profile, then you can use the following code, too, which has the
|
||||
advantage that it doesn't contain any paths from the Nix store, i.e. those
|
||||
settings always remain valid even if a `nix-env -u` operation updates the GHC
|
||||
environment in your profile:
|
||||
|
||||
if [ -e ~/.nix-profile/bin/ghc ]; then
|
||||
export NIX_GHC="$HOME/.nix-profile/bin/ghc"
|
||||
export NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg"
|
||||
export NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html"
|
||||
export NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$($NIX_GHC --numeric-version)"
|
||||
fi
|
||||
|
||||
### How to install a compiler with libraries, hoogle and documentation indexes
|
||||
|
||||
If you plan to use your environment for interactive programming, not just
|
||||
compiling random Haskell code, you might want to replace `ghcWithPackages` in
|
||||
all the listings above with `ghcWithHoogle`.
|
||||
|
||||
This environment generator not only produces an environment with GHC and all
|
||||
the specified libraries, but also generates a `hoogle` and `haddock` indexes
|
||||
for all the packages, and provides a wrapper script around `hoogle` binary that
|
||||
uses all those things. A precise name for this thing would be
|
||||
"`ghcWithPackagesAndHoogleAndDocumentationIndexes`", which is, regrettably, too
|
||||
long and scary.
|
||||
|
||||
For example, installing the following environment
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
myHaskellEnv = self.haskellPackages.ghcWithHoogle
|
||||
(haskellPackages: with haskellPackages; [
|
||||
# libraries
|
||||
arrows async cgi criterion
|
||||
# tools
|
||||
cabal-install haskintex
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
allows one to browse module documentation index [not too dissimilar to
|
||||
this](https://downloads.haskell.org/~ghc/latest/docs/html/libraries/index.html)
|
||||
for all the specified packages and their dependencies by directing a browser of
|
||||
choice to `~/.nix-profiles/share/doc/hoogle/index.html` (or
|
||||
`/run/current-system/sw/share/doc/hoogle/index.html` in case you put it in
|
||||
`environment.systemPackages` in NixOS).
|
||||
|
||||
After you've marveled enough at that try adding the following to your
|
||||
`~/.ghc/ghci.conf`
|
||||
|
||||
:def hoogle \s -> return $ ":! hoogle search -cl --count=15 \"" ++ s ++ "\""
|
||||
:def doc \s -> return $ ":! hoogle search -cl --info \"" ++ s ++ "\""
|
||||
|
||||
and test it by typing into `ghci`:
|
||||
|
||||
:hoogle a -> a
|
||||
:doc a -> a
|
||||
|
||||
Be sure to note the links to `haddock` files in the output. With any modern and
|
||||
properly configured terminal emulator you can just click those links to
|
||||
navigate there.
|
||||
|
||||
Finally, you can run
|
||||
|
||||
hoogle server -p 8080
|
||||
|
||||
and navigate to http://localhost:8080/ for your own local
|
||||
[Hoogle](https://www.haskell.org/hoogle/). Note, however, that Firefox and
|
||||
possibly other browsers disallow navigation from `http:` to `file:` URIs for
|
||||
security reasons, which might be quite an inconvenience. See [this
|
||||
page](http://kb.mozillazine.org/Links_to_local_pages_do_not_work) for
|
||||
workarounds.
|
||||
|
||||
### How to build a Haskell project using Stack
|
||||
|
||||
[Stack](http://haskellstack.org) is a popular build tool for Haskell projects.
|
||||
It has first-class support for Nix. Stack can optionally use Nix to
|
||||
automatically select the right version of GHC and other build tools to build,
|
||||
test and execute apps in an existing project downloaded from somewhere on the
|
||||
Internet. Pass the `--nix` flag to any `stack` command to do so, e.g.
|
||||
|
||||
$ git clone --recursive http://github.com/yesodweb/wai
|
||||
$ cd wai
|
||||
$ stack --nix build
|
||||
|
||||
If you want `stack` to use Nix by default, you can add a `nix` section to the
|
||||
`stack.yaml` file, as explained in the [Stack documentation][stack-nix-doc]. For
|
||||
example:
|
||||
|
||||
nix:
|
||||
enable: true
|
||||
packages: [pkgconfig zeromq zlib]
|
||||
|
||||
The example configuration snippet above tells Stack to create an ad hoc
|
||||
environment for `nix-shell` as in the below section, in which the `pkgconfig`,
|
||||
`zeromq` and `zlib` packages from Nixpkgs are available. All `stack` commands
|
||||
will implicitly be executed inside this ad hoc environment.
|
||||
|
||||
Some projects have more sophisticated needs. For examples, some ad hoc
|
||||
environments might need to expose Nixpkgs packages compiled in a certain way, or
|
||||
with extra environment variables. In these cases, you'll need a `shell` field
|
||||
instead of `packages`:
|
||||
|
||||
nix:
|
||||
enable: true
|
||||
shell-file: shell.nix
|
||||
|
||||
For more on how to write a `shell.nix` file see the below section. You'll need
|
||||
to express a derivation. Note that Nixpkgs ships with a convenience wrapper
|
||||
function around `mkDerivation` called `haskell.lib.buildStackProject` to help you
|
||||
create this derivation in exactly the way Stack expects. All of the same inputs
|
||||
as `mkDerivation` can be provided. For example, to build a Stack project that
|
||||
including packages that link against a version of the R library compiled with
|
||||
special options turned on:
|
||||
|
||||
with (import <nixpkgs> { });
|
||||
|
||||
let R = pkgs.R.override { enableStrictBarrier = true; };
|
||||
in
|
||||
haskell.lib.buildStackProject {
|
||||
name = "HaskellR";
|
||||
buildInputs = [ R zeromq zlib ];
|
||||
}
|
||||
|
||||
You can select a particular GHC version to compile with by setting the
|
||||
`ghc` attribute as an argument to `buildStackProject`. Better yet, let
|
||||
Stack choose what GHC version it wants based on the snapshot specified
|
||||
in `stack.yaml` (only works with Stack >= 1.1.3):
|
||||
|
||||
{nixpkgs ? import <nixpkgs> { }, ghc ? nixpkgs.ghc}
|
||||
|
||||
with nixpkgs;
|
||||
|
||||
let R = pkgs.R.override { enableStrictBarrier = true; };
|
||||
in
|
||||
haskell.lib.buildStackProject {
|
||||
name = "HaskellR";
|
||||
buildInputs = [ R zeromq zlib ];
|
||||
inherit ghc;
|
||||
}
|
||||
|
||||
[stack-nix-doc]: http://docs.haskellstack.org/en/stable/nix_integration.html
|
||||
|
||||
### How to create ad hoc environments for `nix-shell`
|
||||
|
||||
The easiest way to create an ad hoc development environment is to run
|
||||
`nix-shell` with the appropriate GHC environment given on the command-line:
|
||||
|
||||
nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [mtl pandoc])"
|
||||
|
||||
For more sophisticated use-cases, however, it's more convenient to save the
|
||||
desired configuration in a file called `shell.nix` that looks like this:
|
||||
|
||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||
let
|
||||
inherit (nixpkgs) pkgs;
|
||||
ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
|
||||
monad-par mtl
|
||||
]);
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "my-haskell-env-0";
|
||||
buildInputs = [ ghc ];
|
||||
shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)";
|
||||
}
|
||||
|
||||
Now run `nix-shell` --- or even `nix-shell --pure` --- to enter a shell
|
||||
environment that has the appropriate compiler in `$PATH`. If you use `--pure`,
|
||||
then add all other packages that your development environment needs into the
|
||||
`buildInputs` attribute. If you'd like to switch to a different compiler
|
||||
version, then pass an appropriate `compiler` argument to the expression, i.e.
|
||||
`nix-shell --argstr compiler ghc784`.
|
||||
|
||||
If you need such an environment because you'd like to compile a Hackage package
|
||||
outside of Nix --- i.e. because you're hacking on the latest version from Git
|
||||
---, then the package set provides suitable nix-shell environments for you
|
||||
already! Every Haskell package has an `env` attribute that provides a shell
|
||||
environment suitable for compiling that particular package. If you'd like to
|
||||
hack the `lens` library, for example, then you just have to check out the
|
||||
source code and enter the appropriate environment:
|
||||
|
||||
$ cabal get lens-4.11 && cd lens-4.11
|
||||
Downloading lens-4.11...
|
||||
Unpacking to lens-4.11/
|
||||
|
||||
$ nix-shell "<nixpkgs>" -A haskellPackages.lens.env
|
||||
[nix-shell:/tmp/lens-4.11]$
|
||||
|
||||
At point, you can run `cabal configure`, `cabal build`, and all the other
|
||||
development commands. Note that you need `cabal-install` installed in your
|
||||
`$PATH` already to use it here --- the `nix-shell` environment does not provide
|
||||
it.
|
||||
|
||||
## How to create Nix builds for your own private Haskell packages
|
||||
|
||||
If your own Haskell packages have build instructions for Cabal, then you can
|
||||
convert those automatically into build instructions for Nix using the
|
||||
`cabal2nix` utility, which you can install into your profile by running
|
||||
`nix-env -i cabal2nix`.
|
||||
|
||||
### How to build a stand-alone project
|
||||
|
||||
For example, let's assume that you're working on a private project called
|
||||
`foo`. To generate a Nix build expression for it, change into the project's
|
||||
top-level directory and run the command:
|
||||
|
||||
$ cabal2nix . >foo.nix
|
||||
|
||||
Then write the following snippet into a file called `default.nix`:
|
||||
|
||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||
nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./foo.nix { }
|
||||
|
||||
Finally, store the following code in a file called `shell.nix`:
|
||||
|
||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||
(import ./default.nix { inherit nixpkgs compiler; }).env
|
||||
|
||||
At this point, you can run `nix-build` to have Nix compile your project and
|
||||
install it into a Nix store path. The local directory will contain a symlink
|
||||
called `result` after `nix-build` returns that points into that location. Of
|
||||
course, passing the flag `--argstr compiler ghc763` allows switching the build
|
||||
to any version of GHC currently supported.
|
||||
|
||||
Furthermore, you can call `nix-shell` to enter an interactive development
|
||||
environment in which you can use `cabal configure` and `cabal build` to develop
|
||||
your code. That environment will automatically contain a proper GHC derivation
|
||||
with all the required libraries registered as well as all the system-level
|
||||
libraries your package might need.
|
||||
|
||||
If your package does not depend on any system-level libraries, then it's
|
||||
sufficient to run
|
||||
|
||||
$ nix-shell --command "cabal configure"
|
||||
|
||||
once to set up your build. `cabal-install` determines the absolute paths to all
|
||||
resources required for the build and writes them into a config file in the
|
||||
`dist/` directory. Once that's done, you can run `cabal build` and any other
|
||||
command for that project even outside of the `nix-shell` environment. This
|
||||
feature is particularly nice for those of us who like to edit their code with
|
||||
an IDE, like Emacs' `haskell-mode`, because it's not necessary to start Emacs
|
||||
inside of nix-shell just to make it find out the necessary settings for
|
||||
building the project; `cabal-install` has already done that for us.
|
||||
|
||||
If you want to do some quick-and-dirty hacking and don't want to bother setting
|
||||
up a `default.nix` and `shell.nix` file manually, then you can use the
|
||||
`--shell` flag offered by `cabal2nix` to have it generate a stand-alone
|
||||
`nix-shell` environment for you. With that feature, running
|
||||
|
||||
$ cabal2nix --shell . >shell.nix
|
||||
$ nix-shell --command "cabal configure"
|
||||
|
||||
is usually enough to set up a build environment for any given Haskell package.
|
||||
You can even use that generated file to run `nix-build`, too:
|
||||
|
||||
$ nix-build shell.nix
|
||||
|
||||
### How to build projects that depend on each other
|
||||
|
||||
If you have multiple private Haskell packages that depend on each other, then
|
||||
you'll have to register those packages in the Nixpkgs set to make them visible
|
||||
for the dependency resolution performed by `callPackage`. First of all, change
|
||||
into each of your projects top-level directories and generate a `default.nix`
|
||||
file with `cabal2nix`:
|
||||
|
||||
$ cd ~/src/foo && cabal2nix . >default.nix
|
||||
$ cd ~/src/bar && cabal2nix . >default.nix
|
||||
|
||||
Then edit your `~/.nixpkgs/config.nix` file to register those builds in the
|
||||
default Haskell package set:
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
haskellPackages = super.haskellPackages.override {
|
||||
overrides = self: super: {
|
||||
foo = self.callPackage ../src/foo {};
|
||||
bar = self.callPackage ../src/bar {};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Once that's accomplished, `nix-env -f "<nixpkgs>" -qA haskellPackages` will
|
||||
show your packages like any other package from Hackage, and you can build them
|
||||
|
||||
$ nix-build "<nixpkgs>" -A haskellPackages.foo
|
||||
|
||||
or enter an interactive shell environment suitable for building them:
|
||||
|
||||
$ nix-shell "<nixpkgs>" -A haskellPackages.bar.env
|
||||
|
||||
## Miscellaneous Topics
|
||||
|
||||
### How to build with profiling enabled
|
||||
|
||||
Every Haskell package set takes a function called `overrides` that you can use
|
||||
to manipulate the package as much as you please. One useful application of this
|
||||
feature is to replace the default `mkDerivation` function with one that enables
|
||||
library profiling for all packages. To accomplish that, add configure the
|
||||
following snippet in your `~/.nixpkgs/config.nix` file:
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
profiledHaskellPackages = self.haskellPackages.override {
|
||||
overrides = self: super: {
|
||||
mkDerivation = args: super.mkDerivation (args // {
|
||||
enableLibraryProfiling = true;
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Then, replace instances of `haskellPackages` in the `cabal2nix`-generated
|
||||
`default.nix` or `shell.nix` files with `profiledHaskellPackages`.
|
||||
|
||||
### How to override package versions in a compiler-specific package set
|
||||
|
||||
Nixpkgs provides the latest version of
|
||||
[`ghc-events`](http://hackage.haskell.org/package/ghc-events), which is 0.4.4.0
|
||||
at the time of this writing. This is fine for users of GHC 7.10.x, but GHC
|
||||
7.8.4 cannot compile that binary. Now, one way to solve that problem is to
|
||||
register an older version of `ghc-events` in the 7.8.x-specific package set.
|
||||
The first step is to generate Nix build instructions with `cabal2nix`:
|
||||
|
||||
$ cabal2nix cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
|
||||
|
||||
Then add the override in `~/.nixpkgs/config.nix`:
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
{
|
||||
haskell = super.haskell // {
|
||||
packages = super.haskell.packages // {
|
||||
ghc784 = super.haskell.packages.ghc784.override {
|
||||
overrides = self: super: {
|
||||
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
This code is a little crazy, no doubt, but it's necessary because the intuitive
|
||||
version
|
||||
|
||||
haskell.packages.ghc784 = super.haskell.packages.ghc784.override {
|
||||
overrides = self: super: {
|
||||
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
|
||||
};
|
||||
};
|
||||
|
||||
doesn't do what we want it to: that code replaces the `haskell` package set in
|
||||
Nixpkgs with one that contains only one entry,`packages`, which contains only
|
||||
one entry `ghc784`. This override loses the `haskell.compiler` set, and it
|
||||
loses the `haskell.packages.ghcXYZ` sets for all compilers but GHC 7.8.4. To
|
||||
avoid that problem, we have to perform the convoluted little dance from above,
|
||||
iterating over each step in hierarchy.
|
||||
|
||||
Once it's accomplished, however, we can install a variant of `ghc-events`
|
||||
that's compiled with GHC 7.8.4:
|
||||
|
||||
nix-env -f "<nixpkgs>" -iA haskell.packages.ghc784.ghc-events
|
||||
|
||||
Unfortunately, it turns out that this build fails again while executing the
|
||||
test suite! Apparently, the release archive on Hackage is missing some data
|
||||
files that the test suite requires, so we cannot run it. We accomplish that by
|
||||
re-generating the Nix expression with the `--no-check` flag:
|
||||
|
||||
$ cabal2nix --no-check cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
|
||||
|
||||
Now the builds succeeds.
|
||||
|
||||
Of course, in the concrete example of `ghc-events` this whole exercise is not
|
||||
an ideal solution, because `ghc-events` can analyze the output emitted by any
|
||||
version of GHC later than 6.12 regardless of the compiler version that was used
|
||||
to build the `ghc-events' executable, so strictly speaking there's no reason to
|
||||
prefer one built with GHC 7.8.x in the first place. However, for users who
|
||||
cannot use GHC 7.10.x at all for some reason, the approach of downgrading to an
|
||||
older version might be useful.
|
||||
|
||||
### How to recover from GHC's infamous non-deterministic library ID bug
|
||||
|
||||
GHC and distributed build farms don't get along well:
|
||||
|
||||
https://ghc.haskell.org/trac/ghc/ticket/4012
|
||||
|
||||
When you see an error like this one
|
||||
|
||||
package foo-0.7.1.0 is broken due to missing package
|
||||
text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
|
||||
|
||||
then you have to download and re-install `foo` and all its dependents from
|
||||
scratch:
|
||||
|
||||
# nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \
|
||||
| xargs -L 1 nix-store --repair-path
|
||||
|
||||
If you're using additional Hydra servers other than `hydra.nixos.org`, then it
|
||||
might be necessary to purge the local caches that store data from those
|
||||
machines to disable these binary channels for the duration of the previous
|
||||
command, i.e. by running:
|
||||
|
||||
rm /nix/var/nix/binary-cache-v3.sqlite
|
||||
rm /nix/var/nix/manifests/*
|
||||
rm /nix/var/nix/channel-cache/*
|
||||
|
||||
### How to use the Haste Haskell-to-Javascript transpiler
|
||||
|
||||
Open a shell with `haste-compiler` and `haste-cabal-install` (you don't actually need
|
||||
`node`, but it can be useful to test stuff):
|
||||
|
||||
$ nix-shell -p "haskellPackages.ghcWithPackages (self: with self; [haste-cabal-install haste-compiler])" -p nodejs
|
||||
|
||||
You may not need the following step but if `haste-boot` fails to compile all the
|
||||
packages it needs, this might do the trick
|
||||
|
||||
$ haste-cabal update
|
||||
|
||||
`haste-boot` builds a set of core libraries so that they can be used from Javascript
|
||||
transpiled programs:
|
||||
|
||||
$ haste-boot
|
||||
|
||||
Transpile and run a "Hello world" program:
|
||||
|
||||
$ echo 'module Main where main = putStrLn "Hello world"' > hello-world.hs
|
||||
$ hastec --onexec hello-world.hs
|
||||
$ node hello-world.js
|
||||
Hello world
|
||||
|
||||
### Builds on Darwin fail with `math.h` not found
|
||||
|
||||
Users of GHC on Darwin have occasionally reported that builds fail, because the
|
||||
compiler complains about a missing include file:
|
||||
|
||||
fatal error: 'math.h' file not found
|
||||
|
||||
The issue has been discussed at length in [ticket
|
||||
6390](https://github.com/NixOS/nixpkgs/issues/6390), and so far no good
|
||||
solution has been proposed. As a work-around, users who run into this problem
|
||||
can configure the environment variables
|
||||
|
||||
export NIX_CFLAGS_COMPILE="-idirafter /usr/include"
|
||||
export NIX_CFLAGS_LINK="-L/usr/lib"
|
||||
|
||||
in their `~/.bashrc` file to avoid the compiler error.
|
||||
|
||||
### Builds using Stack complain about missing system libraries
|
||||
|
||||
-- While building package zlib-0.5.4.2 using:
|
||||
runhaskell -package=Cabal-1.22.4.0 -clear-package-db [... lots of flags ...]
|
||||
Process exited with code: ExitFailure 1
|
||||
Logs have been written to: /home/foo/src/stack-ide/.stack-work/logs/zlib-0.5.4.2.log
|
||||
|
||||
Configuring zlib-0.5.4.2...
|
||||
Setup.hs: Missing dependency on a foreign library:
|
||||
* Missing (or bad) header file: zlib.h
|
||||
This problem can usually be solved by installing the system package that
|
||||
provides this library (you may need the "-dev" version). If the library is
|
||||
already installed but in a non-standard location then you can use the flags
|
||||
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
|
||||
If the header file does exist, it may contain errors that are caught by the C
|
||||
compiler at the preprocessing stage. In this case you can re-run configure
|
||||
with the verbosity flag -v3 to see the error messages.
|
||||
|
||||
When you run the build inside of the nix-shell environment, the system
|
||||
is configured to find libz.so without any special flags -- the compiler
|
||||
and linker "just know" how to find it. Consequently, Cabal won't record
|
||||
any search paths for libz.so in the package description, which means
|
||||
that the package works fine inside of nix-shell, but once you leave the
|
||||
shell the shared object can no longer be found. That issue is by no
|
||||
means specific to Stack: you'll have that problem with any other
|
||||
Haskell package that's built inside of nix-shell but run outside of that
|
||||
environment.
|
||||
|
||||
You can remedy this issue in several ways. The easiest is to add a `nix` section
|
||||
to the `stack.yaml` like the following:
|
||||
|
||||
nix:
|
||||
enable: true
|
||||
packages: [ zlib ]
|
||||
|
||||
Stack's Nix support knows to add `${zlib.out}/lib` and `${zlib.dev}/include` as an
|
||||
`--extra-lib-dirs` and `extra-include-dirs`, respectively. Alternatively, you
|
||||
can achieve the same effect by hand. First of all, run
|
||||
|
||||
$ nix-build --no-out-link "<nixpkgs>" -A zlib
|
||||
/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8
|
||||
|
||||
to find out the store path of the system's zlib library. Now, you can
|
||||
|
||||
1) add that path (plus a "/lib" suffix) to your $LD_LIBRARY_PATH
|
||||
environment variable to make sure your system linker finds libz.so
|
||||
automatically. It's no pretty solution, but it will work.
|
||||
|
||||
2) As a variant of (1), you can also install any number of system
|
||||
libraries into your user's profile (or some other profile) and point
|
||||
$LD_LIBRARY_PATH to that profile instead, so that you don't have to
|
||||
list dozens of those store paths all over the place.
|
||||
|
||||
3) The solution I prefer is to call stack with an appropriate
|
||||
--extra-lib-dirs flag like so:
|
||||
|
||||
$ stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build
|
||||
|
||||
Typically, you'll need --extra-include-dirs as well. It's possible
|
||||
to add those flag to the project's "stack.yaml" or your user's
|
||||
global "~/.stack/global/stack.yaml" file so that you don't have to
|
||||
specify them manually every time. But again, you're likely better off using
|
||||
Stack's Nix support instead.
|
||||
|
||||
The same thing applies to `cabal configure`, of course, if you're
|
||||
building with `cabal-install` instead of Stack.
|
||||
|
||||
### Creating statically linked binaries
|
||||
|
||||
There are two levels of static linking. The first option is to configure the
|
||||
build with the Cabal flag `--disable-executable-dynamic`. In Nix expressions,
|
||||
this can be achieved by setting the attribute:
|
||||
|
||||
enableSharedExecutables = false;
|
||||
|
||||
That gives you a binary with statically linked Haskell libraries and
|
||||
dynamically linked system libraries.
|
||||
|
||||
To link both Haskell libraries and system libraries statically, the additional
|
||||
flags `--ghc-option=-optl=-static --ghc-option=-optl=-pthread` need to be used.
|
||||
In Nix, this is accomplished with:
|
||||
|
||||
configureFlags = [ "--ghc-option=-optl=-static" "--ghc-option=-optl=-pthread" ];
|
||||
|
||||
It's important to realize, however, that most system libraries in Nix are built
|
||||
as shared libraries only, i.e. there is just no static library available that
|
||||
Cabal could link!
|
||||
|
||||
|
||||
## Other resources
|
||||
|
||||
- The Youtube video [Nix Loves Haskell](https://www.youtube.com/watch?v=BsBhi_r-OeE)
|
||||
provides an introduction into Haskell NG aimed at beginners. The slides are
|
||||
available at http://cryp.to/nixos-meetup-3-slides.pdf and also -- in a form
|
||||
ready for cut & paste -- at
|
||||
https://github.com/NixOS/cabal2nix/blob/master/doc/nixos-meetup-3-slides.md.
|
||||
|
||||
- Another Youtube video is [Escaping Cabal Hell with Nix](https://www.youtube.com/watch?v=mQd3s57n_2Y),
|
||||
which discusses the subject of Haskell development with Nix but also provides
|
||||
a basic introduction to Nix as well, i.e. it's suitable for viewers with
|
||||
almost no prior Nix experience.
|
||||
|
||||
- Oliver Charles wrote a very nice [Tutorial how to develop Haskell packages with Nix](http://wiki.ocharles.org.uk/Nix).
|
||||
|
||||
- The *Journey into the Haskell NG infrastructure* series of postings
|
||||
describe the new Haskell infrastructure in great detail:
|
||||
|
||||
- [Part 1](http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015591.html)
|
||||
explains the differences between the old and the new code and gives
|
||||
instructions how to migrate to the new setup.
|
||||
|
||||
- [Part 2](http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015608.html)
|
||||
looks in-depth at how to tweak and configure your setup by means of
|
||||
overrides.
|
||||
|
||||
- [Part 3](http://lists.science.uu.nl/pipermail/nix-dev/2015-April/016912.html)
|
||||
describes the infrastructure that keeps the Haskell package set in Nixpkgs
|
||||
up-to-date.
|
||||
@@ -13,20 +13,33 @@ in Nixpkgs to easily build packages for other programming languages,
|
||||
such as Perl or Haskell. These are described in this chapter.</para>
|
||||
|
||||
|
||||
<xi:include href="beam.xml" />
|
||||
<xi:include href="bower.xml" />
|
||||
<xi:include href="coq.xml" />
|
||||
<xi:include href="go.xml" />
|
||||
<xi:include href="haskell.xml" />
|
||||
<xi:include href="idris.xml" /> <!-- generated from ../../pkgs/development/idris-modules/README.md -->
|
||||
<xi:include href="java.xml" />
|
||||
<xi:include href="lua.xml" />
|
||||
<xi:include href="perl.xml" />
|
||||
<xi:include href="python.xml" />
|
||||
<xi:include href="qt.xml" />
|
||||
<xi:include href="r.xml" /> <!-- generated from ../../pkgs/development/r-modules/README.md -->
|
||||
<xi:include href="ruby.xml" />
|
||||
<xi:include href="go.xml" />
|
||||
<xi:include href="java.xml" />
|
||||
<xi:include href="lua.xml" />
|
||||
<xi:include href="coq.xml" />
|
||||
<xi:include href="idris.xml" /> <!-- generated from ../../pkgs/development/idris-modules/README.md -->
|
||||
<xi:include href="r.xml" /> <!-- generated from ../../pkgs/development/r-modules/README.md -->
|
||||
<xi:include href="qt.xml" />
|
||||
<xi:include href="texlive.xml" />
|
||||
|
||||
|
||||
<!--
|
||||
<section><title>Haskell</title>
|
||||
|
||||
<para>TODO</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>TeX / LaTeX</title>
|
||||
|
||||
<para>* Special support for building TeX documents</para>
|
||||
|
||||
</section>
|
||||
-->
|
||||
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -1,831 +0,0 @@
|
||||
# Python
|
||||
|
||||
## User Guide
|
||||
|
||||
Several versions of Python are available on Nix as well as a high amount of
|
||||
packages. The default interpreter is CPython 2.7.
|
||||
|
||||
### Using Python
|
||||
|
||||
#### Installing Python and packages
|
||||
|
||||
It is important to make a distinction between Python packages that are
|
||||
used as libraries, and applications that are written in Python.
|
||||
|
||||
Applications on Nix are installed typically into your user
|
||||
profile imperatively using `nix-env -i`, and on NixOS declaratively by adding the
|
||||
package name to `environment.systemPackages` in `/etc/nixos/configuration.nix`.
|
||||
Dependencies such as libraries are automatically installed and should not be
|
||||
installed explicitly.
|
||||
|
||||
The same goes for Python applications and libraries. Python applications can be
|
||||
installed in your profile, but Python libraries you would like to use to develop
|
||||
cannot. If you do install libraries in your profile, then you will end up with
|
||||
import errors.
|
||||
|
||||
#### Python environments using `nix-shell`
|
||||
|
||||
The recommended method for creating Python environments for development is with
|
||||
`nix-shell`. Executing
|
||||
|
||||
```sh
|
||||
$ nix-shell -p python35Packages.numpy python35Packages.toolz
|
||||
```
|
||||
|
||||
opens a Nix shell which has available the requested packages and dependencies.
|
||||
Now you can launch the Python interpreter (which is itself a dependency)
|
||||
|
||||
```sh
|
||||
[nix-shell:~] python3
|
||||
```
|
||||
|
||||
If the packages were not available yet in the Nix store, Nix would download or
|
||||
build them automatically. A convenient option with `nix-shell` is the `--run`
|
||||
option, with which you can execute a command in the `nix-shell`. Let's say we
|
||||
want the above environment and directly run the Python interpreter
|
||||
|
||||
```sh
|
||||
$ nix-shell -p python35Packages.numpy python35Packages.toolz --run "python3"
|
||||
```
|
||||
|
||||
This way you can use the `--run` option also to directly run a script
|
||||
|
||||
```sh
|
||||
$ nix-shell -p python35Packages.numpy python35Packages.toolz --run "python3 myscript.py"
|
||||
```
|
||||
|
||||
In fact, for this specific use case there is a more convenient method. You can
|
||||
add a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) to your script
|
||||
specifying which dependencies Nix shell needs. With the following shebang, you
|
||||
can use `nix-shell myscript.py` and it will make available all dependencies and
|
||||
run the script in the `python3` shell.
|
||||
|
||||
```py
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i python3 -p python3Packages.numpy
|
||||
|
||||
import numpy
|
||||
|
||||
print(numpy.__version__)
|
||||
```
|
||||
|
||||
Likely you do not want to type your dependencies each and every time. What you
|
||||
can do is write a simple Nix expression which sets up an environment for you,
|
||||
requiring you only to type `nix-shell`. Say we want to have Python 3.5, `numpy`
|
||||
and `toolz`, like before, in an environment. With a `shell.nix` file
|
||||
containing
|
||||
|
||||
```nix
|
||||
with import <nixpkgs> {};
|
||||
|
||||
(pkgs.python35.withPackages (ps: [ps.numpy ps.toolz])).env
|
||||
```
|
||||
executing `nix-shell` gives you again a Nix shell from which you can run Python.
|
||||
|
||||
What's happening here?
|
||||
|
||||
1. We begin with importing the Nix Packages collections. `import <nixpkgs>` import the `<nixpkgs>` function, `{}` calls it and the `with` statement brings all attributes of `nixpkgs` in the local scope. Therefore we can now use `pkgs`.
|
||||
2. Then we create a Python 3.5 environment with the `withPackages` function.
|
||||
3. The `withPackages` function expects us to provide a function as an argument that takes the set of all python packages and returns a list of packages to include in the environment. Here, we select the packages `numpy` and `toolz` from the package set.
|
||||
4. And finally, for in interactive use we return the environment by using the `env` attribute.
|
||||
|
||||
### Developing with Python
|
||||
|
||||
|
||||
Now that you know how to get a working Python environment on Nix, it is time to go forward and start actually developing with Python.
|
||||
We will first have a look at how Python packages are packaged on Nix. Then, we will look how you can use development mode with your code.
|
||||
|
||||
#### Python packaging on Nix
|
||||
|
||||
On Nix all packages are built by functions. The main function in Nix for building Python packages is [`buildPythonPackage`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/generic/default.nix).
|
||||
Let's see how we would build the `toolz` package. According to [`python-packages.nix`](https://raw.githubusercontent.com/NixOS/nixpkgs/master/pkgs/top-level/python-packages.nix) `toolz` is build using
|
||||
|
||||
```nix
|
||||
toolz = buildPythonPackage rec{
|
||||
name = "toolz-${version}";
|
||||
version = "0.7.4";
|
||||
|
||||
src = pkgs.fetchurl{
|
||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
||||
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
||||
};
|
||||
|
||||
meta = {
|
||||
homepage = "http://github.com/pytoolz/toolz/";
|
||||
description = "List processing tools and functional utilities";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ fridh ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
What happens here? The function `buildPythonPackage` is called and as argument
|
||||
it accepts a set. In this case the set is a recursive set ([`rec`](http://nixos.org/nix/manual/#sec-constructs)).
|
||||
One of the arguments is the name of the package, which consists of a basename
|
||||
(generally following the name on PyPi) and a version. Another argument, `src`
|
||||
specifies the source, which in this case is fetched from an url. `fetchurl` not
|
||||
only downloads the target file, but also validates its hash. Furthermore, we
|
||||
specify some (optional) [meta information](http://nixos.org/nixpkgs/manual/#chap-meta).
|
||||
|
||||
The output of the function is a derivation, which is an attribute with the name
|
||||
`toolz` of the set `pythonPackages`. Actually, sets are created for all interpreter versions,
|
||||
so `python27Packages`, `python34Packages`, `python35Packages` and `pypyPackages`.
|
||||
|
||||
The above example works when you're directly working on
|
||||
`pkgs/top-level/python-packages.nix` in the Nixpkgs repository. Often though,
|
||||
you will want to test a Nix expression outside of the Nixpkgs tree. If you
|
||||
create a `shell.nix` file with the following contents
|
||||
|
||||
```nix
|
||||
with import <nixpkgs> {};
|
||||
|
||||
pkgs.python35Packages.buildPythonPackage rec {
|
||||
name = "toolz-${version}";
|
||||
version = "0.7.4";
|
||||
|
||||
src = pkgs.fetchurl{
|
||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
||||
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
||||
};
|
||||
|
||||
meta = {
|
||||
homepage = "http://github.com/pytoolz/toolz/";
|
||||
description = "List processing tools and functional utilities";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ fridh ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
and then execute `nix-shell` will result in an environment in which you can use
|
||||
Python 3.5 and the `toolz` package. As you can see we had to explicitly mention
|
||||
for which Python version we want to build a package.
|
||||
|
||||
The above example considered only a single package. Generally you will want to use multiple packages.
|
||||
If we create a `shell.nix` file with the following contents
|
||||
|
||||
```nix
|
||||
with import <nixpkgs> {};
|
||||
|
||||
( let
|
||||
toolz = pkgs.python35Packages.buildPythonPackage rec {
|
||||
name = "toolz-${version}";
|
||||
version = "0.7.4";
|
||||
|
||||
src = pkgs.fetchurl{
|
||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
||||
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
||||
};
|
||||
|
||||
meta = {
|
||||
homepage = "http://github.com/pytoolz/toolz/";
|
||||
description = "List processing tools and functional utilities";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ fridh ];
|
||||
};
|
||||
};
|
||||
|
||||
in pkgs.python35.withPackages (ps: [ps.numpy toolz])
|
||||
).env
|
||||
```
|
||||
|
||||
and again execute `nix-shell`, then we get a Python 3.5 environment with our
|
||||
locally defined package as well as `numpy` which is build according to the
|
||||
definition in Nixpkgs. What did we do here? Well, we took the Nix expression
|
||||
that we used earlier to build a Python environment, and said that we wanted to
|
||||
include our own version of `toolz`. To introduce our own package in the scope of
|
||||
`withPackages` we used a
|
||||
[`let`](http://nixos.org/nix/manual/#sec-constructs) expression.
|
||||
You can see that we used `ps.numpy` to select numpy from the nixpkgs package set (`ps`).
|
||||
But we do not take `toolz` from the nixpkgs package set this time.
|
||||
Instead, `toolz` will resolve to our local definition that we introduced with `let`.
|
||||
|
||||
### Handling dependencies
|
||||
|
||||
Our example, `toolz`, doesn't have any dependencies on other Python
|
||||
packages or system libraries. According to the manual, `buildPythonPackage`
|
||||
uses the arguments `buildInputs` and `propagatedBuildInputs` to specify dependencies. If something is
|
||||
exclusively a build-time dependency, then the dependency should be included as a
|
||||
`buildInput`, but if it is (also) a runtime dependency, then it should be added
|
||||
to `propagatedBuildInputs`. Test dependencies are considered build-time dependencies.
|
||||
|
||||
The following example shows which arguments are given to `buildPythonPackage` in
|
||||
order to build [`datashape`](https://github.com/blaze/datashape).
|
||||
|
||||
```nix
|
||||
datashape = buildPythonPackage rec {
|
||||
name = "datashape-${version}";
|
||||
version = "0.4.7";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "mirror://pypi/D/DataShape/${name}.tar.gz";
|
||||
sha256 = "14b2ef766d4c9652ab813182e866f493475e65e558bed0822e38bf07bba1a278";
|
||||
};
|
||||
|
||||
buildInputs = with self; [ pytest ];
|
||||
propagatedBuildInputs = with self; [ numpy multipledispatch dateutil ];
|
||||
|
||||
meta = {
|
||||
homepage = https://github.com/ContinuumIO/datashape;
|
||||
description = "A data description language";
|
||||
license = licenses.bsd2;
|
||||
maintainers = with maintainers; [ fridh ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
We can see several runtime dependencies, `numpy`, `multipledispatch`, and
|
||||
`dateutil`. Furthermore, we have one `buildInput`, i.e. `pytest`. `pytest` is a
|
||||
test runner and is only used during the `checkPhase` and is therefore not added
|
||||
to `propagatedBuildInputs`.
|
||||
|
||||
In the previous case we had only dependencies on other Python packages to consider.
|
||||
Occasionally you have also system libraries to consider. E.g., `lxml` provides
|
||||
Python bindings to `libxml2` and `libxslt`. These libraries are only required
|
||||
when building the bindings and are therefore added as `buildInputs`.
|
||||
|
||||
```nix
|
||||
lxml = buildPythonPackage rec {
|
||||
name = "lxml-3.4.4";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "mirror://pypi/l/lxml/${name}.tar.gz";
|
||||
sha256 = "16a0fa97hym9ysdk3rmqz32xdjqmy4w34ld3rm3jf5viqjx65lxk";
|
||||
};
|
||||
|
||||
buildInputs = with self; [ pkgs.libxml2 pkgs.libxslt ];
|
||||
|
||||
meta = {
|
||||
description = "Pythonic binding for the libxml2 and libxslt libraries";
|
||||
homepage = http://lxml.de;
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ sjourdois ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
In this example `lxml` and Nix are able to work out exactly where the relevant
|
||||
files of the dependencies are. This is not always the case.
|
||||
|
||||
The example below shows bindings to The Fastest Fourier Transform in the West, commonly known as
|
||||
FFTW. On Nix we have separate packages of FFTW for the different types of floats
|
||||
(`"single"`, `"double"`, `"long-double"`). The bindings need all three types,
|
||||
and therefore we add all three as `buildInputs`. The bindings don't expect to
|
||||
find each of them in a different folder, and therefore we have to set `LDFLAGS`
|
||||
and `CFLAGS`.
|
||||
|
||||
```nix
|
||||
pyfftw = buildPythonPackage rec {
|
||||
name = "pyfftw-${version}";
|
||||
version = "0.9.2";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "mirror://pypi/p/pyFFTW/pyFFTW-${version}.tar.gz";
|
||||
sha256 = "f6bbb6afa93085409ab24885a1a3cdb8909f095a142f4d49e346f2bd1b789074";
|
||||
};
|
||||
|
||||
buildInputs = [ pkgs.fftw pkgs.fftwFloat pkgs.fftwLongDouble];
|
||||
|
||||
propagatedBuildInputs = with self; [ numpy scipy ];
|
||||
|
||||
# Tests cannot import pyfftw. pyfftw works fine though.
|
||||
doCheck = false;
|
||||
|
||||
LDFLAGS="-L${pkgs.fftw.dev}/lib -L${pkgs.fftwFloat.out}/lib -L${pkgs.fftwLongDouble.out}/lib"
|
||||
CFLAGS="-I${pkgs.fftw.dev}/include -I${pkgs.fftwFloat.dev}/include -I${pkgs.fftwLongDouble.dev}/include"
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "A pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms";
|
||||
homepage = http://hgomersall.github.com/pyFFTW/;
|
||||
license = with licenses; [ bsd2 bsd3 ];
|
||||
maintainer = with maintainers; [ fridh ];
|
||||
};
|
||||
};
|
||||
```
|
||||
Note also the line `doCheck = false;`, we explicitly disabled running the test-suite.
|
||||
|
||||
|
||||
#### Develop local package
|
||||
|
||||
As a Python developer you're likely aware of [development mode](http://pythonhosted.org/setuptools/setuptools.html#development-mode) (`python setup.py develop`);
|
||||
instead of installing the package this command creates a special link to the project code.
|
||||
That way, you can run updated code without having to reinstall after each and every change you make.
|
||||
Development mode is also available on Nix as [explained](http://nixos.org/nixpkgs/manual/#ssec-python-development) in the Nixpkgs manual.
|
||||
Let's see how you can use it.
|
||||
|
||||
In the previous Nix expression the source was fetched from an url. We can also refer to a local source instead using
|
||||
|
||||
```nix
|
||||
src = ./path/to/source/tree;
|
||||
```
|
||||
|
||||
If we create a `shell.nix` file which calls `buildPythonPackage`, and if `src`
|
||||
is a local source, and if the local source has a `setup.py`, then development
|
||||
mode is activated.
|
||||
|
||||
In the following example we create a simple environment that
|
||||
has a Python 3.5 version of our package in it, as well as its dependencies and
|
||||
other packages we like to have in the environment, all specified with `propagatedBuildInputs`.
|
||||
Indeed, we can just add any package we like to have in our environment to `propagatedBuildInputs`.
|
||||
|
||||
```nix
|
||||
with import <nixpkgs>;
|
||||
with pkgs.python35Packages;
|
||||
|
||||
buildPythonPackage rec {
|
||||
name = "mypackage";
|
||||
src = ./path/to/package/source;
|
||||
propagatedBuildInputs = [ pytest numpy pkgs.libsndfile ];
|
||||
};
|
||||
```
|
||||
|
||||
It is important to note that due to how development mode is implemented on Nix it is not possible to have multiple packages simultaneously in development mode.
|
||||
|
||||
|
||||
### Organising your packages
|
||||
|
||||
So far we discussed how you can use Python on Nix, and how you can develop with
|
||||
it. We've looked at how you write expressions to package Python packages, and we
|
||||
looked at how you can create environments in which specified packages are
|
||||
available.
|
||||
|
||||
At some point you'll likely have multiple packages which you would
|
||||
like to be able to use in different projects. In order to minimise unnecessary
|
||||
duplication we now look at how you can maintain yourself a repository with your
|
||||
own packages. The important functions here are `import` and `callPackage`.
|
||||
|
||||
### Including a derivation using `callPackage`
|
||||
|
||||
Earlier we created a Python environment using `withPackages`, and included the
|
||||
`toolz` package via a `let` expression.
|
||||
Let's split the package definition from the environment definition.
|
||||
|
||||
We first create a function that builds `toolz` in `~/path/to/toolz/release.nix`
|
||||
|
||||
```nix
|
||||
{ pkgs, buildPythonPackage }:
|
||||
|
||||
buildPythonPackage rec {
|
||||
name = "toolz-${version}";
|
||||
version = "0.7.4";
|
||||
|
||||
src = pkgs.fetchurl{
|
||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
||||
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
||||
};
|
||||
|
||||
meta = {
|
||||
homepage = "http://github.com/pytoolz/toolz/";
|
||||
description = "List processing tools and functional utilities";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ fridh ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
It takes two arguments, `pkgs` and `buildPythonPackage`.
|
||||
We now call this function using `callPackage` in the definition of our environment
|
||||
|
||||
```nix
|
||||
with import <nixpkgs> {};
|
||||
|
||||
( let
|
||||
toolz = pkgs.callPackage ~/path/to/toolz/release.nix { pkgs=pkgs; buildPythonPackage=pkgs.python35Packages.buildPythonPackage; };
|
||||
in pkgs.python35.withPackages (ps: [ ps.numpy toolz ])
|
||||
).env
|
||||
```
|
||||
|
||||
Important to remember is that the Python version for which the package is made
|
||||
depends on the `python` derivation that is passed to `buildPythonPackage`. Nix
|
||||
tries to automatically pass arguments when possible, which is why generally you
|
||||
don't explicitly define which `python` derivation should be used. In the above
|
||||
example we use `buildPythonPackage` that is part of the set `python35Packages`,
|
||||
and in this case the `python35` interpreter is automatically used.
|
||||
|
||||
|
||||
|
||||
## Reference
|
||||
|
||||
### Interpreters
|
||||
|
||||
Versions 2.6, 2.7, 3.3, 3.4 and 3.5 of the CPython interpreter are available on
|
||||
Nix and are available as `python26`, `python27`, `python33`, `python34` and
|
||||
`python35`. The PyPy interpreter is also available as `pypy`. Currently, the
|
||||
aliases `python` and `python3` correspond to respectively `python27` and
|
||||
`python35`. The Nix expressions for the interpreters can be found in
|
||||
`pkgs/development/interpreters/python`.
|
||||
|
||||
|
||||
#### Missing modules standard library
|
||||
|
||||
The interpreters `python26` and `python27` do not include modules that
|
||||
require external dependencies. This is done in order to reduce the closure size.
|
||||
The following modules need to be added as `buildInput` explicitly:
|
||||
|
||||
* `python.modules.bsddb`
|
||||
* `python.modules.curses`
|
||||
* `python.modules.curses_panel`
|
||||
* `python.modules.crypt`
|
||||
* `python.modules.gdbm`
|
||||
* `python.modules.sqlite3`
|
||||
* `python.modules.tkinter`
|
||||
* `python.modules.readline`
|
||||
|
||||
For convenience `python27Full` and `python26Full` are provided with all
|
||||
modules included.
|
||||
|
||||
All packages depending on any Python interpreter get appended
|
||||
`out/{python.sitePackages}` to `$PYTHONPATH` if such directory
|
||||
exists.
|
||||
|
||||
#### Attributes on interpreters packages
|
||||
|
||||
Each interpreter has the following attributes:
|
||||
|
||||
- `libPrefix`. Name of the folder in `${python}/lib/` for corresponding interpreter.
|
||||
- `interpreter`. Alias for `${python}/bin/${executable}`.
|
||||
- `buildEnv`. Function to build python interpreter environments with extra packages bundled together. See section *python.buildEnv function* for usage and documentation.
|
||||
- `withPackages`. Simpler interface to `buildEnv`. See section *python.withPackages function* for usage and documentation.
|
||||
- `sitePackages`. Alias for `lib/${libPrefix}/site-packages`.
|
||||
- `executable`. Name of the interpreter executable, ie `python3.4`.
|
||||
|
||||
### Building packages and applications
|
||||
|
||||
Python packages (libraries) and applications that use `setuptools` or
|
||||
`distutils` are typically built with respectively the `buildPythonPackage` and
|
||||
`buildPythonApplication` functions.
|
||||
|
||||
All Python packages reside in `pkgs/top-level/python-packages.nix` and all
|
||||
applications elsewhere. Some packages are also defined in
|
||||
`pkgs/development/python-modules`. It is important that these packages are
|
||||
called in `pkgs/top-level/python-packages.nix` and not elsewhere, to guarantee
|
||||
the right version of the package is built.
|
||||
|
||||
Based on the packages defined in `pkgs/top-level/python-packages.nix` an
|
||||
attribute set is created for each available Python interpreter. The available
|
||||
sets are
|
||||
|
||||
* `pkgs.python26Packages`
|
||||
* `pkgs.python27Packages`
|
||||
* `pkgs.python33Packages`
|
||||
* `pkgs.python34Packages`
|
||||
* `pkgs.python35Packages`
|
||||
* `pkgs.pypyPackages`
|
||||
|
||||
and the aliases
|
||||
|
||||
* `pkgs.pythonPackages` pointing to `pkgs.python27Packages`
|
||||
* `pkgs.python3Packages` pointing to `pkgs.python35Packages`
|
||||
|
||||
#### `buildPythonPackage` function
|
||||
|
||||
The `buildPythonPackage` function is implemented in
|
||||
`pkgs/development/interpreters/python/build-python-package.nix`
|
||||
|
||||
and can be used as:
|
||||
|
||||
twisted = buildPythonPackage {
|
||||
name = "twisted-8.1.0";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2;
|
||||
sha256 = "0q25zbr4xzknaghha72mq57kh53qw1bf8csgp63pm9sfi72qhirl";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [ self.ZopeInterface ];
|
||||
|
||||
meta = {
|
||||
homepage = http://twistedmatrix.com/;
|
||||
description = "Twisted, an event-driven networking engine written in Python";
|
||||
license = stdenv.lib.licenses.mit; };
|
||||
};
|
||||
|
||||
The `buildPythonPackage` mainly does four things:
|
||||
|
||||
* In the `buildPhase`, it calls `${python.interpreter} setup.py bdist_wheel` to
|
||||
build a wheel binary zipfile.
|
||||
* In the `installPhase`, it installs the wheel file using `pip install *.whl`.
|
||||
* In the `postFixup` phase, the `wrapPythonPrograms` bash function is called to
|
||||
wrap all programs in the `$out/bin/*` directory to include `$PATH`
|
||||
environment variable and add dependent libraries to script's `sys.path`.
|
||||
* In the `installCheck` phase, `${python.interpreter} setup.py test` is ran.
|
||||
|
||||
As in Perl, dependencies on other Python packages can be specified in the
|
||||
`buildInputs` and `propagatedBuildInputs` attributes. If something is
|
||||
exclusively a build-time dependency, use `buildInputs`; if it’s (also) a runtime
|
||||
dependency, use `propagatedBuildInputs`.
|
||||
|
||||
By default tests are run because `doCheck = true`. Test dependencies, like
|
||||
e.g. the test runner, should be added to `buildInputs`.
|
||||
|
||||
By default `meta.platforms` is set to the same value
|
||||
as the interpreter unless overriden otherwise.
|
||||
|
||||
##### `buildPythonPackage` parameters
|
||||
|
||||
All parameters from `mkDerivation` function are still supported.
|
||||
|
||||
* `namePrefix`: Prepended text to `${name}` parameter. Defaults to `"python3.3-"` for Python 3.3, etc. Set it to `""` if you're packaging an application or a command line tool.
|
||||
* `disabled`: If `true`, package is not build for particular python interpreter version. Grep around `pkgs/top-level/python-packages.nix` for examples.
|
||||
* `setupPyBuildFlags`: List of flags passed to `setup.py build_ext` command.
|
||||
* `pythonPath`: List of packages to be added into `$PYTHONPATH`. Packages in `pythonPath` are not propagated (contrary to `propagatedBuildInputs`).
|
||||
* `preShellHook`: Hook to execute commands before `shellHook`.
|
||||
* `postShellHook`: Hook to execute commands after `shellHook`.
|
||||
* `makeWrapperArgs`: A list of strings. Arguments to be passed to `makeWrapper`, which wraps generated binaries. By default, the arguments to `makeWrapper` set `PATH` and `PYTHONPATH` environment variables before calling the binary. Additional arguments here can allow a developer to set environment variables which will be available when the binary is run. For example, `makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]`.
|
||||
* `installFlags`: A list of strings. Arguments to be passed to `pip install`. To pass options to `python setup.py install`, use `--install-option`. E.g., `installFlags=["--install-option='--cpp_implementation'"].
|
||||
* `format`: Format of the source. Options are `setup` for when the source has a `setup.py` and `setuptools` is used to build a wheel, and `wheel` in case the source is already a binary wheel. The default value is `setup`.
|
||||
* `catchConflicts` If `true`, abort package build if a package name appears more than once in dependency tree. Default is `true`.
|
||||
* `checkInputs` Dependencies needed for running the `checkPhase`. These are added to `buildInputs` when `doCheck = true`.
|
||||
|
||||
#### `buildPythonApplication` function
|
||||
|
||||
The `buildPythonApplication` function is practically the same as `buildPythonPackage`.
|
||||
The difference is that `buildPythonPackage` by default prefixes the names of the packages with the version of the interpreter.
|
||||
Because with an application we're not interested in multiple version the prefix is dropped.
|
||||
|
||||
#### python.buildEnv function
|
||||
|
||||
Python environments can be created using the low-level `pkgs.buildEnv` function.
|
||||
This example shows how to create an environment that has the Pyramid Web Framework.
|
||||
Saving the following as `default.nix`
|
||||
|
||||
with import <nixpkgs> {};
|
||||
|
||||
python.buildEnv.override {
|
||||
extraLibs = [ pkgs.pythonPackages.pyramid ];
|
||||
ignoreCollisions = true;
|
||||
}
|
||||
|
||||
and running `nix-build` will create
|
||||
|
||||
/nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env
|
||||
|
||||
with wrapped binaries in `bin/`.
|
||||
|
||||
You can also use the `env` attribute to create local environments with needed
|
||||
packages installed. This is somewhat comparable to `virtualenv`. For example,
|
||||
running `nix-shell` with the following `shell.nix`
|
||||
|
||||
with import <nixpkgs> {};
|
||||
|
||||
(python3.buildEnv.override {
|
||||
extraLibs = with python3Packages; [ numpy requests2 ];
|
||||
}).env
|
||||
|
||||
will drop you into a shell where Python will have the
|
||||
specified packages in its path.
|
||||
|
||||
|
||||
##### `python.buildEnv` arguments
|
||||
|
||||
* `extraLibs`: List of packages installed inside the environment.
|
||||
* `postBuild`: Shell command executed after the build of environment.
|
||||
* `ignoreCollisions`: Ignore file collisions inside the environment (default is `false`).
|
||||
|
||||
#### python.withPackages function
|
||||
|
||||
The `python.withPackages` function provides a simpler interface to the `python.buildEnv` functionality.
|
||||
It takes a function as an argument that is passed the set of python packages and returns the list
|
||||
of the packages to be included in the environment. Using the `withPackages` function, the previous
|
||||
example for the Pyramid Web Framework environment can be written like this:
|
||||
|
||||
with import <nixpkgs> {};
|
||||
|
||||
python.withPackages (ps: [ps.pyramid])
|
||||
|
||||
`withPackages` passes the correct package set for the specific interpreter version as an
|
||||
argument to the function. In the above example, `ps` equals `pythonPackages`.
|
||||
But you can also easily switch to using python3:
|
||||
|
||||
with import <nixpkgs> {};
|
||||
|
||||
python3.withPackages (ps: [ps.pyramid])
|
||||
|
||||
Now, `ps` is set to `python3Packages`, matching the version of the interpreter.
|
||||
|
||||
As `python.withPackages` simply uses `python.buildEnv` under the hood, it also supports the `env`
|
||||
attribute. The `shell.nix` file from the previous section can thus be also written like this:
|
||||
|
||||
with import <nixpkgs> {};
|
||||
|
||||
(python33.withPackages (ps: [ps.numpy ps.requests2])).env
|
||||
|
||||
In contrast to `python.buildEnv`, `python.withPackages` does not support the more advanced options
|
||||
such as `ignoreCollisions = true` or `postBuild`. If you need them, you have to use `python.buildEnv`.
|
||||
|
||||
### Development mode
|
||||
|
||||
Development or editable mode is supported. To develop Python packages
|
||||
`buildPythonPackage` has additional logic inside `shellPhase` to run `pip
|
||||
install -e . --prefix $TMPDIR/`for the package.
|
||||
|
||||
Warning: `shellPhase` is executed only if `setup.py` exists.
|
||||
|
||||
Given a `default.nix`:
|
||||
|
||||
with import <nixpkgs> {};
|
||||
|
||||
buildPythonPackage { name = "myproject";
|
||||
|
||||
buildInputs = with pkgs.pythonPackages; [ pyramid ];
|
||||
|
||||
src = ./.; }
|
||||
|
||||
Running `nix-shell` with no arguments should give you
|
||||
the environment in which the package would be built with
|
||||
`nix-build`.
|
||||
|
||||
Shortcut to setup environments with C headers/libraries and python packages:
|
||||
|
||||
$ nix-shell -p pythonPackages.pyramid zlib libjpeg git
|
||||
|
||||
Note: There is a boolean value `lib.inNixShell` set to `true` if nix-shell is invoked.
|
||||
|
||||
### Tools
|
||||
|
||||
Packages inside nixpkgs are written by hand. However many tools exist in
|
||||
community to help save time. No tool is preferred at the moment.
|
||||
|
||||
- [python2nix](https://github.com/proger/python2nix) by Vladimir Kirillov
|
||||
- [pypi2nix](https://github.com/garbas/pypi2nix) by Rok Garbas
|
||||
- [pypi2nix](https://github.com/offlinehacker/pypi2nix) by Jaka Hudoklin
|
||||
|
||||
## FAQ
|
||||
|
||||
### How can I install a working Python environment?
|
||||
|
||||
As explained in the user's guide installing individual Python packages
|
||||
imperatively with `nix-env -i` or declaratively in `environment.systemPackages`
|
||||
is not supported. However, it is possible to install a Python environment with packages (`python.buildEnv`).
|
||||
|
||||
In the following examples we create an environment with Python 3.5, `numpy` and `ipython`.
|
||||
As you might imagine there is one limitation here, and that's you can install
|
||||
only one environment at a time. You will notice the complaints about collisions
|
||||
when you try to install a second environment.
|
||||
|
||||
#### Environment defined in separate `.nix` file
|
||||
|
||||
Create a file, e.g. `build.nix`, with the following expression
|
||||
```nix
|
||||
with import <nixpkgs> {};
|
||||
with python35Packages;
|
||||
|
||||
python.withPackages (ps: with ps; [ numpy ipython ])
|
||||
```
|
||||
and install it in your profile with
|
||||
```
|
||||
nix-env -if build.nix
|
||||
```
|
||||
Now you can use the Python interpreter, as well as the extra packages that you added to the environment.
|
||||
|
||||
#### Environment defined in `~/.nixpkgs/config.nix`
|
||||
|
||||
If you prefer to, you could also add the environment as a package override to the Nixpkgs set.
|
||||
```
|
||||
packageOverrides = pkgs: with pkgs; with python35Packages; {
|
||||
myEnv = python.withPackages (ps: with ps; [ numpy ipython ]);
|
||||
};
|
||||
```
|
||||
and install it in your profile with
|
||||
```
|
||||
nix-env -iA nixos.blogEnv
|
||||
```
|
||||
Note that I'm using the attribute path here.
|
||||
|
||||
#### Environment defined in `/etc/nixos/configuration.nix`
|
||||
|
||||
For the sake of completeness, here's another example how to install the environment system-wide.
|
||||
|
||||
```nix
|
||||
environment.systemPackages = with pkgs; [
|
||||
(python35Packages.python.withPackages (ps: callPackage ../packages/common-python-packages.nix { pythonPackages = ps; }))
|
||||
];
|
||||
```
|
||||
|
||||
### How to solve circular dependencies?
|
||||
|
||||
Consider the packages `A` and `B` that depend on each other. When packaging `B`,
|
||||
a solution is to override package `A` not to depend on `B` as an input. The same
|
||||
should also be done when packaging `A`.
|
||||
|
||||
### How to override a Python package?
|
||||
|
||||
Recursively updating a package can be done with `pkgs.overridePackages` as explained in the Nixpkgs manual.
|
||||
Python attribute sets are created for each interpreter version. We will therefore override the attribute set for the interpreter version we're interested.
|
||||
In the following example we change the name of the package `pandas` to `foo`.
|
||||
```
|
||||
newpkgs = pkgs.overridePackages(self: super: rec {
|
||||
python35Packages = (super.python35Packages.override { self = python35Packages;})
|
||||
// { pandas = super.python35Packages.pandas.override {name = "foo";};
|
||||
};
|
||||
});
|
||||
```
|
||||
This can be tested with
|
||||
```
|
||||
with import <nixpkgs> {};
|
||||
|
||||
(let
|
||||
|
||||
newpkgs = pkgs.overridePackages(self: super: rec {
|
||||
python35Packages = (super.python35Packages.override { self = python35Packages;})
|
||||
// { pandas = super.python35Packages.pandas.override {name = "foo";};
|
||||
};
|
||||
});
|
||||
in newpkgs.python35.withPackages (ps: [ps.blaze])
|
||||
).env
|
||||
```
|
||||
A typical use case is to switch to another version of a certain package. For example, in the Nixpkgs repository we have multiple versions of `django` and `scipy`.
|
||||
In the following example we use a different version of `scipy`. All packages in `newpkgs` will now use the updated `scipy` version.
|
||||
```
|
||||
with import <nixpkgs> {};
|
||||
|
||||
(let
|
||||
|
||||
newpkgs = pkgs.overridePackages(self: super: rec {
|
||||
python35Packages = super.python35Packages.override {
|
||||
self = python35Packages // { scipy = python35Packages.scipy_0_17;};
|
||||
};
|
||||
});
|
||||
in newpkgs.python35.withPackages (ps: [ps.blaze])
|
||||
).env
|
||||
```
|
||||
The requested package `blaze` depends upon `pandas` which itself depends on `scipy`.
|
||||
|
||||
A similar example but now using `django`
|
||||
```
|
||||
with import <nixpkgs> {};
|
||||
|
||||
(let
|
||||
|
||||
newpkgs = pkgs.overridePackages(self: super: rec {
|
||||
python27Packages = (super.python27Packages.override {self = python27Packages;})
|
||||
// { django = super.python27Packages.django_1_9; };
|
||||
});
|
||||
in newpkgs.python27.withPackages (ps: [ps.django_guardian ])
|
||||
).env
|
||||
```
|
||||
|
||||
### `python setup.py bdist_wheel` cannot create .whl
|
||||
|
||||
Executing `python setup.py bdist_wheel` in a `nix-shell `fails with
|
||||
```
|
||||
ValueError: ZIP does not support timestamps before 1980
|
||||
```
|
||||
This is because files are included that depend on items in the Nix store which have a timestamp of, that is, it corresponds to January the 1st, 1970 at 00:00:00. And as the error informs you, ZIP does not support that.
|
||||
The command `bdist_wheel` takes into account `SOURCE_DATE_EPOCH`, and `nix-shell` sets this to 1. By setting it to a value corresponding to 1980 or later, or by unsetting it, it is possible to build wheels.
|
||||
|
||||
Use 1980 as timestamp:
|
||||
```
|
||||
nix-shell --run "SOURCE_DATE_EPOCH=315532800 python3 setup.py bdist_wheel"
|
||||
```
|
||||
or the current time:
|
||||
```
|
||||
nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
|
||||
```
|
||||
or unset:
|
||||
"""
|
||||
nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
|
||||
"""
|
||||
|
||||
### `install_data` / `data_files` problems
|
||||
|
||||
If you get the following error:
|
||||
|
||||
could not create '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc':
|
||||
Permission denied
|
||||
|
||||
This is a [known bug](https://bitbucket.org/pypa/setuptools/issue/130/install_data-doesnt-respect-prefix) in setuptools.
|
||||
Setuptools `install_data` does not respect `--prefix`. An example of such package using the feature is `pkgs/tools/X11/xpra/default.nix`.
|
||||
As workaround install it as an extra `preInstall` step:
|
||||
|
||||
${python.interpreter} setup.py install_data --install-dir=$out --root=$out
|
||||
sed -i '/ = data\_files/d' setup.py
|
||||
|
||||
|
||||
### Rationale of non-existent global site-packages
|
||||
|
||||
On most operating systems a global `site-packages` is maintained. This however
|
||||
becomes problematic if you want to run multiple Python versions or have multiple
|
||||
versions of certain libraries for your projects. Generally, you would solve such
|
||||
issues by creating virtual environments using `virtualenv`.
|
||||
|
||||
On Nix each package has an isolated dependency tree which, in the case of
|
||||
Python, guarantees the right versions of the interpreter and libraries or
|
||||
packages are available. There is therefore no need to maintain a global `site-packages`.
|
||||
|
||||
If you want to create a Python environment for development, then the recommended
|
||||
method is to use `nix-shell`, either with or without the `python.buildEnv`
|
||||
function.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
### Contributing guidelines
|
||||
|
||||
Following rules are desired to be respected:
|
||||
|
||||
* Make sure package builds for all python interpreters. Use `disabled` argument to `buildPythonPackage` to set unsupported interpreters.
|
||||
* If tests need to be disabled for a package, make sure you leave a comment about reasoning.
|
||||
* Packages in `pkgs/top-level/python-packages.nix` are sorted quasi-alphabetically to avoid merge conflicts.
|
||||
* Python libraries are supposed to be in `python-packages.nix` and packaged with `buildPythonPackage`. Python applications live outside of `python-packages.nix` and are packaged with `buildPythonApplication`.
|
||||
447
doc/languages-frameworks/python.xml
Normal file
447
doc/languages-frameworks/python.xml
Normal file
@@ -0,0 +1,447 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="sec-python">
|
||||
|
||||
<title>Python</title>
|
||||
|
||||
<para>
|
||||
Currently supported interpreters are <varname>python26</varname>, <varname>python27</varname>,
|
||||
<varname>python33</varname>, <varname>python34</varname>, <varname>python35</varname>
|
||||
and <varname>pypy</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<varname>python</varname> is an alias to <varname>python27</varname> and <varname>python3</varname> is an alias to <varname>python34</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<varname>python26</varname> and <varname>python27</varname> do not include modules that require
|
||||
external dependencies (to reduce dependency bloat). Following modules need to be added as
|
||||
<varname>buildInput</varname> explicitly:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para><varname>python.modules.bsddb</varname></para></listitem>
|
||||
<listitem><para><varname>python.modules.curses</varname></para></listitem>
|
||||
<listitem><para><varname>python.modules.curses_panel</varname></para></listitem>
|
||||
<listitem><para><varname>python.modules.crypt</varname></para></listitem>
|
||||
<listitem><para><varname>python.modules.gdbm</varname></para></listitem>
|
||||
<listitem><para><varname>python.modules.sqlite3</varname></para></listitem>
|
||||
<listitem><para><varname>python.modules.tkinter</varname></para></listitem>
|
||||
<listitem><para><varname>python.modules.readline</varname></para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>For convenience <varname>python27Full</varname> and <varname>python26Full</varname>
|
||||
are provided with all modules included.</para>
|
||||
|
||||
<para>
|
||||
Python packages that
|
||||
use <link xlink:href="http://pypi.python.org/pypi/setuptools/"><literal>setuptools</literal></link> or <literal>distutils</literal>,
|
||||
can be built using the <varname>buildPythonPackage</varname> function as documented below.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All packages depending on any Python interpreter get appended <varname>$out/${python.sitePackages}</varname>
|
||||
to <literal>$PYTHONPATH</literal> if such directory exists.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<title>
|
||||
Useful attributes on interpreters packages:
|
||||
</title>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>libPrefix</varname></term>
|
||||
<listitem><para>
|
||||
Name of the folder in <literal>${python}/lib/</literal> for corresponding interpreter.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>interpreter</varname></term>
|
||||
<listitem><para>
|
||||
Alias for <literal>${python}/bin/${executable}.</literal>
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>buildEnv</varname></term>
|
||||
<listitem><para>
|
||||
Function to build python interpreter environments with extra packages bundled together.
|
||||
See <xref linkend="ssec-python-build-env" /> for usage and documentation.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>sitePackages</varname></term>
|
||||
<listitem><para>
|
||||
Alias for <literal>lib/${libPrefix}/site-packages</literal>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>executable</varname></term>
|
||||
<listitem><para>
|
||||
Name of the interpreter executable, ie <literal>python3.4</literal>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
<section xml:id="ssec-build-python-package"><title><varname>buildPythonPackage</varname> function</title>
|
||||
|
||||
<para>
|
||||
The function is implemented in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/generic/default.nix">
|
||||
<filename>pkgs/development/python-modules/generic/default.nix</filename></link>.
|
||||
Example usage:
|
||||
|
||||
<programlisting language="nix">
|
||||
twisted = buildPythonPackage {
|
||||
name = "twisted-8.1.0";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2;
|
||||
sha256 = "0q25zbr4xzknaghha72mq57kh53qw1bf8csgp63pm9sfi72qhirl";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [ self.ZopeInterface ];
|
||||
|
||||
meta = {
|
||||
homepage = http://twistedmatrix.com/;
|
||||
description = "Twisted, an event-driven networking engine written in Python";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
};
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
Most of Python packages that use <varname>buildPythonPackage</varname> are defined
|
||||
in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/python-packages.nix"><filename>pkgs/top-level/python-packages.nix</filename></link>
|
||||
and generated for each python interpreter separately into attribute sets <varname>python26Packages</varname>,
|
||||
<varname>python27Packages</varname>, <varname>python35Packages</varname>, <varname>python33Packages</varname>,
|
||||
<varname>python34Packages</varname> and <varname>pypyPackages</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>buildPythonPackage</function> mainly does four things:
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
In the <varname>buildPhase</varname>, it calls
|
||||
<literal>${python.interpreter} setup.py bdist_wheel</literal> to build a wheel binary zipfile.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
In the <varname>installPhase</varname>, it installs the wheel file using
|
||||
<literal>pip install *.whl</literal>.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
In the <varname>postFixup</varname> phase, <literal>wrapPythonPrograms</literal>
|
||||
bash function is called to wrap all programs in <filename>$out/bin/*</filename>
|
||||
directory to include <literal>$PYTHONPATH</literal> and <literal>$PATH</literal>
|
||||
environment variables.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
In the <varname>installCheck</varname> phase, <literal>${python.interpreter} setup.py test</literal>
|
||||
is ran.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
|
||||
<para>By default <varname>doCheck = true</varname> is set</para>
|
||||
|
||||
<para>
|
||||
As in Perl, dependencies on other Python packages can be specified in the
|
||||
<varname>buildInputs</varname> and
|
||||
<varname>propagatedBuildInputs</varname> attributes. If something is
|
||||
exclusively a build-time dependency, use
|
||||
<varname>buildInputs</varname>; if it’s (also) a runtime dependency,
|
||||
use <varname>propagatedBuildInputs</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
By default <varname>meta.platforms</varname> is set to the same value
|
||||
as the interpreter unless overriden otherwise.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<title>
|
||||
<varname>buildPythonPackage</varname> parameters
|
||||
(all parameters from <varname>mkDerivation</varname> function are still supported)
|
||||
</title>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>namePrefix</varname></term>
|
||||
<listitem><para>
|
||||
Prepended text to <varname>${name}</varname> parameter.
|
||||
Defaults to <literal>"python3.3-"</literal> for Python 3.3, etc. Set it to
|
||||
<literal>""</literal>
|
||||
if you're packaging an application or a command line tool.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>disabled</varname></term>
|
||||
<listitem><para>
|
||||
If <varname>true</varname>, package is not build for
|
||||
particular python interpreter version. Grep around
|
||||
<filename>pkgs/top-level/python-packages.nix</filename>
|
||||
for examples.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>setupPyBuildFlags</varname></term>
|
||||
<listitem><para>
|
||||
List of flags passed to <command>setup.py build_ext</command> command.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>pythonPath</varname></term>
|
||||
<listitem><para>
|
||||
List of packages to be added into <literal>$PYTHONPATH</literal>.
|
||||
Packages in <varname>pythonPath</varname> are not propagated
|
||||
(contrary to <varname>propagatedBuildInputs</varname>).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>preShellHook</varname></term>
|
||||
<listitem><para>
|
||||
Hook to execute commands before <varname>shellHook</varname>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>postShellHook</varname></term>
|
||||
<listitem><para>
|
||||
Hook to execute commands after <varname>shellHook</varname>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>makeWrapperArgs</varname></term>
|
||||
<listitem><para>
|
||||
A list of strings. Arguments to be passed to
|
||||
<varname>makeWrapper</varname>, which wraps generated binaries. By
|
||||
default, the arguments to <varname>makeWrapper</varname> set
|
||||
<varname>PATH</varname> and <varname>PYTHONPATH</varname> environment
|
||||
variables before calling the binary. Additional arguments here can
|
||||
allow a developer to set environment variables which will be
|
||||
available when the binary is run. For example,
|
||||
<varname>makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]</varname>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-python-build-env"><title><function>python.buildEnv</function> function</title>
|
||||
<para>
|
||||
Create Python environments using low-level <function>pkgs.buildEnv</function> function. Example <filename>default.nix</filename>:
|
||||
|
||||
<programlisting language="nix">
|
||||
<![CDATA[with import <nixpkgs> {};
|
||||
|
||||
python.buildEnv.override {
|
||||
extraLibs = [ pkgs.pythonPackages.pyramid ];
|
||||
ignoreCollisions = true;
|
||||
}]]>
|
||||
</programlisting>
|
||||
|
||||
Running <command>nix-build</command> will create
|
||||
<filename>/nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env</filename>
|
||||
with wrapped binaries in <filename>bin/</filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can also use <varname>env</varname> attribute to create local
|
||||
environments with needed packages installed (somewhat comparable to
|
||||
<literal>virtualenv</literal>). For example, with the following
|
||||
<filename>shell.nix</filename>:
|
||||
|
||||
<programlisting language="nix">
|
||||
<![CDATA[with import <nixpkgs> {};
|
||||
|
||||
(python3.buildEnv.override {
|
||||
extraLibs = with python3Packages;
|
||||
[ numpy
|
||||
requests
|
||||
];
|
||||
}).env]]>
|
||||
</programlisting>
|
||||
|
||||
Running <command>nix-shell</command> will drop you into a shell where
|
||||
<command>python</command> will have specified packages in its path.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<title>
|
||||
<function>python.buildEnv</function> arguments
|
||||
</title>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>extraLibs</varname></term>
|
||||
<listitem><para>
|
||||
List of packages installed inside the environment.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>postBuild</varname></term>
|
||||
<listitem><para>
|
||||
Shell command executed after the build of environment.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>ignoreCollisions</varname></term>
|
||||
<listitem><para>
|
||||
Ignore file collisions inside the environment (default is <varname>false</varname>).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-python-tools"><title>Tools</title>
|
||||
|
||||
<para>Packages inside nixpkgs are written by hand. However many tools
|
||||
exist in community to help save time. No tool is preferred at the moment.
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>
|
||||
<link xlink:href="https://github.com/proger/python2nix">python2nix</link>
|
||||
by Vladimir Kirillov
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<link xlink:href="https://github.com/garbas/pypi2nix">pypi2nix</link>
|
||||
by Rok Garbas
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<link xlink:href="https://github.com/offlinehacker/pypi2nix">pypi2nix</link>
|
||||
by Jaka Hudoklin
|
||||
</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-python-development"><title>Development</title>
|
||||
|
||||
<para>
|
||||
To develop Python packages <function>buildPythonPackage</function> has
|
||||
additional logic inside <varname>shellPhase</varname> to run
|
||||
<command>pip install -e . --prefix $TMPDIR/</command> for the package.
|
||||
</para>
|
||||
|
||||
<warning><para><varname>shellPhase</varname> is executed only if <filename>setup.py</filename>
|
||||
exists.</para></warning>
|
||||
|
||||
<para>
|
||||
Given a <filename>default.nix</filename>:
|
||||
|
||||
<programlisting language="nix">
|
||||
<![CDATA[with import <nixpkgs> {};
|
||||
|
||||
buildPythonPackage {
|
||||
name = "myproject";
|
||||
|
||||
buildInputs = with pkgs.pythonPackages; [ pyramid ];
|
||||
|
||||
src = ./.;
|
||||
}]]>
|
||||
</programlisting>
|
||||
|
||||
Running <command>nix-shell</command> with no arguments should give you
|
||||
the environment in which the package would be build with
|
||||
<command>nix-build</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Shortcut to setup environments with C headers/libraries and python packages:
|
||||
|
||||
<programlisting language="bash">$ nix-shell -p pythonPackages.pyramid zlib libjpeg git</programlisting>
|
||||
</para>
|
||||
|
||||
<note><para>
|
||||
There is a boolean value <varname>lib.inNixShell</varname> set to
|
||||
<varname>true</varname> if nix-shell is invoked.
|
||||
</para></note>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-python-faq"><title>FAQ</title>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>How to solve circular dependencies?</term>
|
||||
<listitem><para>
|
||||
If you have packages <varname>A</varname> and <varname>B</varname> that
|
||||
depend on each other, when packaging <varname>B</varname> override package
|
||||
<varname>A</varname> not to depend on <varname>B</varname> as input
|
||||
(and also the other way around).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>install_data / data_files</varname> problems resulting into <literal>error: could not create '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc': Permission denied</literal></term>
|
||||
<listitem><para>
|
||||
<link xlink:href="https://bitbucket.org/pypa/setuptools/issue/130/install_data-doesnt-respect-prefix">
|
||||
Known bug in setuptools <varname>install_data</varname> does not respect --prefix</link>. Example of
|
||||
such package using the feature is <filename>pkgs/tools/X11/xpra/default.nix</filename>. As workaround
|
||||
install it as an extra <varname>preInstall</varname> step:
|
||||
|
||||
<programlisting>${python.interpreter} setup.py install_data --install-dir=$out --root=$out
|
||||
sed -i '/ = data_files/d' setup.py</programlisting>
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Rationale of non-existent global site-packages</term>
|
||||
<listitem><para>
|
||||
There is no need to have global site-packages in Nix. Each package has isolated
|
||||
dependency tree and installing any python package will only populate <varname>$PATH</varname>
|
||||
inside user environment. See <xref linkend="ssec-python-build-env" /> to create self-contained
|
||||
interpreter with a set of packages.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section xml:id="ssec-python-contrib"><title>Contributing guidelines</title>
|
||||
<para>
|
||||
Following rules are desired to be respected:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>
|
||||
Make sure package builds for all python interpreters. Use <varname>disabled</varname> argument to
|
||||
<function>buildPythonPackage</function> to set unsupported interpreters.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
If tests need to be disabled for a package, make sure you leave a comment about reasoning.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Packages in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/python-packages.nix"><filename>pkgs/top-level/python-packages.nix</filename></link>
|
||||
are sorted quasi-alphabetically to avoid merge conflicts.
|
||||
</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -12,26 +12,25 @@
|
||||
<screen>
|
||||
<![CDATA[$ cd pkgs/servers/monitoring
|
||||
$ mkdir sensu
|
||||
$ cd sensu
|
||||
$ cat > Gemfile
|
||||
source 'https://rubygems.org'
|
||||
gem 'sensu'
|
||||
$ nix-shell -p bundler --command "bundler package --path /tmp/vendor/bundle"
|
||||
$ bundler package --path /tmp/vendor/bundle
|
||||
$ $(nix-build '<nixpkgs>' -A bundix)/bin/bundix
|
||||
$ cat > default.nix
|
||||
{ lib, bundlerEnv, ruby }:
|
||||
|
||||
bundlerEnv rec {
|
||||
name = "sensu-${version}";
|
||||
bundlerEnv {
|
||||
name = "sensu-0.17.1";
|
||||
|
||||
version = (import gemset).sensu.version;
|
||||
inherit ruby;
|
||||
gemfile = ./Gemfile;
|
||||
lockfile = ./Gemfile.lock;
|
||||
gemset = ./gemset.nix;
|
||||
|
||||
meta = with lib; {
|
||||
description = "A monitoring framework that aims to be simple, malleable, and scalable";
|
||||
description = "A monitoring framework that aims to be simple, malleable,
|
||||
and scalable";
|
||||
homepage = http://sensuapp.org/;
|
||||
license = with licenses; mit;
|
||||
maintainers = with maintainers; [ theuni ];
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<xi:include href="introduction.xml" />
|
||||
<xi:include href="quick-start.xml" />
|
||||
<xi:include href="stdenv.xml" />
|
||||
<xi:include href="multiple-output.xml" />
|
||||
<xi:include href="configuration.xml" />
|
||||
<xi:include href="functions.xml" />
|
||||
<xi:include href="meta.xml" />
|
||||
@@ -20,6 +19,8 @@
|
||||
<xi:include href="package-notes.xml" />
|
||||
<xi:include href="coding-conventions.xml" />
|
||||
<xi:include href="submitting-changes.xml" />
|
||||
<xi:include href="haskell-users-guide.xml" />
|
||||
<xi:include href="erlang-users-guide.xml" />
|
||||
<xi:include href="contributing.xml" />
|
||||
|
||||
</book>
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter [
|
||||
<!ENTITY ndash "–"> <!-- @vcunat likes to use this one ;-) -->
|
||||
]>
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="chap-multiple-output">
|
||||
|
||||
<title>Multiple-output packages</title>
|
||||
|
||||
<section><title>Introduction</title>
|
||||
<para>The Nix language allows a derivation to produce multiple outputs, which is similar to what is utilized by other Linux distribution packaging systems. The outputs reside in separate nix store paths, so they can be mostly handled independently of each other, including passing to build inputs, garbage collection or binary substitution. The exception is that building from source always produces all the outputs.</para>
|
||||
<para>The main motivation is to save disk space by reducing runtime closure sizes; consequently also sizes of substituted binaries get reduced. Splitting can be used to have more granular runtime dependencies, for example the typical reduction is to split away development-only files, as those are typically not needed during runtime. As a result, closure sizes of many packages can get reduced to a half or even much less.</para>
|
||||
<note><para>The reduction effects could be instead achieved by building the parts in completely separate derivations. That would often additionally reduce build-time closures, but it tends to be much harder to write such derivations, as build systems typically assume all parts are being built at once. This compromise approach of single source package producing multiple binary packages is also utilized often by rpm and deb.</para></note>
|
||||
</section>
|
||||
|
||||
<section><title>Installing a split package</title>
|
||||
<para>When installing a package via <varname>systemPackages</varname> or <command>nix-env</command> you have several options:</para>
|
||||
<warning><para>Currently <command>nix-env</command> almost always installs all outputs until https://github.com/NixOS/nix/pull/815 gets merged.</para></warning>
|
||||
<itemizedlist>
|
||||
<listitem><para>You can install particular outputs explicitly, as each is available in the Nix language as an attribute of the package. The <varname>outputs</varname> attribute contains a list of output names.</para></listitem>
|
||||
<listitem><para>You can let it use the default outputs. These are handled by <varname>meta.outputsToInstall</varname> attribute that contains a list of output names.</para>
|
||||
<para>TODO: more about tweaking the attribute, etc.</para></listitem>
|
||||
<listitem><para>NixOS provides configuration option <varname>environment.extraOutputsToInstall</varname> that allows adding extra outputs of <varname>environment.systemPackages</varname> atop the default ones. It's mainly meant for documentation and debug symbols, and it's also modified by specific options.</para>
|
||||
<note><para>At this moment there is no similar configurability for packages installed by <command>nix-env</command>. You can still use approach from <xref linkend="sec-modify-via-packageOverrides" /> to override <varname>meta.outputsToInstall</varname> attributes, but that's a rather inconvenient way.</para></note>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section><title>Using a split package</title>
|
||||
<para>In the Nix language the individual outputs can be reached explicitly as attributes, e.g. <varname>coreutils.info</varname>, but the typical case is just using packages as build inputs.</para>
|
||||
<para>When a multiple-output derivation gets into a build input of another derivation, the <varname>dev</varname> output is added if it exists, otherwise the first output is added. In addition to that, <varname>propagatedBuildOutputs</varname> of that package which by default contain <varname>$outputBin</varname> and <varname>$outputLib</varname> are also added. (See <xref linkend="multiple-output-file-type-groups" />.)</para>
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>Writing a split derivation</title>
|
||||
<para>Here you find how to write a derivation that produces multiple outputs.</para>
|
||||
<para>In nixpkgs there is a framework supporting multiple-output derivations. It tries to cover most cases by default behavior. You can find the source separated in <<filename>nixpkgs/pkgs/build-support/setup-hooks/multiple-outputs.sh</filename>>; it's relatively well-readable. The whole machinery is triggered by defining the <varname>outputs</varname> attribute to contain the list of desired output names (strings).</para>
|
||||
<programlisting>outputs = [ "bin" "dev" "out" "doc" ];</programlisting>
|
||||
<para>Often such a single line is enough. For each output an equally named environment variable is passed to the builder and contains the path in nix store for that output. By convention, the first output should contain the executable programs provided by the package as that output is used by Nix in string conversions, allowing references to binaries like <literal>${pkgs.perl}/bin/perl</literal> to always work. Typically you also want to have the main <varname>out</varname> output, as it catches any files that didn't get elsewhere.</para>
|
||||
|
||||
<note><para>There is a special handling of the <varname>debug</varname> output, described at <xref linkend="stdenv-separateDebugInfo" />.</para></note>
|
||||
|
||||
<section xml:id="multiple-output-file-type-groups">
|
||||
<title>File type groups</title>
|
||||
<para>The support code currently recognizes some particular kinds of outputs and either instructs the build system of the package to put files into their desired outputs or it moves the files during the fixup phase. Each group of file types has an <varname>outputFoo</varname> variable specifying the output name where they should go. If that variable isn't defined by the derivation writer, it is guessed – a default output name is defined, falling back to other possibilities if the output isn't defined.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><varname>
|
||||
$outputDev</varname></term><listitem><para>
|
||||
is for development-only files. These include C(++) headers, pkg-config, cmake and aclocal files. They go to <varname>dev</varname> or <varname>out</varname> by default.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term><varname>
|
||||
$outputBin</varname></term><listitem><para>
|
||||
is meant for user-facing binaries, typically residing in bin/. They go to <varname>bin</varname> or <varname>out</varname> by default.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term><varname>
|
||||
$outputLib</varname></term><listitem><para>
|
||||
is meant for libraries, typically residing in <filename>lib/</filename> and <filename>libexec/</filename>. They go to <varname>lib</varname> or <varname>out</varname> by default.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term><varname>
|
||||
$outputDoc</varname></term><listitem><para>
|
||||
is for user documentation, typically residing in <filename>share/doc/</filename>. It goes to <varname>doc</varname> or <varname>out</varname> by default.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term><varname>
|
||||
$outputDocdev</varname></term><listitem><para>
|
||||
is for <emphasis>developer</emphasis> documentation. Currently we count gtk-doc and man3 pages in there. It goes to <varname>devdoc</varname> or is removed (!) by default. This is because e.g. gtk-doc tends to be rather large and completely unused by nixpkgs users.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term><varname>
|
||||
$outputMan</varname></term><listitem><para>
|
||||
is for man pages (except for section 3). They go to <varname>man</varname> or <varname>doc</varname> or <varname>$outputBin</varname> by default.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term><varname>
|
||||
$outputInfo</varname></term><listitem><para>
|
||||
is for info pages. They go to <varname>info</varname> or <varname>doc</varname> or <varname>$outputMan</varname> by default.
|
||||
</para></listitem></varlistentry>
|
||||
</variablelist>
|
||||
</section>
|
||||
|
||||
<section><title>Common caveats</title>
|
||||
<itemizedlist>
|
||||
<listitem><para>Some configure scripts don't like some of the parameters passed by default by the framework, e.g. <literal>--docdir=/foo/bar</literal>. You can disable this by setting <literal>setOutputFlags = false;</literal>.</para></listitem>
|
||||
<listitem><para>The outputs of a single derivation can retain references to each other, but note that circular references are not allowed. (And each strongly-connected component would act as a single output anyway.)</para></listitem>
|
||||
<listitem><para>Most of split packages contain their core functionality in libraries. These libraries tend to refer to various kind of data that typically gets into <varname>out</varname>, e.g. locale strings, so there is often no advantage in separating the libraries into <varname>lib</varname>, as keeping them in <varname>out</varname> is easier.</para></listitem>
|
||||
<listitem><para>Some packages have hidden assumptions on install paths, which complicates splitting.</para></listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
</section><!--Writing a split derivation-->
|
||||
|
||||
</chapter>
|
||||
|
||||
14
doc/old/update-upstream-data.txt
Normal file
14
doc/old/update-upstream-data.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Semi-automatic source information updating using "update-upstream-data.sh" script and "src-{,info-}for-*.nix"
|
||||
|
||||
1. Recognizing when a pre-existing package uses this mechanism.
|
||||
|
||||
Packages using this automatical update mechanism have src-info-for-default.nix and src-for-default.nix next to default.nix. src-info-for-default.nix describes getting the freshest source from upstream web site; src-for-default.nix is a generated file with the current data about used source. Both files define a simple attrSet.
|
||||
|
||||
src-info-for-default.nix (for a file grabbed via http) contains at least downloadPage attribute - it is the page we need to look at to find out the latest version. It also contains baseName that is used for automatical generation of package name containing version. It can contain extra data for trickier cases.
|
||||
|
||||
src-for-default.nix will contain advertisedUrl (raw URL chosen on the site; its change prompts regeneration of source data), url for fetchurl, hash, version retrieved from the download URL and suggested package name.
|
||||
|
||||
2. Updating a package
|
||||
|
||||
nixpkgs/pkgs/build-support/upstream-updater directory contains some scripts. The worker script is called update-upstream-data.sh. This script requires main expression name (e.g. default.nix). It can optionally accpet a second parameter, URL which will be used instead of getting one by parsing the downloadPage (version extraction, mirror URL creation etc. will still be run). After running the script, check src-for-default.nix (or replace default.nix with expression name, if there are seceral expressions in the directory) for new version information.
|
||||
|
||||
@@ -366,20 +366,4 @@ it. Place the resulting <filename>package.nix</filename> file into
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-autojump">
|
||||
|
||||
<title>Autojump</title>
|
||||
|
||||
<para>
|
||||
autojump needs the shell integration to be useful but unlike other systems,
|
||||
nix doesn't have a standard share directory location. This is why a
|
||||
<command>autojump-share</command> script is shipped that prints the location
|
||||
of the shared folder. This can then be used in the .bashrc like this:
|
||||
<screen>
|
||||
source "$(autojump-share)/autojump.bash"
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
270
doc/stdenv.xml
270
doc/stdenv.xml
@@ -557,8 +557,8 @@ script) if it exists.</para>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>configureFlags</varname></term>
|
||||
<listitem><para>A list of strings passed as additional arguments to the
|
||||
configure script.</para></listitem>
|
||||
<listitem><para>Additional arguments passed to the configure
|
||||
script.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@@ -658,7 +658,7 @@ nothing.</para>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>makeFlags</varname></term>
|
||||
<listitem><para>A list of strings passed as additional flags to
|
||||
<listitem><para>Additional flags passed to
|
||||
<command>make</command>. These flags are also used by the default
|
||||
install and check phase. For setting make flags specific to the
|
||||
build phase, use <varname>buildFlags</varname> (see
|
||||
@@ -685,7 +685,7 @@ makeFlagsArray=(CFLAGS="-O0 -g" LDFLAGS="-lfoo -lbar")
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>buildFlags</varname> / <varname>buildFlagsArray</varname></term>
|
||||
<listitem><para>A list of strings passed as additional flags to
|
||||
<listitem><para>Additional flags passed to
|
||||
<command>make</command>. Like <varname>makeFlags</varname> and
|
||||
<varname>makeFlagsArray</varname>, but only used by the build
|
||||
phase.</para></listitem>
|
||||
@@ -753,7 +753,7 @@ doCheck = true;</programlisting>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>checkFlags</varname> / <varname>checkFlagsArray</varname></term>
|
||||
<listitem><para>A list of strings passed as additional flags to
|
||||
<listitem><para>Additional flags passed to
|
||||
<command>make</command>. Like <varname>makeFlags</varname> and
|
||||
<varname>makeFlagsArray</varname>, but only used by the check
|
||||
phase.</para></listitem>
|
||||
@@ -808,7 +808,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>installFlags</varname> / <varname>installFlagsArray</varname></term>
|
||||
<listitem><para>A list of strings passed as additional flags to
|
||||
<listitem><para>Additional flags passed to
|
||||
<command>make</command>. Like <varname>makeFlags</varname> and
|
||||
<varname>makeFlagsArray</varname>, but only used by the install
|
||||
phase.</para></listitem>
|
||||
@@ -956,7 +956,7 @@ following:
|
||||
phase.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="stdenv-separateDebugInfo">
|
||||
<varlistentry>
|
||||
<term><varname>separateDebugInfo</varname></term>
|
||||
<listitem><para>If set to <literal>true</literal>, the standard
|
||||
environment will enable debug information in C/C++ builds. After
|
||||
@@ -1169,17 +1169,7 @@ PATH=/nix/store/68afga4khv0w...-coreutils-6.12/bin
|
||||
echo @foo@
|
||||
</programlisting>
|
||||
|
||||
That is, no substitution is performed for undefined variables.</para>
|
||||
|
||||
<para>Environment variables that start with an uppercase letter or an
|
||||
underscore are filtered out,
|
||||
to prevent global variables (like <literal>HOME</literal>) or private
|
||||
variables (like <literal>__ETC_PROFILE_DONE</literal>) from accidentally
|
||||
getting substituted.
|
||||
The variables also have to be valid bash “names”, as
|
||||
defined in the bash manpage (alphanumeric or <literal>_</literal>,
|
||||
must not start with a number).</para>
|
||||
</listitem>
|
||||
That is, no substitution is performed for undefined variables.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -1196,24 +1186,10 @@ echo @foo@
|
||||
<term><function>stripHash</function>
|
||||
<replaceable>path</replaceable></term>
|
||||
<listitem><para>Strips the directory and hash part of a store
|
||||
path, storing the name part in the environment variable
|
||||
<literal>strippedName</literal>. For example:
|
||||
|
||||
<programlisting>
|
||||
stripHash "/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
|
||||
# prints coreutils-8.24
|
||||
echo $strippedName
|
||||
</programlisting>
|
||||
|
||||
If you wish to store the result in another variable, then the
|
||||
following idiom may be useful:
|
||||
|
||||
<programlisting>
|
||||
name="/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
|
||||
someVar=$(stripHash $name; echo $strippedName)
|
||||
</programlisting>
|
||||
|
||||
</para></listitem>
|
||||
path, and prints (on standard output) only the name part. For
|
||||
instance, <literal>stripHash
|
||||
/nix/store/68afga4khv0w...-coreutils-6.12</literal> print
|
||||
<literal>coreutils-6.12</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -1319,25 +1295,6 @@ someVar=$(stripHash $name; echo $strippedName)
|
||||
<envar>GST_PLUGIN_SYSTEM_PATH</envar> environment variable.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>paxctl</term>
|
||||
<listitem><para>Defines the <varname>paxmark</varname> helper for
|
||||
setting per-executable PaX flags on Linux (where it is available by
|
||||
default; on all other platforms, <varname>paxmark</varname> is a no-op).
|
||||
For example, to disable secure memory protections on the executable
|
||||
<replaceable>foo</replaceable>:
|
||||
<programlisting>
|
||||
postFixup = ''
|
||||
paxmark m $out/bin/<replaceable>foo</replaceable>
|
||||
'';
|
||||
</programlisting>
|
||||
The <literal>m</literal> flag is the most common flag and is typically
|
||||
required for applications that employ JIT compilation or otherwise need to
|
||||
execute code generated at run-time. Disabling PaX protections should be
|
||||
considered a last resort: if possible, problematic features should be
|
||||
disabled or patched to work with PaX.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
@@ -1360,209 +1317,6 @@ in the default system locations.</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-hardening-in-nixpkgs"><title>Hardening in Nixpkgs</title>
|
||||
|
||||
<para>There are flags available to harden packages at compile or link-time.
|
||||
These can be toggled using the <varname>stdenv.mkDerivation</varname> parameters
|
||||
<varname>hardeningDisable</varname> and <varname>hardeningEnable</varname>.
|
||||
</para>
|
||||
|
||||
<para>The following flags are enabled by default and might require disabling
|
||||
if the program to package is incompatible.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>format</varname></term>
|
||||
<listitem><para>Adds the <option>-Wformat -Wformat-security
|
||||
-Werror=format-security</option> compiler options. At present,
|
||||
this warns about calls to <varname>printf</varname> and
|
||||
<varname>scanf</varname> functions where the format string is
|
||||
not a string literal and there are no format arguments, as in
|
||||
<literal>printf(foo);</literal>. This may be a security hole
|
||||
if the format string came from untrusted input and contains
|
||||
<literal>%n</literal>.</para>
|
||||
|
||||
<para>This needs to be turned off or fixed for errors similar to:</para>
|
||||
|
||||
<programlisting>
|
||||
/tmp/nix-build-zynaddsubfx-2.5.2.drv-0/zynaddsubfx-2.5.2/src/UI/guimain.cpp:571:28: error: format not a string literal and no format arguments [-Werror=format-security]
|
||||
printf(help_message);
|
||||
^
|
||||
cc1plus: some warnings being treated as errors
|
||||
</programlisting></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>stackprotector</varname></term>
|
||||
<listitem>
|
||||
<para>Adds the <option>-fstack-protector-strong
|
||||
--param ssp-buffer-size=4</option>
|
||||
compiler options. This adds safety checks against stack overwrites
|
||||
rendering many potential code injection attacks into aborting situations.
|
||||
In the best case this turns code injection vulnerabilities into denial
|
||||
of service or into non-issues (depending on the application).</para>
|
||||
|
||||
<para>This needs to be turned off or fixed for errors similar to:</para>
|
||||
|
||||
<programlisting>
|
||||
bin/blib.a(bios_console.o): In function `bios_handle_cup':
|
||||
/tmp/nix-build-ipxe-20141124-5cbdc41.drv-0/ipxe-5cbdc41/src/arch/i386/firmware/pcbios/bios_console.c:86: undefined reference to `__stack_chk_fail'
|
||||
</programlisting></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>fortify</varname></term>
|
||||
<listitem>
|
||||
<para>Adds the <option>-O2 -D_FORTIFY_SOURCE=2</option> compiler
|
||||
options. During code generation the compiler knows a great deal of
|
||||
information about buffer sizes (where possible), and attempts to replace
|
||||
insecure unlimited length buffer function calls with length-limited ones.
|
||||
This is especially useful for old, crufty code. Additionally, format
|
||||
strings in writable memory that contain '%n' are blocked. If an application
|
||||
depends on such a format string, it will need to be worked around.
|
||||
</para>
|
||||
|
||||
<para>Addtionally, some warnings are enabled which might trigger build
|
||||
failures if compiler warnings are treated as errors in the package build.
|
||||
In this case, set <option>NIX_CFLAGS_COMPILE</option> to
|
||||
<option>-Wno-error=warning-type</option>.</para>
|
||||
|
||||
<para>This needs to be turned off or fixed for errors similar to:</para>
|
||||
|
||||
<programlisting>
|
||||
malloc.c:404:15: error: return type is an incomplete type
|
||||
malloc.c:410:19: error: storage size of 'ms' isn't known
|
||||
</programlisting>
|
||||
<programlisting>
|
||||
strdup.h:22:1: error: expected identifier or '(' before '__extension__'
|
||||
</programlisting>
|
||||
<programlisting>
|
||||
strsep.c:65:23: error: register name not specified for 'delim'
|
||||
</programlisting>
|
||||
<programlisting>
|
||||
installwatch.c:3751:5: error: conflicting types for '__open_2'
|
||||
</programlisting>
|
||||
<programlisting>
|
||||
fcntl2.h:50:4: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>pic</varname></term>
|
||||
<listitem>
|
||||
<para>Adds the <option>-fPIC</option> compiler options. This options adds
|
||||
support for position independant code in shared libraries and thus making
|
||||
ASLR possible.</para>
|
||||
<para>Most notably, the Linux kernel, kernel modules and other code
|
||||
not running in an operating system environment like boot loaders won't
|
||||
build with PIC enabled. The compiler will is most cases complain that
|
||||
PIC is not supported for a specific build.
|
||||
</para>
|
||||
|
||||
<para>This needs to be turned off or fixed for assembler errors similar to:</para>
|
||||
|
||||
<programlisting>
|
||||
ccbLfRgg.s: Assembler messages:
|
||||
ccbLfRgg.s:33: Error: missing or invalid displacement expression `private_key_len@GOTOFF'
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>strictoverflow</varname></term>
|
||||
<listitem>
|
||||
<para>Signed integer overflow is undefined behaviour according to the C
|
||||
standard. If it happens, it is an error in the program as it should check
|
||||
for overflow before it can happen, not afterwards. GCC provides built-in
|
||||
functions to perform arithmetic with overflow checking, which are correct
|
||||
and faster than any custom implementation. As a workaround, the option
|
||||
<option>-fno-strict-overflow</option> makes gcc behave as if signed
|
||||
integer overflows were defined.
|
||||
</para>
|
||||
|
||||
<para>This flag should not trigger any build or runtime errors.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>relro</varname></term>
|
||||
<listitem>
|
||||
<para>Adds the <option>-z relro</option> linker option. During program
|
||||
load, several ELF memory sections need to be written to by the linker,
|
||||
but can be turned read-only before turning over control to the program.
|
||||
This prevents some GOT (and .dtors) overwrite attacks, but at least the
|
||||
part of the GOT used by the dynamic linker (.got.plt) is still vulnerable.
|
||||
</para>
|
||||
|
||||
<para>This flag can break dynamic shared object loading. For instance, the
|
||||
module systems of Xorg and OpenCV are incompatible with this flag. In almost
|
||||
all cases the <varname>bindnow</varname> flag must also be disabled and
|
||||
incompatible programs typically fail with similar errors at runtime.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>bindnow</varname></term>
|
||||
<listitem>
|
||||
<para>Adds the <option>-z bindnow</option> linker option. During program
|
||||
load, all dynamic symbols are resolved, allowing for the complete GOT to
|
||||
be marked read-only (due to <varname>relro</varname>). This prevents GOT
|
||||
overwrite attacks. For very large applications, this can incur some
|
||||
performance loss during initial load while symbols are resolved, but this
|
||||
shouldn't be an issue for daemons.
|
||||
</para>
|
||||
|
||||
<para>This flag can break dynamic shared object loading. For instance, the
|
||||
module systems of Xorg and PHP are incompatible with this flag. Programs
|
||||
incompatible with this flag often fail at runtime due to missing symbols,
|
||||
like:</para>
|
||||
|
||||
<programlisting>
|
||||
intel_drv.so: undefined symbol: vgaHWFreeHWRec
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>The following flags are disabled by default and should be enabled
|
||||
for packages that take untrusted input, like network services.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>pie</varname></term>
|
||||
<listitem>
|
||||
<para>Adds the <option>-fPIE</option> compiler and <option>-pie</option>
|
||||
linker options. Position Independent Executables are needed to take
|
||||
advantage of Address Space Layout Randomization, supported by modern
|
||||
kernel versions. While ASLR can already be enforced for data areas in
|
||||
the stack and heap (brk and mmap), the code areas must be compiled as
|
||||
position-independent. Shared libraries already do this with the
|
||||
<varname>pic</varname> flag, so they gain ASLR automatically, but binary
|
||||
.text regions need to be build with <varname>pie</varname> to gain ASLR.
|
||||
When this happens, ROP attacks are much harder since there are no static
|
||||
locations to bounce off of during a memory corruption attack.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>For more in-depth information on these hardening flags and hardening in
|
||||
general, refer to the
|
||||
<link xlink:href="https://wiki.debian.org/Hardening">Debian Wiki</link>,
|
||||
<link xlink:href="https://wiki.ubuntu.com/Security/Features">Ubuntu Wiki</link>,
|
||||
<link xlink:href="https://wiki.gentoo.org/wiki/Project:Hardened">Gentoo Wiki</link>,
|
||||
and the <link xlink:href="https://wiki.archlinux.org/index.php/DeveloperWiki:Security">
|
||||
Arch Wiki</link>.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
|
||||
173
lib/attrsets.nix
173
lib/attrsets.nix
@@ -12,15 +12,9 @@ rec {
|
||||
inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr;
|
||||
|
||||
|
||||
/* Return an attribute from nested attribute sets.
|
||||
|
||||
Example:
|
||||
x = { a = { b = 3; }; }
|
||||
attrByPath ["a" "b"] 6 x
|
||||
=> 3
|
||||
attrByPath ["z" "z"] 6 x
|
||||
=> 6
|
||||
*/
|
||||
/* Return an attribute from nested attribute sets. For instance
|
||||
["x" "y"] applied to some set e returns e.x.y, if it exists. The
|
||||
default value is returned otherwise. */
|
||||
attrByPath = attrPath: default: e:
|
||||
let attr = head attrPath;
|
||||
in
|
||||
@@ -30,15 +24,8 @@ rec {
|
||||
else default;
|
||||
|
||||
/* Return if an attribute from nested attribute set exists.
|
||||
|
||||
Example:
|
||||
x = { a = { b = 3; }; }
|
||||
hasAttrByPath ["a" "b"] x
|
||||
=> true
|
||||
hasAttrByPath ["z" "z"] x
|
||||
=> false
|
||||
|
||||
*/
|
||||
For instance ["x" "y"] applied to some set e returns true, if e.x.y exists. False
|
||||
is returned otherwise. */
|
||||
hasAttrByPath = attrPath: e:
|
||||
let attr = head attrPath;
|
||||
in
|
||||
@@ -48,28 +35,14 @@ rec {
|
||||
else false;
|
||||
|
||||
|
||||
/* Return nested attribute set in which an attribute is set.
|
||||
|
||||
Example:
|
||||
setAttrByPath ["a" "b"] 3
|
||||
=> { a = { b = 3; }; }
|
||||
*/
|
||||
/* Return nested attribute set in which an attribute is set. For instance
|
||||
["x" "y"] applied with some value v returns `x.y = v;' */
|
||||
setAttrByPath = attrPath: value:
|
||||
if attrPath == [] then value
|
||||
else listToAttrs
|
||||
[ { name = head attrPath; value = setAttrByPath (tail attrPath) value; } ];
|
||||
|
||||
|
||||
/* Like `getAttrPath' without a default value. If it doesn't find the
|
||||
path it will throw.
|
||||
|
||||
Example:
|
||||
x = { a = { b = 3; }; }
|
||||
getAttrFromPath ["a" "b"] x
|
||||
=> 3
|
||||
getAttrFromPath ["z" "z"] x
|
||||
=> error: cannot find attribute `z.z'
|
||||
*/
|
||||
getAttrFromPath = attrPath: set:
|
||||
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
|
||||
in attrByPath attrPath (abort errorMsg) set;
|
||||
@@ -136,11 +109,9 @@ rec {
|
||||
) (attrNames set)
|
||||
);
|
||||
|
||||
/* Apply fold functions to values grouped by key.
|
||||
|
||||
Example:
|
||||
foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
|
||||
=> { a = [ 2 3 ]; }
|
||||
/* foldAttrs: apply fold functions to values grouped by key. Eg accumulate values as list:
|
||||
foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
|
||||
=> { a = [ 2 3 ]; }
|
||||
*/
|
||||
foldAttrs = op: nul: list_of_attrs:
|
||||
fold (n: a:
|
||||
@@ -176,12 +147,7 @@ rec {
|
||||
|
||||
|
||||
/* Utility function that creates a {name, value} pair as expected by
|
||||
builtins.listToAttrs.
|
||||
|
||||
Example:
|
||||
nameValuePair "some" 6
|
||||
=> { name = "some"; value = 6; }
|
||||
*/
|
||||
builtins.listToAttrs. */
|
||||
nameValuePair = name: value: { inherit name value; };
|
||||
|
||||
|
||||
@@ -282,76 +248,46 @@ rec {
|
||||
listToAttrs (map (n: nameValuePair n (f n)) names);
|
||||
|
||||
|
||||
/* Check whether the argument is a derivation. Any set with
|
||||
{ type = "derivation"; } counts as a derivation.
|
||||
|
||||
Example:
|
||||
nixpkgs = import <nixpkgs> {}
|
||||
isDerivation nixpkgs.ruby
|
||||
=> true
|
||||
isDerivation "foobar"
|
||||
=> false
|
||||
*/
|
||||
/* Check whether the argument is a derivation. */
|
||||
isDerivation = x: isAttrs x && x ? type && x.type == "derivation";
|
||||
|
||||
/* Converts a store path to a fake derivation. */
|
||||
|
||||
/* Convert a store path to a fake derivation. */
|
||||
toDerivation = path:
|
||||
let
|
||||
path' = builtins.storePath path;
|
||||
res =
|
||||
{ type = "derivation";
|
||||
name = builtins.unsafeDiscardStringContext (builtins.substring 33 (-1) (baseNameOf path'));
|
||||
outPath = path';
|
||||
outputs = [ "out" ];
|
||||
out = res;
|
||||
outputName = "out";
|
||||
};
|
||||
in res;
|
||||
let path' = builtins.storePath path; in
|
||||
{ type = "derivation";
|
||||
name = builtins.unsafeDiscardStringContext (builtins.substring 33 (-1) (baseNameOf path'));
|
||||
outPath = path';
|
||||
outputs = [ "out" ];
|
||||
};
|
||||
|
||||
|
||||
/* If `cond' is true, return the attribute set `as',
|
||||
otherwise an empty attribute set.
|
||||
|
||||
Example:
|
||||
optionalAttrs (true) { my = "set"; }
|
||||
=> { my = "set"; }
|
||||
optionalAttrs (false) { my = "set"; }
|
||||
=> { }
|
||||
*/
|
||||
/* If the Boolean `cond' is true, return the attribute set `as',
|
||||
otherwise an empty attribute set. */
|
||||
optionalAttrs = cond: as: if cond then as else {};
|
||||
|
||||
|
||||
/* Merge sets of attributes and use the function f to merge attributes
|
||||
values.
|
||||
|
||||
Example:
|
||||
zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}]
|
||||
=> { a = ["x" "y"]; }
|
||||
*/
|
||||
values. */
|
||||
zipAttrsWithNames = names: f: sets:
|
||||
listToAttrs (map (name: {
|
||||
inherit name;
|
||||
value = f name (catAttrs name sets);
|
||||
}) names);
|
||||
|
||||
/* Implentation note: Common names appear multiple times in the list of
|
||||
names, hopefully this does not affect the system because the maximal
|
||||
laziness avoid computing twice the same expression and listToAttrs does
|
||||
not care about duplicated attribute names.
|
||||
|
||||
Example:
|
||||
zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
|
||||
=> { a = ["x" "y"]; b = ["z"] }
|
||||
*/
|
||||
# implentation note: Common names appear multiple times in the list of
|
||||
# names, hopefully this does not affect the system because the maximal
|
||||
# laziness avoid computing twice the same expression and listToAttrs does
|
||||
# not care about duplicated attribute names.
|
||||
zipAttrsWith = f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets;
|
||||
/* Like `zipAttrsWith' with `(name: values: value)' as the function.
|
||||
|
||||
Example:
|
||||
zipAttrs [{a = "x";} {a = "y"; b = "z";}]
|
||||
=> { a = ["x" "y"]; b = ["z"] }
|
||||
*/
|
||||
zipAttrs = zipAttrsWith (name: values: values);
|
||||
|
||||
/* backward compatibility */
|
||||
zipWithNames = zipAttrsWithNames;
|
||||
zip = builtins.trace "lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
|
||||
|
||||
|
||||
/* Does the same as the update operator '//' except that attributes are
|
||||
merged until the given pedicate is verified. The predicate should
|
||||
accept 3 arguments which are the path to reach the attribute, a part of
|
||||
@@ -415,15 +351,6 @@ rec {
|
||||
!(isAttrs lhs && isAttrs rhs)
|
||||
) lhs rhs;
|
||||
|
||||
/* Returns true if the pattern is contained in the set. False otherwise.
|
||||
|
||||
FIXME(zimbatm): this example doesn't work !!!
|
||||
|
||||
Example:
|
||||
sys = mkSystem { }
|
||||
matchAttrs { cpu = { bits = 64; }; } sys
|
||||
=> true
|
||||
*/
|
||||
matchAttrs = pattern: attrs:
|
||||
fold or false (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
|
||||
let pat = head values; val = head (tail values); in
|
||||
@@ -432,40 +359,10 @@ rec {
|
||||
else pat == val
|
||||
) [pattern attrs]));
|
||||
|
||||
/* Override only the attributes that are already present in the old set
|
||||
useful for deep-overriding.
|
||||
|
||||
Example:
|
||||
x = { a = { b = 4; c = 3; }; }
|
||||
overrideExisting x { a = { b = 6; d = 2; }; }
|
||||
=> { a = { b = 6; d = 2; }; }
|
||||
*/
|
||||
# override only the attributes that are already present in the old set
|
||||
# useful for deep-overriding
|
||||
overrideExisting = old: new:
|
||||
old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] old.${attr} new)) (attrNames old));
|
||||
|
||||
/* Get a package output.
|
||||
If no output is found, fallback to `.out` and then to the default.
|
||||
|
||||
Example:
|
||||
getOutput "dev" pkgs.openssl
|
||||
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
|
||||
*/
|
||||
getOutput = output: pkg:
|
||||
if pkg.outputUnspecified or false
|
||||
then pkg.${output} or pkg.out or pkg
|
||||
else pkg;
|
||||
|
||||
getBin = getOutput "bin";
|
||||
getLib = getOutput "lib";
|
||||
getDev = getOutput "dev";
|
||||
|
||||
/* Pick the outputs of packages to place in buildInputs */
|
||||
chooseDevOutputs = drvs: builtins.map getDev drvs;
|
||||
|
||||
/*** deprecated stuff ***/
|
||||
|
||||
zipWithNames = zipAttrsWithNames;
|
||||
zip = builtins.trace
|
||||
"lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
|
||||
|
||||
deepSeqAttrs = x: y: deepSeqList (attrValues x) y;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ let inherit (lib) nv nvs; in
|
||||
# nice features:
|
||||
# declaring "optional featuers" is modular. For instance:
|
||||
# flags.curl = {
|
||||
# configureFlags = ["--with-curl=${curl.dev}" "--with-curlwrappers"];
|
||||
# configureFlags = ["--with-curl=${curl}" "--with-curlwrappers"];
|
||||
# buildInputs = [curl openssl];
|
||||
# };
|
||||
# flags.other = { .. }
|
||||
|
||||
@@ -129,7 +129,7 @@ rec {
|
||||
};
|
||||
|
||||
outputsList = map outputToAttrListElement outputs;
|
||||
in commonAttrs // { outputUnspecified = true; };
|
||||
in commonAttrs.${drv.outputName};
|
||||
|
||||
|
||||
/* Strip a derivation of all non-essential attributes, returning
|
||||
|
||||
@@ -19,10 +19,6 @@ rec {
|
||||
traceXMLVal = x: trace (builtins.toXML x) x;
|
||||
traceXMLValMarked = str: x: trace (str + builtins.toXML x) x;
|
||||
|
||||
# strict trace functions (traced structure is fully evaluated and printed)
|
||||
traceSeq = x: y: trace (builtins.deepSeq x x) y;
|
||||
traceValSeq = v: traceVal (builtins.deepSeq v v);
|
||||
|
||||
# this can help debug your code as well - designed to not produce thousands of lines
|
||||
traceShowVal = x : trace (showVal x) x;
|
||||
traceShowValMarked = str: x: trace (str + showVal x) x;
|
||||
@@ -73,9 +69,27 @@ rec {
|
||||
# usage: { testX = allTrue [ true ]; }
|
||||
testAllTrue = expr : { inherit expr; expected = map (x: true) expr; };
|
||||
|
||||
strict = v:
|
||||
trace "Warning: strict is deprecated and will be removed in the next release"
|
||||
(builtins.seq v v);
|
||||
# evaluate everything once so that errors will occur earlier
|
||||
# hacky: traverse attrs by adding a dummy
|
||||
# ignores functions (should this behavior change?) See strictf
|
||||
#
|
||||
# Note: This should be a primop! Something like seq of haskell would be nice to
|
||||
# have as well. It's used fore debugging only anyway
|
||||
strict = x :
|
||||
let
|
||||
traverse = x :
|
||||
if isString x then true
|
||||
else if isAttrs x then
|
||||
if x ? outPath then true
|
||||
else all id (mapAttrsFlatten (n: traverse) x)
|
||||
else if isList x then
|
||||
all id (map traverse x)
|
||||
else if isBool x then true
|
||||
else if isFunction x then true
|
||||
else if isInt x then true
|
||||
else if x == null then true
|
||||
else true; # a (store) path?
|
||||
in if traverse x then x else throw "else never reached";
|
||||
|
||||
# example: (traceCallXml "myfun" id 3) will output something like
|
||||
# calling myfun arg 1: 3 result: 3
|
||||
|
||||
@@ -175,12 +175,6 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "Eclipse Public License 1.0";
|
||||
};
|
||||
|
||||
epson = {
|
||||
fullName = "Seiko Epson Corporation Software License Agreement for Linux";
|
||||
url = https://download.ebz.epson.net/dsc/du/02/eula/global/LINUX_EN.html;
|
||||
free = false;
|
||||
};
|
||||
|
||||
fdl12 = spdx {
|
||||
spdxId = "GFDL-1.2";
|
||||
fullName = "GNU Free Documentation License v1.2";
|
||||
@@ -188,24 +182,13 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
|
||||
fdl13 = spdx {
|
||||
spdxId = "GFDL-1.3";
|
||||
fullName = "GNU Free Documentation License v1.3";
|
||||
fullName = "GNU Free Documentation License v1.2";
|
||||
};
|
||||
|
||||
free = {
|
||||
fullName = "Unspecified free software license";
|
||||
};
|
||||
|
||||
g4sl = {
|
||||
fullName = "Geant4 Software License";
|
||||
url = https://geant4.web.cern.ch/geant4/license/LICENSE.html;
|
||||
};
|
||||
|
||||
geogebra = {
|
||||
fullName = "GeoGebra Non-Commercial License Agreement";
|
||||
url = https://www.geogebra.org/license;
|
||||
free = false;
|
||||
};
|
||||
|
||||
gpl1 = spdx {
|
||||
spdxId = "GPL-1.0";
|
||||
fullName = "GNU General Public License v1.0 only";
|
||||
|
||||
432
lib/lists.nix
432
lib/lists.nix
@@ -6,26 +6,17 @@ rec {
|
||||
|
||||
inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
|
||||
|
||||
/* Create a list consisting of a single element. `singleton x' is
|
||||
sometimes more convenient with respect to indentation than `[x]'
|
||||
when x spans multiple lines.
|
||||
|
||||
Example:
|
||||
singleton "foo"
|
||||
=> [ "foo" ]
|
||||
*/
|
||||
# Create a list consisting of a single element. `singleton x' is
|
||||
# sometimes more convenient with respect to indentation than `[x]'
|
||||
# when x spans multiple lines.
|
||||
singleton = x: [x];
|
||||
|
||||
/* "Fold" a binary function `op' between successive elements of
|
||||
`list' with `nul' as the starting value, i.e., `fold op nul [x_1
|
||||
x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'. (This is
|
||||
Haskell's foldr).
|
||||
|
||||
Example:
|
||||
concat = fold (a: b: a + b) "z"
|
||||
concat [ "a" "b" "c" ]
|
||||
=> "abcz"
|
||||
*/
|
||||
# "Fold" a binary function `op' between successive elements of
|
||||
# `list' with `nul' as the starting value, i.e., `fold op nul [x_1
|
||||
# x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'. (This is
|
||||
# Haskell's foldr).
|
||||
fold = op: nul: list:
|
||||
let
|
||||
len = length list;
|
||||
@@ -35,14 +26,8 @@ rec {
|
||||
else op (elemAt list n) (fold' (n + 1));
|
||||
in fold' 0;
|
||||
|
||||
/* Left fold: `fold op nul [x_1 x_2 ... x_n] == op (... (op (op nul
|
||||
x_1) x_2) ... x_n)'.
|
||||
|
||||
Example:
|
||||
lconcat = foldl (a: b: a + b) "z"
|
||||
lconcat [ "a" "b" "c" ]
|
||||
=> "zabc"
|
||||
*/
|
||||
# Left fold: `fold op nul [x_1 x_2 ... x_n] == op (... (op (op nul
|
||||
# x_1) x_2) ... x_n)'.
|
||||
foldl = op: nul: list:
|
||||
let
|
||||
len = length list;
|
||||
@@ -52,299 +37,145 @@ rec {
|
||||
else op (foldl' (n - 1)) (elemAt list n);
|
||||
in foldl' (length list - 1);
|
||||
|
||||
/* Strict version of foldl.
|
||||
|
||||
The difference is that evaluation is forced upon access. Usually used
|
||||
with small whole results (in contract with lazily-generated list or large
|
||||
lists where only a part is consumed.)
|
||||
*/
|
||||
# Strict version of foldl.
|
||||
foldl' = builtins.foldl' or foldl;
|
||||
|
||||
/* Map with index
|
||||
|
||||
FIXME(zimbatm): why does this start to count at 1?
|
||||
# Map with index: `imap (i: v: "${v}-${toString i}") ["a" "b"] ==
|
||||
# ["a-1" "b-2"]'. FIXME: why does this start to count at 1?
|
||||
imap =
|
||||
if builtins ? genList then
|
||||
f: list: genList (n: f (n + 1) (elemAt list n)) (length list)
|
||||
else
|
||||
f: list:
|
||||
let
|
||||
len = length list;
|
||||
imap' = n:
|
||||
if n == len
|
||||
then []
|
||||
else [ (f (n + 1) (elemAt list n)) ] ++ imap' (n + 1);
|
||||
in imap' 0;
|
||||
|
||||
Example:
|
||||
imap (i: v: "${v}-${toString i}") ["a" "b"]
|
||||
=> [ "a-1" "b-2" ]
|
||||
*/
|
||||
imap = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
|
||||
|
||||
/* Map and concatenate the result.
|
||||
|
||||
Example:
|
||||
concatMap (x: [x] ++ ["z"]) ["a" "b"]
|
||||
=> [ "a" "z" "b" "z" ]
|
||||
*/
|
||||
# Map and concatenate the result.
|
||||
concatMap = f: list: concatLists (map f list);
|
||||
|
||||
/* Flatten the argument into a single list; that is, nested lists are
|
||||
spliced into the top-level lists.
|
||||
|
||||
Example:
|
||||
flatten [1 [2 [3] 4] 5]
|
||||
=> [1 2 3 4 5]
|
||||
flatten 1
|
||||
=> [1]
|
||||
*/
|
||||
# Flatten the argument into a single list; that is, nested lists are
|
||||
# spliced into the top-level lists. E.g., `flatten [1 [2 [3] 4] 5]
|
||||
# == [1 2 3 4 5]' and `flatten 1 == [1]'.
|
||||
flatten = x:
|
||||
if isList x
|
||||
then concatMap (y: flatten y) x
|
||||
then foldl' (x: y: x ++ (flatten y)) [] x
|
||||
else [x];
|
||||
|
||||
/* Remove elements equal to 'e' from a list. Useful for buildInputs.
|
||||
|
||||
Example:
|
||||
remove 3 [ 1 3 4 3 ]
|
||||
=> [ 1 4 ]
|
||||
*/
|
||||
# Remove elements equal to 'e' from a list. Useful for buildInputs.
|
||||
remove = e: filter (x: x != e);
|
||||
|
||||
/* Find the sole element in the list matching the specified
|
||||
predicate, returns `default' if no such element exists, or
|
||||
`multiple' if there are multiple matching elements.
|
||||
|
||||
Example:
|
||||
findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ]
|
||||
=> "multiple"
|
||||
findSingle (x: x == 3) "none" "multiple" [ 1 3 ]
|
||||
=> 3
|
||||
findSingle (x: x == 3) "none" "multiple" [ 1 9 ]
|
||||
=> "none"
|
||||
*/
|
||||
# Find the sole element in the list matching the specified
|
||||
# predicate, returns `default' if no such element exists, or
|
||||
# `multiple' if there are multiple matching elements.
|
||||
findSingle = pred: default: multiple: list:
|
||||
let found = filter pred list; len = length found;
|
||||
in if len == 0 then default
|
||||
else if len != 1 then multiple
|
||||
else head found;
|
||||
|
||||
/* Find the first element in the list matching the specified
|
||||
predicate or returns `default' if no such element exists.
|
||||
|
||||
Example:
|
||||
findFirst (x: x > 3) 7 [ 1 6 4 ]
|
||||
=> 6
|
||||
findFirst (x: x > 9) 7 [ 1 6 4 ]
|
||||
=> 7
|
||||
*/
|
||||
# Find the first element in the list matching the specified
|
||||
# predicate or returns `default' if no such element exists.
|
||||
findFirst = pred: default: list:
|
||||
let found = filter pred list;
|
||||
in if found == [] then default else head found;
|
||||
|
||||
/* Return true iff function `pred' returns true for at least element
|
||||
of `list'.
|
||||
|
||||
Example:
|
||||
any isString [ 1 "a" { } ]
|
||||
=> true
|
||||
any isString [ 1 { } ]
|
||||
=> false
|
||||
*/
|
||||
# Return true iff function `pred' returns true for at least element
|
||||
# of `list'.
|
||||
any = builtins.any or (pred: fold (x: y: if pred x then true else y) false);
|
||||
|
||||
/* Return true iff function `pred' returns true for all elements of
|
||||
`list'.
|
||||
|
||||
Example:
|
||||
all (x: x < 3) [ 1 2 ]
|
||||
=> true
|
||||
all (x: x < 3) [ 1 2 3 ]
|
||||
=> false
|
||||
*/
|
||||
# Return true iff function `pred' returns true for all elements of
|
||||
# `list'.
|
||||
all = builtins.all or (pred: fold (x: y: if pred x then y else false) true);
|
||||
|
||||
/* Count how many times function `pred' returns true for the elements
|
||||
of `list'.
|
||||
|
||||
Example:
|
||||
count (x: x == 3) [ 3 2 3 4 6 ]
|
||||
=> 2
|
||||
*/
|
||||
# Count how many times function `pred' returns true for the elements
|
||||
# of `list'.
|
||||
count = pred: foldl' (c: x: if pred x then c + 1 else c) 0;
|
||||
|
||||
/* Return a singleton list or an empty list, depending on a boolean
|
||||
value. Useful when building lists with optional elements
|
||||
(e.g. `++ optional (system == "i686-linux") flashplayer').
|
||||
|
||||
Example:
|
||||
optional true "foo"
|
||||
=> [ "foo" ]
|
||||
optional false "foo"
|
||||
=> [ ]
|
||||
*/
|
||||
# Return a singleton list or an empty list, depending on a boolean
|
||||
# value. Useful when building lists with optional elements
|
||||
# (e.g. `++ optional (system == "i686-linux") flashplayer').
|
||||
optional = cond: elem: if cond then [elem] else [];
|
||||
|
||||
/* Return a list or an empty list, dependening on a boolean value.
|
||||
|
||||
Example:
|
||||
optionals true [ 2 3 ]
|
||||
=> [ 2 3 ]
|
||||
optionals false [ 2 3 ]
|
||||
=> [ ]
|
||||
*/
|
||||
# Return a list or an empty list, dependening on a boolean value.
|
||||
optionals = cond: elems: if cond then elems else [];
|
||||
|
||||
|
||||
/* If argument is a list, return it; else, wrap it in a singleton
|
||||
list. If you're using this, you should almost certainly
|
||||
reconsider if there isn't a more "well-typed" approach.
|
||||
|
||||
Example:
|
||||
toList [ 1 2 ]
|
||||
=> [ 1 2 ]
|
||||
toList "hi"
|
||||
=> [ "hi "]
|
||||
*/
|
||||
# If argument is a list, return it; else, wrap it in a singleton
|
||||
# list. If you're using this, you should almost certainly
|
||||
# reconsider if there isn't a more "well-typed" approach.
|
||||
toList = x: if isList x then x else [x];
|
||||
|
||||
/* Return a list of integers from `first' up to and including `last'.
|
||||
|
||||
Example:
|
||||
range 2 4
|
||||
=> [ 2 3 4 ]
|
||||
range 3 2
|
||||
=> [ ]
|
||||
*/
|
||||
range = first: last:
|
||||
if first > last then
|
||||
[]
|
||||
# Return a list of integers from `first' up to and including `last'.
|
||||
range =
|
||||
if builtins ? genList then
|
||||
first: last:
|
||||
if first > last
|
||||
then []
|
||||
else genList (n: first + n) (last - first + 1)
|
||||
else
|
||||
genList (n: first + n) (last - first + 1);
|
||||
first: last:
|
||||
if last < first
|
||||
then []
|
||||
else [first] ++ range (first + 1) last;
|
||||
|
||||
/* Splits the elements of a list in two lists, `right' and
|
||||
`wrong', depending on the evaluation of a predicate.
|
||||
|
||||
Example:
|
||||
partition (x: x > 2) [ 5 1 2 3 4 ]
|
||||
=> { right = [ 5 3 4 ]; wrong = [ 1 2 ]; }
|
||||
*/
|
||||
partition = builtins.partition or (pred:
|
||||
# Partition the elements of a list in two lists, `right' and
|
||||
# `wrong', depending on the evaluation of a predicate.
|
||||
partition = pred:
|
||||
fold (h: t:
|
||||
if pred h
|
||||
then { right = [h] ++ t.right; wrong = t.wrong; }
|
||||
else { right = t.right; wrong = [h] ++ t.wrong; }
|
||||
) { right = []; wrong = []; });
|
||||
) { right = []; wrong = []; };
|
||||
|
||||
/* Merges two lists of the same size together. If the sizes aren't the same
|
||||
the merging stops at the shortest. How both lists are merged is defined
|
||||
by the first argument.
|
||||
|
||||
Example:
|
||||
zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
|
||||
=> ["he" "lo"]
|
||||
*/
|
||||
zipListsWith = f: fst: snd:
|
||||
genList
|
||||
(n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd));
|
||||
zipListsWith =
|
||||
if builtins ? genList then
|
||||
f: fst: snd: genList (n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd))
|
||||
else
|
||||
f: fst: snd:
|
||||
let
|
||||
len = min (length fst) (length snd);
|
||||
zipListsWith' = n:
|
||||
if n != len then
|
||||
[ (f (elemAt fst n) (elemAt snd n)) ]
|
||||
++ zipListsWith' (n + 1)
|
||||
else [];
|
||||
in zipListsWith' 0;
|
||||
|
||||
/* Merges two lists of the same size together. If the sizes aren't the same
|
||||
the merging stops at the shortest.
|
||||
|
||||
Example:
|
||||
zipLists [ 1 2 ] [ "a" "b" ]
|
||||
=> [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]
|
||||
*/
|
||||
zipLists = zipListsWith (fst: snd: { inherit fst snd; });
|
||||
|
||||
/* Reverse the order of the elements of a list.
|
||||
|
||||
Example:
|
||||
# Reverse the order of the elements of a list.
|
||||
reverseList =
|
||||
if builtins ? genList then
|
||||
xs: let l = length xs; in genList (n: elemAt xs (l - n - 1)) l
|
||||
else
|
||||
fold (e: acc: acc ++ [ e ]) [];
|
||||
|
||||
reverseList [ "b" "o" "j" ]
|
||||
=> [ "j" "o" "b" ]
|
||||
*/
|
||||
reverseList = xs:
|
||||
let l = length xs; in genList (n: elemAt xs (l - n - 1)) l;
|
||||
|
||||
/* Depth-First Search (DFS) for lists `list != []`.
|
||||
|
||||
`before a b == true` means that `b` depends on `a` (there's an
|
||||
edge from `b` to `a`).
|
||||
|
||||
Examples:
|
||||
|
||||
listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ]
|
||||
== { minimal = "/"; # minimal element
|
||||
visited = [ "/home/user" ]; # seen elements (in reverse order)
|
||||
rest = [ "/home" "other" ]; # everything else
|
||||
}
|
||||
|
||||
listDfs true hasPrefix [ "/home/user" "other" "/" "/home" "/" ]
|
||||
== { cycle = "/"; # cycle encountered at this element
|
||||
loops = [ "/" ]; # and continues to these elements
|
||||
visited = [ "/" "/home/user" ]; # elements leading to the cycle (in reverse order)
|
||||
rest = [ "/home" "other" ]; # everything else
|
||||
|
||||
*/
|
||||
|
||||
listDfs = stopOnCycles: before: list:
|
||||
let
|
||||
dfs' = us: visited: rest:
|
||||
let
|
||||
c = filter (x: before x us) visited;
|
||||
b = partition (x: before x us) rest;
|
||||
in if stopOnCycles && (length c > 0)
|
||||
then { cycle = us; loops = c; inherit visited rest; }
|
||||
else if length b.right == 0
|
||||
then # nothing is before us
|
||||
{ minimal = us; inherit visited rest; }
|
||||
else # grab the first one before us and continue
|
||||
dfs' (head b.right)
|
||||
([ us ] ++ visited)
|
||||
(tail b.right ++ b.wrong);
|
||||
in dfs' (head list) [] (tail list);
|
||||
|
||||
/* Sort a list based on a partial ordering using DFS. This
|
||||
implementation is O(N^2), if your ordering is linear, use `sort`
|
||||
instead.
|
||||
|
||||
`before a b == true` means that `b` should be after `a`
|
||||
in the result.
|
||||
|
||||
Examples:
|
||||
|
||||
toposort hasPrefix [ "/home/user" "other" "/" "/home" ]
|
||||
== { result = [ "/" "/home" "/home/user" "other" ]; }
|
||||
|
||||
toposort hasPrefix [ "/home/user" "other" "/" "/home" "/" ]
|
||||
== { cycle = [ "/home/user" "/" "/" ]; # path leading to a cycle
|
||||
loops = [ "/" ]; } # loops back to these elements
|
||||
|
||||
toposort hasPrefix [ "other" "/home/user" "/home" "/" ]
|
||||
== { result = [ "other" "/" "/home" "/home/user" ]; }
|
||||
|
||||
toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; }
|
||||
|
||||
*/
|
||||
|
||||
toposort = before: list:
|
||||
let
|
||||
dfsthis = listDfs true before list;
|
||||
toporest = toposort before (dfsthis.visited ++ dfsthis.rest);
|
||||
in
|
||||
if length list < 2
|
||||
then # finish
|
||||
{ result = list; }
|
||||
else if dfsthis ? "cycle"
|
||||
then # there's a cycle, starting from the current vertex, return it
|
||||
{ cycle = reverseList ([ dfsthis.cycle ] ++ dfsthis.visited);
|
||||
inherit (dfsthis) loops; }
|
||||
else if toporest ? "cycle"
|
||||
then # there's a cycle somewhere else in the graph, return it
|
||||
toporest
|
||||
# Slow, but short. Can be made a bit faster with an explicit stack.
|
||||
else # there are no cycles
|
||||
{ result = [ dfsthis.minimal ] ++ toporest.result; };
|
||||
|
||||
/* Sort a list based on a comparator function which compares two
|
||||
elements and returns true if the first argument is strictly below
|
||||
the second argument. The returned list is sorted in an increasing
|
||||
order. The implementation does a quick-sort.
|
||||
|
||||
Example:
|
||||
sort (a: b: a < b) [ 5 3 7 ]
|
||||
=> [ 3 5 7 ]
|
||||
*/
|
||||
# Sort a list based on a comparator function which compares two
|
||||
# elements and returns true if the first argument is strictly below
|
||||
# the second argument. The returned list is sorted in an increasing
|
||||
# order. The implementation does a quick-sort.
|
||||
sort = builtins.sort or (
|
||||
strictLess: list:
|
||||
let
|
||||
@@ -362,35 +193,41 @@ rec {
|
||||
if len < 2 then list
|
||||
else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right));
|
||||
|
||||
/* Return the first (at most) N elements of a list.
|
||||
|
||||
Example:
|
||||
take 2 [ "a" "b" "c" "d" ]
|
||||
=> [ "a" "b" ]
|
||||
take 2 [ ]
|
||||
=> [ ]
|
||||
*/
|
||||
take = count: sublist 0 count;
|
||||
# Return the first (at most) N elements of a list.
|
||||
take =
|
||||
if builtins ? genList then
|
||||
count: sublist 0 count
|
||||
else
|
||||
count: list:
|
||||
let
|
||||
len = length list;
|
||||
take' = n:
|
||||
if n == len || n == count
|
||||
then []
|
||||
else
|
||||
[ (elemAt list n) ] ++ take' (n + 1);
|
||||
in take' 0;
|
||||
|
||||
/* Remove the first (at most) N elements of a list.
|
||||
|
||||
Example:
|
||||
drop 2 [ "a" "b" "c" "d" ]
|
||||
=> [ "c" "d" ]
|
||||
drop 2 [ ]
|
||||
=> [ ]
|
||||
*/
|
||||
drop = count: list: sublist count (length list) list;
|
||||
# Remove the first (at most) N elements of a list.
|
||||
drop =
|
||||
if builtins ? genList then
|
||||
count: list: sublist count (length list) list
|
||||
else
|
||||
count: list:
|
||||
let
|
||||
len = length list;
|
||||
drop' = n:
|
||||
if n == -1 || n < count
|
||||
then []
|
||||
else
|
||||
drop' (n - 1) ++ [ (elemAt list n) ];
|
||||
in drop' (len - 1);
|
||||
|
||||
/* Return a list consisting of at most ‘count’ elements of ‘list’,
|
||||
starting at index ‘start’.
|
||||
|
||||
Example:
|
||||
sublist 1 3 [ "a" "b" "c" "d" "e" ]
|
||||
=> [ "b" "c" "d" ]
|
||||
sublist 1 3 [ ]
|
||||
=> [ ]
|
||||
*/
|
||||
# Return a list consisting of at most ‘count’ elements of ‘list’,
|
||||
# starting at index ‘start’.
|
||||
sublist = start: count: list:
|
||||
let len = length list; in
|
||||
genList
|
||||
@@ -399,36 +236,23 @@ rec {
|
||||
else if start + count > len then len - start
|
||||
else count);
|
||||
|
||||
/* Return the last element of a list.
|
||||
|
||||
Example:
|
||||
last [ 1 2 3 ]
|
||||
=> 3
|
||||
*/
|
||||
# Return the last element of a list.
|
||||
last = list:
|
||||
assert list != []; elemAt list (length list - 1);
|
||||
|
||||
/* Return all elements but the last
|
||||
|
||||
Example:
|
||||
init [ 1 2 3 ]
|
||||
=> [ 1 2 ]
|
||||
*/
|
||||
# Return all elements but the last
|
||||
init = list: assert list != []; take (length list - 1) list;
|
||||
|
||||
|
||||
/* FIXME(zimbatm) Not used anywhere
|
||||
*/
|
||||
deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y;
|
||||
|
||||
|
||||
crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f];
|
||||
|
||||
|
||||
/* Remove duplicate elements from the list. O(n^2) complexity.
|
||||
|
||||
Example:
|
||||
|
||||
unique [ 3 2 3 4 ]
|
||||
=> [ 3 2 4 ]
|
||||
*/
|
||||
# Remove duplicate elements from the list. O(n^2) complexity.
|
||||
unique = list:
|
||||
if list == [] then
|
||||
[]
|
||||
@@ -438,20 +262,12 @@ rec {
|
||||
xs = unique (drop 1 list);
|
||||
in [x] ++ remove x xs;
|
||||
|
||||
/* Intersects list 'e' and another list. O(nm) complexity.
|
||||
|
||||
Example:
|
||||
intersectLists [ 1 2 3 ] [ 6 3 2 ]
|
||||
=> [ 3 2 ]
|
||||
*/
|
||||
# Intersects list 'e' and another list. O(nm) complexity.
|
||||
intersectLists = e: filter (x: elem x e);
|
||||
|
||||
/* Subtracts list 'e' from another list. O(nm) complexity.
|
||||
|
||||
Example:
|
||||
subtractLists [ 3 2 ] [ 1 2 3 4 5 3 ]
|
||||
=> [ 1 4 5 ]
|
||||
*/
|
||||
# Subtracts list 'e' from another list. O(nm) complexity.
|
||||
subtractLists = e: filter (x: !(elem x e));
|
||||
|
||||
}
|
||||
|
||||
@@ -10,16 +10,10 @@
|
||||
aaronschif = "Aaron Schif <aaronschif@gmail.com>";
|
||||
abaldeau = "Andreas Baldeau <andreas@baldeau.net>";
|
||||
abbradar = "Nikolay Amiantov <ab@fmap.me>";
|
||||
aboseley = "Adam Boseley <adam.boseley@gmail.com>";
|
||||
abuibrahim = "Ruslan Babayev <ruslan@babayev.com>";
|
||||
adev = "Adrien Devresse <adev@adev.name>";
|
||||
Adjective-Object = "Maxwell Huang-Hobbs <mhuan13@gmail.com>";
|
||||
adnelson = "Allen Nelson <ithinkican@gmail.com>";
|
||||
adolfogc = "Adolfo E. García Castro <adolfo.garcia.cr@gmail.com>";
|
||||
aespinosa = "Allan Espinosa <allan.espinosa@outlook.com>";
|
||||
aflatter = "Alexander Flatter <flatter@fastmail.fm>";
|
||||
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
|
||||
afranchuk = "Alex Franchuk <alex.franchuk@gmail.com>";
|
||||
aherrmann = "Andreas Herrmann <andreash87@gmx.ch>";
|
||||
ak = "Alexander Kjeldaas <ak@formalprivacy.com>";
|
||||
akaWolf = "Artjom Vejsel <akawolf0@gmail.com>";
|
||||
@@ -38,8 +32,6 @@
|
||||
ardumont = "Antoine R. Dumont <eniotna.t@gmail.com>";
|
||||
aristid = "Aristid Breitkreuz <aristidb@gmail.com>";
|
||||
arobyn = "Alexei Robyn <shados@shados.net>";
|
||||
artuuge = "Artur E. Ruuge <artuuge@gmail.com>";
|
||||
ashalkhakov = "Artyom Shalkhakov <artyom.shalkhakov@gmail.com>";
|
||||
asppsa = "Alastair Pharo <asppsa@gmail.com>";
|
||||
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
|
||||
aszlig = "aszlig <aszlig@redmoonstudios.org>";
|
||||
@@ -55,7 +47,6 @@
|
||||
bdimcheff = "Brandon Dimcheff <brandon@dimcheff.com>";
|
||||
benley = "Benjamin Staffin <benley@gmail.com>";
|
||||
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
|
||||
benwbooth = "Ben Booth <benwbooth@gmail.com>";
|
||||
berdario = "Dario Bertini <berdario@gmail.com>";
|
||||
bergey = "Daniel Bergey <bergey@teallabs.org>";
|
||||
bjg = "Brian Gough <bjg@gnu.org>";
|
||||
@@ -65,25 +56,18 @@
|
||||
bodil = "Bodil Stokke <nix@bodil.org>";
|
||||
boothead = "Ben Ford <ben@perurbis.com>";
|
||||
bosu = "Boris Sukholitko <boriss@gmail.com>";
|
||||
bradediger = "Brad Ediger <brad@bradediger.com>";
|
||||
bramd = "Bram Duvigneau <bram@bramd.nl>";
|
||||
bstrik = "Berno Strik <dutchman55@gmx.com>";
|
||||
bzizou = "Bruno Bzeznik <Bruno@bzizou.net>";
|
||||
c0dehero = "CodeHero <codehero@nerdpol.ch>";
|
||||
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
|
||||
campadrenalin = "Philip Horger <campadrenalin@gmail.com>";
|
||||
carlsverre = "Carl Sverre <accounts@carlsverre.com>";
|
||||
cdepillabout = "Dennis Gosnell <cdep.illabout@gmail.com>";
|
||||
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
|
||||
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
||||
chattered = "Phil Scott <me@philscotted.com>";
|
||||
choochootrain = "Hurshal Patel <hurshal@imap.cc>";
|
||||
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
||||
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
||||
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
|
||||
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
||||
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
||||
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
||||
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
|
||||
codsl = "codsl <codsl@riseup.net>";
|
||||
codyopel = "Cody Opel <codyopel@gmail.com>";
|
||||
@@ -91,17 +75,13 @@
|
||||
copumpkin = "Dan Peebles <pumpkingod@gmail.com>";
|
||||
coroa = "Jonas Hörsch <jonas@chaoflow.net>";
|
||||
couchemar = "Andrey Pavlov <couchemar@yandex.ru>";
|
||||
cransom = "Casey Ransom <cransom@hubns.net>";
|
||||
CrystalGamma = "Jona Stubbe <nixos@crystalgamma.de>";
|
||||
cstrahan = "Charles Strahan <charles@cstrahan.com>";
|
||||
cstrahan = "Charles Strahan <charles.c.strahan@gmail.com>";
|
||||
cwoac = "Oliver Matthews <oliver@codersoffortune.net>";
|
||||
DamienCassou = "Damien Cassou <damien@cassou.me>";
|
||||
dasuxullebt = "Christoph-Simon Senjak <christoph.senjak@googlemail.com>";
|
||||
danbst = "Danylo Hlynskyi <abcz2.uprola@gmail.com>";
|
||||
davidak = "David Kleuker <post@davidak.de>";
|
||||
davidrusu = "David Rusu <davidrusu.me@gmail.com>";
|
||||
dbohdan = "Danyil Bohdan <danyil.bohdan@gmail.com>";
|
||||
dbrock = "Daniel Brockman <daniel@brockman.se>";
|
||||
deepfire = "Kosyrev Serge <_deepfire@feelingofgreen.ru>";
|
||||
demin-dmitriy = "Dmitriy Demin <demindf@gmail.com>";
|
||||
DerGuteMoritz = "Moritz Heidkamp <moritz@twoticketsplease.de>";
|
||||
@@ -113,8 +93,6 @@
|
||||
dmalikov = "Dmitry Malikov <malikov.d.y@gmail.com>";
|
||||
dochang = "Desmond O. Chang <dochang@gmail.com>";
|
||||
doublec = "Chris Double <chris.double@double.co.nz>";
|
||||
drets = "Dmytro Rets <dmitryrets@gmail.com>";
|
||||
drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
|
||||
ebzzry = "Rommel Martinez <ebzzry@gmail.com>";
|
||||
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
||||
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
|
||||
@@ -130,21 +108,18 @@
|
||||
ericbmerritt = "Eric Merritt <eric@afiniate.com>";
|
||||
ericsagnes = "Eric Sagnes <eric.sagnes@gmail.com>";
|
||||
erikryb = "Erik Rybakken <erik.rybakken@math.ntnu.no>";
|
||||
ertes = "Ertugrul Söylemez <esz@posteo.de>";
|
||||
ertes = "Ertugrul Söylemez <ertesx@gmx.de>";
|
||||
exi = "Reno Reckling <nixos@reckling.org>";
|
||||
exlevan = "Alexey Levan <exlevan@gmail.com>";
|
||||
expipiplus1 = "Joe Hermaszewski <nix@monoid.al>";
|
||||
fadenb = "Tristan Helmich <tristan.helmich+nixos@gmail.com>";
|
||||
falsifian = "James Cook <james.cook@utoronto.ca>";
|
||||
flosse = "Markus Kohlhase <mail@markus-kohlhase.de>";
|
||||
fluffynukeit = "Daniel Austin <dan@fluffynukeit.com>";
|
||||
fmthoma = "Franz Thoma <f.m.thoma@googlemail.com>";
|
||||
forkk = "Andrew Okin <forkk@forkk.net>";
|
||||
fornever = "Friedrich von Never <friedrich@fornever.me>";
|
||||
fpletz = "Franz Pletz <fpletz@fnordicwalking.de>";
|
||||
fps = "Florian Paul Schmidt <mista.tapas@gmx.net>";
|
||||
fridh = "Frederik Rietdijk <fridh@fridh.nl>";
|
||||
frlan = "Frank Lanitz <frank@frank.uvena.de>";
|
||||
fro_ozen = "fro_ozen <fro_ozen@gmx.de>";
|
||||
ftrvxmtrx = "Siarhei Zirukin <ftrvxmtrx@gmail.com>";
|
||||
funfunctor = "Edward O'Callaghan <eocallaghan@alterapraxis.com>";
|
||||
@@ -155,26 +130,23 @@
|
||||
garrison = "Jim Garrison <jim@garrison.cc>";
|
||||
gavin = "Gavin Rogers <gavin@praxeology.co.uk>";
|
||||
gebner = "Gabriel Ebner <gebner@gebner.org>";
|
||||
gilligan = "Tobias Pflug <tobias.pflug@gmail.com>";
|
||||
gfxmonk = "Tim Cuthbertson <tim@gfxmonk.net>";
|
||||
giogadi = "Luis G. Torres <lgtorres42@gmail.com>";
|
||||
gleber = "Gleb Peregud <gleber.p@gmail.com>";
|
||||
globin = "Robin Gloster <mail@glob.in>";
|
||||
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
|
||||
Gonzih = "Max Gonzih <gonzih@gmail.com>";
|
||||
gpyh = "Yacine Hmito <yacine.hmito@gmail.com>";
|
||||
grahamc = "Graham Christensen <graham@grahamc.com>";
|
||||
gridaphobe = "Eric Seidel <eric@seidel.io>";
|
||||
guibert = "David Guibert <david.guibert@gmail.com>";
|
||||
havvy = "Ryan Scheel <ryan.havvy@gmail.com>";
|
||||
hbunke = "Hendrik Bunke <bunke.hendrik@gmail.com>";
|
||||
hce = "Hans-Christian Esperer <hc@hcesperer.org>";
|
||||
henrytill = "Henry Till <henrytill@gmail.com>";
|
||||
hiberno = "Christian Lask <hiberno@hiberno.net>";
|
||||
hiberno = "Christian Lask <mail@elfsechsundzwanzig.de>";
|
||||
hinton = "Tom Hinton <t@larkery.com>";
|
||||
hrdinka = "Christoph Hrdinka <c.nix@hrdinka.at>";
|
||||
iand675 = "Ian Duncan <ian@iankduncan.com>";
|
||||
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
|
||||
domenkozar = "Domen Kozar <domen@dev.si>";
|
||||
iElectric = "Domen Kozar <domen@dev.si>";
|
||||
igsha = "Igor Sharonov <igor.sharonov@gmail.com>";
|
||||
ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>";
|
||||
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
|
||||
@@ -191,10 +163,7 @@
|
||||
joamaki = "Jussi Maki <joamaki@gmail.com>";
|
||||
joelmo = "Joel Moberg <joel.moberg@gmail.com>";
|
||||
joelteon = "Joel Taylor <me@joelt.io>";
|
||||
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
|
||||
jpbernardy = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
|
||||
jraygauthier = "Raymond Gauthier <jraygauthier@gmail.com>";
|
||||
juliendehos = "Julien Dehos <dehos@lisic.univ-littoral.fr>";
|
||||
jwiegley = "John Wiegley <johnw@newartisans.com>";
|
||||
jwilberding = "Jordan Wilberding <jwilberding@afiniate.com>";
|
||||
jzellner = "Jeff Zellner <jeffz@eml.cc>";
|
||||
@@ -209,7 +178,6 @@
|
||||
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
|
||||
lassulus = "Lassulus <lassulus@gmail.com>";
|
||||
layus = "Guillaume Maudoux <layus.on@gmail.com>";
|
||||
ldesgoui = "Lucas Desgouilles <ldesgoui@gmail.com>";
|
||||
lebastr = "Alexander Lebedev <lebastr@gmail.com>";
|
||||
leenaars = "Michiel Leenaars <ml.software@leenaa.rs>";
|
||||
leonardoce = "Leonardo Cecchi <leonardo.cecchi@gmail.com>";
|
||||
@@ -235,75 +203,52 @@
|
||||
malyn = "Michael Alyn Miller <malyn@strangeGizmo.com>";
|
||||
manveru = "Michael Fellinger <m.fellinger@gmail.com>";
|
||||
marcweber = "Marc Weber <marco-oweber@gmx.de>";
|
||||
markus1189 = "Markus Hauck <markus1189@gmail.com>";
|
||||
markWot = "Markus Wotringer <markus@wotringer.de>";
|
||||
martijnvermaat = "Martijn Vermaat <martijn@vermaat.name>";
|
||||
martingms = "Martin Gammelsæter <martin@mg.am>";
|
||||
matejc = "Matej Cotman <cotman.matej@gmail.com>";
|
||||
mathnerd314 = "Mathnerd314 <mathnerd314.gph+hs@gmail.com>";
|
||||
matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>";
|
||||
maurer = "Matthew Maurer <matthew.r.maurer+nix@gmail.com>";
|
||||
mbakke = "Marius Bakke <mbakke@fastmail.com>";
|
||||
matthewbauer = "Matthew Bauer <mjbauer95@gmail.com>";
|
||||
mbakke = "Marius Bakke <ymse@tuta.io>";
|
||||
mbe = "Brandon Edens <brandonedens@gmail.com>";
|
||||
mboes = "Mathieu Boespflug <mboes@tweag.net>";
|
||||
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
||||
meditans = "Carlo Nucera <meditans@gmail.com>";
|
||||
meisternu = "Matt Miemiec <meister@krutt.org>";
|
||||
mic92 = "Jörg Thalheim <joerg@higgsboson.tk>";
|
||||
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
||||
michalrus = "Michal Rus <m@michalrus.com>";
|
||||
michelk = "Michel Kuhlmann <michel@kuhlmanns.info>";
|
||||
mimadrid = "Miguel Madrid <mimadrid@ucm.es>";
|
||||
mingchuan = "Ming Chuan <ming@culpring.com>";
|
||||
mirdhyn = "Merlin Gaillard <mirdhyn@gmail.com>";
|
||||
mirrexagon = "Andrew Abbott <mirrexagon@mirrexagon.com>";
|
||||
modulistic = "Pablo Costa <modulistic@gmail.com>";
|
||||
mog = "Matthew O'Gorman <mog-lists@rldn.net>";
|
||||
moosingin3space = "Nathan Moos <moosingin3space@gmail.com>";
|
||||
moretea = "Maarten Hoogendoorn <maarten@moretea.nl>";
|
||||
mornfall = "Petr Ročkai <me@mornfall.net>";
|
||||
MostAwesomeDude = "Corbin Simpson <cds@corbinsimpson.com>";
|
||||
mounium = "Katona László <muoniurn@gmail.com>";
|
||||
MP2E = "Cray Elliott <MP2E@archlinux.us>";
|
||||
mpscholten = "Marc Scholten <marc@mpscholten.de>";
|
||||
msackman = "Matthew Sackman <matthew@wellquite.org>";
|
||||
mschristiansen = "Mikkel Christiansen <mikkel@rheosystems.com>";
|
||||
msteen = "Matthijs Steen <emailmatthijs@gmail.com>";
|
||||
mtreskin = "Max Treskin <zerthurd@gmail.com>";
|
||||
mudri = "James Wood <lamudri@gmail.com>";
|
||||
muflax = "Stefan Dorn <mail@muflax.com>";
|
||||
myrl = "Myrl Hex <myrl.0xf@gmail.com>";
|
||||
nand0p = "Fernando Jose Pando <nando@hex7.com>";
|
||||
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
|
||||
Nate-Devv = "Nathan Moore <natedevv@gmail.com>";
|
||||
nckx = "Tobias Geerinckx-Rice <tobias.geerinckx.rice@gmail.com>";
|
||||
nequissimus = "Tim Steinbach <tim@nequissimus.com>";
|
||||
nfjinjing = "Jinjing Wang <nfjinjing@gmail.com>";
|
||||
nico202 = "Nicolò Balzarotti <anothersms@gmail.com>";
|
||||
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
|
||||
NikolaMandic = "Ratko Mladic <nikola@mandic.email>";
|
||||
np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>";
|
||||
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
|
||||
obadz = "obadz <obadz-nixos@obadz.com>";
|
||||
obadz = "obadz <dav-nixos@odav.org>";
|
||||
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
||||
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
|
||||
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
|
||||
olcai = "Erik Timan <dev@timan.info>";
|
||||
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
||||
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
||||
osener = "Ozan Sener <ozan@ozansener.com>";
|
||||
otwieracz = "Slawomir Gonet <slawek@otwiera.cz>";
|
||||
oxij = "Jan Malakhovski <oxij@oxij.org>";
|
||||
page = "Carles Pagès <page@cubata.homelinux.net>";
|
||||
paholg = "Paho Lurie-Gregg <paho@paholg.com>";
|
||||
pakhfn = "Fedor Pakhomov <pakhfn@gmail.com>";
|
||||
palo = "Ingolf Wanger <palipalo9@googlemail.com>";
|
||||
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
||||
pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>";
|
||||
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
|
||||
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
|
||||
peti = "Peter Simons <simons@cryp.to>";
|
||||
philandstuff = "Philip Potter <philip.g.potter@gmail.com>";
|
||||
phile314 = "Philipp Hausmann <nix@314.ch>";
|
||||
Phlogistique = "Noé Rubinstein <noe.rubinstein@gmail.com>";
|
||||
@@ -319,25 +264,17 @@
|
||||
pmiddend = "Philipp Middendorf <pmidden@secure.mailbox.org>";
|
||||
prikhi = "Pavan Rikhi <pavan.rikhi@gmail.com>";
|
||||
profpatsch = "Profpatsch <mail@profpatsch.de>";
|
||||
proglodyte = "Proglodyte <proglodyte23@gmail.com>";
|
||||
pshendry = "Paul Hendry <paul@pshendry.com>";
|
||||
psibi = "Sibi <sibi@psibi.in>";
|
||||
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
|
||||
puffnfresh = "Brian McKenna <brian@brianmckenna.org>";
|
||||
pxc = "Patrick Callahan <patrick.callahan@latitudeengineering.com>";
|
||||
qknight = "Joachim Schiele <js@lastlog.de>";
|
||||
ragge = "Ragnar Dahlen <r.dahlen@gmail.com>";
|
||||
ralith = "Benjamin Saunders <ben.e.saunders@gmail.com>";
|
||||
ramkromberg = "Ram Kromberg <ramkromberg@mail.com>";
|
||||
rardiol = "Ricardo Ardissone <ricardo.ardissone@gmail.com>";
|
||||
rasendubi = "Alexey Shmalko <rasen.dubi@gmail.com>";
|
||||
raskin = "Michael Raskin <7c6f434c@mail.ru>";
|
||||
redbaron = "Maxim Ivanov <ivanov.maxim@gmail.com>";
|
||||
redvers = "Redvers Davies <red@infect.me>";
|
||||
refnil = "Martin Lavoie <broemartino@gmail.com>";
|
||||
relrod = "Ricky Elrod <ricky@elrod.me>";
|
||||
renzo = "Renzo Carbonara <renzocarbonara@gmail.com>";
|
||||
retrry = "Tadas Barzdžius <retrry@gmail.com>";
|
||||
rick68 = "Wei-Ming Yang <rick68@gmail.com>";
|
||||
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
||||
rnhmjoj = "Michele Guerini Rocco <micheleguerinirocco@me.com>";
|
||||
@@ -345,76 +282,60 @@
|
||||
robberer = "Longrin Wischnewski <robberer@freakmail.de>";
|
||||
robbinch = "Robbin C. <robbinch33@gmail.com>";
|
||||
robgssp = "Rob Glossop <robgssp@gmail.com>";
|
||||
roblabla = "Robin Lambertz <robinlambertz+dev@gmail.com>";
|
||||
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
|
||||
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
|
||||
rszibele = "Richard Szibele <richard_szibele@hotmail.com>";
|
||||
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
|
||||
rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>";
|
||||
rvlander = "Gaëtan André <rvlander@gaetanandre.eu>";
|
||||
ryanartecona = "Ryan Artecona <ryanartecona@gmail.com>";
|
||||
ryantm = "Ryan Mulligan <ryan@ryantm.com>";
|
||||
ryansydnor = "Ryan Sydnor <ryan.t.sydnor@gmail.com>";
|
||||
rycee = "Robert Helgesson <robert@rycee.net>";
|
||||
ryneeverett = "Ryne Everett <ryneeverett@gmail.com>";
|
||||
s1lvester = "Markus Silvester <s1lvester@bockhacker.me>";
|
||||
samuelrivas = "Samuel Rivas <samuelrivas@gmail.com>";
|
||||
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
|
||||
schmitthenner = "Fabian Schmitthenner <development@schmitthenner.eu>";
|
||||
schristo = "Scott Christopher <schristopher@konputa.com>";
|
||||
scolobb = "Sergiu Ivanov <sivanov@colimite.fr>";
|
||||
sepi = "Raffael Mancini <raffael@mancini.lu>";
|
||||
seppeljordan = "Sebastian Jordan <sebastian.jordan.mail@googlemail.com>";
|
||||
sheenobu = "Sheena Artrip <sheena.artrip@gmail.com>";
|
||||
sheganinans = "Aistis Raulinaitis <sheganinans@gmail.com>";
|
||||
shell = "Shell Turner <cam.turn@gmail.com>";
|
||||
shlevy = "Shea Levy <shea@shealevy.com>";
|
||||
siddharthist = "Langston Barrett <langston.barrett@gmail.com>";
|
||||
simons = "Peter Simons <simons@cryp.to>";
|
||||
simonvandel = "Simon Vandel Sillesen <simon.vandel@gmail.com>";
|
||||
sjagoe = "Simon Jagoe <simon@simonjagoe.com>";
|
||||
sjmackenzie = "Stewart Mackenzie <setori88@gmail.com>";
|
||||
sjourdois = "Stéphane ‘kwisatz’ Jourdois <sjourdois@gmail.com>";
|
||||
skeidel = "Sven Keidel <svenkeidel@gmail.com>";
|
||||
skrzyp = "Jakub Skrzypnik <jot.skrzyp@gmail.com>";
|
||||
sleexyz = "Sean Lee <freshdried@gmail.com>";
|
||||
smironov = "Sergey Mironov <ierton@gmail.com>";
|
||||
solson = "Scott Olson <scott@solson.me>";
|
||||
spacefrogg = "Michael Raitza <spacefrogg-nixos@meterriblecrew.net>";
|
||||
spencerjanssen = "Spencer Janssen <spencerjanssen@gmail.com>";
|
||||
spinus = "Tomasz Czyż <tomasz.czyz@gmail.com>";
|
||||
sprock = "Roger Mason <rmason@mun.ca>";
|
||||
spwhitt = "Spencer Whitt <sw@swhitt.me>";
|
||||
SShrike = "Severen Redwood <severen@shrike.me>";
|
||||
stephenmw = "Stephen Weinberg <stephen@q5comm.com>";
|
||||
steveej = "Stefan Junker <mail@stefanjunker.de>";
|
||||
swarren83 = "Shawn Warren <shawn.w.warren@gmail.com>";
|
||||
swistak35 = "Rafał Łasocha <me@swistak35.com>";
|
||||
szczyp = "Szczyp <qb@szczyp.com>";
|
||||
sztupi = "Attila Sztupak <attila.sztupak@gmail.com>";
|
||||
taeer = "Taeer Bar-Yam <taeer@necsi.edu>";
|
||||
tailhook = "Paul Colomiets <paul@colomiets.name>";
|
||||
taktoa = "Remy Goldschmidt <taktoa@gmail.com>";
|
||||
tavyc = "Octavian Cerna <octavian.cerna@gmail.com>";
|
||||
teh = "Tom Hunger <tehunger@gmail.com>";
|
||||
telotortium = "Robert Irelan <rirelan@gmail.com>";
|
||||
thall = "Niclas Thall <niclas.thall@gmail.com>";
|
||||
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
|
||||
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
|
||||
theuni = "Christian Theune <ct@flyingcircus.io>";
|
||||
thoughtpolice = "Austin Seipp <aseipp@pobox.com>";
|
||||
timbertson = "Tim Cuthbertson <tim@gfxmonk.net>";
|
||||
titanous = "Jonathan Rudenberg <jonathan@titanous.com>";
|
||||
tohl = "Tomas Hlavaty <tom@logand.com>";
|
||||
tokudan = "Daniel Frank <git@danielfrank.net>";
|
||||
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
|
||||
travisbhartwell = "Travis B. Hartwell <nafai@travishartwell.net>";
|
||||
trino = "Hubert Mühlhans <muehlhans.hubert@ekodia.de>";
|
||||
tstrobel = "Thomas Strobel <4ZKTUB6TEP74PYJOPWIR013S2AV29YUBW5F9ZH2F4D5UMJUJ6S@hash.domains>";
|
||||
tstrobel = "Thomas Strobel <ts468@cam.ac.uk>";
|
||||
ttuegel = "Thomas Tuegel <ttuegel@gmail.com>";
|
||||
tv = "Tomislav Viljetić <tv@shackspace.de>";
|
||||
tvestelind = "Tomas Vestelind <tomas.vestelind@fripost.org>";
|
||||
twey = "James ‘Twey’ Kay <twey@twey.co.uk>";
|
||||
uralbash = "Svintsov Dmitry <root@uralbash.ru>";
|
||||
urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>";
|
||||
vandenoever = "Jos van den Oever <jos@vandenoever.info>";
|
||||
vanzef = "Ivan Solyankin <vanzef@gmail.com>";
|
||||
@@ -426,7 +347,6 @@
|
||||
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
||||
vmandela = "Venkateswara Rao Mandela <venkat.mandela@gmail.com>";
|
||||
vozz = "Oliver Hunt <oliver.huntuk@gmail.com>";
|
||||
vrthra = "Rahul Gopinath <rahul@gopinath.org>";
|
||||
wedens = "wedens <kirill.wedens@gmail.com>";
|
||||
willtim = "Tim Philip Williams <tim.williams.public@gmail.com>";
|
||||
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
|
||||
@@ -438,12 +358,10 @@
|
||||
wscott = "Wayne Scott <wsc9tt@gmail.com>";
|
||||
wyvie = "Elijah Rum <elijahrum@gmail.com>";
|
||||
yarr = "Dmitry V. <savraz@gmail.com>";
|
||||
yurrriq = "Eric Bailey <eric@ericb.me>";
|
||||
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
||||
zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
|
||||
zef = "Zef Hemel <zef@zef.me>";
|
||||
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
|
||||
zohl = "Al Zohali <zohl@fmap.me>";
|
||||
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
|
||||
amiloradovsky = "Andrew Miloradovsky <miloradovsky@gmail.com>";
|
||||
}
|
||||
|
||||
@@ -105,12 +105,8 @@ rec {
|
||||
/* Massage a module into canonical form, that is, a set consisting
|
||||
of ‘options’, ‘config’ and ‘imports’ attributes. */
|
||||
unifyModuleSyntax = file: key: m:
|
||||
let metaSet = if m ? meta
|
||||
then { meta = m.meta; }
|
||||
else {};
|
||||
in
|
||||
if m ? config || m ? options then
|
||||
let badAttrs = removeAttrs m ["imports" "options" "config" "key" "_file" "meta"]; in
|
||||
let badAttrs = removeAttrs m ["imports" "options" "config" "key" "_file"]; in
|
||||
if badAttrs != {} then
|
||||
throw "Module `${key}' has an unsupported attribute `${head (attrNames badAttrs)}'. This is caused by assignments to the top-level attributes `config' or `options'."
|
||||
else
|
||||
@@ -118,14 +114,14 @@ rec {
|
||||
key = toString m.key or key;
|
||||
imports = m.imports or [];
|
||||
options = m.options or {};
|
||||
config = mkMerge [ (m.config or {}) metaSet ];
|
||||
config = m.config or {};
|
||||
}
|
||||
else
|
||||
{ file = m._file or file;
|
||||
key = toString m.key or key;
|
||||
imports = m.require or [] ++ m.imports or [];
|
||||
options = {};
|
||||
config = mkMerge [ (removeAttrs m ["key" "_file" "require" "imports"]) metaSet ];
|
||||
config = removeAttrs m ["key" "_file" "require" "imports"];
|
||||
};
|
||||
|
||||
applyIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
|
||||
@@ -507,25 +503,19 @@ rec {
|
||||
/* Return a module that causes a warning to be shown if the
|
||||
specified option is defined. For example,
|
||||
|
||||
mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "<replacement instructions>"
|
||||
mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ]
|
||||
|
||||
causes a warning if the user defines boot.loader.grub.bootDevice.
|
||||
|
||||
replacementInstructions is a string that provides instructions on
|
||||
how to achieve the same functionality without the removed option,
|
||||
or alternatively a reasoning why the functionality is not needed.
|
||||
replacementInstructions SHOULD be provided!
|
||||
*/
|
||||
mkRemovedOptionModule = optionName: replacementInstructions:
|
||||
mkRemovedOptionModule = optionName:
|
||||
{ options, ... }:
|
||||
{ options = setAttrByPath optionName (mkOption {
|
||||
visible = false;
|
||||
});
|
||||
config.warnings =
|
||||
let opt = getAttrFromPath optionName options; in
|
||||
optional opt.isDefined ''
|
||||
The option definition `${showOption optionName}' in ${showFiles opt.files} no longer has any effect; please remove it.
|
||||
${replacementInstructions}'';
|
||||
optional opt.isDefined
|
||||
"The option definition `${showOption optionName}' in ${showFiles opt.files} no longer has any effect; please remove it.";
|
||||
};
|
||||
|
||||
/* Return a module that causes a warning to be shown if the
|
||||
@@ -564,10 +554,12 @@ rec {
|
||||
apply = x: use (toOf config);
|
||||
});
|
||||
config = {
|
||||
/*
|
||||
warnings =
|
||||
let opt = getAttrFromPath from options; in
|
||||
optional (warn && opt.isDefined)
|
||||
"The option `${showOption from}' defined in ${showFiles opt.files} has been renamed to `${showOption to}'.";
|
||||
*/
|
||||
} // setAttrByPath to (mkAliasDefinitions (getAttrFromPath from options));
|
||||
};
|
||||
|
||||
|
||||
@@ -4,11 +4,6 @@ let lib = import ./default.nix; in
|
||||
|
||||
rec {
|
||||
|
||||
# Returns the type of a path: regular (for file), symlink, or directory
|
||||
pathType = p: with builtins; getAttr (baseNameOf p) (readDir (dirOf p));
|
||||
|
||||
# Returns true if the path exists and is a directory, false otherwise
|
||||
pathIsDirectory = p: if builtins.pathExists p then (pathType p) == "directory" else false;
|
||||
|
||||
# Bring in a path as a source, filtering out all Subversion and CVS
|
||||
# directories, as well as backup files (*~).
|
||||
@@ -20,9 +15,7 @@ rec {
|
||||
lib.hasSuffix "~" baseName ||
|
||||
# Filter out generates files.
|
||||
lib.hasSuffix ".o" baseName ||
|
||||
lib.hasSuffix ".so" baseName ||
|
||||
# Filter out nix-build result symlinks
|
||||
(type == "symlink" && lib.hasPrefix "result" baseName)
|
||||
lib.hasSuffix ".so" baseName
|
||||
);
|
||||
in src: builtins.filterSource filter src;
|
||||
|
||||
@@ -36,32 +29,4 @@ rec {
|
||||
in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
|
||||
in builtins.filterSource filter path;
|
||||
|
||||
|
||||
# Get the commit id of a git repo
|
||||
# Example: commitIdFromGitRepo <nixpkgs/.git>
|
||||
commitIdFromGitRepo =
|
||||
let readCommitFromFile = path: file:
|
||||
with builtins;
|
||||
let fileName = toString path + "/" + file;
|
||||
packedRefsName = toString path + "/packed-refs";
|
||||
in if lib.pathExists fileName
|
||||
then
|
||||
let fileContent = lib.fileContents fileName;
|
||||
# Sometimes git stores the commitId directly in the file but
|
||||
# sometimes it stores something like: «ref: refs/heads/branch-name»
|
||||
matchRef = match "^ref: (.*)$" fileContent;
|
||||
in if isNull matchRef
|
||||
then fileContent
|
||||
else readCommitFromFile path (lib.head matchRef)
|
||||
# Sometimes, the file isn't there at all and has been packed away in the
|
||||
# packed-refs file, so we have to grep through it:
|
||||
else if lib.pathExists packedRefsName
|
||||
then
|
||||
let fileContent = readFile packedRefsName;
|
||||
matchRef = match (".*\n([^\n ]*) " + file + "\n.*") fileContent;
|
||||
in if isNull matchRef
|
||||
then throw ("Could not find " + file + " in " + packedRefsName)
|
||||
else lib.head matchRef
|
||||
else throw ("Not a .git directory: " + path);
|
||||
in lib.flip readCommitFromFile "HEAD";
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ Usage:
|
||||
Attention:
|
||||
|
||||
let
|
||||
pkgs = (import <nixpkgs>) {};
|
||||
pkgs = (import /etc/nixos/nixpkgs/pkgs/top-level/all-packages.nix) {};
|
||||
in let
|
||||
inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap;
|
||||
inherit (pkgs.lib) id;
|
||||
|
||||
388
lib/strings.nix
388
lib/strings.nix
@@ -10,216 +10,102 @@ rec {
|
||||
|
||||
inherit (builtins) stringLength substring head tail isString replaceStrings;
|
||||
|
||||
/* Concatenate a list of strings.
|
||||
|
||||
Example:
|
||||
concatStrings ["foo" "bar"]
|
||||
=> "foobar"
|
||||
*/
|
||||
concatStrings = builtins.concatStringsSep "";
|
||||
# Concatenate a list of strings.
|
||||
concatStrings =
|
||||
if builtins ? concatStringsSep then
|
||||
builtins.concatStringsSep ""
|
||||
else
|
||||
lib.foldl' (x: y: x + y) "";
|
||||
|
||||
/* Map a function over a list and concatenate the resulting strings.
|
||||
|
||||
Example:
|
||||
concatMapStrings (x: "a" + x) ["foo" "bar"]
|
||||
=> "afooabar"
|
||||
*/
|
||||
# Map a function over a list and concatenate the resulting strings.
|
||||
concatMapStrings = f: list: concatStrings (map f list);
|
||||
|
||||
/* Like `concatMapStrings' except that the f functions also gets the
|
||||
position as a parameter.
|
||||
|
||||
Example:
|
||||
concatImapStrings (pos: x: "${toString pos}-${x}") ["foo" "bar"]
|
||||
=> "1-foo2-bar"
|
||||
*/
|
||||
concatImapStrings = f: list: concatStrings (lib.imap f list);
|
||||
|
||||
/* Place an element between each element of a list
|
||||
|
||||
Example:
|
||||
intersperse "/" ["usr" "local" "bin"]
|
||||
=> ["usr" "/" "local" "/" "bin"].
|
||||
*/
|
||||
# Place an element between each element of a list, e.g.,
|
||||
# `intersperse "," ["a" "b" "c"]' returns ["a" "," "b" "," "c"].
|
||||
intersperse = separator: list:
|
||||
if list == [] || length list == 1
|
||||
then list
|
||||
else tail (lib.concatMap (x: [separator x]) list);
|
||||
|
||||
/* Concatenate a list of strings with a separator between each element
|
||||
|
||||
Example:
|
||||
concatStringsSep "/" ["usr" "local" "bin"]
|
||||
=> "usr/local/bin"
|
||||
*/
|
||||
# Concatenate a list of strings with a separator between each element, e.g.
|
||||
# concatStringsSep " " ["foo" "bar" "xyzzy"] == "foo bar xyzzy"
|
||||
concatStringsSep = builtins.concatStringsSep or (separator: list:
|
||||
concatStrings (intersperse separator list));
|
||||
|
||||
/* First maps over the list and then concatenates it.
|
||||
|
||||
Example:
|
||||
concatMapStringsSep "-" (x: toUpper x) ["foo" "bar" "baz"]
|
||||
=> "FOO-BAR-BAZ"
|
||||
*/
|
||||
concatMapStringsSep = sep: f: list: concatStringsSep sep (map f list);
|
||||
|
||||
/* First imaps over the list and then concatenates it.
|
||||
|
||||
Example:
|
||||
|
||||
concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ]
|
||||
=> "6-3-2"
|
||||
*/
|
||||
concatImapStringsSep = sep: f: list: concatStringsSep sep (lib.imap f list);
|
||||
|
||||
/* Construct a Unix-style search path consisting of each `subDir"
|
||||
directory of the given list of packages.
|
||||
|
||||
Example:
|
||||
makeSearchPath "bin" ["/root" "/usr" "/usr/local"]
|
||||
=> "/root/bin:/usr/bin:/usr/local/bin"
|
||||
makeSearchPath "bin" ["/"]
|
||||
=> "//bin"
|
||||
*/
|
||||
# Construct a Unix-style search path consisting of each `subDir"
|
||||
# directory of the given list of packages. For example,
|
||||
# `makeSearchPath "bin" ["x" "y" "z"]' returns "x/bin:y/bin:z/bin".
|
||||
makeSearchPath = subDir: packages:
|
||||
concatStringsSep ":" (map (path: path + "/" + subDir) packages);
|
||||
|
||||
/* Construct a Unix-style search path, using given package output.
|
||||
If no output is found, fallback to `.out` and then to the default.
|
||||
|
||||
Example:
|
||||
makeSearchPathOutput "dev" "bin" [ pkgs.openssl pkgs.zlib ]
|
||||
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev/bin:/nix/store/wwh7mhwh269sfjkm6k5665b5kgp7jrk2-zlib-1.2.8/bin"
|
||||
*/
|
||||
makeSearchPathOutput = output: subDir: pkgs: makeSearchPath subDir (map (lib.getOutput output) pkgs);
|
||||
# Construct a library search path (such as RPATH) containing the
|
||||
# libraries for a set of packages, e.g. "${pkg1}/lib:${pkg2}/lib:...".
|
||||
makeLibraryPath = makeSearchPath "lib";
|
||||
|
||||
/* Construct a library search path (such as RPATH) containing the
|
||||
libraries for a set of packages
|
||||
|
||||
Example:
|
||||
makeLibraryPath [ "/usr" "/usr/local" ]
|
||||
=> "/usr/lib:/usr/local/lib"
|
||||
pkgs = import <nixpkgs> { }
|
||||
makeLibraryPath [ pkgs.openssl pkgs.zlib ]
|
||||
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r/lib:/nix/store/wwh7mhwh269sfjkm6k5665b5kgp7jrk2-zlib-1.2.8/lib"
|
||||
*/
|
||||
makeLibraryPath = makeSearchPathOutput "lib" "lib";
|
||||
|
||||
/* Construct a binary search path (such as $PATH) containing the
|
||||
binaries for a set of packages.
|
||||
|
||||
Example:
|
||||
makeBinPath ["/root" "/usr" "/usr/local"]
|
||||
=> "/root/bin:/usr/bin:/usr/local/bin"
|
||||
*/
|
||||
makeBinPath = makeSearchPathOutput "bin" "bin";
|
||||
# Construct a binary search path (such as $PATH) containing the
|
||||
# binaries for a set of packages, e.g. "${pkg1}/bin:${pkg2}/bin:...".
|
||||
makeBinPath = makeSearchPath "bin";
|
||||
|
||||
|
||||
/* Construct a perl search path (such as $PERL5LIB)
|
||||
# Idem for Perl search paths.
|
||||
makePerlPath = makeSearchPath "lib/perl5/site_perl";
|
||||
|
||||
FIXME(zimbatm): this should be moved in perl-specific code
|
||||
|
||||
Example:
|
||||
pkgs = import <nixpkgs> { }
|
||||
makePerlPath [ pkgs.perlPackages.NetSMTP ]
|
||||
=> "/nix/store/n0m1fk9c960d8wlrs62sncnadygqqc6y-perl-Net-SMTP-1.25/lib/perl5/site_perl"
|
||||
*/
|
||||
makePerlPath = makeSearchPathOutput "lib" "lib/perl5/site_perl";
|
||||
|
||||
/* Dependening on the boolean `cond', return either the given string
|
||||
or the empty string. Useful to contatenate against a bigger string.
|
||||
|
||||
Example:
|
||||
optionalString true "some-string"
|
||||
=> "some-string"
|
||||
optionalString false "some-string"
|
||||
=> ""
|
||||
*/
|
||||
# Dependening on the boolean `cond', return either the given string
|
||||
# or the empty string.
|
||||
optionalString = cond: string: if cond then string else "";
|
||||
|
||||
/* Determine whether a string has given prefix.
|
||||
|
||||
Example:
|
||||
hasPrefix "foo" "foobar"
|
||||
=> true
|
||||
hasPrefix "foo" "barfoo"
|
||||
=> false
|
||||
*/
|
||||
# Determine whether a string has given prefix/suffix.
|
||||
hasPrefix = pref: str:
|
||||
substring 0 (stringLength pref) str == pref;
|
||||
|
||||
/* Determine whether a string has given suffix.
|
||||
|
||||
Example:
|
||||
hasSuffix "foo" "foobar"
|
||||
=> false
|
||||
hasSuffix "foo" "barfoo"
|
||||
=> true
|
||||
*/
|
||||
hasSuffix = suffix: content:
|
||||
hasSuffix = suff: str:
|
||||
let
|
||||
lenContent = stringLength content;
|
||||
lenSuffix = stringLength suffix;
|
||||
in lenContent >= lenSuffix &&
|
||||
substring (lenContent - lenSuffix) lenContent content == suffix;
|
||||
lenStr = stringLength str;
|
||||
lenSuff = stringLength suff;
|
||||
in lenStr >= lenSuff &&
|
||||
substring (lenStr - lenSuff) lenStr str == suff;
|
||||
|
||||
/* Convert a string to a list of characters (i.e. singleton strings).
|
||||
This allows you to, e.g., map a function over each character. However,
|
||||
note that this will likely be horribly inefficient; Nix is not a
|
||||
general purpose programming language. Complex string manipulations
|
||||
should, if appropriate, be done in a derivation.
|
||||
Also note that Nix treats strings as a list of bytes and thus doesn't
|
||||
handle unicode.
|
||||
|
||||
Example:
|
||||
stringToCharacters ""
|
||||
=> [ ]
|
||||
stringToCharacters "abc"
|
||||
=> [ "a" "b" "c" ]
|
||||
stringToCharacters "💩"
|
||||
=> [ "<EFBFBD>" "<EFBFBD>" "<EFBFBD>" "<EFBFBD>" ]
|
||||
*/
|
||||
# Convert a string to a list of characters (i.e. singleton strings).
|
||||
# For instance, "abc" becomes ["a" "b" "c"]. This allows you to,
|
||||
# e.g., map a function over each character. However, note that this
|
||||
# will likely be horribly inefficient; Nix is not a general purpose
|
||||
# programming language. Complex string manipulations should, if
|
||||
# appropriate, be done in a derivation.
|
||||
stringToCharacters = s:
|
||||
map (p: substring p 1 s) (lib.range 0 (stringLength s - 1));
|
||||
|
||||
/* Manipulate a string character by character and replace them by
|
||||
strings before concatenating the results.
|
||||
|
||||
Example:
|
||||
stringAsChars (x: if x == "a" then "i" else x) "nax"
|
||||
=> "nix"
|
||||
*/
|
||||
# Manipulate a string charactter by character and replace them by
|
||||
# strings before concatenating the results.
|
||||
stringAsChars = f: s:
|
||||
concatStrings (
|
||||
map f (stringToCharacters s)
|
||||
);
|
||||
|
||||
/* Escape occurrence of the elements of ‘list’ in ‘string’ by
|
||||
prefixing it with a backslash.
|
||||
|
||||
Example:
|
||||
escape ["(" ")"] "(foo)"
|
||||
=> "\\(foo\\)"
|
||||
*/
|
||||
# Escape occurrence of the elements of ‘list’ in ‘string’ by
|
||||
# prefixing it with a backslash. For example, ‘escape ["(" ")"]
|
||||
# "(foo)"’ returns the string ‘\(foo\)’.
|
||||
escape = list: replaceChars list (map (c: "\\${c}") list);
|
||||
|
||||
/* Quote string to be used safely within the Bourne shell.
|
||||
|
||||
Example:
|
||||
escapeShellArg "esc'ape\nme"
|
||||
=> "'esc'\\''ape\nme'"
|
||||
*/
|
||||
escapeShellArg = arg: "'${replaceStrings ["'"] ["'\\''"] (toString arg)}'";
|
||||
# Escape all characters that have special meaning in the Bourne shell.
|
||||
escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]");
|
||||
|
||||
/* Quote all arguments to be safely passed to the Bourne shell.
|
||||
|
||||
Example:
|
||||
escapeShellArgs ["one" "two three" "four'five"]
|
||||
=> "'one' 'two three' 'four'\\''five'"
|
||||
*/
|
||||
escapeShellArgs = concatMapStringsSep " " escapeShellArg;
|
||||
|
||||
/* Obsolete - use replaceStrings instead. */
|
||||
# Obsolete - use replaceStrings instead.
|
||||
replaceChars = builtins.replaceStrings or (
|
||||
del: new: s:
|
||||
let
|
||||
@@ -233,52 +119,21 @@ rec {
|
||||
in
|
||||
stringAsChars subst s);
|
||||
|
||||
|
||||
# Case conversion utilities.
|
||||
lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz";
|
||||
upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
/* Converts an ASCII string to lower-case.
|
||||
|
||||
Example:
|
||||
toLower "HOME"
|
||||
=> "home"
|
||||
*/
|
||||
toLower = replaceChars upperChars lowerChars;
|
||||
|
||||
/* Converts an ASCII string to upper-case.
|
||||
|
||||
Example:
|
||||
toUpper "home"
|
||||
=> "HOME"
|
||||
*/
|
||||
toUpper = replaceChars lowerChars upperChars;
|
||||
|
||||
/* Appends string context from another string. This is an implementation
|
||||
detail of Nix.
|
||||
|
||||
Strings in Nix carry an invisible `context' which is a list of strings
|
||||
representing store paths. If the string is later used in a derivation
|
||||
attribute, the derivation will properly populate the inputDrvs and
|
||||
inputSrcs.
|
||||
|
||||
Example:
|
||||
pkgs = import <nixpkgs> { };
|
||||
addContextFrom pkgs.coreutils "bar"
|
||||
=> "bar"
|
||||
*/
|
||||
# Appends string context from another string.
|
||||
addContextFrom = a: b: substring 0 0 a + b;
|
||||
|
||||
/* Cut a string with a separator and produces a list of strings which
|
||||
were separated by this separator.
|
||||
|
||||
NOTE: this function is not performant and should never be used.
|
||||
|
||||
Example:
|
||||
splitString "." "foo.bar.baz"
|
||||
=> [ "foo" "bar" "baz" ]
|
||||
splitString "/" "/usr/local/bin"
|
||||
=> [ "" "usr" "local" "bin" ]
|
||||
*/
|
||||
# Cut a string with a separator and produces a list of strings which
|
||||
# were separated by this separator; e.g., `splitString "."
|
||||
# "foo.bar.baz"' returns ["foo" "bar" "baz"].
|
||||
splitString = _sep: _s:
|
||||
let
|
||||
sep = addContextFrom _s _sep;
|
||||
@@ -302,15 +157,10 @@ rec {
|
||||
in
|
||||
recurse 0 0;
|
||||
|
||||
/* Return the suffix of the second argument if the first argument matches
|
||||
its prefix.
|
||||
|
||||
Example:
|
||||
removePrefix "foo." "foo.bar.baz"
|
||||
=> "bar.baz"
|
||||
removePrefix "xxx" "foo.bar.baz"
|
||||
=> "foo.bar.baz"
|
||||
*/
|
||||
# return the suffix of the second argument if the first argument match its
|
||||
# prefix. e.g.,
|
||||
# `removePrefix "foo." "foo.bar.baz"' returns "bar.baz".
|
||||
removePrefix = pre: s:
|
||||
let
|
||||
preLen = stringLength pre;
|
||||
@@ -321,15 +171,6 @@ rec {
|
||||
else
|
||||
s;
|
||||
|
||||
/* Return the prefix of the second argument if the first argument matches
|
||||
its suffix.
|
||||
|
||||
Example:
|
||||
removeSuffix "front" "homefront"
|
||||
=> "home"
|
||||
removeSuffix "xxx" "homefront"
|
||||
=> "homefront"
|
||||
*/
|
||||
removeSuffix = suf: s:
|
||||
let
|
||||
sufLen = stringLength suf;
|
||||
@@ -340,54 +181,25 @@ rec {
|
||||
else
|
||||
s;
|
||||
|
||||
/* Return true iff string v1 denotes a version older than v2.
|
||||
|
||||
Example:
|
||||
versionOlder "1.1" "1.2"
|
||||
=> true
|
||||
versionOlder "1.1" "1.1"
|
||||
=> false
|
||||
*/
|
||||
# Return true iff string v1 denotes a version older than v2.
|
||||
versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1;
|
||||
|
||||
/* Return true iff string v1 denotes a version equal to or newer than v2.
|
||||
|
||||
Example:
|
||||
versionAtLeast "1.1" "1.0"
|
||||
=> true
|
||||
versionAtLeast "1.1" "1.1"
|
||||
=> true
|
||||
versionAtLeast "1.1" "1.2"
|
||||
=> false
|
||||
*/
|
||||
# Return true iff string v1 denotes a version equal to or newer than v2.
|
||||
versionAtLeast = v1: v2: !versionOlder v1 v2;
|
||||
|
||||
/* This function takes an argument that's either a derivation or a
|
||||
derivation's "name" attribute and extracts the version part from that
|
||||
argument.
|
||||
|
||||
Example:
|
||||
getVersion "youtube-dl-2016.01.01"
|
||||
=> "2016.01.01"
|
||||
getVersion pkgs.youtube-dl
|
||||
=> "2016.01.01"
|
||||
*/
|
||||
getVersion = x:
|
||||
let
|
||||
parse = drv: (builtins.parseDrvName drv).version;
|
||||
in if isString x
|
||||
then parse x
|
||||
else x.version or (parse x.name);
|
||||
# This function takes an argument that's either a derivation or a
|
||||
# derivation's "name" attribute and extracts the version part from that
|
||||
# argument. For example:
|
||||
#
|
||||
# lib.getVersion "youtube-dl-2016.01.01" ==> "2016.01.01"
|
||||
# lib.getVersion pkgs.youtube-dl ==> "2016.01.01"
|
||||
getVersion = x: (builtins.parseDrvName (x.name or x)).version;
|
||||
|
||||
/* Extract name with version from URL. Ask for separator which is
|
||||
supposed to start extension.
|
||||
|
||||
Example:
|
||||
nameFromURL "https://nixos.org/releases/nix/nix-1.7/nix-1.7-x86_64-linux.tar.bz2" "-"
|
||||
=> "nix"
|
||||
nameFromURL "https://nixos.org/releases/nix/nix-1.7/nix-1.7-x86_64-linux.tar.bz2" "_"
|
||||
=> "nix-1.7-x86"
|
||||
*/
|
||||
# Extract name with version from URL. Ask for separator which is
|
||||
# supposed to start extension.
|
||||
nameFromURL = url: sep:
|
||||
let
|
||||
components = splitString "/" url;
|
||||
@@ -395,24 +207,14 @@ rec {
|
||||
name = builtins.head (splitString sep filename);
|
||||
in assert name != filename; name;
|
||||
|
||||
/* Create an --{enable,disable}-<feat> string that can be passed to
|
||||
standard GNU Autoconf scripts.
|
||||
|
||||
Example:
|
||||
enableFeature true "shared"
|
||||
=> "--enable-shared"
|
||||
enableFeature false "shared"
|
||||
=> "--disable-shared"
|
||||
*/
|
||||
# Create an --{enable,disable}-<feat> string that can be passed to
|
||||
# standard GNU Autoconf scripts.
|
||||
enableFeature = enable: feat: "--${if enable then "enable" else "disable"}-${feat}";
|
||||
|
||||
/* Create a fixed width string with additional prefix to match
|
||||
required width.
|
||||
|
||||
Example:
|
||||
fixedWidthString 5 "0" (toString 15)
|
||||
=> "00015"
|
||||
*/
|
||||
# Create a fixed width string with additional prefix to match
|
||||
# required width.
|
||||
fixedWidthString = width: filler: str:
|
||||
let
|
||||
strw = lib.stringLength str;
|
||||
@@ -421,58 +223,25 @@ rec {
|
||||
assert strw <= width;
|
||||
if strw == width then str else filler + fixedWidthString reqWidth filler str;
|
||||
|
||||
/* Format a number adding leading zeroes up to fixed width.
|
||||
|
||||
Example:
|
||||
fixedWidthNumber 5 15
|
||||
=> "00015"
|
||||
*/
|
||||
# Format a number adding leading zeroes up to fixed width.
|
||||
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
|
||||
|
||||
/* Check whether a value is a store path.
|
||||
|
||||
Example:
|
||||
isStorePath "/nix/store/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11/bin/python"
|
||||
=> false
|
||||
isStorePath "/nix/store/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11/"
|
||||
=> true
|
||||
isStorePath pkgs.python
|
||||
=> true
|
||||
*/
|
||||
# Check whether a value is a store path.
|
||||
isStorePath = x: builtins.substring 0 1 (toString x) == "/" && dirOf (builtins.toPath x) == builtins.storeDir;
|
||||
|
||||
/* Convert string to int
|
||||
Obviously, it is a bit hacky to use fromJSON that way.
|
||||
|
||||
Example:
|
||||
toInt "1337"
|
||||
=> 1337
|
||||
toInt "-4"
|
||||
=> -4
|
||||
toInt "3.14"
|
||||
=> error: floating point JSON numbers are not supported
|
||||
*/
|
||||
# Convert string to int
|
||||
# Obviously, it is a bit hacky to use fromJSON that way.
|
||||
toInt = str:
|
||||
let may_be_int = builtins.fromJSON str; in
|
||||
if builtins.isInt may_be_int
|
||||
then may_be_int
|
||||
else throw "Could not convert ${str} to int.";
|
||||
|
||||
/* Read a list of paths from `file', relative to the `rootPath'. Lines
|
||||
beginning with `#' are treated as comments and ignored. Whitespace
|
||||
is significant.
|
||||
|
||||
NOTE: this function is not performant and should be avoided
|
||||
|
||||
Example:
|
||||
readPathsFromFile /prefix
|
||||
./pkgs/development/libraries/qt-5/5.4/qtbase/series
|
||||
=> [ "/prefix/dlopen-resolv.patch" "/prefix/tzdir.patch"
|
||||
"/prefix/dlopen-libXcursor.patch" "/prefix/dlopen-openssl.patch"
|
||||
"/prefix/dlopen-dbus.patch" "/prefix/xdg-config-dirs.patch"
|
||||
"/prefix/nix-profiles-library-paths.patch"
|
||||
"/prefix/compose-search-path.patch" ]
|
||||
*/
|
||||
# Read a list of paths from `file', relative to the `rootPath'. Lines
|
||||
# beginning with `#' are treated as comments and ignored. Whitespace
|
||||
# is significant.
|
||||
readPathsFromFile = rootPath: file:
|
||||
let
|
||||
root = toString rootPath;
|
||||
@@ -485,13 +254,4 @@ rec {
|
||||
in
|
||||
absolutePaths;
|
||||
|
||||
/* Read the contents of a file removing the trailing \n
|
||||
|
||||
Example:
|
||||
$ echo "1.0" > ./version
|
||||
|
||||
fileContents ./version
|
||||
=> "1.0"
|
||||
*/
|
||||
fileContents = file: removeSuffix "\n" (builtins.readFile file);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ nixpkgs }:
|
||||
|
||||
with import ../.. { };
|
||||
with import ./../.. { };
|
||||
with lib;
|
||||
|
||||
stdenv.mkDerivation {
|
||||
|
||||
@@ -62,55 +62,17 @@ rec {
|
||||
isInt add sub lessThan
|
||||
seq deepSeq genericClosure;
|
||||
|
||||
inherit (import ./strings.nix) fileContents;
|
||||
|
||||
# Return the Nixpkgs version number.
|
||||
nixpkgsVersion =
|
||||
let suffixFile = ../.version-suffix; in
|
||||
fileContents ../.version
|
||||
+ (if pathExists suffixFile then fileContents suffixFile else "pre-git");
|
||||
readFile ../.version
|
||||
+ (if pathExists suffixFile then readFile suffixFile else "pre-git");
|
||||
|
||||
# Whether we're being called by nix-shell.
|
||||
inNixShell = builtins.getEnv "IN_NIX_SHELL" != "";
|
||||
inNixShell = builtins.getEnv "IN_NIX_SHELL" == "1";
|
||||
|
||||
# Return minimum/maximum of two numbers.
|
||||
min = x: y: if x < y then x else y;
|
||||
max = x: y: if x > y then x else y;
|
||||
|
||||
/* Reads a JSON file. It is useful to import pure data into other nix
|
||||
expressions.
|
||||
|
||||
Example:
|
||||
|
||||
mkDerivation {
|
||||
src = fetchgit (importJSON ./repo.json)
|
||||
#...
|
||||
}
|
||||
|
||||
where repo.json contains:
|
||||
|
||||
{
|
||||
"url": "git://some-domain/some/repo",
|
||||
"rev": "265de7283488964f44f0257a8b4a055ad8af984d",
|
||||
"sha256": "0sb3h3067pzf3a7mlxn1hikpcjrsvycjcnj9hl9b1c3ykcgvps7h"
|
||||
}
|
||||
|
||||
*/
|
||||
importJSON = path:
|
||||
builtins.fromJSON (builtins.readFile path);
|
||||
|
||||
/* See https://github.com/NixOS/nix/issues/749. Eventually we'd like these
|
||||
to expand to Nix builtins that carry metadata so that Nix can filter out
|
||||
the INFO messages without parsing the message string.
|
||||
|
||||
Usage:
|
||||
{
|
||||
foo = lib.warn "foo is deprecated" oldFoo;
|
||||
}
|
||||
|
||||
TODO: figure out a clever way to integrate location information from
|
||||
something like __unsafeGetAttrPos.
|
||||
*/
|
||||
warn = msg: builtins.trace "WARNING: ${msg}";
|
||||
info = msg: builtins.trace "INFO: ${msg}";
|
||||
}
|
||||
|
||||
@@ -100,10 +100,6 @@ rec {
|
||||
in if isDerivation res then res else toDerivation res;
|
||||
};
|
||||
|
||||
shellPackage = package // {
|
||||
check = x: (package.check x) && (hasAttr "shellPath" x);
|
||||
};
|
||||
|
||||
path = mkOptionType {
|
||||
name = "path";
|
||||
# Hacky: there is no ‘isPath’ primop.
|
||||
@@ -118,17 +114,13 @@ rec {
|
||||
name = "list of ${elemType.name}s";
|
||||
check = isList;
|
||||
merge = loc: defs:
|
||||
map (x: x.value) (filter (x: x ? value) (concatLists (imap (n: def:
|
||||
if isList def.value then
|
||||
imap (m: def':
|
||||
(mergeDefinitions
|
||||
(loc ++ ["[definition ${toString n}-entry ${toString m}]"])
|
||||
elemType
|
||||
[{ inherit (def) file; value = def'; }]
|
||||
).optionalValue
|
||||
) def.value
|
||||
else
|
||||
throw "The option value `${showOption loc}' in `${def.file}' is not a list.") defs)));
|
||||
map (x: x.value) (filter (x: x ? value) (concatLists (imap (n: def: imap (m: def':
|
||||
(mergeDefinitions
|
||||
(loc ++ ["[definition ${toString n}-entry ${toString m}]"])
|
||||
elemType
|
||||
[{ inherit (def) file; value = def'; }]
|
||||
).optionalValue
|
||||
) def.value) defs)));
|
||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]);
|
||||
getSubModules = elemType.getSubModules;
|
||||
substSubModules = m: listOf (elemType.substSubModules m);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# content-addressed cache used by fetchurl as a fallback for when
|
||||
# upstream tarballs disappear or change. Usage:
|
||||
#
|
||||
# 1) To upload one or more files:
|
||||
# 1) To upload a single file:
|
||||
#
|
||||
# $ copy-tarballs.pl --file /path/to/tarball.tar.gz
|
||||
#
|
||||
@@ -22,38 +22,9 @@ use JSON;
|
||||
use Net::Amazon::S3;
|
||||
use Nix::Store;
|
||||
|
||||
isValidPath("/nix/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo"); # FIXME: forces Nix::Store initialisation
|
||||
|
||||
sub usage {
|
||||
die "Syntax: $0 [--dry-run] [--exclude REGEXP] [--expr EXPR | --file FILES...]\n";
|
||||
}
|
||||
|
||||
my $dryRun = 0;
|
||||
my $expr;
|
||||
my @fileNames;
|
||||
my $exclude;
|
||||
|
||||
while (@ARGV) {
|
||||
my $flag = shift @ARGV;
|
||||
|
||||
if ($flag eq "--expr") {
|
||||
$expr = shift @ARGV or die "--expr requires an argument";
|
||||
} elsif ($flag eq "--file") {
|
||||
@fileNames = @ARGV;
|
||||
last;
|
||||
} elsif ($flag eq "--dry-run") {
|
||||
$dryRun = 1;
|
||||
} elsif ($flag eq "--exclude") {
|
||||
$exclude = shift @ARGV or die "--exclude requires an argument";
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# S3 setup.
|
||||
my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die "AWS_ACCESS_KEY_ID not set\n";
|
||||
my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die "AWS_SECRET_ACCESS_KEY not set\n";
|
||||
my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die;
|
||||
my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die;
|
||||
|
||||
my $s3 = Net::Amazon::S3->new(
|
||||
{ aws_access_key_id => $aws_access_key_id,
|
||||
@@ -63,15 +34,12 @@ my $s3 = Net::Amazon::S3->new(
|
||||
|
||||
my $bucket = $s3->bucket("nixpkgs-tarballs") or die;
|
||||
|
||||
my $doWrite = 0;
|
||||
my $cacheFile = ($ENV{"HOME"} or die "\$HOME is not set") . "/.cache/nix/copy-tarballs";
|
||||
my $cacheFile = "/tmp/copy-tarballs-cache";
|
||||
my %cache;
|
||||
$cache{$_} = 1 foreach read_file($cacheFile, err_mode => 'quiet', chomp => 1);
|
||||
$doWrite = 1;
|
||||
|
||||
END() {
|
||||
File::Path::mkpath(dirname($cacheFile), 0, 0755);
|
||||
write_file($cacheFile, map { "$_\n" } keys %cache) if $doWrite;
|
||||
write_file($cacheFile, map { "$_\n" } keys %cache);
|
||||
}
|
||||
|
||||
sub alreadyMirrored {
|
||||
@@ -116,9 +84,11 @@ sub uploadFile {
|
||||
$cache{$mainKey} = 1;
|
||||
}
|
||||
|
||||
if (scalar @fileNames) {
|
||||
my $op = shift @ARGV;
|
||||
|
||||
if ($op eq "--file") {
|
||||
my $res = 0;
|
||||
foreach my $fn (@fileNames) {
|
||||
foreach my $fn (@ARGV) {
|
||||
eval {
|
||||
if (alreadyMirrored("sha512", hashFile("sha512", 0, $fn))) {
|
||||
print STDERR "$fn is already mirrored\n";
|
||||
@@ -127,16 +97,17 @@ if (scalar @fileNames) {
|
||||
}
|
||||
};
|
||||
if ($@) {
|
||||
warn "$@";
|
||||
warn "$@\n";
|
||||
$res = 1;
|
||||
}
|
||||
}
|
||||
exit $res;
|
||||
}
|
||||
|
||||
elsif (defined $expr) {
|
||||
elsif ($op eq "--expr") {
|
||||
|
||||
# Evaluate find-tarballs.nix.
|
||||
my $expr = $ARGV[0] // die "$0: --expr requires a Nix expression\n";
|
||||
my $pid = open(JSON, "-|", "nix-instantiate", "--eval", "--json", "--strict",
|
||||
"<nixpkgs/maintainers/scripts/find-tarballs.nix>",
|
||||
"--arg", "expr", $expr);
|
||||
@@ -152,11 +123,10 @@ elsif (defined $expr) {
|
||||
# Check every fetchurl call discovered by find-tarballs.nix.
|
||||
my $mirrored = 0;
|
||||
my $have = 0;
|
||||
foreach my $fetch (sort { $a->{url} cmp $b->{url} } @{$fetches}) {
|
||||
foreach my $fetch (@{$fetches}) {
|
||||
my $url = $fetch->{url};
|
||||
my $algo = $fetch->{type};
|
||||
my $hash = $fetch->{hash};
|
||||
my $name = $fetch->{name};
|
||||
|
||||
if (defined $ENV{DEBUG}) {
|
||||
print "$url $algo $hash\n";
|
||||
@@ -168,44 +138,26 @@ elsif (defined $expr) {
|
||||
next;
|
||||
}
|
||||
|
||||
next if defined $exclude && $url =~ /$exclude/;
|
||||
|
||||
if (alreadyMirrored($algo, $hash)) {
|
||||
$have++;
|
||||
next;
|
||||
}
|
||||
|
||||
my $storePath = makeFixedOutputPath(0, $algo, $hash, $name);
|
||||
print STDERR "mirroring $url...\n";
|
||||
|
||||
print STDERR "mirroring $url ($storePath)...\n";
|
||||
next if $ENV{DRY_RUN};
|
||||
|
||||
if ($dryRun) {
|
||||
$mirrored++;
|
||||
# Download the file using nix-prefetch-url.
|
||||
$ENV{QUIET} = 1;
|
||||
$ENV{PRINT_PATH} = 1;
|
||||
my $fh;
|
||||
my $pid = open($fh, "-|", "nix-prefetch-url", "--type", $algo, $url, $hash) or die;
|
||||
waitpid($pid, 0) or die;
|
||||
if ($? != 0) {
|
||||
print STDERR "failed to fetch $url: $?\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Substitute the output.
|
||||
if (!isValidPath($storePath)) {
|
||||
system("nix-store", "-r", $storePath);
|
||||
}
|
||||
|
||||
# Otherwise download the file using nix-prefetch-url.
|
||||
if (!isValidPath($storePath)) {
|
||||
$ENV{QUIET} = 1;
|
||||
$ENV{PRINT_PATH} = 1;
|
||||
my $fh;
|
||||
my $pid = open($fh, "-|", "nix-prefetch-url", "--type", $algo, $url, $hash) or die;
|
||||
waitpid($pid, 0) or die;
|
||||
if ($? != 0) {
|
||||
print STDERR "failed to fetch $url: $?\n";
|
||||
next;
|
||||
}
|
||||
<$fh>; my $storePath2 = <$fh>; chomp $storePath2;
|
||||
if ($storePath ne $storePath2) {
|
||||
warn "strange: $storePath != $storePath2\n";
|
||||
next;
|
||||
}
|
||||
}
|
||||
<$fh>; my $storePath = <$fh>; chomp $storePath;
|
||||
|
||||
uploadFile($storePath, $url);
|
||||
$mirrored++;
|
||||
@@ -215,5 +167,5 @@ elsif (defined $expr) {
|
||||
}
|
||||
|
||||
else {
|
||||
usage();
|
||||
die "Syntax: $0 --file FILENAMES... | --expr EXPR\n";
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash -p coreutils findutils gnused nix wget
|
||||
|
||||
SRCS=
|
||||
if [ -d "$1" ]; then
|
||||
SRCS="$(pwd)/$1/srcs.nix"
|
||||
. "$1/fetch.sh"
|
||||
else
|
||||
SRCS="$(pwd)/$(dirname $1)/srcs.nix"
|
||||
. "$1"
|
||||
fi
|
||||
|
||||
tmp=$(mktemp -d)
|
||||
pushd $tmp >/dev/null
|
||||
wget -nH -r -c --no-parent "${WGET_ARGS[@]}" >/dev/null
|
||||
|
||||
csv=$(mktemp)
|
||||
find . -type f | while read src; do
|
||||
# Sanitize file name
|
||||
filename=$(basename "$src" | tr '@' '_')
|
||||
nameVersion="${filename%.tar.*}"
|
||||
name=$(echo "$nameVersion" | sed -e 's,-[[:digit:]].*,,' | sed -e 's,-opensource-src$,,')
|
||||
version=$(echo "$nameVersion" | sed -e 's,^\([[:alpha:]][[:alnum:]]*-\)\+,,')
|
||||
echo "$name,$version,$src,$filename" >>$csv
|
||||
done
|
||||
|
||||
cat >"$SRCS" <<EOF
|
||||
# DO NOT EDIT! This file is generated automatically by fetch-kde-qt.sh
|
||||
{ fetchurl, mirror }:
|
||||
|
||||
{
|
||||
EOF
|
||||
|
||||
gawk -F , "{ print \$1 }" $csv | sort | uniq | while read name; do
|
||||
versions=$(gawk -F , "/^$name,/ { print \$2 }" $csv)
|
||||
latestVersion=$(echo "$versions" | sort -rV | head -n 1)
|
||||
src=$(gawk -F , "/^$name,$latestVersion,/ { print \$3 }" $csv)
|
||||
filename=$(gawk -F , "/^$name,$latestVersion,/ { print \$4 }" $csv)
|
||||
url="${src:2}"
|
||||
sha256=$(nix-hash --type sha256 --base32 --flat "$src")
|
||||
cat >>"$SRCS" <<EOF
|
||||
$name = {
|
||||
version = "$latestVersion";
|
||||
src = fetchurl {
|
||||
url = "\${mirror}/$url";
|
||||
sha256 = "$sha256";
|
||||
name = "$filename";
|
||||
};
|
||||
};
|
||||
EOF
|
||||
done
|
||||
|
||||
echo "}" >>"$SRCS"
|
||||
|
||||
popd >/dev/null
|
||||
rm -fr $tmp >/dev/null
|
||||
|
||||
rm -f $csv >/dev/null
|
||||
@@ -14,12 +14,12 @@ let
|
||||
operator = const [ ];
|
||||
});
|
||||
|
||||
urls = map (drv: { url = head (drv.urls or [ drv.url ]); hash = drv.outputHash; type = drv.outputHashAlgo; name = drv.name; }) fetchurlDependencies;
|
||||
urls = map (drv: { url = head drv.urls; hash = drv.outputHash; type = drv.outputHashAlgo; }) fetchurlDependencies;
|
||||
|
||||
fetchurlDependencies =
|
||||
filter
|
||||
(drv: drv.outputHash or "" != "" && drv.outputHashMode or "flat" == "flat"
|
||||
&& drv.postFetch or "" == "" && (drv ? url || drv ? urls))
|
||||
&& drv.postFetch or "" == "" && drv ? urls)
|
||||
dependencies;
|
||||
|
||||
dependencies = map (x: x.value) (genericClosure {
|
||||
|
||||
22
maintainers/scripts/map-files.pl
Normal file
22
maintainers/scripts/map-files.pl
Normal file
@@ -0,0 +1,22 @@
|
||||
#! /usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
|
||||
my %map;
|
||||
open LIST1, "<$ARGV[0]" or die;
|
||||
while (<LIST1>) {
|
||||
/^(\S+)\s+(.*)$/;
|
||||
$map{$1} = $2;
|
||||
}
|
||||
|
||||
open LIST1, "<$ARGV[1]" or die;
|
||||
while (<LIST1>) {
|
||||
/^(\S+)\s+(.*)$/;
|
||||
if (!defined $map{$1}) {
|
||||
print STDERR "missing file: $2\n";
|
||||
next;
|
||||
}
|
||||
print "$2\n";
|
||||
print "$map{$1}\n";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ stdenv, makeWrapper, perl, perlPackages }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "nix-generate-from-cpan-3";
|
||||
name = "nix-generate-from-cpan-2";
|
||||
|
||||
buildInputs = with perlPackages; [
|
||||
makeWrapper perl CPANMeta GetoptLongDescriptive CPANPLUS Readonly Log4Perl
|
||||
@@ -20,6 +20,5 @@ stdenv.mkDerivation {
|
||||
meta = {
|
||||
maintainers = with stdenv.lib.maintainers; [ eelco rycee ];
|
||||
description = "Utility to generate a Nix expression for a Perl package from CPAN";
|
||||
platforms = stdenv.lib.platforms.unix;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -278,13 +278,13 @@ sub get_deps {
|
||||
foreach my $n ( $deps->required_modules ) {
|
||||
next if $n eq "perl";
|
||||
|
||||
# Figure out whether the module is a core module by attempting
|
||||
# to `use` the module in a pure Perl interpreter and checking
|
||||
# whether it succeeded. Note, $^X is a magic variable holding
|
||||
# the path to the running Perl interpreter.
|
||||
if ( system("env -i $^X -M$n -e1 >/dev/null 2>&1") == 0 ) {
|
||||
DEBUG("skipping Perl-builtin module $n");
|
||||
next;
|
||||
# Hacky way to figure out if this module is part of Perl.
|
||||
if ( $n !~ /^JSON/ && $n !~ /^YAML/ && $n !~ /^Module::Pluggable/ && $n !~ /^if$/ ) {
|
||||
eval "use $n;";
|
||||
if ( !$@ ) {
|
||||
DEBUG("skipping Perl-builtin module $n");
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
my $pkg = module_to_pkg( $cb, $n );
|
||||
@@ -395,21 +395,16 @@ my $meta = read_meta($pkg_path);
|
||||
|
||||
DEBUG( "metadata: ", encode_json( $meta->as_struct ) ) if defined $meta;
|
||||
|
||||
my @runtime_deps = sort( uniq( get_deps( $cb, $meta, "runtime" ) ) );
|
||||
INFO("runtime deps: @runtime_deps");
|
||||
|
||||
my @build_deps = sort( uniq(
|
||||
get_deps( $cb, $meta, "configure" ),
|
||||
get_deps( $cb, $meta, "build" ),
|
||||
get_deps( $cb, $meta, "test" )
|
||||
) );
|
||||
|
||||
# Filter out runtime dependencies since those are already handled.
|
||||
my %in_runtime_deps = map { $_ => 1 } @runtime_deps;
|
||||
@build_deps = grep { not $in_runtime_deps{$_} } @build_deps;
|
||||
|
||||
INFO("build deps: @build_deps");
|
||||
|
||||
my @runtime_deps = sort( uniq( get_deps( $cb, $meta, "runtime" ) ) );
|
||||
INFO("runtime deps: @runtime_deps");
|
||||
|
||||
my $homepage = $meta ? $meta->resources->{homepage} : undef;
|
||||
INFO("homepage: $homepage") if defined $homepage;
|
||||
|
||||
|
||||
@@ -18,6 +18,5 @@ stdenv.mkDerivation {
|
||||
meta = {
|
||||
maintainers = [ stdenv.lib.maintainers.eelco ];
|
||||
description = "A utility for Nixpkgs contributors to check Nixpkgs for common errors";
|
||||
platforms = stdenv.lib.platforms.unix;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,76 +1,46 @@
|
||||
#! /usr/bin/env bash
|
||||
set -e
|
||||
|
||||
while test -n "$1"; do
|
||||
export NIX_CURL_FLAGS=-sS
|
||||
|
||||
# tell Travis to use folding
|
||||
echo -en "travis_fold:start:$1\r"
|
||||
if [[ $1 == nix ]]; then
|
||||
echo "=== Installing Nix..."
|
||||
# Install Nix
|
||||
bash <(curl -sS https://nixos.org/nix/install)
|
||||
source $HOME/.nix-profile/etc/profile.d/nix.sh
|
||||
|
||||
case $1 in
|
||||
# Make sure we can use hydra's binary cache
|
||||
sudo mkdir /etc/nix
|
||||
sudo sh -c 'echo "build-max-jobs = 4" > /etc/nix/nix.conf'
|
||||
|
||||
nixpkgs-verify)
|
||||
echo "=== Verifying that nixpkgs evaluates..."
|
||||
# Verify evaluation
|
||||
echo "=== Verifying that nixpkgs evaluates..."
|
||||
nix-env -f. -qa --json >/dev/null
|
||||
elif [[ $1 == nox ]]; then
|
||||
echo "=== Installing nox..."
|
||||
git clone -q https://github.com/madjar/nox
|
||||
pip --quiet install -e nox
|
||||
elif [[ $1 == build ]]; then
|
||||
source $HOME/.nix-profile/etc/profile.d/nix.sh
|
||||
|
||||
nix-env --file $TRAVIS_BUILD_DIR --query --available --json > /dev/null
|
||||
;;
|
||||
echo "=== Checking tarball creation"
|
||||
nix-build pkgs/top-level/release.nix -A tarball
|
||||
|
||||
nixos-options)
|
||||
echo "=== Checking NixOS options"
|
||||
if [[ $TRAVIS_PULL_REQUEST == false ]]; then
|
||||
echo "=== Not a pull request"
|
||||
else
|
||||
echo "=== Checking PR"
|
||||
|
||||
nix-build $TRAVIS_BUILD_DIR/nixos/release.nix --attr options --show-trace
|
||||
;;
|
||||
|
||||
nixos-manual)
|
||||
echo "=== Checking NixOS manuals"
|
||||
|
||||
nix-build $TRAVIS_BUILD_DIR/nixos/release.nix --attr manual --show-trace
|
||||
;;
|
||||
|
||||
nixpkgs-manual)
|
||||
echo "=== Checking nixpkgs manuals"
|
||||
|
||||
nix-build $TRAVIS_BUILD_DIR/pkgs/top-level/release.nix --attr manual --show-trace
|
||||
;;
|
||||
|
||||
nixpkgs-tarball)
|
||||
echo "=== Checking nixpkgs tarball creation"
|
||||
|
||||
nix-build $TRAVIS_BUILD_DIR/pkgs/top-level/release.nix --attr tarball --show-trace
|
||||
;;
|
||||
|
||||
nixpkgs-lint)
|
||||
echo "=== Checking nixpkgs lint"
|
||||
|
||||
nix-shell --packages nixpkgs-lint --run "nixpkgs-lint -f $TRAVIS_BUILD_DIR"
|
||||
;;
|
||||
|
||||
nox)
|
||||
echo "=== Fetching Nox from binary cache"
|
||||
|
||||
# build nox silently so it's not in the log
|
||||
nix-build "<nixpkgs>" -A nox -A stdenv
|
||||
;;
|
||||
|
||||
pr)
|
||||
if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
||||
echo "=== No pull request found"
|
||||
else
|
||||
echo "=== Building pull request #$TRAVIS_PULL_REQUEST"
|
||||
|
||||
token=""
|
||||
if [ -n "$GITHUB_TOKEN" ]; then
|
||||
token="--token $GITHUB_TOKEN"
|
||||
fi
|
||||
|
||||
nix-shell --packages nox --run "nox-review pr --slug $TRAVIS_REPO_SLUG $token $TRAVIS_PULL_REQUEST"
|
||||
if ! nox-review pr ${TRAVIS_PULL_REQUEST}; then
|
||||
if sudo dmesg | egrep 'Out of memory|Killed process' > /tmp/oom-log; then
|
||||
echo "=== The build failed due to running out of memory:"
|
||||
cat /tmp/oom-log
|
||||
echo "=== Please disregard the result of this Travis build."
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Skipping unknown option $1"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -en "travis_fold:end:$1\r"
|
||||
shift
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "$0: Unknown option $1" >&2
|
||||
false
|
||||
fi
|
||||
|
||||
@@ -39,5 +39,5 @@ in
|
||||
vmWithBootLoader = vmWithBootLoaderConfig.system.build.vm;
|
||||
|
||||
# The following are used by nixos-rebuild.
|
||||
nixFallback = pkgs.nixUnstable.out;
|
||||
nixFallback = pkgs.nixUnstable;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ Alternatively, you can use a systemd unit that does the same in the
|
||||
background:
|
||||
|
||||
<screen>
|
||||
# systemctl start nix-gc.service
|
||||
$ systemctl start nix-gc.service
|
||||
</screen>
|
||||
|
||||
You can tell NixOS in <filename>configuration.nix</filename> to run
|
||||
@@ -59,4 +59,4 @@ $ nix-store --optimise
|
||||
Since this command needs to read the entire Nix store, it can take
|
||||
quite a while to finish.</para>
|
||||
|
||||
</chapter>
|
||||
</chapter>
|
||||
@@ -13,7 +13,7 @@ create</literal>, it gets it own private IPv4 address in the range
|
||||
address as follows:
|
||||
|
||||
<screen>
|
||||
# nixos-container show-ip foo
|
||||
$ nixos-container show-ip foo
|
||||
10.233.4.2
|
||||
|
||||
$ ping -c1 10.233.4.2
|
||||
@@ -47,4 +47,4 @@ where <literal>eth0</literal> should be replaced with the desired
|
||||
external interface. Note that <literal>ve-+</literal> is a wildcard
|
||||
that matches all container interfaces.</para>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
@@ -7,15 +7,11 @@
|
||||
<title>Imperative Container Management</title>
|
||||
|
||||
<para>We’ll cover imperative container management using
|
||||
<command>nixos-container</command> first.
|
||||
Be aware that container management is currently only possible
|
||||
as <literal>root</literal>.</para>
|
||||
|
||||
<para>You create a container with
|
||||
<command>nixos-container</command> first. You create a container with
|
||||
identifier <literal>foo</literal> as follows:
|
||||
|
||||
<screen>
|
||||
# nixos-container create foo
|
||||
$ nixos-container create foo
|
||||
</screen>
|
||||
|
||||
This creates the container’s root directory in
|
||||
@@ -29,7 +25,7 @@ line. For instance, to create a container that has
|
||||
<literal>root</literal>:
|
||||
|
||||
<screen>
|
||||
# nixos-container create foo --config 'services.openssh.enable = true; \
|
||||
$ nixos-container create foo --config 'services.openssh.enable = true; \
|
||||
users.extraUsers.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];'
|
||||
</screen>
|
||||
|
||||
@@ -39,7 +35,7 @@ line. For instance, to create a container that has
|
||||
run:
|
||||
|
||||
<screen>
|
||||
# nixos-container start foo
|
||||
$ nixos-container start foo
|
||||
</screen>
|
||||
|
||||
This command will return as soon as the container has booted and has
|
||||
@@ -50,7 +46,7 @@ Thus, if something went wrong, you can get status info using
|
||||
<command>systemctl</command>:
|
||||
|
||||
<screen>
|
||||
# systemctl status container@foo
|
||||
$ systemctl status container@foo
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
@@ -59,7 +55,7 @@ Thus, if something went wrong, you can get status info using
|
||||
root using the <command>root-login</command> operation:
|
||||
|
||||
<screen>
|
||||
# nixos-container root-login foo
|
||||
$ nixos-container root-login foo
|
||||
[root@foo:~]#
|
||||
</screen>
|
||||
|
||||
@@ -69,7 +65,7 @@ authentication). You can also get a regular login prompt using the
|
||||
the host:
|
||||
|
||||
<screen>
|
||||
# nixos-container login foo
|
||||
$ nixos-container login foo
|
||||
foo login: alice
|
||||
Password: ***
|
||||
</screen>
|
||||
@@ -78,7 +74,7 @@ With <command>nixos-container run</command>, you can execute arbitrary
|
||||
commands in the container:
|
||||
|
||||
<screen>
|
||||
# nixos-container run foo -- uname -a
|
||||
$ nixos-container run foo -- uname -a
|
||||
Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
|
||||
</screen>
|
||||
|
||||
@@ -90,17 +86,17 @@ container. First, on the host, you can edit
|
||||
and run
|
||||
|
||||
<screen>
|
||||
# nixos-container update foo
|
||||
$ nixos-container update foo
|
||||
</screen>
|
||||
|
||||
This will build and activate the new configuration. You can also
|
||||
specify a new configuration on the command line:
|
||||
|
||||
<screen>
|
||||
# nixos-container update foo --config 'services.httpd.enable = true; \
|
||||
$ nixos-container update foo --config 'services.httpd.enable = true; \
|
||||
services.httpd.adminAddr = "foo@example.org";'
|
||||
|
||||
# curl http://$(nixos-container show-ip foo)/
|
||||
$ curl http://$(nixos-container show-ip foo)/
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
|
||||
</screen>
|
||||
|
||||
@@ -120,9 +116,9 @@ start</literal>, respectively, or by using
|
||||
destroy a container, including its file system, do
|
||||
|
||||
<screen>
|
||||
# nixos-container destroy foo
|
||||
$ nixos-container destroy foo
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
@@ -9,10 +9,10 @@
|
||||
<para>You can enter rescue mode by running:
|
||||
|
||||
<screen>
|
||||
# systemctl rescue</screen>
|
||||
$ systemctl rescue</screen>
|
||||
|
||||
This will eventually give you a single-user root shell. Systemd will
|
||||
stop (almost) all system services. To get out of maintenance mode,
|
||||
just exit from the rescue shell.</para>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
@@ -18,14 +18,14 @@ You can disable the use of the binary cache by adding <option>--option
|
||||
use-binary-caches false</option>, e.g.
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch --option use-binary-caches false
|
||||
$ nixos-rebuild switch --option use-binary-caches false
|
||||
</screen>
|
||||
|
||||
If you have an alternative binary cache at your disposal, you can use
|
||||
it instead:
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch --option binary-caches http://my-cache.example.org/
|
||||
$ nixos-rebuild switch --option binary-caches http://my-cache.example.org/
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
doing:
|
||||
|
||||
<screen>
|
||||
# shutdown
|
||||
$ shutdown
|
||||
</screen>
|
||||
|
||||
This is equivalent to running <command>systemctl
|
||||
@@ -19,7 +19,7 @@ poweroff</command>.</para>
|
||||
<para>To reboot the system, run
|
||||
|
||||
<screen>
|
||||
# reboot
|
||||
$ reboot
|
||||
</screen>
|
||||
|
||||
which is equivalent to <command>systemctl reboot</command>.
|
||||
@@ -28,7 +28,7 @@ Alternatively, you can quickly reboot the system using
|
||||
the new kernel into memory:
|
||||
|
||||
<screen>
|
||||
# systemctl kexec
|
||||
$ systemctl kexec
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
@@ -41,4 +41,4 @@ the new kernel into memory:
|
||||
i.e. on a virtual console or in X11; otherwise, the user is asked for
|
||||
authentication.</para>
|
||||
|
||||
</chapter>
|
||||
</chapter>
|
||||
@@ -19,7 +19,7 @@ fails to boot. After the system has booted, you can make the selected
|
||||
configuration the default for subsequent boots:
|
||||
|
||||
<screen>
|
||||
# /run/current-system/bin/switch-to-configuration boot</screen>
|
||||
$ /run/current-system/bin/switch-to-configuration boot</screen>
|
||||
|
||||
</para>
|
||||
|
||||
@@ -27,12 +27,12 @@ configuration the default for subsequent boots:
|
||||
system:
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch --rollback</screen>
|
||||
$ nixos-rebuild switch --rollback</screen>
|
||||
|
||||
This is equivalent to running:
|
||||
|
||||
<screen>
|
||||
# /nix/var/nix/profiles/system-<replaceable>N</replaceable>-link/bin/switch-to-configuration switch</screen>
|
||||
$ /nix/var/nix/profiles/system-<replaceable>N</replaceable>-link/bin/switch-to-configuration switch</screen>
|
||||
|
||||
where <replaceable>N</replaceable> is the number of the NixOS system
|
||||
configuration. To get a list of the available configurations, do:
|
||||
@@ -45,4 +45,4 @@ lrwxrwxrwx 1 root root 78 Aug 12 13:54 /nix/var/nix/profiles/system-268-link ->
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
@@ -66,9 +66,9 @@ messages from the service.
|
||||
<para>Units can be stopped, started or restarted:
|
||||
|
||||
<screen>
|
||||
# systemctl stop postgresql.service
|
||||
# systemctl start postgresql.service
|
||||
# systemctl restart postgresql.service
|
||||
$ systemctl stop postgresql.service
|
||||
$ systemctl start postgresql.service
|
||||
$ systemctl restart postgresql.service
|
||||
</screen>
|
||||
|
||||
These operations are synchronous: they wait until the service has
|
||||
|
||||
@@ -18,7 +18,7 @@ you may be able to fix it automatically.</para>
|
||||
system configuration, you can fix it by doing
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch --repair
|
||||
$ nixos-rebuild switch --repair
|
||||
</screen>
|
||||
|
||||
This will cause Nix to check every path in the closure, and if its
|
||||
@@ -28,10 +28,10 @@ the path is rebuilt or redownloaded.</para>
|
||||
<para>You can also scan the entire Nix store for corrupt paths:
|
||||
|
||||
<screen>
|
||||
# nix-store --verify --check-contents --repair
|
||||
$ nix-store --verify --check-contents --repair
|
||||
</screen>
|
||||
|
||||
Any corrupt paths will be redownloaded if they’re available in a
|
||||
binary cache; otherwise, they cannot be repaired.</para>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
@@ -45,9 +45,9 @@ track of this, you can terminate a session in a way that ensures that
|
||||
all the session’s processes are gone:
|
||||
|
||||
<screen>
|
||||
# loginctl terminate-session c3
|
||||
$ loginctl terminate-session c3
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
</chapter>
|
||||
@@ -31,7 +31,7 @@ and you run <command>nixos-rebuild</command>, specifying your own
|
||||
Nixpkgs tree:
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen>
|
||||
$ nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen>
|
||||
|
||||
</para>
|
||||
|
||||
|
||||
@@ -106,15 +106,11 @@ networking.extraHosts =
|
||||
'';
|
||||
</programlisting>
|
||||
|
||||
The main difference is that it strips from each line
|
||||
a number of spaces equal to the minimal indentation of
|
||||
the string as a whole (disregarding the indentation of
|
||||
empty lines), and that characters like
|
||||
The main difference is that preceding whitespace is
|
||||
automatically stripped from each line, and that characters like
|
||||
<literal>"</literal> and <literal>\</literal> are not special
|
||||
(making it more convenient for including things like shell
|
||||
code).
|
||||
See more info about this in the Nix manual <link
|
||||
xlink:href="https://nixos.org/nix/manual/#ssec-values">here</link>.</para>
|
||||
code).</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -24,9 +24,11 @@ effect after you run <command>nixos-rebuild</command>.</para>
|
||||
<xi:include href="networking.xml" />
|
||||
<xi:include href="linux-kernel.xml" />
|
||||
|
||||
<xi:include href="modules.xml" xpointer="xpointer(//section[@id='modules']/*)" />
|
||||
<!-- FIXME: auto-include NixOS module docs -->
|
||||
<xi:include href="postgresql.xml" />
|
||||
<xi:include href="gitlab.xml" />
|
||||
<xi:include href="acme.xml" />
|
||||
|
||||
<!-- Apache; libvirtd virtualisation -->
|
||||
|
||||
</part>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ kernel.</para>
|
||||
|
||||
<para>The default Linux kernel configuration should be fine for most users. You can see the configuration of your current kernel with the following command:
|
||||
<programlisting>
|
||||
zcat /proc/config.gz
|
||||
cat /proc/config.gz | gunzip
|
||||
</programlisting>
|
||||
If you want to change the kernel configuration, you can use the
|
||||
<option>packageOverrides</option> feature (see <xref
|
||||
@@ -66,25 +66,4 @@ boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
|
||||
sets the kernel’s TCP keepalive time to 120 seconds. To see the
|
||||
available parameters, run <command>sysctl -a</command>.</para>
|
||||
|
||||
<section>
|
||||
<title>Developing kernel modules</title>
|
||||
|
||||
<para>When developing kernel modules it's often convenient to run
|
||||
edit-compile-run loop as quickly as possible.
|
||||
|
||||
See below snippet as an example of developing <literal>mellanox</literal>
|
||||
drivers.
|
||||
</para>
|
||||
|
||||
<screen><![CDATA[
|
||||
$ nix-build '<nixpkgs>' -A linuxPackages.kernel.dev
|
||||
$ nix-shell '<nixpkgs>' -A linuxPackages.kernel
|
||||
$ unpackPhase
|
||||
$ cd linux-*
|
||||
$ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules
|
||||
# insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
|
||||
]]></screen>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -9,23 +9,23 @@
|
||||
<para>NixOS supports file systems that are encrypted using
|
||||
<emphasis>LUKS</emphasis> (Linux Unified Key Setup). For example,
|
||||
here is how you create an encrypted Ext4 file system on the device
|
||||
<filename>/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d</filename>:
|
||||
<filename>/dev/sda2</filename>:
|
||||
|
||||
<screen>
|
||||
# cryptsetup luksFormat /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d
|
||||
$ cryptsetup luksFormat /dev/sda2
|
||||
|
||||
WARNING!
|
||||
========
|
||||
This will overwrite data on /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d irrevocably.
|
||||
This will overwrite data on /dev/sda2 irrevocably.
|
||||
|
||||
Are you sure? (Type uppercase yes): YES
|
||||
Enter LUKS passphrase: ***
|
||||
Verify passphrase: ***
|
||||
|
||||
# cryptsetup luksOpen /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d crypted
|
||||
Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***
|
||||
$ cryptsetup luksOpen /dev/sda2 crypted
|
||||
Enter passphrase for /dev/sda2: ***
|
||||
|
||||
# mkfs.ext4 /dev/mapper/crypted
|
||||
$ mkfs.ext4 /dev/mapper/crypted
|
||||
</screen>
|
||||
|
||||
To ensure that this file system is automatically mounted at boot time
|
||||
@@ -33,7 +33,7 @@ as <filename>/</filename>, add the following to
|
||||
<filename>configuration.nix</filename>:
|
||||
|
||||
<programlisting>
|
||||
boot.initrd.luks.devices.crypted.device = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
|
||||
boot.initrd.luks.devices = [ { device = "/dev/sda2"; name = "crypted"; } ];
|
||||
fileSystems."/".device = "/dev/mapper/crypted";
|
||||
</programlisting>
|
||||
|
||||
|
||||
@@ -63,14 +63,14 @@ commands such as <command>useradd</command>,
|
||||
account named <literal>alice</literal>:
|
||||
|
||||
<screen>
|
||||
# useradd -m alice</screen>
|
||||
$ useradd -m alice</screen>
|
||||
|
||||
To make all nix tools available to this new user use `su - USER` which
|
||||
opens a login shell (==shell that loads the profile) for given user.
|
||||
This will create the ~/.nix-defexpr symlink. So run:
|
||||
|
||||
<screen>
|
||||
# su - alice -c "true"</screen>
|
||||
$ su - alice -c "true"</screen>
|
||||
|
||||
|
||||
The flag <option>-m</option> causes the creation of a home directory
|
||||
@@ -79,7 +79,7 @@ have an initial password and therefore cannot log in. A password can
|
||||
be set using the <command>passwd</command> utility:
|
||||
|
||||
<screen>
|
||||
# passwd alice
|
||||
$ passwd alice
|
||||
Enter new UNIX password: ***
|
||||
Retype new UNIX password: ***
|
||||
</screen>
|
||||
@@ -87,7 +87,7 @@ Retype new UNIX password: ***
|
||||
A user can be deleted using <command>userdel</command>:
|
||||
|
||||
<screen>
|
||||
# userdel -r alice</screen>
|
||||
$ userdel -r alice</screen>
|
||||
|
||||
The flag <option>-r</option> deletes the user’s home directory.
|
||||
Accounts can be modified using <command>usermod</command>. Unix
|
||||
|
||||
@@ -41,13 +41,13 @@ If you are using WPA2 the <command>wpa_passphrase</command> tool might be useful
|
||||
to generate the <literal>wpa_supplicant.conf</literal>.
|
||||
|
||||
<screen>
|
||||
# wpa_passphrase ESSID PSK > /etc/wpa_supplicant.conf</screen>
|
||||
$ wpa_passphrase ESSID PSK > /etc/wpa_supplicant.conf</screen>
|
||||
|
||||
After you have edited the <literal>wpa_supplicant.conf</literal>,
|
||||
you need to restart the wpa_supplicant service.
|
||||
|
||||
<screen>
|
||||
# systemctl restart wpa_supplicant.service</screen>
|
||||
$ systemctl restart wpa_supplicant.service</screen>
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xml:id="sec-x11">
|
||||
|
||||
<title>X Window System</title>
|
||||
|
||||
|
||||
<para>The X Window System (X11) provides the basis of NixOS’ graphical
|
||||
user interface. It can be enabled as follows:
|
||||
<programlisting>
|
||||
@@ -48,7 +48,7 @@ services.xserver.autorun = false;
|
||||
</programlisting>
|
||||
The X server can then be started manually:
|
||||
<screen>
|
||||
# systemctl start display-manager.service
|
||||
$ systemctl start display-manager.service
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
@@ -115,14 +115,5 @@ services.xserver.synaptics.twoFingerScroll = true;
|
||||
|
||||
</simplesect>
|
||||
|
||||
<simplesect><title>GTK/Qt themes</title>
|
||||
|
||||
<para>GTK themes can be installed either to user profile or system-wide (via
|
||||
<literal>system.environmentPackages</literal>). To make Qt 5 applications look similar
|
||||
to GTK2 ones, you can install <literal>qt5.qtbase.gtk</literal> package into your
|
||||
system environment. It should work for all Qt 5 library versions.
|
||||
</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
{ pkgs, options, config, version, revision, extraSources ? [] }:
|
||||
{ pkgs, options, version, revision, extraSources ? [] }:
|
||||
|
||||
with pkgs;
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
|
||||
# Remove invisible and internal options.
|
||||
optionsList = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
|
||||
optionsList = filter (opt: opt.visible && !opt.internal) (optionAttrSetToDocList options);
|
||||
|
||||
# Replace functions by the string <function>
|
||||
substFunction = x:
|
||||
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
||||
if builtins.isAttrs x then mapAttrs (name: substFunction) x
|
||||
else if builtins.isList x then map substFunction x
|
||||
else if builtins.isFunction x then "<function>"
|
||||
else x;
|
||||
|
||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||
optionsList' = lib.flip map optionsList (opt: opt // {
|
||||
optionsList' = flip map optionsList (opt: opt // {
|
||||
declarations = map stripAnyPrefixes opt.declarations;
|
||||
}
|
||||
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
||||
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
||||
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; });
|
||||
// optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
||||
// optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
||||
// optionalAttrs (opt ? type) { type = substFunction opt.type; });
|
||||
|
||||
# We need to strip references to /nix/store/* from options,
|
||||
# including any `extraSources` if some modules came from elsewhere,
|
||||
@@ -30,7 +30,7 @@ let
|
||||
# E.g. if some `options` came from modules in ${pkgs.customModules}/nix,
|
||||
# you'd need to include `extraSources = [ pkgs.customModules ]`
|
||||
prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
|
||||
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
|
||||
stripAnyPrefixes = flip (fold removePrefix) prefixesToStrip;
|
||||
|
||||
# Convert the list of options into an XML file.
|
||||
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList');
|
||||
@@ -44,26 +44,20 @@ let
|
||||
echo "for hints about the offending path)."
|
||||
exit 1
|
||||
fi
|
||||
${libxslt.bin}/bin/xsltproc \
|
||||
${libxslt}/bin/xsltproc \
|
||||
--stringparam revision '${revision}' \
|
||||
-o $out ${./options-to-docbook.xsl} $optionsXML
|
||||
'';
|
||||
|
||||
sources = lib.sourceFilesBySuffices ./. [".xml"];
|
||||
|
||||
modulesDoc = builtins.toFile "modules.xml" ''
|
||||
<section xmlns:xi="http://www.w3.org/2001/XInclude" id="modules">
|
||||
${(lib.concatMapStrings (path: ''
|
||||
<xi:include href="${path}" />
|
||||
'') (lib.catAttrs "value" config.meta.doc))}
|
||||
</section>
|
||||
'';
|
||||
sources = sourceFilesBySuffices ./. [".xml"];
|
||||
|
||||
copySources =
|
||||
''
|
||||
cp -prd $sources/* . # */
|
||||
chmod -R u+w .
|
||||
ln -s ${modulesDoc} configuration/modules.xml
|
||||
cp ${../../modules/services/databases/postgresql.xml} configuration/postgresql.xml
|
||||
cp ${../../modules/services/misc/gitlab.xml} configuration/gitlab.xml
|
||||
cp ${../../modules/security/acme.xml} configuration/acme.xml
|
||||
ln -s ${optionsDocBook} options-db.xml
|
||||
echo "${version}" > version
|
||||
'';
|
||||
@@ -78,63 +72,6 @@ let
|
||||
</toc>
|
||||
'';
|
||||
|
||||
manualXsltprocOptions = toString [
|
||||
"--param section.autolabel 1"
|
||||
"--param section.label.includes.component.label 1"
|
||||
"--stringparam html.stylesheet style.css"
|
||||
"--param xref.with.number.and.title 1"
|
||||
"--param toc.section.depth 3"
|
||||
"--stringparam admon.style ''"
|
||||
"--stringparam callout.graphics.extension .gif"
|
||||
"--stringparam current.docid manual"
|
||||
"--param chunk.section.depth 0"
|
||||
"--param chunk.first.sections 1"
|
||||
"--param use.id.as.filename 1"
|
||||
"--stringparam generate.toc 'book toc appendix toc'"
|
||||
"--stringparam chunk.toc ${toc}"
|
||||
];
|
||||
|
||||
olinkDB = stdenv.mkDerivation {
|
||||
name = "manual-olinkdb";
|
||||
|
||||
inherit sources;
|
||||
|
||||
buildInputs = [ libxml2 libxslt ];
|
||||
|
||||
buildCommand = ''
|
||||
${copySources}
|
||||
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam collect.xref.targets only \
|
||||
--stringparam targets.filename "$out/manual.db" \
|
||||
--nonet --xinclude \
|
||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||
./manual.xml
|
||||
|
||||
# Check the validity of the man pages sources.
|
||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||
./man-pages.xml
|
||||
|
||||
cat > "$out/olinkdb.xml" <<EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE targetset SYSTEM
|
||||
"file://${docbook5_xsl}/xml/xsl/docbook/common/targetdatabase.dtd" [
|
||||
<!ENTITY manualtargets SYSTEM "file://$out/manual.db">
|
||||
]>
|
||||
<targetset>
|
||||
<targetsetinfo>
|
||||
Allows for cross-referencing olinks between the manpages
|
||||
and manual.
|
||||
</targetsetinfo>
|
||||
|
||||
<document targetdoc="manual">&manualtargets;</document>
|
||||
</targetset>
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
|
||||
in rec {
|
||||
|
||||
# The NixOS options in JSON format.
|
||||
@@ -147,7 +84,7 @@ in rec {
|
||||
mkdir -p $dst
|
||||
|
||||
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
|
||||
(builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList'))))
|
||||
(listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList'))))
|
||||
} $dst/options.json
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
@@ -177,8 +114,18 @@ in rec {
|
||||
dst=$out/share/doc/nixos
|
||||
mkdir -p $dst
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--param section.autolabel 1 \
|
||||
--param section.label.includes.component.label 1 \
|
||||
--stringparam html.stylesheet style.css \
|
||||
--param xref.with.number.and.title 1 \
|
||||
--param toc.section.depth 3 \
|
||||
--stringparam admon.style "" \
|
||||
--stringparam callout.graphics.extension .gif \
|
||||
--param chunk.section.depth 0 \
|
||||
--param chunk.first.sections 1 \
|
||||
--param use.id.as.filename 1 \
|
||||
--stringparam generate.toc "book toc appendix toc" \
|
||||
--stringparam chunk.toc ${toc} \
|
||||
--nonet --xinclude --output $dst/ \
|
||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl ./manual.xml
|
||||
|
||||
@@ -197,42 +144,24 @@ in rec {
|
||||
allowedReferences = ["out"];
|
||||
};
|
||||
|
||||
|
||||
manualEpub = stdenv.mkDerivation {
|
||||
name = "nixos-manual-epub";
|
||||
manualPDF = stdenv.mkDerivation {
|
||||
name = "nixos-manual-pdf";
|
||||
|
||||
inherit sources;
|
||||
|
||||
buildInputs = [ libxml2 libxslt zip ];
|
||||
buildInputs = [ libxml2 libxslt dblatex dblatex.tex ];
|
||||
|
||||
buildCommand = ''
|
||||
${copySources}
|
||||
|
||||
# Check the validity of the manual sources.
|
||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||
manual.xml
|
||||
|
||||
# Generate the epub manual.
|
||||
dst=$out/share/doc/nixos
|
||||
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--nonet --xinclude --output $dst/epub/ \
|
||||
${docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl ./manual.xml
|
||||
|
||||
mkdir -p $dst/epub/OEBPS/images/callouts
|
||||
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/epub/OEBPS/images/callouts
|
||||
echo "application/epub+zip" > mimetype
|
||||
manual="$dst/nixos-manual.epub"
|
||||
zip -0Xq "$manual" mimetype
|
||||
cd $dst/epub && zip -Xr9D "$manual" *
|
||||
|
||||
rm -rf $dst/epub
|
||||
mkdir -p $dst
|
||||
xmllint --xinclude manual.xml | dblatex -o $dst/manual.pdf - \
|
||||
-P doc.collab.show=0 \
|
||||
-P latex.output.revhistory=0
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "doc-epub manual $manual" >> $out/nix-support/hydra-build-products
|
||||
echo "doc-pdf manual $dst/manual.pdf" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -247,7 +176,7 @@ in rec {
|
||||
buildCommand = ''
|
||||
${copySources}
|
||||
|
||||
# Check the validity of the man pages sources.
|
||||
# Check the validity of the manual sources.
|
||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||
./man-pages.xml
|
||||
@@ -259,7 +188,6 @@ in rec {
|
||||
--param man.output.base.dir "'$out/share/man/'" \
|
||||
--param man.endnotes.are.numbered 0 \
|
||||
--param man.break.after.slash 1 \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
|
||||
./man-pages.xml
|
||||
'';
|
||||
|
||||
@@ -25,8 +25,8 @@ $ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd
|
||||
suggested by the following command:
|
||||
|
||||
<screen>
|
||||
# mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
|
||||
$ mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
</chapter>
|
||||
@@ -94,8 +94,8 @@ $ nix-build -A 'config.systemd.units."httpd.service".unit'
|
||||
<screen>
|
||||
$ cp $(nix-build -A 'config.systemd.units."httpd.service".unit')/httpd.service \
|
||||
/run/systemd/system/tmp-httpd.service
|
||||
# systemctl daemon-reload
|
||||
# systemctl start tmp-httpd.service
|
||||
$ systemctl daemon-reload
|
||||
$ systemctl start tmp-httpd.service
|
||||
</screen>
|
||||
|
||||
Note that the unit must not have the same name as any unit in
|
||||
@@ -110,4 +110,4 @@ $ cp $(nix-build -A 'config.systemd.units."httpd.service".unit')/httpd.service \
|
||||
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
</chapter>
|
||||
@@ -1,62 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-meta-attributes">
|
||||
|
||||
<title>Meta Attributes</title>
|
||||
|
||||
<para>Like Nix packages, NixOS modules can declare meta-attributes to provide
|
||||
extra information. Module meta attributes are defined in the
|
||||
<filename
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/misc/meta.nix">meta.nix</filename>
|
||||
special module.</para>
|
||||
|
||||
<para><literal>meta</literal> is a top level attribute like
|
||||
<literal>options</literal> and <literal>config</literal>. Available
|
||||
meta-attributes are <literal>maintainers</literal> and
|
||||
<literal>doc</literal>.</para>
|
||||
|
||||
<para>Each of the meta-attributes must be defined at most once per module
|
||||
file.</para>
|
||||
|
||||
<programlisting>
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
options = {
|
||||
...
|
||||
};
|
||||
|
||||
config = {
|
||||
...
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ ericsagnes ]; <co
|
||||
xml:id='modules-meta-1' />
|
||||
doc = ./default.xml; <co xml:id='modules-meta-2' />
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs='modules-meta-1'>
|
||||
<para>
|
||||
<varname>maintainers</varname> contains a list of the module maintainers.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs='modules-meta-2'>
|
||||
<para>
|
||||
<varname>doc</varname> points to a valid DocBook file containing the module
|
||||
documentation. Its contents is automatically added to <xref
|
||||
linkend="ch-configuration"/>.
|
||||
Changes to a module documentation have to be checked to not break
|
||||
building the NixOS manual:
|
||||
</para>
|
||||
<programlisting>$ nix-build nixos/release.nix -A manual</programlisting>
|
||||
</callout>
|
||||
|
||||
</calloutlist>
|
||||
|
||||
</section>
|
||||
@@ -7,8 +7,8 @@
|
||||
<title>Option Declarations</title>
|
||||
|
||||
<para>An option declaration specifies the name, type and description
|
||||
of a NixOS configuration option. It is invalid to define an option
|
||||
that hasn’t been declared in any module. An option declaration
|
||||
of a NixOS configuration option. It is illegal to define an option
|
||||
that hasn’t been declared in any module. A option declaration
|
||||
generally looks like this:
|
||||
|
||||
<programlisting>
|
||||
@@ -42,7 +42,7 @@ options = {
|
||||
<listitem>
|
||||
<para>The default value used if no value is defined by any
|
||||
module. A default is not required; in that case, if the option
|
||||
value is never used, an error will be thrown.</para>
|
||||
value is ever used, an error will be thrown.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -11,25 +11,35 @@ uses the NixOS and Nixpkgs sources provided by the
|
||||
<literal>nixos-unstable</literal> channel (kept in
|
||||
<filename>/nix/var/nix/profiles/per-user/root/channels/nixos</filename>).
|
||||
To modify NixOS, however, you should check out the latest sources from
|
||||
Git. This is as follows:
|
||||
Git. This is done using the following command:
|
||||
|
||||
<screen>
|
||||
$ nixos-checkout <replaceable>/my/sources</replaceable>
|
||||
</screen>
|
||||
|
||||
or
|
||||
|
||||
<screen>
|
||||
$ mkdir -p <replaceable>/my/sources</replaceable>
|
||||
$ cd <replaceable>/my/sources</replaceable>
|
||||
$ nix-env -i git
|
||||
$ git clone git://github.com/NixOS/nixpkgs.git
|
||||
$ cd nixpkgs
|
||||
$ git remote add channels git://github.com/NixOS/nixpkgs-channels.git
|
||||
$ git remote update channels
|
||||
</screen>
|
||||
|
||||
This will check out the latest Nixpkgs sources to
|
||||
<filename>./nixpkgs</filename> the NixOS sources to
|
||||
<filename>./nixpkgs/nixos</filename>. (The NixOS source tree lives in
|
||||
a subdirectory of the Nixpkgs repository.) The remote
|
||||
<literal>channels</literal> refers to a read-only repository that
|
||||
tracks the Nixpkgs/NixOS channels (see <xref linkend="sec-upgrading"/>
|
||||
for more information about channels). Thus, the Git branch
|
||||
<literal>channels/nixos-14.12</literal> will contain the latest built
|
||||
and tested version available in the <literal>nixos-14.12</literal>
|
||||
channel.</para>
|
||||
This will check out the latest NixOS sources to
|
||||
<filename><replaceable>/my/sources</replaceable>/nixpkgs/nixos</filename>
|
||||
and the Nixpkgs sources to
|
||||
<filename><replaceable>/my/sources</replaceable>/nixpkgs</filename>.
|
||||
(The NixOS source tree lives in a subdirectory of the Nixpkgs
|
||||
repository.) The remote <literal>channels</literal> refers to a
|
||||
read-only repository that tracks the Nixpkgs/NixOS channels (see <xref
|
||||
linkend="sec-upgrading"/> for more information about channels). Thus,
|
||||
the Git branch <literal>channels/nixos-14.12</literal> will contain
|
||||
the latest built and tested version available in the
|
||||
<literal>nixos-14.12</literal> channel.</para>
|
||||
|
||||
<para>It’s often inconvenient to develop directly on the master
|
||||
branch, since if somebody has just committed (say) a change to GCC,
|
||||
@@ -70,7 +80,7 @@ sources, you need to tell <command>nixos-rebuild</command> about them
|
||||
using the <option>-I</option> flag:
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch -I nixpkgs=<replaceable>/my/sources</replaceable>/nixpkgs
|
||||
$ nixos-rebuild switch -I nixpkgs=<replaceable>/my/sources</replaceable>/nixpkgs
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
@@ -12,16 +12,16 @@ properly:
|
||||
|
||||
<screen>
|
||||
$ nix-build -A config.system.build.nixos-install
|
||||
# mount -t tmpfs none /mnt
|
||||
# ./result/bin/nixos-install</screen>
|
||||
$ mount -t tmpfs none /mnt
|
||||
$ ./result/bin/nixos-install</screen>
|
||||
|
||||
To start a login shell in the new NixOS installation in
|
||||
<filename>/mnt</filename>:
|
||||
|
||||
<screen>
|
||||
# ./result/bin/nixos-install --chroot
|
||||
$ ./result/bin/nixos-install --chroot
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
</chapter>
|
||||
@@ -177,6 +177,5 @@ in {
|
||||
|
||||
<xi:include href="option-declarations.xml" />
|
||||
<xi:include href="option-def.xml" />
|
||||
<xi:include href="meta-attributes.xml" />
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -10,7 +10,7 @@ contains the current configuration of your machine. Whenever you’ve
|
||||
changed something to that file, you should do
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch</screen>
|
||||
$ nixos-rebuild switch</screen>
|
||||
|
||||
to build the new configuration, make it the default configuration for
|
||||
booting, and try to realise the configuration in the running system
|
||||
@@ -23,7 +23,7 @@ either run them from a root shell or by prefixing them with
|
||||
<para>You can also do
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild test</screen>
|
||||
$ nixos-rebuild test</screen>
|
||||
|
||||
to build the configuration and switch the running system to it, but
|
||||
without making it the boot default. So if (say) the configuration
|
||||
@@ -33,7 +33,7 @@ configuration.</para>
|
||||
<para>There is also
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild boot</screen>
|
||||
$ nixos-rebuild boot</screen>
|
||||
|
||||
to build the configuration and make it the boot default, but not
|
||||
switch to it now (so it will only take effect after the next
|
||||
@@ -44,7 +44,7 @@ of the GRUB 2 boot screen by giving it a different <emphasis>profile
|
||||
name</emphasis>, e.g.
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch -p test </screen>
|
||||
$ nixos-rebuild switch -p test </screen>
|
||||
|
||||
which causes the new configuration (and previous ones created using
|
||||
<literal>-p test</literal>) to show up in the GRUB submenu “NixOS -
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-booting-from-pxe">
|
||||
|
||||
<title>Booting from the <quote>netboot</quote> media (PXE)</title>
|
||||
<para>
|
||||
Advanced users may wish to install NixOS using an existing PXE or
|
||||
iPXE setup.
|
||||
</para>
|
||||
<para>
|
||||
These instructions assume that you have an existing PXE or iPXE
|
||||
infrastructure and simply want to add the NixOS installer as another
|
||||
option. To build the necessary files from a recent version of
|
||||
nixpkgs, you can run:
|
||||
</para>
|
||||
<programlisting>
|
||||
nix-build -A netboot nixos/release.nix
|
||||
</programlisting>
|
||||
<para>
|
||||
This will create a <literal>result</literal> directory containing: *
|
||||
<literal>bzImage</literal> – the Linux kernel *
|
||||
<literal>initrd</literal> – the initrd file *
|
||||
<literal>netboot.ipxe</literal> – an example ipxe script
|
||||
demonstrating the appropriate kernel command line arguments for this
|
||||
image
|
||||
</para>
|
||||
<para>
|
||||
If you’re using plain PXE, configure your boot loader to use the
|
||||
<literal>bzImage</literal> and <literal>initrd</literal> files and
|
||||
have it provide the same kernel command line arguments found in
|
||||
<literal>netboot.ipxe</literal>.
|
||||
</para>
|
||||
<para>
|
||||
If you’re using iPXE, depending on how your HTTP/FTP/etc. server is
|
||||
configured you may be able to use <literal>netboot.ipxe</literal>
|
||||
unmodified, or you may need to update the paths to the files to
|
||||
match your server’s directory layout
|
||||
</para>
|
||||
<para>
|
||||
In the future we may begin making these files available as build
|
||||
products from hydra at which point we will update this documentation
|
||||
with instructions on how to obtain them either for placing on a
|
||||
dedicated TFTP server or to boot them directly over the internet.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
@@ -5,7 +5,7 @@
|
||||
xml:id="sec-uefi-installation">
|
||||
|
||||
<title>UEFI Installation</title>
|
||||
|
||||
|
||||
<para>NixOS can also be installed on UEFI systems. The procedure
|
||||
is by and large the same as a BIOS installation, with the following
|
||||
changes:
|
||||
@@ -26,7 +26,7 @@ changes:
|
||||
<literal>vfat</literal> filesystem.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>You must set <option>boot.loader.systemd-boot.enable</option> to
|
||||
<para>You must set <option>boot.loader.gummiboot.enable</option> to
|
||||
<literal>true</literal>. <command>nixos-generate-config</command>
|
||||
should do this automatically for new configurations when booted in
|
||||
UEFI mode.</para>
|
||||
@@ -38,7 +38,7 @@ changes:
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>You may want to look at the options starting with
|
||||
<option>boot.loader.efi</option> and <option>boot.loader.systemd-boot</option>
|
||||
<option>boot.loader.efi</option> and <option>boot.loader.gummiboot</option>
|
||||
as well.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
@@ -7,18 +7,10 @@
|
||||
<title>Booting from a USB Drive</title>
|
||||
|
||||
<para>For systems without CD drive, the NixOS live CD can be booted from
|
||||
a USB stick. You can use the <command>dd</command> utility to write the image:
|
||||
<command>dd if=<replaceable>path-to-image</replaceable>
|
||||
of=<replaceable>/dev/sdb</replaceable></command>. Be careful about specifying the
|
||||
correct drive; you can use the <command>lsblk</command> command to get a list of
|
||||
block devices.</para>
|
||||
|
||||
<para>The <command>dd</command> utility will write the image verbatim to the drive,
|
||||
making it the recommended option for both UEFI and non-UEFI installations. For
|
||||
non-UEFI installations, you can alternatively use
|
||||
<link xlink:href="http://unetbootin.sourceforge.net/">unetbootin</link>. If you
|
||||
cannot use <command>dd</command> for a UEFI installation, you can also mount the
|
||||
ISO, copy its contents verbatim to your drive, then either:
|
||||
a USB stick. For non-UEFI installations,
|
||||
<link xlink:href="http://unetbootin.sourceforge.net/">unetbootin</link>
|
||||
will work. For UEFI installations, you should mount the ISO, copy its contents
|
||||
verbatim to your drive, then either:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-instaling-virtualbox-guest">
|
||||
|
||||
<title>Installing in a Virtualbox guest</title>
|
||||
<para>
|
||||
Installing NixOS into a Virtualbox guest is convenient for users who want to
|
||||
try NixOS without installing it on bare metal. If you want to use a pre-made
|
||||
Virtualbox appliance, it is available at <link
|
||||
xlink:href="https://nixos.org/nixos/download.html">the downloads page</link>.
|
||||
If you want to set up a Virtualbox guest manually, follow these instructions:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
|
||||
<listitem><para>Add a New Machine in Virtualbox with OS Type "Linux / Other
|
||||
Linux"</para></listitem>
|
||||
|
||||
<listitem><para>Base Memory Size: 768 MB or higher.</para></listitem>
|
||||
|
||||
<listitem><para>New Hard Disk of 8 GB or higher.</para></listitem>
|
||||
|
||||
<listitem><para>Mount the CD-ROM with the NixOS ISO (by clicking on
|
||||
CD/DVD-ROM)</para></listitem>
|
||||
|
||||
<listitem><para>Click on Settings / System / Processor and enable
|
||||
PAE/NX</para></listitem>
|
||||
|
||||
<listitem><para>Click on Settings / System / Acceleration and enable
|
||||
"VT-x/AMD-V" acceleration</para></listitem>
|
||||
|
||||
<listitem><para>Save the settings, start the virtual machine, and continue
|
||||
installation like normal</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
There are a few modifications you should make in configuration.nix. Enable
|
||||
the virtualbox guest service in the main block:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
virtualisation.virtualbox.guest.enable = true;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Enable booting:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Also remove the fsck that runs at startup. It will always fail to run,
|
||||
stopping your boot until you press <literal>*</literal>.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
boot.initrd.checkJournalingFS = false;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Shared folders can be given a name and a path in the host system in the
|
||||
VirtualBox settings (Machine / Settings / Shared Folders, then click on the
|
||||
"Add" icon). Add the following to the
|
||||
<literal>/etc/nixos/configuration.nix</literal> to auto-mount them:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
{ config, pkgs, ...} :
|
||||
{
|
||||
...
|
||||
|
||||
fileSystems."/virtualboxshare" = {
|
||||
fsType = "vboxsf";
|
||||
device = "nameofthesharedfolder";
|
||||
options = [ "rw" ];
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
The folder will be available directly under the root directory.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
@@ -22,7 +22,7 @@
|
||||
(with empty password).</para></listitem>
|
||||
|
||||
<listitem><para>If you downloaded the graphical ISO image, you can
|
||||
run <command>systemctl start display-manager</command> to start KDE. If you
|
||||
run <command>start display-manager</command> to start KDE. If you
|
||||
want to continue on the terminal, you can use
|
||||
<command>loadkeys</command> to switch to your preferred keyboard layout.
|
||||
(We even provide neo2 via <command>loadkeys de neo</command>!)</para></listitem>
|
||||
@@ -54,7 +54,7 @@
|
||||
changes. For example:
|
||||
|
||||
<screen>
|
||||
# mkfs.ext4 -L nixos /dev/sda1</screen>
|
||||
$ mkfs.ext4 -L nixos /dev/sda1</screen>
|
||||
|
||||
</para></listitem>
|
||||
|
||||
@@ -66,10 +66,10 @@
|
||||
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
|
||||
|
||||
<screen>
|
||||
# pvcreate /dev/sda1 /dev/sdb1
|
||||
# vgcreate MyVolGroup /dev/sda1 /dev/sdb1
|
||||
# lvcreate --size 2G --name bigdisk MyVolGroup
|
||||
# lvcreate --size 1G --name smalldisk MyVolGroup</screen>
|
||||
$ pvcreate /dev/sda1 /dev/sdb1
|
||||
$ vgcreate MyVolGroup /dev/sda1 /dev/sdb1
|
||||
$ lvcreate --size 2G --name bigdisk MyVolGroup
|
||||
$ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
|
||||
|
||||
</para></listitem>
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
be installed on <filename>/mnt</filename>, e.g.
|
||||
|
||||
<screen>
|
||||
# mount /dev/disk/by-label/nixos /mnt
|
||||
$ mount /dev/disk/by-label/nixos /mnt
|
||||
</screen>
|
||||
|
||||
</para></listitem>
|
||||
@@ -113,14 +113,14 @@
|
||||
generate an initial configuration file for you:
|
||||
|
||||
<screen>
|
||||
# nixos-generate-config --root /mnt</screen>
|
||||
$ nixos-generate-config --root /mnt</screen>
|
||||
|
||||
You should then edit
|
||||
<filename>/mnt/etc/nixos/configuration.nix</filename> to suit your
|
||||
needs:
|
||||
|
||||
<screen>
|
||||
# nano /mnt/etc/nixos/configuration.nix
|
||||
$ nano /mnt/etc/nixos/configuration.nix
|
||||
</screen>
|
||||
|
||||
If you’re using the graphical ISO image, other editors may be
|
||||
@@ -157,12 +157,16 @@
|
||||
<command>nixos-generate-config</command> will figure out the
|
||||
required modules.</para></note>
|
||||
|
||||
<para>Examples of real-world NixOS configuration files can be
|
||||
found at <link
|
||||
xlink:href="https://nixos.org/repos/nix/configurations/trunk/"/>.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
<listitem><para>Do the installation:
|
||||
|
||||
<screen>
|
||||
# nixos-install</screen>
|
||||
$ nixos-install</screen>
|
||||
|
||||
Cross fingers. If this fails due to a temporary problem (such as
|
||||
a network issue while downloading binaries from the NixOS binary
|
||||
@@ -186,7 +190,7 @@ Retype new UNIX password: ***
|
||||
<listitem><para>If everything went well:
|
||||
|
||||
<screen>
|
||||
# reboot</screen>
|
||||
$ reboot</screen>
|
||||
|
||||
</para></listitem>
|
||||
|
||||
@@ -235,15 +239,15 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
||||
|
||||
<example xml:id='ex-install-sequence'><title>Commands for Installing NixOS on <filename>/dev/sda</filename></title>
|
||||
<screen>
|
||||
# fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
||||
# mkfs.ext4 -L nixos /dev/sda1
|
||||
# mkswap -L swap /dev/sda2
|
||||
# swapon /dev/sda2
|
||||
# mount /dev/disk/by-label/nixos /mnt
|
||||
# nixos-generate-config --root /mnt
|
||||
# nano /mnt/etc/nixos/configuration.nix
|
||||
# nixos-install
|
||||
# reboot</screen>
|
||||
$ fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
||||
$ mkfs.ext4 -L nixos /dev/sda1
|
||||
$ mkswap -L swap /dev/sda2
|
||||
$ swapon /dev/sda2
|
||||
$ mount /dev/disk/by-label/nixos /mnt
|
||||
$ nixos-generate-config --root /mnt
|
||||
$ nano /mnt/etc/nixos/configuration.nix
|
||||
$ nixos-install
|
||||
$ reboot</screen>
|
||||
</example>
|
||||
|
||||
<example xml:id='ex-config'><title>NixOS Configuration</title>
|
||||
@@ -270,7 +274,5 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
||||
|
||||
<xi:include href="installing-uefi.xml" />
|
||||
<xi:include href="installing-usb.xml" />
|
||||
<xi:include href="installing-pxe.xml" />
|
||||
<xi:include href="installing-virtualbox-guest.xml" />
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -60,33 +60,33 @@ the <literal>nixos-14.12</literal> channel. To see which NixOS
|
||||
channel you’re subscribed to, run the following as root:
|
||||
|
||||
<screen>
|
||||
# nix-channel --list | grep nixos
|
||||
$ nix-channel --list | grep nixos
|
||||
nixos https://nixos.org/channels/nixos-unstable
|
||||
</screen>
|
||||
|
||||
To switch to a different NixOS channel, do
|
||||
|
||||
<screen>
|
||||
# nix-channel --add https://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
|
||||
$ nix-channel --add https://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
|
||||
</screen>
|
||||
|
||||
(Be sure to include the <literal>nixos</literal> parameter at the
|
||||
end.) For instance, to use the NixOS 14.12 stable channel:
|
||||
|
||||
<screen>
|
||||
# nix-channel --add https://nixos.org/channels/nixos-14.12 nixos
|
||||
$ nix-channel --add https://nixos.org/channels/nixos-14.12 nixos
|
||||
</screen>
|
||||
|
||||
If you have a server, you may want to use the “small” channel instead:
|
||||
|
||||
<screen>
|
||||
# nix-channel --add https://nixos.org/channels/nixos-14.12-small nixos
|
||||
$ nix-channel --add https://nixos.org/channels/nixos-14.12-small nixos
|
||||
</screen>
|
||||
|
||||
And if you want to live on the bleeding edge:
|
||||
|
||||
<screen>
|
||||
# nix-channel --add https://nixos.org/channels/nixos-unstable nixos
|
||||
$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
@@ -95,7 +95,7 @@ And if you want to live on the bleeding edge:
|
||||
channel by running
|
||||
|
||||
<screen>
|
||||
# nixos-rebuild switch --upgrade
|
||||
$ nixos-rebuild switch --upgrade
|
||||
</screen>
|
||||
|
||||
which is equivalent to the more verbose <literal>nix-channel --update
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle><filename>configuration.nix</filename></refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
@@ -34,5 +34,5 @@ therein.</para>
|
||||
<xi:include href="options-db.xml" />
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
</refentry>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle><command>nixos-build-vms</command></refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
@@ -42,10 +42,10 @@ points to the generated virtual network.
|
||||
services.openssh.enable = true;
|
||||
nixpkgs.system = "i686-linux";
|
||||
deployment.targetHost = "test1.example.net";
|
||||
|
||||
|
||||
# Other NixOS options
|
||||
};
|
||||
|
||||
|
||||
test2 = {pkgs, config, ...}:
|
||||
{
|
||||
services.openssh.enable = true;
|
||||
@@ -53,7 +53,7 @@ points to the generated virtual network.
|
||||
environment.systemPackages = [ pkgs.lynx ];
|
||||
nixpkgs.system = "x86_64-linux";
|
||||
deployment.targetHost = "test2.example.net";
|
||||
|
||||
|
||||
# Other NixOS options
|
||||
};
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@
|
||||
<varlistentry>
|
||||
<term><option>--no-filesystems</option></term>
|
||||
<listitem>
|
||||
<para>Omit everything concerning file systems and swap devices
|
||||
from the hardware configuration.</para>
|
||||
<para>Omit everything concerning file system information
|
||||
(which includes swap devices) from the hardware configuration.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -25,19 +25,6 @@
|
||||
<arg choice='plain'><option>--root</option></arg>
|
||||
<replaceable>root</replaceable>
|
||||
</arg>
|
||||
<arg>
|
||||
<arg choice='plain'><option>--closure</option></arg>
|
||||
<replaceable>closure</replaceable>
|
||||
</arg>
|
||||
<arg>
|
||||
<arg choice='plain'><option>--no-channel-copy</option></arg>
|
||||
</arg>
|
||||
<arg>
|
||||
<arg choice='plain'><option>--no-root-passwd</option></arg>
|
||||
</arg>
|
||||
<arg>
|
||||
<arg choice='plain'><option>--no-bootloader</option></arg>
|
||||
</arg>
|
||||
<arg>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'><option>--max-jobs</option></arg>
|
||||
@@ -84,13 +71,12 @@ the following steps:
|
||||
<filename>/mnt/etc/nixos/configuration.nix</filename>.</para></listitem>
|
||||
|
||||
<listitem><para>It installs the GRUB boot loader on the device
|
||||
specified in the option <option>boot.loader.grub.device</option>
|
||||
(unless <option>--no-bootloader</option> is specified),
|
||||
specified in the option <option>boot.loader.grub.device</option>,
|
||||
and generates a GRUB configuration file that boots into the NixOS
|
||||
configuration just installed.</para></listitem>
|
||||
|
||||
<listitem><para>It prompts you for a password for the root account
|
||||
(unless <option>--no-root-passwd</option> is specified).</para></listitem>
|
||||
<listitem><para>It prompts you for a password for the root
|
||||
account.</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
@@ -117,19 +103,6 @@ it.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--closure</option></term>
|
||||
<listitem>
|
||||
<para>If this option is provided, <command>nixos-install</command> will install the specified closure
|
||||
rather than attempt to build one from <filename>/mnt/etc/nixos/configuration.nix</filename>.</para>
|
||||
|
||||
<para>The closure must be an appropriately configured NixOS system, with boot loader and partition
|
||||
configuration that fits the target host. Such a closure is typically obtained with a command such as
|
||||
<command>nix-build -I nixos-config=./configuration.nix '<nixos>' -A system --no-out-link</command>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-I</option></term>
|
||||
<listitem>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle><command>nixos-option</command></refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
@@ -64,7 +64,7 @@ $ nixos-option boot.loader.grub.enable
|
||||
Value:
|
||||
true
|
||||
|
||||
Default:
|
||||
Default:
|
||||
true
|
||||
|
||||
Description:
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</group>
|
||||
<sbr />
|
||||
<arg><option>--upgrade</option></arg>
|
||||
<arg><option>--install-bootloader</option></arg>
|
||||
<arg><option>--install-grub</option></arg>
|
||||
<arg><option>--no-build-nix</option></arg>
|
||||
<arg><option>--fast</option></arg>
|
||||
<arg><option>--rollback</option></arg>
|
||||
@@ -212,11 +212,12 @@ $ ./result/bin/run-*-vm
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--install-bootloader</option></term>
|
||||
<term><option>--install-grub</option></term>
|
||||
<listitem>
|
||||
<para>Causes the boot loader to be (re)installed on the
|
||||
device specified by the relevant configuration options.
|
||||
</para>
|
||||
<para>Causes the GRUB boot loader to be (re)installed on the
|
||||
device specified by the
|
||||
<varname>boot.loader.grub.device</varname> configuration
|
||||
option.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle><command>nixos-version</command></refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
<refmiscinfo class="source">NixOS</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname><command>nixos-version</command></refname>
|
||||
<refpurpose>show the NixOS version</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>nixos-version</command>
|
||||
<arg><option>--hash</option></arg>
|
||||
<arg><option>--revision</option></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>This command shows the version of the currently active NixOS
|
||||
configuration. For example:
|
||||
|
||||
<screen>$ nixos-version
|
||||
16.03.1011.6317da4 (Emu)
|
||||
</screen>
|
||||
|
||||
The version consists of the following elements:
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>16.03</literal></term>
|
||||
<listitem><para>The NixOS release, indicating the year and month
|
||||
in which it was released (e.g. March 2016).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>1011</literal></term>
|
||||
<listitem><para>The number of commits in the Nixpkgs Git
|
||||
repository between the start of the release branch and the commit
|
||||
from which this version was built. This ensures that NixOS
|
||||
versions are monotonically increasing. It is
|
||||
<literal>git</literal> when the current NixOS configuration was
|
||||
built from a checkout of the Nixpkgs Git repository rather than
|
||||
from a NixOS channel.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>6317da4</literal></term>
|
||||
<listitem><para>The first 7 characters of the commit in the
|
||||
Nixpkgs Git repository from which this version was
|
||||
built.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>Emu</literal></term>
|
||||
<listitem><para>The code name of the NixOS release. The first
|
||||
letter of the code name indicates that this is the N'th stable
|
||||
NixOS release; for example, Emu is the fifth
|
||||
release.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Options</title>
|
||||
|
||||
<para>This command accepts the following options:</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--hash</option></term>
|
||||
<term><option>--revision</option></term>
|
||||
<listitem>
|
||||
<para>Show the full SHA1 hash of the Git commit from which this
|
||||
configuration was built, e.g.
|
||||
<screen>$ nixos-version --hash
|
||||
6317da40006f6bc2480c6781999c52d88dde2acf
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsection>
|
||||
</refentry>
|
||||
@@ -27,6 +27,5 @@
|
||||
<xi:include href="man-nixos-install.xml" />
|
||||
<xi:include href="man-nixos-option.xml" />
|
||||
<xi:include href="man-nixos-rebuild.xml" />
|
||||
<xi:include href="man-nixos-version.xml" />
|
||||
|
||||
</reference>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="book-nixos-manual">
|
||||
|
||||
|
||||
<info>
|
||||
<title>NixOS Manual</title>
|
||||
<subtitle>Version <xi:include href="version" parse="text" /></subtitle>
|
||||
@@ -26,9 +26,6 @@
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/issues">NixOS’ GitHub
|
||||
issue tracker</link>.</para>
|
||||
|
||||
<note><para>Commands prefixed with <literal>#</literal> have to be run as
|
||||
root, either requiring to login as root user or temporarily switching
|
||||
to it using <literal>sudo</literal> for example.</para></note>
|
||||
</preface>
|
||||
|
||||
<xi:include href="installation/installation.xml" />
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<xsl:output method='xml' encoding="UTF-8" />
|
||||
|
||||
<xsl:param name="revision" />
|
||||
<xsl:param name="program" />
|
||||
|
||||
|
||||
<xsl:template match="/expr/list">
|
||||
@@ -189,7 +188,7 @@
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:when test="$revision != 'local' and $program = 'nixops' and contains(@value, '/nix/')">
|
||||
<xsl:when test="$revision != 'local' and contains(@value, 'nixops') and contains(@value, '/nix/')">
|
||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixops/blob/<xsl:value-of select="$revision"/>/nix/<xsl:value-of select="substring-after(@value, '/nix/')"/></xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
<para>This section lists the release notes for each stable version of NixOS
|
||||
and current unstable revision.</para>
|
||||
|
||||
<xi:include href="rl-1609.xml" />
|
||||
<xi:include href="rl-1603.xml" />
|
||||
<xi:include href="rl-1509.xml" />
|
||||
<xi:include href="rl-1412.xml" />
|
||||
|
||||
@@ -471,7 +471,7 @@ in
|
||||
<listitem> <para>
|
||||
A newly packaged TeX Live 2015 is provided in <literal>pkgs.texlive</literal>,
|
||||
split into 6500 nix packages. For basic user documentation see
|
||||
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/release-15.09/pkgs/tools/typesetting/tex/texlive/default.nix#L1"
|
||||
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/release-15.09/pkgs/tools/typesetting/tex/texlive-new/default.nix#L1"
|
||||
>the source</link>.
|
||||
Beware of <link xlink:href="https://github.com/NixOS/nixpkgs/issues/9757"
|
||||
>an issue</link> when installing a too large package set.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
version="5.0"
|
||||
xml:id="sec-release-16.03">
|
||||
|
||||
<title>Release 16.03 (“Emu”, 2016/03/31)</title>
|
||||
<title>Release 16.03 (“Emu”, 2016/03/??)</title>
|
||||
|
||||
<para>In addition to numerous new and upgraded packages, this release
|
||||
has the following highlights:</para>
|
||||
@@ -33,10 +33,6 @@ has the following highlights:</para>
|
||||
<para>Glibc 2.23 (was 2.21).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Binutils 2.26 (was 2.23.1). See #909</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Improved support for ensuring <link
|
||||
xlink:href="https://reproducible-builds.org/">bitwise reproducible
|
||||
@@ -63,11 +59,11 @@ has the following highlights:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>services/monitoring/longview.nix</literal></para></listitem>
|
||||
<listitem><para><literal>hardware/video/webcam/facetimehd.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/input-method/default.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/input-method/fcitx.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/input-method/ibus.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/input-method/nabi.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/input-method/uim.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/inputMethod/default.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/inputMethod/fcitx.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/inputMethod/ibus.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/inputMethod/nabi.nix</literal></para></listitem>
|
||||
<listitem><para><literal>i18n/inputMethod/uim.nix</literal></para></listitem>
|
||||
<listitem><para><literal>programs/fish.nix</literal></para></listitem>
|
||||
<listitem><para><literal>security/acme.nix</literal></para></listitem>
|
||||
<listitem><para><literal>security/audit.nix</literal></para></listitem>
|
||||
@@ -165,7 +161,7 @@ following incompatible changes:</para>
|
||||
|
||||
<programlisting><![CDATA[
|
||||
{
|
||||
imports = [ <nixpkgs/nixos/modules/services/misc/gitit.nix> ];
|
||||
imports = [ <nixos/modules/services/misc/gitit.nix> ];
|
||||
}
|
||||
]]></programlisting>
|
||||
|
||||
@@ -279,7 +275,7 @@ fileSystems."/example" = {
|
||||
|
||||
<listitem>
|
||||
<para><literal>services.xserver.vaapiDrivers</literal> has been removed. Use
|
||||
<literal>hardware.opengl.extraPackages{,32}</literal> instead. You can
|
||||
<literal>services.hardware.opengl.extraPackages{,32}</literal> instead. You can
|
||||
also specify VDPAU drivers there.</para>
|
||||
</listitem>
|
||||
|
||||
@@ -348,7 +344,7 @@ $TTL 1800
|
||||
<para>
|
||||
<literal>service.syncthing.dataDir</literal> options now has to point
|
||||
to exact folder where syncthing is writing to. Example configuration should
|
||||
look something like:
|
||||
loook something like:
|
||||
</para>
|
||||
<programlisting>
|
||||
services.syncthing = {
|
||||
@@ -385,41 +381,6 @@ services.syncthing = {
|
||||
the github issue</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>services.xserver.startGnuPGAgent</literal> option has been removed.
|
||||
GnuPG 2.1.x changed the way the gpg-agent works, and that new approach no
|
||||
longer requires (or even supports) the "start everything as a child of the
|
||||
agent" scheme we've implemented in NixOS for older versions.
|
||||
To configure the gpg-agent for your X session, add the following code to
|
||||
<filename>~/.bashrc</filename> or some file that’s sourced when your shell is started:
|
||||
<programlisting>
|
||||
GPG_TTY=$(tty)
|
||||
export GPG_TTY
|
||||
</programlisting>
|
||||
If you want to use gpg-agent for SSH, too, add the following to your session
|
||||
initialization (e.g. <literal>displayManager.sessionCommands</literal>)
|
||||
<programlisting>
|
||||
gpg-connect-agent /bye
|
||||
unset SSH_AGENT_PID
|
||||
export SSH_AUTH_SOCK="''${HOME}/.gnupg/S.gpg-agent.ssh"
|
||||
</programlisting>
|
||||
and make sure that
|
||||
<programlisting>
|
||||
enable-ssh-support
|
||||
</programlisting>
|
||||
is included in your <filename>~/.gnupg/gpg-agent.conf</filename>.
|
||||
You will need to use <command>ssh-add</command> to re-add your ssh keys.
|
||||
If gpg’s automatic transformation of the private keys to the new format fails,
|
||||
you will need to re-import your private keyring as well:
|
||||
<programlisting>
|
||||
gpg --import ~/.gnupg/secring.gpg
|
||||
</programlisting>
|
||||
The <command>gpg-agent(1)</command> man page has more details about this subject,
|
||||
i.e. in the "EXAMPLES" section.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-release-16.09">
|
||||
|
||||
<title>Release 16.09 (“Flounder”, 2016/09/30)</title>
|
||||
|
||||
<para>In addition to numerous new and upgraded packages, this release
|
||||
has the following highlights: </para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>Many NixOS configurations and Nix packages now use
|
||||
significantly less disk space, thanks to the <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/issues/7117">extensive
|
||||
work on closure size reduction</link>. For example, the closure
|
||||
size of a minimal NixOS container went down from ~424 MiB in 16.03
|
||||
to ~212 MiB in 16.09, while the closure size of Firefox went from
|
||||
~651 MiB to ~259 MiB.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>To improve security, packages are now <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pull/12895">built
|
||||
using various hardening features</link>. See the Nixpkgs manual
|
||||
for more information.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Support for PXE netboot. See <xref
|
||||
linkend="sec-booting-from-pxe" /> for documentation.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>X.org server 1.18. If you use the
|
||||
<literal>ati_unfree</literal> driver, 1.17 is still used due to an
|
||||
ABI incompatibility.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>This release is based on Glibc 2.24, GCC 5.4.0 and systemd
|
||||
231. The default Linux kernel remains 4.4.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
<para>The following new services were added since the last release:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>hardware/video/amdgpu.nix</literal></para></listitem>
|
||||
<listitem><para><literal>hardware/video/displaylink.nix</literal></para></listitem>
|
||||
<listitem><para><literal>programs/info.nix</literal></para></listitem>
|
||||
<listitem><para><literal>programs/mosh.nix</literal></para></listitem>
|
||||
<listitem><para><literal>programs/spacefm.nix</literal></para></listitem>
|
||||
<listitem><para><literal>programs/tmux.nix</literal></para></listitem>
|
||||
<listitem><para><literal>programs/xonsh.nix</literal></para></listitem>
|
||||
<listitem><para><literal>security/chromium-suid-sandbox.nix</literal></para></listitem>
|
||||
<listitem><para><literal>security/hidepid.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/audio/squeezelite.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/backup/znapzend.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/continuous-integration/buildkite-agent.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/continuous-integration/hydra/default.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/continuous-integration/gocd-agent/default.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/continuous-integration/gocd-server/default.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/development/hoogle.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/editors/emacs.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/games/factorio.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/games/terraria.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/logging/awstats.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/logging/graylog.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/misc/emby.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/misc/mantisbt.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/misc/nzbget.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/misc/packagekit.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/misc/sonarr.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/misc/spice-vdagentd.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/misc/taskserver</literal></para></listitem>
|
||||
<listitem><para><literal>services/network-filesystems/tahoe.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/coturn.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/ferm.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/gdomap.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/libreswan.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/logmein-hamachi.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/mfi.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/mjpg-streamer.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/mosquitto.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/nntp-proxy.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/offlineimap.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/pptpd.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/sniproxy.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/smokeping.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/toxvpn.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/xl2tpd.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/networking/zerobin.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/security/oauth2_proxy.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/torrent/flexget.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/web-apps/mattermost.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/web-apps/tt-rss.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/web-servers/caddy.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/web-servers/lighttpd/inginious.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/x11/compton.nix</literal></para></listitem>
|
||||
<listitem><para><literal>services/x11/xbanish.nix</literal></para></listitem>
|
||||
<listitem><para><literal>system/boot/loader/systemd-boot/systemd-boot.nix</literal></para></listitem>
|
||||
<listitem><para><literal>system/boot/plymouth.nix</literal></para></listitem>
|
||||
<listitem><para><literal>virtualisation/xe-guest-utilities.nix</literal></para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>When upgrading from a previous release, please be aware of the
|
||||
following incompatible changes:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>A large number of packages have been converted to use the multiple outputs feature
|
||||
of Nix to greatly reduce the amount of required disk space, as
|
||||
mentioned above. This may require changes
|
||||
to any custom packages to make them build again; see the relevant chapter in the
|
||||
Nixpkgs manual for more information. (Additional caveat to packagers: some packaging conventions
|
||||
related to multiple-output packages
|
||||
<link xlink:href="https://github.com/NixOS/nixpkgs/pull/14766">were changed</link>
|
||||
late (August 2016) in the release cycle and differ from the initial introduction of multiple outputs.)
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Previous versions of Nixpkgs had support for all versions of the LTS
|
||||
Haskell package set. That support has been dropped. The previously provided
|
||||
<literal>haskell.packages.lts-x_y</literal> package sets still exist in
|
||||
name to aviod breaking user code, but these package sets don't actually
|
||||
contain the versions mandated by the corresponding LTS release. Instead,
|
||||
our package set it loosely based on the latest available LTS release, i.e.
|
||||
LTS 7.x at the time of this writing. New releases of NixOS and Nixpkgs will
|
||||
drop those old names entirely. <link
|
||||
xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2016-June/020585.html">The
|
||||
motivation for this change</link> has been discussed at length on the
|
||||
<literal>nix-dev</literal> mailing list and in <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/issues/14897">Github issue
|
||||
#14897</link>. Development strategies for Haskell hackers who want to rely
|
||||
on Nix and NixOS have been described in <link
|
||||
xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2016-June/020642.html">another
|
||||
nix-dev article</link>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Shell aliases for systemd sub-commands
|
||||
<link xlink:href="https://github.com/NixOS/nixpkgs/pull/15598">were dropped</link>:
|
||||
<command>start</command>, <command>stop</command>,
|
||||
<command>restart</command>, <command>status</command>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Redis now binds to 127.0.0.1 only instead of listening to all network interfaces. This is the default
|
||||
behavior of Redis 3.2</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>/var/empty</literal> is now immutable. Activation script runs <command>chattr +i</command>
|
||||
to forbid any modifications inside the folder. See <link xlink:href="https://github.com/NixOS/nixpkgs/pull/18365">
|
||||
the pull request</link> for what bugs this caused.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Using packages compiled with older Wayland may yield an error "undefined reference to `wl_proxy_*`".
|
||||
Please upgrade those packages and <link xlink:href="https://github.com/NixOS/nixpkgs/issues/16779">see bug report for more details.</link>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Gitlab's maintainance script
|
||||
<command>gitlab-runner</command> was removed and split up into the
|
||||
more clearer <command>gitlab-run</command> and
|
||||
<command>gitlab-rake</command> scripts, because
|
||||
<command>gitlab-runner</command> is a component of Gitlab
|
||||
CI.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>services.xserver.libinput.accelProfile</literal> default
|
||||
changed from <literal>flat</literal> to <literal>adaptive</literal>,
|
||||
as per <link xlink:href="https://wayland.freedesktop.org/libinput/doc/latest/group__config.html#gad63796972347f318b180e322e35cee79">
|
||||
official documentation</link>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>fonts.fontconfig.ultimate.rendering</literal> was removed
|
||||
because our presets were obsolete for some time. New presets are hardcoded
|
||||
into FreeType; you can select a preset via <literal>fonts.fontconfig.ultimate.preset</literal>.
|
||||
You can customize those presets via ordinary environment variables, using
|
||||
<literal>environment.variables</literal>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The <literal>audit</literal> service is no longer enabled by default.
|
||||
Use <literal>security.audit.enable = true</literal> to explicitly enable it.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>pkgs.linuxPackages.virtualbox</literal> now contains only the
|
||||
kernel modules instead of the VirtualBox user space binaries.
|
||||
If you want to reference the user space binaries, you have to use the new
|
||||
<literal>pkgs.virtualbox</literal> instead.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>goPackages</literal> was replaced with separated Go
|
||||
applications in appropriate <literal>nixpkgs</literal>
|
||||
categories. Each Go package uses its own dependency set. There's
|
||||
also a new <literal>go2nix</literal> tool introduced to generate a
|
||||
Go package definition from its Go source automatically.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>services.mongodb.extraConfig</literal> configuration format
|
||||
was changed to YAML.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
PHP has been upgraded to 7.0
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
<para>Other notable improvements:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>Revamped grsecurity/PaX support. There is now only a single
|
||||
general-purpose distribution kernel and the configuration interface has been
|
||||
streamlined. Desktop users should be able to simply set
|
||||
<programlisting>security.grsecurity.enable = true</programlisting> to get
|
||||
a reasonably secure system without having to sacrifice too much
|
||||
functionality. See <xref linkend="sec-grsecurity" /> for documentation
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>Special filesystems, like <literal>/proc</literal>,
|
||||
<literal>/run</literal> and others, now have the same mount options
|
||||
as recommended by systemd and are unified across different places in
|
||||
NixOS. Mount options are updated during <command>nixos-rebuild
|
||||
switch</command> if possible. One benefit from this is improved
|
||||
security — most such filesystems are now mounted with
|
||||
<literal>noexec</literal>, <literal>nodev</literal> and/or
|
||||
<literal>nosuid</literal> options.</para></listitem>
|
||||
|
||||
<listitem><para>The reverse path filter was interfering with DHCPv4 server
|
||||
operation in the past. An exception for DHCPv4 and a new option to log
|
||||
packets that were dropped due to the reverse path filter was added
|
||||
(<literal>networking.firewall.logReversePathDrops</literal>) for easier
|
||||
debugging.</para></listitem>
|
||||
|
||||
<listitem><para>Containers configuration within
|
||||
<literal>containers.<name>.config</literal> is <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pull/17365">now
|
||||
properly typed and checked</link>. In particular, partial
|
||||
configurations are merged correctly.</para></listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The directory container setuid wrapper programs,
|
||||
<filename>/var/setuid-wrappers</filename>, <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pull/18124">is now
|
||||
updated atomically to prevent failures if the switch to a new
|
||||
configuration is interrupted.</link></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>services.xserver.startGnuPGAgent</literal>
|
||||
has been removed due to GnuPG 2.1.x bump. See <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/commit/5391882ebd781149e213e8817fba6ac3c503740c">
|
||||
how to achieve similar behavior</link>. You might need to
|
||||
<literal>pkill gpg-agent</literal> after the upgrade
|
||||
to prevent a stale agent being in the way.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem><para>
|
||||
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/e561edc322d275c3687fec431935095cfc717147">
|
||||
Declarative users could share the uid due to the bug in
|
||||
the script handling conflict resolution.
|
||||
</link>
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Gummi boot has been replaced using systemd-boot.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Hydra package and NixOS module were added for convenience.
|
||||
</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
</section>
|
||||
@@ -12,9 +12,6 @@
|
||||
# directly.
|
||||
partitioned ? true
|
||||
|
||||
# Whether to invoke switch-to-configuration boot during image creation
|
||||
, installBootLoader ? true
|
||||
|
||||
, # The root file system type.
|
||||
fsType ? "ext4"
|
||||
|
||||
@@ -67,24 +64,40 @@ pkgs.vmTools.runInLinuxVM (
|
||||
mkdir /mnt
|
||||
mount $rootDisk /mnt
|
||||
|
||||
# The initrd expects these directories to exist.
|
||||
mkdir /mnt/dev /mnt/proc /mnt/sys
|
||||
|
||||
mount -o bind /proc /mnt/proc
|
||||
mount -o bind /dev /mnt/dev
|
||||
mount -o bind /sys /mnt/sys
|
||||
|
||||
# Copy all paths in the closure to the filesystem.
|
||||
storePaths=$(perl ${pkgs.pathsFromGraph} /tmp/xchg/closure)
|
||||
|
||||
mkdir -p /mnt/nix/store
|
||||
echo "copying everything (will take a while)..."
|
||||
set -f
|
||||
cp -prd $storePaths /mnt/nix/store/
|
||||
|
||||
# Register the paths in the Nix database.
|
||||
printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
|
||||
${config.nix.package.out}/bin/nix-store --load-db --option build-users-group ""
|
||||
chroot /mnt ${config.nix.package}/bin/nix-store --load-db --option build-users-group ""
|
||||
|
||||
# Add missing size/hash fields to the database. FIXME:
|
||||
# exportReferencesGraph should provide these directly.
|
||||
${config.nix.package.out}/bin/nix-store --verify --check-contents --option build-users-group ""
|
||||
chroot /mnt ${config.nix.package}/bin/nix-store --verify --check-contents
|
||||
|
||||
# In case the bootloader tries to write to /dev/sda…
|
||||
ln -s vda /dev/xvda
|
||||
ln -s vda /dev/sda
|
||||
# Create the system profile to allow nixos-rebuild to work.
|
||||
chroot /mnt ${config.nix.package}/bin/nix-env --option build-users-group "" \
|
||||
-p /nix/var/nix/profiles/system --set ${config.system.build.toplevel}
|
||||
|
||||
# Install the closure onto the image
|
||||
USER=root ${config.system.build.nixos-install}/bin/nixos-install \
|
||||
--closure ${config.system.build.toplevel} \
|
||||
--no-channel-copy \
|
||||
--no-root-passwd \
|
||||
${optionalString (!installBootLoader) "--no-bootloader"}
|
||||
# `nixos-rebuild' requires an /etc/NIXOS.
|
||||
mkdir -p /mnt/etc
|
||||
touch /mnt/etc/NIXOS
|
||||
|
||||
# `switch-to-configuration' requires a /bin/sh
|
||||
mkdir -p /mnt/bin
|
||||
ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
|
||||
|
||||
# Install a configuration.nix.
|
||||
mkdir -p /mnt/etc/nixos
|
||||
@@ -92,9 +105,12 @@ pkgs.vmTools.runInLinuxVM (
|
||||
cp ${configFile} /mnt/etc/nixos/configuration.nix
|
||||
''}
|
||||
|
||||
# Remove /etc/machine-id so that each machine cloning this image will get its own id
|
||||
rm -f /mnt/etc/machine-id
|
||||
# Generate the GRUB menu.
|
||||
ln -s vda /dev/xvda
|
||||
ln -s vda /dev/sda
|
||||
chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
|
||||
|
||||
umount /mnt/proc /mnt/dev /mnt/sys
|
||||
umount /mnt
|
||||
|
||||
# Do a fsck to make sure resize2fs works.
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
, # Whether this should be an efi-bootable El-Torito CD.
|
||||
efiBootable ? false
|
||||
|
||||
, # Whether this should be an hybrid CD (bootable from USB as well as CD).
|
||||
, # Wheter this should be an hybrid CD (bootable from USB as well as CD).
|
||||
usbBootable ? false
|
||||
|
||||
, # The path (in the ISO file system) of the boot image.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user