Merge branch 'staging' into mesa_3

This commit is contained in:
Matthew Bauer 2019-05-02 17:37:20 -04:00 committed by GitHub
commit 296e8fef61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11257 changed files with 487607 additions and 251764 deletions

View File

@ -1,8 +0,0 @@
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((nil
(bug-reference-bug-regexp . "\\(\\(?:[Ii]ssue \\|[Ff]ixe[ds] \\|[Rr]esolve[ds]? \\|[Cc]lose[ds]? \\|[Pp]\\(?:ull [Rr]equest\\|[Rr]\\) \\|(\\)#\\([0-9]+\\))?\\)")
(bug-reference-url-format . "https://github.com/NixOS/nixpkgs/issues/%s"))
(nix-mode
(tab-width . 2)))

66
.github/CODEOWNERS vendored
View File

@ -12,7 +12,7 @@
# Libraries
/lib @edolstra @nbp
/lib/systems @nbp @ericson2314
/lib/systems @nbp @ericson2314 @matthewbauer
/lib/generators.nix @edolstra @nbp @Profpatsch
/lib/debug.nix @edolstra @nbp @Profpatsch
@ -20,9 +20,11 @@
/default.nix @nbp
/pkgs/top-level/default.nix @nbp @Ericson2314
/pkgs/top-level/impure.nix @nbp @Ericson2314
/pkgs/top-level/stage.nix @nbp @Ericson2314
/pkgs/stdenv/generic @Ericson2314
/pkgs/stdenv/cross @Ericson2314
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
/pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
/pkgs/stdenv/generic @Ericson2314 @matthewbauer
/pkgs/stdenv/cross @Ericson2314 @matthewbauer
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
/pkgs/build-support/setup-hooks @Ericson2314
@ -45,27 +47,35 @@
/nixos/doc/manual/man-nixos-option.xml @nbp
/nixos/modules/installer/tools/nixos-option.sh @nbp
# NixOS modules
/nixos/modules @Infinisil
# Python-related code and docs
/maintainers/scripts/update-python-libraries @FRidh
/pkgs/top-level/python-packages.nix @FRidh
/pkgs/development/interpreters/python @FRidh
/pkgs/development/python-modules @FRidh
/doc/languages-frameworks/python.md @FRidh
/doc/languages-frameworks/python.section.md @FRidh
# Haskell
/pkgs/development/compilers/ghc @peti @ryantm @basvandijk
/pkgs/development/haskell-modules @peti @ryantm @basvandijk
/pkgs/development/haskell-modules/default.nix @peti @ryantm @basvandijk
/pkgs/development/haskell-modules/generic-builder.nix @peti @ryantm @basvandijk
/pkgs/development/haskell-modules/hoogle.nix @peti @ryantm @basvandijk
/pkgs/development/compilers/ghc @basvandijk
/pkgs/development/haskell-modules @basvandijk
/pkgs/development/haskell-modules/default.nix @basvandijk
/pkgs/development/haskell-modules/generic-builder.nix @basvandijk
/pkgs/development/haskell-modules/hoogle.nix @basvandijk
# Perl
/pkgs/development/interpreters/perl @volth
/pkgs/top-level/perl-packages.nix @volth
/pkgs/development/perl-modules @volth
# R
/pkgs/applications/science/math/R @peti
/pkgs/development/r-modules @peti
# Ruby
/pkgs/development/interpreters/ruby @zimbatm
/pkgs/development/ruby-modules @zimbatm
/pkgs/development/interpreters/ruby @alyssais @zimbatm
/pkgs/development/ruby-modules @alyssais @zimbatm
# Rust
/pkgs/development/compilers/rust @Mic92 @LnL7
@ -74,6 +84,14 @@
/pkgs/stdenv/darwin @NixOS/darwin-maintainers
/pkgs/os-specific/darwin @NixOS/darwin-maintainers
# C compilers
/pkgs/development/compilers/gcc @matthewbauer
/pkgs/development/compilers/llvm @matthewbauer
# Compatibility stuff
/pkgs/top-level/unix-tools.nix @matthewbauer
/pkgs/development/tools/xcbuild @matthewbauer
# Beam-related (Erlang, Elixir, LFE, etc)
/pkgs/development/beam-modules @gleber
/pkgs/development/interpreters/erlang @gleber
@ -97,3 +115,27 @@
/pkgs/desktops/plasma-5 @ttuegel
/pkgs/development/libraries/kde-frameworks @ttuegel
/pkgs/development/libraries/qt-5 @ttuegel
# PostgreSQL and related stuff
/pkgs/servers/sql/postgresql @thoughtpolice
/nixos/modules/services/databases/postgresql.xml @thoughtpolice
/nixos/modules/services/databases/postgresql.nix @thoughtpolice
/nixos/tests/postgresql.nix @thoughtpolice
# Hardened profile & related modules
/nixos/modules/profiles/hardened.nix @joachifm
/nixos/modules/security/hidepid.nix @joachifm
/nixos/modules/security/lock-kernel-modules.nix @joachifm
/nixos/modules/security/misc.nix @joachifm
/nixos/tests/hardened.nix @joachifm
/pkgs/os-specific/linux/kernel/hardened-config.nix @joachifm
# Dhall
/pkgs/development/dhall-modules @Gabriel439 @Profpatsch
/pkgs/development/interpreters/dhall @Gabriel439 @Profpatsch
# Idris
/pkgs/development/idris-modules @Infinisil
# Bazel
/pkgs/development/tools/build-managers/bazel @mboes @Profpatsch

View File

@ -20,6 +20,8 @@ under the terms of [COPYING](../COPYING), which is an MIT-like license.
(Motivation for change. Additional information.)
```
For consistency, there should not be a period at the end of the commit message's summary line (the first line of the commit message).
Examples:
* nginx: init at 2.0.1
@ -43,7 +45,7 @@ See the nixpkgs manual for more details on [standard meta-attributes](https://ni
## Writing good commit messages
In addition to writing properly formatted commit messages, it's important to include relevant information so other developers can later understand *why* a change was made. While this information usually can be found by digging code, mailing list archives, pull request discussions or upstream changes, it may require a lot of work.
In addition to writing properly formatted commit messages, it's important to include relevant information so other developers can later understand *why* a change was made. While this information usually can be found by digging code, mailing list/Discourse archives, pull request discussions or upstream changes, it may require a lot of work.
For package version upgrades and such a one-line commit message is usually sufficient.

View File

@ -1,3 +1,4 @@
<!-- Nixpkgs has a lot of new incoming Pull Requests, but not enough people to review this constant stream. Even if you aren't a committer, we would appreciate reviews of other PRs, especially simple ones like package updates. Just testing the relevant package/service and leaving a comment saying what you tested, how you tested it and whether it worked would be great. List of open PRs: <https://github.com/NixOS/nixpkgs/pulls>, for more about reviewing contributions: <https://hydra.nixos.org/job/nixpkgs/trunk/manual/latest/download/1/nixpkgs/manual.html#sec-reviewing-contributions>. Reviewing isn't mandatory, but it would help out a lot and reduce the average time-to-merge for all of us. Thanks a lot if you do! -->
###### Motivation for this change
@ -11,10 +12,10 @@
- [ ] macOS
- [ ] other Linux distributions
- [ ] Tested via one or more NixOS test(s) if existing and applicable for the change (look inside [nixos/tests](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests))
- [ ] Tested compilation of all pkgs that depend on this change using `nix-shell -p nox --run "nox-review wip"`
- [ ] Tested compilation of all pkgs that depend on this change using `nix-shell -p nix-review --run "nix-review wip"`
- [ ] Tested execution of all binary files (usually in `./result/bin/`)
- [ ] Determined the impact on package closure size (by running `nix path-info -S` before and after)
- [ ] Assured whether relevant documentation is up to date
- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md).
---

3
.gitignore vendored
View File

@ -13,4 +13,5 @@ result-*
.DS_Store
/pkgs/development/libraries/qt-5/*/tmp/
/pkgs/desktops/kde-5/*/tmp/
/pkgs/desktops/kde-5/*/tmp/
/pkgs/development/mobile/androidenv/xml/*

View File

@ -1 +1 @@
18.09
19.09

11
COPYING
View File

@ -1,4 +1,4 @@
Copyright (c) 2003-2018 Eelco Dolstra and the Nixpkgs/NixOS contributors
Copyright (c) 2003-2019 Eelco Dolstra and the Nixpkgs/NixOS contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@ -18,12 +18,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
======================================================================
Note: the license above does not apply to the packages built by the
Nix Packages collection, merely to the package descriptions (i.e., Nix
expressions, build scripts, etc.). It also might not apply to patches
included in Nixpkgs, which may be derivative works of the packages to
which they apply. The aforementioned artifacts are all covered by the
licenses of the respective packages.

View File

@ -12,15 +12,15 @@ 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-18.03` for the latest
custom changes on top of one of the channels, e.g. `nixos-19.03` for the latest
release and `nixos-unstable` for the latest successful build of master:
```
% git remote update channels
% git rebase channels/nixos-18.03
% git rebase channels/nixos-19.03
```
For pull-requests, please rebase onto nixpkgs `master`.
For pull requests, please rebase onto nixpkgs `master`.
[NixOS](https://nixos.org/nixos/) Linux distribution source code is located inside
`nixos/` folder.
@ -31,12 +31,17 @@ For pull-requests, please rebase onto nixpkgs `master`.
* [Manual (NixOS)](https://nixos.org/nixos/manual/)
* [Community maintained wiki](https://nixos.wiki/)
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
* [Continuous package builds for 18.03 release](https://hydra.nixos.org/jobset/nixos/release-18.03)
* [Continuous package builds for 19.03 release](https://hydra.nixos.org/jobset/nixos/release-19.03)
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
* [Tests for 18.03 release](https://hydra.nixos.org/job/nixos/release-18.03/tested#tabs-constituents)
* [Tests for 19.03 release](https://hydra.nixos.org/job/nixos/release-19.03/tested#tabs-constituents)
Communication:
* [Discourse Forum](https://discourse.nixos.org/)
* [Mailing list](https://groups.google.com/forum/#!forum/nix-devel)
* [IRC - #nixos on freenode.net](irc://irc.freenode.net/#nixos)
Note: MIT license does not apply to the packages built by Nixpkgs, merely to
the package descriptions (Nix expressions, build scripts, and so on). It also
might not apply to patches included in Nixpkgs, which may be derivative works
of the packages to which they apply. The aforementioned artifacts are all
covered by the licenses of the respective packages.

View File

@ -15,6 +15,12 @@ if ! builtins ? nixVersion || builtins.compareVersions requiredVersion builtins.
it is safe to upgrade by running it again:
curl https://nixos.org/nix/install | sh
For more information, please see the NixOS release notes at
https://nixos.org/nixos/manual or locally at
${toString ./nixos/doc/manual/release-notes}.
If you need further help, see https://nixos.org/nixos/support.html
''
else

6
doc/.gitignore vendored
View File

@ -1,6 +1,8 @@
*.chapter.xml
*.section.xml
.version
out
manual-full.xml
functions/library/generated
functions/library/locations.xml
highlightjs
manual-full.xml
out

View File

@ -9,8 +9,10 @@ debug:
.PHONY: format
format:
find . -iname '*.xml' -type f -print0 | xargs -0 -I{} -n1 \
xmlformat --config-file "$$XMLFORMAT_CONFIG" -i {}
find . -iname '*.xml' -type f | while read f; do \
echo $$f ;\
xmlformat --config-file "$$XMLFORMAT_CONFIG" -i $$f ;\
done
.PHONY: fix-misc-xml
fix-misc-xml:
@ -19,7 +21,7 @@ fix-misc-xml:
.PHONY: clean
clean:
rm -f ${MD_TARGETS} .version manual-full.xml
rm -f ${MD_TARGETS} .version manual-full.xml functions/library/locations.xml functions/library/generated
rm -rf ./out/ ./highlightjs
.PHONY: validate
@ -69,13 +71,22 @@ highlightjs:
cp -r "$$HIGHLIGHTJS/loader.js" highlightjs/
manual-full.xml: ${MD_TARGETS} .version *.xml
manual-full.xml: ${MD_TARGETS} .version functions/library/locations.xml functions/library/generated *.xml **/*.xml **/**/*.xml
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
.version:
nix-instantiate --eval \
-E '(import ../lib).version' > .version
functions/library/locations.xml:
nix-build ./lib-function-locations.nix \
--out-link $@
functions/library/generated: functions/library/locations.xml
nix-build ./lib-function-docs.nix \
--arg locationsXml $< \
--out-link $@
%.section.xml: %.section.md
pandoc $^ -w docbook+smart \
-f markdown+smart \

View File

@ -56,25 +56,30 @@ foo { arg = ...; }
or list elements should be aligned:
<programlisting>
# A long list.
list =
[ elem1
elem2
elem3
];
list = [
elem1
elem2
elem3
];
# A long attribute set.
attrs =
{ attr1 = short_expr;
attr2 =
if true then big_expr else big_expr;
};
# Alternatively:
attrs = {
attr1 = short_expr;
attr2 =
if true then big_expr else big_expr;
};
# Combined
listOfAttrs = [
{
attr1 = 3;
attr2 = "fff";
}
{
attr1 = 5;
attr2 = "ggg";
}
];
</programlisting>
</para>
</listitem>
@ -191,6 +196,17 @@ args.stdenv.mkDerivation (args // {
<section xml:id="sec-package-naming">
<title>Package naming</title>
<para>
The key words <emphasis>must</emphasis>, <emphasis>must not</emphasis>,
<emphasis>required</emphasis>, <emphasis>shall</emphasis>, <emphasis>shall
not</emphasis>, <emphasis>should</emphasis>, <emphasis>should
not</emphasis>, <emphasis>recommended</emphasis>, <emphasis>may</emphasis>,
and <emphasis>optional</emphasis> in this section are to be interpreted as
described in <link xlink:href="https://tools.ietf.org/html/rfc2119">RFC
2119</link>. Only <emphasis>emphasized</emphasis> words are to be
interpreted in this way.
</para>
<para>
In Nixpkgs, there are generally three different names associated with a
package:
@ -231,14 +247,15 @@ args.stdenv.mkDerivation (args // {
<itemizedlist>
<listitem>
<para>
Generally, try to stick to the upstream package name.
The <literal>name</literal> attribute <emphasis>should</emphasis> be
identical to the upstream package name.
</para>
</listitem>
<listitem>
<para>
Dont use uppercase letters in the <literal>name</literal> attribute
— e.g., <literal>"mplayer-1.0rc2"</literal> instead of
<literal>"MPlayer-1.0rc2"</literal>.
The <literal>name</literal> attribute <emphasis>must not</emphasis>
contain uppercase letters — e.g., <literal>"mplayer-1.0rc2"</literal>
instead of <literal>"MPlayer-1.0rc2"</literal>.
</para>
</listitem>
<listitem>
@ -252,28 +269,29 @@ args.stdenv.mkDerivation (args // {
<para>
If a package is not a release but a commit from a repository, 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.,
(fetched) commit. The date <emphasis>must</emphasis> 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>
<listitem>
<para>
Dashes in the package name should be preserved in new variable names,
rather than converted to underscores or camel cased — e.g.,
<varname>http-parser</varname> instead of <varname>http_parser</varname>
or <varname>httpParser</varname>. The hyphenated style is preferred in
all three package names.
Dashes in the package name <emphasis>should</emphasis> be preserved in
new variable names, rather than converted to underscores or camel cased
— e.g., <varname>http-parser</varname> instead of
<varname>http_parser</varname> or <varname>httpParser</varname>. The
hyphenated style is preferred in all three package names.
</para>
</listitem>
<listitem>
<para>
If there are multiple versions of a package, this should be reflected in
the variable names in <filename>all-packages.nix</filename>, e.g.
<varname>json-c-0-9</varname> and <varname>json-c-0-11</varname>. If
there is an obvious “default” version, make an attribute like
<literal>json-c = json-c-0-9;</literal>. See also
<xref linkend="sec-versioning" />
If there are multiple versions of a package, this
<emphasis>should</emphasis> be reflected in the variable names in
<filename>all-packages.nix</filename>, e.g. <varname>json-c-0-9</varname>
and <varname>json-c-0-11</varname>. If there is an obvious “default”
version, make an attribute like <literal>json-c = json-c-0-9;</literal>.
See also <xref linkend="sec-versioning" />
</para>
</listitem>
</itemizedlist>
@ -791,8 +809,8 @@ args.stdenv.mkDerivation (args // {
<para>
There are multiple ways to fetch a package source in nixpkgs. The general
guideline is that you should package sources with a high degree of
availability. Right now there is only one fetcher which has mirroring
guideline is that you should package reproducible sources with a high degree
of availability. Right now there is only one fetcher which has mirroring
support and that is <literal>fetchurl</literal>. Note that you should also
prefer protocols which have a corresponding proxy environment variable.
</para>
@ -842,14 +860,143 @@ src = fetchFromGitHub {
owner = "NixOS";
repo = "nix";
rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
sha256 = "04yri911rj9j19qqqn6m82266fl05pz98inasni0vxr1cf1gdgv9";
sha256 = "1i2yxndxb6yc9l6c99pypbd92lfq5aac4klq7y2v93c9qvx2cgpc";
}
</programlisting>
Find the value to put as <literal>sha256</literal> by running
<literal>nix run -f '&lt;nixpkgs&gt;' nix-prefetch-github -c
nix-prefetch-github --rev 1f795f9f44607cc5bec70d1300150bfefcef2aae NixOS
nix</literal> or <literal>nix-prefetch-url --unpack
https://github.com/NixOS/nix/archive/1f795f9f44607cc5bec70d1300150bfefcef2aae.tar.gz</literal>.
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section xml:id="sec-source-hashes">
<title>Obtaining source hash</title>
<para>
Preferred source hash type is sha256. There are several ways to get it.
</para>
<orderedlist>
<listitem>
<para>
Prefetch URL (with <literal>nix-prefetch-<replaceable>XXX</replaceable>
<replaceable>URL</replaceable></literal>, where
<replaceable>XXX</replaceable> is one of <literal>url</literal>,
<literal>git</literal>, <literal>hg</literal>, <literal>cvs</literal>,
<literal>bzr</literal>, <literal>svn</literal>). Hash is printed to
stdout.
</para>
</listitem>
<listitem>
<para>
Prefetch by package source (with <literal>nix-prefetch-url
'&lt;nixpkgs&gt;' -A <replaceable>PACKAGE</replaceable>.src</literal>,
where <replaceable>PACKAGE</replaceable> is package attribute name). Hash
is printed to stdout.
</para>
<para>
This works well when you've upgraded existing package version and want to
find out new hash, but is useless if package can't be accessed by
attribute or package has multiple sources (<literal>.srcs</literal>,
architecture-dependent sources, etc).
</para>
</listitem>
<listitem>
<para>
Upstream provided hash: use it when upstream provides
<literal>sha256</literal> or <literal>sha512</literal> (when upstream
provides <literal>md5</literal>, don't use it, compute
<literal>sha256</literal> instead).
</para>
<para>
A little nuance is that <literal>nix-prefetch-*</literal> tools produce
hash encoded with <literal>base32</literal>, but upstream usually provides
hexadecimal (<literal>base16</literal>) encoding. Fetchers understand both
formats. Nixpkgs does not standardize on any one format.
</para>
<para>
You can convert between formats with nix-hash, for example:
<screen>
$ nix-hash --type sha256 --to-base32 <replaceable>HASH</replaceable>
</screen>
</para>
</listitem>
<listitem>
<para>
Extracting hash from local source tarball can be done with
<literal>sha256sum</literal>. Use <literal>nix-prefetch-url
file:///path/to/tarball </literal> if you want base32 hash.
</para>
</listitem>
<listitem>
<para>
Fake hash: set fake hash in package expression, perform build and extract
correct hash from error Nix prints.
</para>
<para>
For package updates it is enough to change one symbol to make hash fake.
For new packages, you can use <literal>lib.fakeSha256</literal>,
<literal>lib.fakeSha512</literal> or any other fake hash.
</para>
<para>
This is last resort method when reconstructing source URL is non-trivial
and <literal>nix-prefetch-url -A</literal> isn't applicable (for example,
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/d2ab091dd308b99e4912b805a5eb088dd536adb9/pkgs/applications/video/kodi/default.nix#L73">
one of <literal>kodi</literal> dependencies</link>). The easiest way then
would be replace hash with a fake one and rebuild. Nix build will fail and
error message will contain desired hash.
</para>
<warning>
<para>
This method has security problems. Check below for details.
</para>
</warning>
</listitem>
</orderedlist>
<section xml:id="sec-source-hashes-security">
<title>Obtaining hashes securely</title>
<para>
Let's say Man-in-the-Middle (MITM) sits close to your network. Then instead
of fetching source you can fetch malware, and instead of source hash you
get hash of malware. Here are security considerations for this scenario:
</para>
<itemizedlist>
<listitem>
<para>
<literal>http://</literal> URLs are not secure to prefetch hash from;
</para>
</listitem>
<listitem>
<para>
hashes from upstream (in method 3) should be obtained via secure
protocol;
</para>
</listitem>
<listitem>
<para>
<literal>https://</literal> URLs are secure in methods 1, 2, 3;
</para>
</listitem>
<listitem>
<para>
<literal>https://</literal> URLs are not secure in method 5. When
obtaining hashes with fake hash method, TLS checks are disabled. So
refetch source hash from several different networks to exclude MITM
scenario. Alternatively, use fake hash method to make Nix error, but
instead of extracting hash from error, extract
<literal>https://</literal> URL and prefetch it with method 1.
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section xml:id="sec-patches">
<title>Patches</title>

View File

@ -132,13 +132,13 @@
</itemizedlist>
<para>
The difference between an a package being unsupported on some system and
being broken is admittedly a bit fuzzy. If a program
<emphasis>ought</emphasis> to work on a certain platform, but doesn't, the
platform should be included in <literal>meta.platforms</literal>, but marked
as broken with e.g. <literal>meta.broken =
!hostPlatform.isWindows</literal>. Of course, this begs the question of what
"ought" means exactly. That is left to the package maintainer.
The difference between a package being unsupported on some system and being
broken is admittedly a bit fuzzy. If a program <emphasis>ought</emphasis> to
work on a certain platform, but doesn't, the platform should be included in
<literal>meta.platforms</literal>, but marked as broken with e.g.
<literal>meta.broken = !hostPlatform.isWindows</literal>. Of course, this
begs the question of what "ought" means exactly. That is left to the package
maintainer.
</para>
</section>
<section xml:id="sec-allow-unfree">
@ -175,11 +175,15 @@
</programlisting>
</para>
<para>
A more useful example, the following configuration allows only allows
flash player and visual studio code:
For a more useful example, try the following. This configuration only
allows unfree packages named flash player and visual studio code:
<programlisting>
{
allowUnfreePredicate = (pkg: elem (builtins.parseDrvName pkg.name).name [ "flashplayer" "vscode" ]);
allowUnfreePredicate = (pkg: builtins.elem
(builtins.parseDrvName pkg.name).name [
"flashplayer"
"vscode"
]);
}
</programlisting>
</para>
@ -286,8 +290,8 @@
<para>
You can define a function called <varname>packageOverrides</varname> in your
local <filename>~/.config/nixpkgs/config.nix</filename> to override nix
packages. It must be a function that takes pkgs as an argument and return
local <filename>~/.config/nixpkgs/config.nix</filename> to override Nix
packages. It must be a function that takes pkgs as an argument and returns a
modified set of packages.
<programlisting>
{
@ -321,11 +325,22 @@
packageOverrides = pkgs: with pkgs; {
myPackages = pkgs.buildEnv {
name = "my-packages";
paths = [ aspell bc coreutils gdb ffmpeg nixUnstable emscripten jq nox silver-searcher ];
paths = [
aspell
bc
coreutils
gdb
ffmpeg
nixUnstable
emscripten
jq
nox
silver-searcher
];
};
};
}
</screen>
</screen>
<para>
To install it into our environment, you can just run <literal>nix-env -iA
@ -342,12 +357,23 @@
packageOverrides = pkgs: with pkgs; {
myPackages = pkgs.buildEnv {
name = "my-packages";
paths = [ aspell bc coreutils gdb ffmpeg nixUnstable emscripten jq nox silver-searcher ];
paths = [
aspell
bc
coreutils
gdb
ffmpeg
nixUnstable
emscripten
jq
nox
silver-searcher
];
pathsToLink = [ "/share" "/bin" ];
};
};
}
</screen>
</screen>
<para>
<literal>pathsToLink</literal> tells Nixpkgs to only link the paths listed
@ -377,13 +403,23 @@
packageOverrides = pkgs: with pkgs; {
myPackages = pkgs.buildEnv {
name = "my-packages";
paths = [ aspell bc coreutils ffmpeg nixUnstable emscripten jq nox silver-searcher ];
paths = [
aspell
bc
coreutils
ffmpeg
nixUnstable
emscripten
jq
nox
silver-searcher
];
pathsToLink = [ "/share/man" "/share/doc" "/bin" ];
extraOutputsToInstall = [ "man" "doc" ];
};
};
}
</screen>
</screen>
<para>
This provides us with some useful documentation for using our packages.
@ -395,15 +431,15 @@
{
packageOverrides = pkgs: with pkgs; rec {
myProfile = writeText "my-profile" ''
export PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/sbin:/bin:/usr/sbin:/usr/bin
export MANPATH=$HOME/.nix-profile/share/man:/nix/var/nix/profiles/default/share/man:/usr/share/man
export PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/sbin:/bin:/usr/sbin:/usr/bin
export MANPATH=$HOME/.nix-profile/share/man:/nix/var/nix/profiles/default/share/man:/usr/share/man
'';
myPackages = pkgs.buildEnv {
name = "my-packages";
paths = [
(runCommand "profile" {} ''
mkdir -p $out/etc/profile.d
cp ${myProfile} $out/etc/profile.d/my-profile.sh
mkdir -p $out/etc/profile.d
cp ${myProfile} $out/etc/profile.d/my-profile.sh
'')
aspell
bc
@ -421,7 +457,7 @@ cp ${myProfile} $out/etc/profile.d/my-profile.sh
};
};
}
</screen>
</screen>
<para>
For this to work fully, you must also have this script sourced when you are
@ -438,7 +474,7 @@ if [ -d $HOME/.nix-profile/etc/profile.d ]; then
fi
done
fi
</screen>
</screen>
<para>
Now just run <literal>source $HOME/.profile</literal> and you can starting
@ -459,16 +495,16 @@ fi
{
packageOverrides = pkgs: with pkgs; rec {
myProfile = writeText "my-profile" ''
export PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/sbin:/bin:/usr/sbin:/usr/bin
export MANPATH=$HOME/.nix-profile/share/man:/nix/var/nix/profiles/default/share/man:/usr/share/man
export INFOPATH=$HOME/.nix-profile/share/info:/nix/var/nix/profiles/default/share/info:/usr/share/info
export PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/sbin:/bin:/usr/sbin:/usr/bin
export MANPATH=$HOME/.nix-profile/share/man:/nix/var/nix/profiles/default/share/man:/usr/share/man
export INFOPATH=$HOME/.nix-profile/share/info:/nix/var/nix/profiles/default/share/info:/usr/share/info
'';
myPackages = pkgs.buildEnv {
name = "my-packages";
paths = [
(runCommand "profile" {} ''
mkdir -p $out/etc/profile.d
cp ${myProfile} $out/etc/profile.d/my-profile.sh
mkdir -p $out/etc/profile.d
cp ${myProfile} $out/etc/profile.d/my-profile.sh
'')
aspell
bc
@ -485,17 +521,17 @@ cp ${myProfile} $out/etc/profile.d/my-profile.sh
pathsToLink = [ "/share/man" "/share/doc" "/share/info" "/bin" "/etc" ];
extraOutputsToInstall = [ "man" "doc" "info" ];
postBuild = ''
if [ -x $out/bin/install-info -a -w $out/share/info ]; then
shopt -s nullglob
for i in $out/share/info/*.info $out/share/info/*.info.gz; do
$out/bin/install-info $i $out/share/info/dir
done
fi
if [ -x $out/bin/install-info -a -w $out/share/info ]; then
shopt -s nullglob
for i in $out/share/info/*.info $out/share/info/*.info.gz; do
$out/bin/install-info $i $out/share/info/dir
done
fi
'';
};
};
}
</screen>
</screen>
<para>
<literal>postBuild</literal> tells Nixpkgs to run a command after building

View File

@ -7,15 +7,16 @@
<para>
"Cross-compilation" means compiling a program on one machine for another
type of machine. For example, a typical use of cross compilation is to
type of machine. For example, a typical use of cross-compilation is to
compile programs for embedded devices. These devices often don't have the
computing power and memory to compile their own programs. One might think
that cross-compilation is a fairly niche concern, but there are advantages
to being rigorous about distinguishing build-time vs run-time environments
even when one is developing and deploying on the same machine. Nixpkgs is
increasingly adopting the opinion that packages should be written with
cross-compilation in mind, and nixpkgs should evaluate in a similar way (by
minimizing cross-compilation-specific special cases) whether or not one is
that cross-compilation is a fairly niche concern. However, there are
significant advantages to rigorously distinguishing between build-time and
run-time environments! Significant, because the benefits apply even when one
is developing and deploying on the same machine. Nixpkgs is increasingly
adopting the opinion that packages should be written with cross-compilation
in mind, and nixpkgs should evaluate in a similar way (by minimizing
cross-compilation-specific special cases) whether or not one is
cross-compiling.
</para>
@ -30,30 +31,28 @@
<section xml:id="sec-cross-packaging">
<title>Packaging in a cross-friendly manner</title>
<section>
<section xml:id="ssec-cross-platform-parameters">
<title>Platform parameters</title>
<para>
Nixpkgs follows the
<link xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html">common
historical convention of GNU autoconf</link> of distinguishing between 3
types of platform: <wordasword>build</wordasword>,
<link
xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html">conventions
of GNU autoconf</link>. We distinguish between 3 types of platforms when
building a derivation: <wordasword>build</wordasword>,
<wordasword>host</wordasword>, and <wordasword>target</wordasword>. In
summary, <wordasword>build</wordasword> is the platform on which a package
is being built, <wordasword>host</wordasword> is the platform on which it
is to run. The third attribute, <wordasword>target</wordasword>, is
relevant only for certain specific compilers and build tools.
will run. The third attribute, <wordasword>target</wordasword>, is relevant
only for certain specific compilers and build tools.
</para>
<para>
In Nixpkgs, these three platforms are defined as attribute sets under the
names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>,
and <literal>targetPlatform</literal>. All three are always defined as
attributes in the standard environment, and at the top level. That means
one can get at them just like a dependency in a function that is imported
with <literal>callPackage</literal>:
<programlisting>{ stdenv, buildPlatform, hostPlatform, fooDep, barDep, .. }: ...buildPlatform...</programlisting>
, or just off <varname>stdenv</varname>:
and <literal>targetPlatform</literal>. They are always defined as
attributes in the standard environment. That means one can access them
like:
<programlisting>{ stdenv, fooDep, barDep, .. }: ...stdenv.buildPlatform...</programlisting>
.
</para>
@ -67,7 +66,7 @@
<para>
The "build platform" is the platform on which a package is built. Once
someone has a built package, or pre-built binary package, the build
platform should not matter and be safe to ignore.
platform should not matter and can be ignored.
</para>
</listitem>
</varlistentry>
@ -97,11 +96,11 @@
<para>
The build process of certain compilers is written in such a way that the
compiler resulting from a single build can itself only produce binaries
for a single platform. The task specifying this single "target platform"
is thus pushed to build time of the compiler. The root cause of this
mistake is often that the compiler (which will be run on the host) and
the the standard library/runtime (which will be run on the target) are
built by a single build process.
for a single platform. The task of specifying this single "target
platform" is thus pushed to build time of the compiler. The root cause
of this is that the compiler (which will be run on the host) and the
standard library/runtime (which will be run on the target) are built by
a single build process.
</para>
<para>
There is no fundamental need to think about a single target ahead of
@ -138,8 +137,10 @@
<para>
This is a two-component shorthand for the platform. Examples of this
would be "x86_64-darwin" and "i686-linux"; see
<literal>lib.systems.doubles</literal> for more. This format isn't very
standard, but has built-in support in Nix, such as the
<literal>lib.systems.doubles</literal> for more. The first component
corresponds to the CPU architecture of the platform and the second to
the operating system of the platform (<literal>[cpu]-[os]</literal>).
This format has built-in support in Nix, such as the
<varname>builtins.currentSystem</varname> impure string.
</para>
</listitem>
@ -151,12 +152,13 @@
<listitem>
<para>
This is a 3- or 4- component shorthand for the platform. Examples of
this would be "x86_64-unknown-linux-gnu" and "aarch64-apple-darwin14".
This is a standard format called the "LLVM target triple", as they are
pioneered by LLVM and traditionally just used for the
<varname>targetPlatform</varname>. This format is strictly more
informative than the "Nix host double", as the previous format could
analogously be termed. This needs a better name than
this would be <literal>x86_64-unknown-linux-gnu</literal> and
<literal>aarch64-apple-darwin14</literal>. This is a standard format
called the "LLVM target triple", as they are pioneered by LLVM. In the
4-part form, this corresponds to
<literal>[cpu]-[vendor]-[os]-[abi]</literal>. This format is strictly
more informative than the "Nix host double", as the previous format
could analogously be termed. This needs a better name than
<varname>config</varname>!
</para>
</listitem>
@ -167,11 +169,9 @@
</term>
<listitem>
<para>
This is a nix representation of a parsed LLVM target triple with
This is a Nix representation of a parsed LLVM target triple with
white-listed components. This can be specified directly, or actually
parsed from the <varname>config</varname>. [Technically, only one need
be specified and the others can be inferred, though the precision of
inference may not be very good.] See
parsed from the <varname>config</varname>. See
<literal>lib.systems.parse</literal> for the exact representation.
</para>
</listitem>
@ -196,7 +196,7 @@
<listitem>
<para>
These predicates are defined in <literal>lib.systems.inspect</literal>,
and slapped on every platform. They are superior to the ones in
and slapped onto every platform. They are superior to the ones in
<varname>stdenv</varname> as they force the user to be explicit about
which platform they are inspecting. Please use these instead of those.
</para>
@ -219,105 +219,132 @@
</variablelist>
</section>
<section>
<title>Specifying Dependencies</title>
<section xml:id="ssec-cross-dependency-categorization">
<title>Theory of dependency categorization</title>
<note>
<para>
This is a rather philosophical description that isn't very
Nixpkgs-specific. For an overview of all the relevant attributes given to
<varname>mkDerivation</varname>, see
<xref
linkend="ssec-stdenv-dependencies"/>. For a description of how
everything is implemented, see
<xref linkend="ssec-cross-dependency-implementation" />.
</para>
</note>
<para>
In this section we explore the relationship between both runtime and
buildtime dependencies and the 3 Autoconf platforms.
build-time dependencies and the 3 Autoconf platforms.
</para>
<para>
A runtime dependency between 2 packages implies that between them both the
host and target platforms match. This is directly implied by the meaning of
"host platform" and "runtime dependency": The package dependency exists
while both packages are running on a single host platform.
A run time dependency between two packages requires that their host
platforms match. This is directly implied by the meaning of "host platform"
and "runtime dependency": The package dependency exists while both packages
are running on a single host platform.
</para>
<para>
A build time dependency, however, implies a shift in platforms between the
depending package and the depended-on package. The meaning of a build time
dependency is that to build the depending package we need to be able to run
the depended-on's package. The depending package's build platform is
therefore equal to the depended-on package's host platform. Analogously,
the depending package's host platform is equal to the depended-on package's
target platform.
A build time dependency, however, has a shift in platforms between the
depending package and the depended-on package. "build time dependency"
means that to build the depending package we need to be able to run the
depended-on's package. The depending package's build platform is therefore
equal to the depended-on package's host platform.
</para>
<para>
In this manner, given the 3 platforms for one package, we can determine the
three platforms for all its transitive dependencies. This is the most
important guiding principle behind cross-compilation with Nixpkgs, and will
be called the <wordasword>sliding window principle</wordasword>.
If both the dependency and depending packages aren't compilers or other
machine-code-producing tools, we're done. And indeed
<varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>
have covered these simpler build-time and run-time (respectively) changes
for many years. But if the dependency does produce machine code, we might
need to worry about its target platform too. In principle, that target
platform might be any of the depending package's build, host, or target
platforms, but we prohibit dependencies from a "later" platform to an
earlier platform to limit confusion because we've never seen a legitimate
use for them.
</para>
<para>
Some examples will probably make this clearer. If a package is being built
with a <literal>(build, host, target)</literal> platform triple of
<literal>(foo, bar, bar)</literal>, then its build-time dependencies would
have a triple of <literal>(foo, foo, bar)</literal>, and <emphasis>those
packages'</emphasis> build-time dependencies would have triple of
<literal>(foo, foo, foo)</literal>. In other words, it should take two
"rounds" of following build-time dependency edges before one reaches a
fixed point where, by the sliding window principle, the platform triple no
longer changes. Indeed, this happens with cross compilation, where only
rounds of native dependencies starting with the second necessarily coincide
with native packages.
Finally, if the depending package is a compiler or other
machine-code-producing tool, it might need dependencies that run at "emit
time". This is for compilers that (regrettably) insist on being built
together with their source langauges' standard libraries. Assuming build !=
host != target, a run-time dependency of the standard library cannot be run
at the compiler's build time or run time, but only at the run time of code
emitted by the compiler.
</para>
<note>
<para>
The depending package's target platform is unconstrained by the sliding
window principle, which makes sense in that one can in principle build
cross compilers targeting arbitrary platforms.
</para>
</note>
<para>
How does this work in practice? Nixpkgs is now structured so that
build-time dependencies are taken from <varname>buildPackages</varname>,
whereas run-time dependencies are taken from the top level attribute set.
For example, <varname>buildPackages.gcc</varname> should be used at build
time, while <varname>gcc</varname> should be used at run time. Now, for
most of Nixpkgs's history, there was no <varname>buildPackages</varname>,
and most packages have not been refactored to use it explicitly. Instead,
one can use the six (<emphasis>gasp</emphasis>) attributes used for
specifying dependencies as documented in
<xref linkend="ssec-stdenv-dependencies"/>. We "splice" together the
run-time and build-time package sets with <varname>callPackage</varname>,
and then <varname>mkDerivation</varname> for each of four attributes pulls
the right derivation out. This splicing can be skipped when not cross
compiling as the package sets are the same, but is a bit slow for cross
compiling. Because of this, a best-of-both-worlds solution is in the works
with no splicing or explicit access of <varname>buildPackages</varname>
needed. For now, feel free to use either method.
Putting this all together, that means we have dependencies in the form
"host → target", in at most the following six combinations:
<table>
<caption>Possible dependency types</caption>
<thead>
<tr>
<th>Dependency's host platform</th>
<th>Dependency's target platform</th>
</tr>
</thead>
<tbody>
<tr>
<td>build</td>
<td>build</td>
</tr>
<tr>
<td>build</td>
<td>host</td>
</tr>
<tr>
<td>build</td>
<td>target</td>
</tr>
<tr>
<td>host</td>
<td>host</td>
</tr>
<tr>
<td>host</td>
<td>target</td>
</tr>
<tr>
<td>target</td>
<td>target</td>
</tr>
</tbody>
</table>
</para>
<note>
<para>
There is also a "backlink" <varname>targetPackages</varname>, yielding a
package set whose <varname>buildPackages</varname> is the current package
set. This is a hack, though, to accommodate compilers with lousy build
systems. Please do not use this unless you are absolutely sure you are
packaging such a compiler and there is no other way.
</para>
</note>
<para>
Some examples will make this table clearer. Suppose there's some package
that is being built with a <literal>(build, host, target)</literal>
platform triple of <literal>(foo, bar, baz)</literal>. If it has a
build-time library dependency, that would be a "host → build" dependency
with a triple of <literal>(foo, foo, *)</literal> (the target platform is
irrelevant). If it needs a compiler to be built, that would be a "build →
host" dependency with a triple of <literal>(foo, foo, *)</literal> (the
target platform is irrelevant). That compiler, would be built with another
compiler, also "build → host" dependency, with a triple of <literal>(foo,
foo, foo)</literal>.
</para>
</section>
<section>
<section xml:id="ssec-cross-cookbook">
<title>Cross packaging cookbook</title>
<para>
Some frequently problems when packaging for cross compilation are good to
just spell and answer. Ideally the information above is exhaustive, so this
section cannot provide any new information, but its ludicrous and cruel to
expect everyone to spend effort working through the interaction of many
features just to figure out the same answer to the same common problem.
Feel free to add to this list!
Some frequently encountered problems when packaging for cross-compilation
should be answered here. Ideally, the information above is exhaustive, so
this section cannot provide any new information, but it is ludicrous and
cruel to expect everyone to spend effort working through the interaction of
many features just to figure out the same answer to the same common
problem. Feel free to add to this list!
</para>
<qandaset>
<qandaentry>
<qandaentry xml:id="cross-qa-build-c-program-in-build-environment">
<question>
<para>
What if my package's build system needs to build a C program to be run
@ -331,7 +358,7 @@
</para>
</answer>
</qandaentry>
<qandaentry>
<qandaentry xml:id="cross-qa-fails-to-find-ar">
<question>
<para>
My package fails to find <command>ar</command>.
@ -347,7 +374,7 @@
</para>
</answer>
</qandaentry>
<qandaentry>
<qandaentry xml:id="cross-testsuite-runs-host-code">
<question>
<para>
My package's testsuite needs to run host platform code.
@ -367,17 +394,9 @@
<section xml:id="sec-cross-usage">
<title>Cross-building packages</title>
<note>
<para>
More information needs to moved from the old wiki, especially
<link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this
section.
</para>
</note>
<para>
Nixpkgs can be instantiated with <varname>localSystem</varname> alone, in
which case there is no cross compiling and everything is built by and for
which case there is no cross-compiling and everything is built by and for
that system, or also with <varname>crossSystem</varname>, in which case
packages run on the latter, but all building happens on the former. Both
parameters take the same schema as the 3 (build, host, and target) platforms
@ -394,7 +413,7 @@ nix-build &lt;nixpkgs&gt; --arg crossSystem '(import &lt;nixpkgs/lib&gt;).system
Eventually we would like to make these platform examples an unnecessary
convenience so that
<programlisting>
nix-build &lt;nixpkgs&gt; --arg crossSystem.config '&lt;arch&gt;-&lt;os&gt;-&lt;vendor&gt;-&lt;abi&gt;' -A whatever</programlisting>
nix-build &lt;nixpkgs&gt; --arg crossSystem '{ config = "&lt;arch&gt;-&lt;os&gt;-&lt;vendor&gt;-&lt;abi&gt;"; }' -A whatever</programlisting>
works in the vast majority of cases. The problem today is dependencies on
other sorts of configuration which aren't given proper defaults. We rely on
the examples to crudely to set those configuration parameters in some
@ -448,7 +467,7 @@ nix-build &lt;nixpkgs&gt; --arg crossSystem.config '&lt;arch&gt;-&lt;os&gt;-&lt;
dependencies or <varname>buildPackages</varname>, the three platforms will
be defined as one of <varname>localSystem</varname> or
<varname>crossSystem</varname>, with the former replacing the latter as one
traverses build-time dependencies. A last simple difference then is
traverses build-time dependencies. A last simple difference is that
<varname>crossSystem</varname> should be null when one doesn't want to
cross-compile, while the <varname>*Platform</varname>s are always non-null.
<varname>localSystem</varname> is always non-null.
@ -458,21 +477,202 @@ nix-build &lt;nixpkgs&gt; --arg crossSystem.config '&lt;arch&gt;-&lt;os&gt;-&lt;
<section xml:id="sec-cross-infra">
<title>Cross-compilation infrastructure</title>
<para>
To be written.
</para>
<section xml:id="ssec-cross-dependency-implementation">
<title>Implementation of dependencies</title>
<note>
<para>
If one explores nixpkgs, they will see derivations with names like
<literal>gccCross</literal>. Such <literal>*Cross</literal> derivations is
a holdover from before we properly distinguished between the host and
target platforms —the derivation with "Cross" in the name covered the
<literal>build = host != target</literal> case, while the other covered the
<literal>host = target</literal>, with build platform the same or not based
on whether one was using its <literal>.nativeDrv</literal> or
<literal>.crossDrv</literal>. This ugliness will disappear soon.
The categorizes of dependencies developed in
<xref
linkend="ssec-cross-dependency-categorization"/> are specified as
lists of derivations given to <varname>mkDerivation</varname>, as
documented in <xref linkend="ssec-stdenv-dependencies"/>. In short,
each list of dependencies for "host → target" of "foo → bar" is called
<varname>depsFooBar</varname>, with exceptions for backwards
compatibility that <varname>depsBuildHost</varname> is instead called
<varname>nativeBuildInputs</varname> and <varname>depsHostTarget</varname>
is instead called <varname>buildInputs</varname>. Nixpkgs is now structured
so that each <varname>depsFooBar</varname> is automatically taken from
<varname>pkgsFooBar</varname>. (These <varname>pkgsFooBar</varname>s are
quite new, so there is no special case for
<varname>nativeBuildInputs</varname> and <varname>buildInputs</varname>.)
For example, <varname>pkgsBuildHost.gcc</varname> should be used at
build-time, while <varname>pkgsHostTarget.gcc</varname> should be used at
run-time.
</para>
</note>
<para>
Now, for most of Nixpkgs's history, there were no
<varname>pkgsFooBar</varname> attributes, and most packages have not been
refactored to use it explicitly. Prior to those, there were just
<varname>buildPackages</varname>, <varname>pkgs</varname>, and
<varname>targetPackages</varname>. Those are now redefined as aliases to
<varname>pkgsBuildHost</varname>, <varname>pkgsHostTarget</varname>, and
<varname>pkgsTargetTarget</varname>. It is acceptable, even
recommended, to use them for libraries to show that the host platform is
irrelevant.
</para>
<para>
But before that, there was just <varname>pkgs</varname>, even though both
<varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>
existed. [Cross barely worked, and those were implemented with some hacks
on <varname>mkDerivation</varname> to override dependencies.] What this
means is the vast majority of packages do not use any explicit package set
to populate their dependencies, just using whatever
<varname>callPackage</varname> gives them even if they do correctly sort
their dependencies into the multiple lists described above. And indeed,
asking that users both sort their dependencies, <emphasis>and</emphasis>
take them from the right attribute set, is both too onerous and redundant,
so the recommended approach (for now) is to continue just categorizing by
list and not using an explicit package set.
</para>
<para>
To make this work, we "splice" together the six
<varname>pkgsFooBar</varname> package sets and have
<varname>callPackage</varname> actually take its arguments from that. This
is currently implemented in <filename>pkgs/top-level/splice.nix</filename>.
<varname>mkDerivation</varname> then, for each dependency attribute, pulls
the right derivation out from the splice. This splicing can be skipped when
not cross-compiling as the package sets are the same, but still is a bit
slow for cross-compiling. We'd like to do something better, but haven't
come up with anything yet.
</para>
</section>
<section xml:id="ssec-bootstrapping">
<title>Bootstrapping</title>
<para>
Each of the package sets described above come from a single bootstrapping
stage. While <filename>pkgs/top-level/default.nix</filename>, coordinates
the composition of stages at a high level,
<filename>pkgs/top-level/stage.nix</filename> "ties the knot" (creates the
fixed point) of each stage. The package sets are defined per-stage however,
so they can be thought of as edges between stages (the nodes) in a graph.
Compositions like <literal>pkgsBuildTarget.targetPackages</literal> can be
thought of as paths to this graph.
</para>
<para>
While there are many package sets, and thus many edges, the stages can also
be arranged in a linear chain. In other words, many of the edges are
redundant as far as connectivity is concerned. This hinges on the type of
bootstrapping we do. Currently for cross it is:
<orderedlist>
<listitem>
<para>
<literal>(native, native, native)</literal>
</para>
</listitem>
<listitem>
<para>
<literal>(native, native, foreign)</literal>
</para>
</listitem>
<listitem>
<para>
<literal>(native, foreign, foreign)</literal>
</para>
</listitem>
</orderedlist>
In each stage, <varname>pkgsBuildHost</varname> refers the the previous
stage, <varname>pkgsBuildBuild</varname> refers to the one before that, and
<varname>pkgsHostTarget</varname> refers to the current one, and
<varname>pkgsTargetTarget</varname> refers to the next one. When there is
no previous or next stage, they instead refer to the current stage. Note
how all the invariants regarding the mapping between dependency and depending
packages' build host and target platforms are preserved.
<varname>pkgsBuildTarget</varname> and <varname>pkgsHostHost</varname> are
more complex in that the stage fitting the requirements isn't always a
fixed chain of "prevs" and "nexts" away (modulo the "saturating"
self-references at the ends). We just special case each instead. All the primary
edges are implemented is in <filename>pkgs/stdenv/booter.nix</filename>,
and secondarily aliases in <filename>pkgs/top-level/stage.nix</filename>.
</para>
<note>
<para>
Note the native stages are bootstrapped in legacy ways that predate the
current cross implementation. This is why the the bootstrapping stages
leading up to the final stages are ignored inthe previous paragraph.
</para>
</note>
<para>
If one looks at the 3 platform triples, one can see that they overlap such
that one could put them together into a chain like:
<programlisting>
(native, native, native, foreign, foreign)
</programlisting>
If one imagines the saturating self references at the end being replaced
with infinite stages, and then overlays those platform triples, one ends up
with the infinite tuple:
<programlisting>
(native..., native, native, native, foreign, foreign, foreign...)
</programlisting>
On can then imagine any sequence of platforms such that there are bootstrap
stages with their 3 platforms determined by "sliding a window" that is the
3 tuple through the sequence. This was the original model for
bootstrapping. Without a target platform (assume a better world where all
compilers are multi-target and all standard libraries are built in their
own derivation), this is sufficient. Conversely if one wishes to cross
compile "faster", with a "Canadian Cross" bootstraping stage where
<literal>build != host != target</literal>, more bootstrapping stages are
needed since no sliding window providess the pesky
<varname>pkgsBuildTarget</varname> package set since it skips the Canadian
cross stage's "host".
</para>
<note>
<para>
It is much better to refer to <varname>buildPackages</varname> than
<varname>targetPackages</varname>, or more broadly package sets that do
not mention "target". There are three reasons for this.
</para>
<para>
First, it is because bootstrapping stages do not have a unique
<varname>targetPackages</varname>. For example a <literal>(x86-linux,
x86-linux, arm-linux)</literal> and <literal>(x86-linux, x86-linux,
x86-windows)</literal> package set both have a <literal>(x86-linux,
x86-linux, x86-linux)</literal> package set. Because there is no canonical
<varname>targetPackages</varname> for such a native (<literal>build ==
host == target</literal>) package set, we set their
<varname>targetPackages</varname>
</para>
<para>
Second, it is because this is a frequent source of hard-to-follow
"infinite recursions" / cycles. When only package sets that don't mention
target are used, the package set forms a directed acyclic graph. This
means that all cycles that exist are confined to one stage. This means
they are a lot smaller, and easier to follow in the code or a backtrace. It
also means they are present in native and cross builds alike, and so more
likely to be caught by CI and other users.
</para>
<para>
Thirdly, it is because everything target-mentioning only exists to
accommodate compilers with lousy build systems that insist on the compiler
itself and standard library being built together. Of course that is bad
because bigger derivations means longer rebuilds. It is also problematic because
it tends to make the standard libraries less like other libraries than
they could be, complicating code and build systems alike. Because of the
other problems, and because of these innate disadvantages, compilers ought
to be packaged another way where possible.
</para>
</note>
<note>
<para>
If one explores Nixpkgs, they will see derivations with names like
<literal>gccCross</literal>. Such <literal>*Cross</literal> derivations is
a holdover from before we properly distinguished between the host and
target platforms—the derivation with "Cross" in the name covered the
<literal>build = host != target</literal> case, while the other covered
the <literal>host = target</literal>, with build platform the same or not
based on whether one was using its <literal>.nativeDrv</literal> or
<literal>.crossDrv</literal>. This ugliness will disappear soon.
</para>
</note>
</section>
</section>
</chapter>

View File

@ -1,8 +1,9 @@
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
let
pkgs = import ./.. { };
lib = pkgs.lib;
in
pkgs.stdenv.mkDerivation {
locationsXml = import ./lib-function-locations.nix { inherit pkgs nixpkgs; };
functionDocs = import ./lib-function-docs.nix { inherit locationsXml pkgs; };
in pkgs.stdenv.mkDerivation {
name = "nixpkgs-manual";
buildInputs = with pkgs; [ pandoc libxml2 libxslt zip jing xmlformat ];
@ -29,6 +30,9 @@ pkgs.stdenv.mkDerivation {
];
postPatch = ''
rm -rf ./functions/library/locations.xml
ln -s ${locationsXml} ./functions/library/locations.xml
ln -s ${functionDocs} ./functions/library/generated
echo ${lib.version} > .version
'';

View File

@ -1,796 +1,22 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-functions">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="chap-functions">
<title>Functions reference</title>
<para>
The nixpkgs repository has several utility functions to manipulate Nix
expressions.
</para>
<section xml:id="sec-overrides">
<title>Overriding</title>
<para>
Sometimes one wants to override parts of <literal>nixpkgs</literal>, e.g.
derivation attributes, the results of derivations or even the whole package
set.
</para>
<section xml:id="sec-pkg-override">
<title>&lt;pkg&gt;.override</title>
<para>
The function <varname>override</varname> is usually available for all the
derivations in the nixpkgs expression (<varname>pkgs</varname>).
</para>
<para>
It is used to override the arguments passed to a function.
</para>
<para>
Example usages:
<programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
<programlisting>import pkgs.path { overlays = [ (self: super: {
foo = super.foo.override { barSupport = true ; };
})]};</programlisting>
<programlisting>mypkg = pkgs.callPackage ./mypkg.nix {
mydep = pkgs.mydep.override { ... };
}</programlisting>
</para>
<para>
In the first example, <varname>pkgs.foo</varname> is the result of a
function call with some default arguments, usually a derivation. Using
<varname>pkgs.foo.override</varname> will call the same function with the
given new arguments.
</para>
</section>
<section xml:id="sec-pkg-overrideAttrs">
<title>&lt;pkg&gt;.overrideAttrs</title>
<para>
The function <varname>overrideAttrs</varname> allows overriding the
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
producing a new derivation based on the original one. This function is
available on all derivations produced by the
<varname>stdenv.mkDerivation</varname> function, which is most packages in
the nixpkgs expression <varname>pkgs</varname>.
</para>
<para>
Example usage:
<programlisting>helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
separateDebugInfo = true;
});</programlisting>
</para>
<para>
In the above example, the <varname>separateDebugInfo</varname> attribute is
overridden to be true, thus building debug info for
<varname>helloWithDebug</varname>, while all other attributes will be
retained from the original <varname>hello</varname> package.
</para>
<para>
The argument <varname>oldAttrs</varname> is conventionally used to refer to
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
</para>
<note>
<para>
Note that <varname>separateDebugInfo</varname> is processed only by the
<varname>stdenv.mkDerivation</varname> function, not the generated, raw
Nix derivation. Thus, using <varname>overrideDerivation</varname> will not
work in this case, as it overrides only the attributes of the final
derivation. It is for this reason that <varname>overrideAttrs</varname>
should be preferred in (almost) all cases to
<varname>overrideDerivation</varname>, i.e. to allow using
<varname>sdenv.mkDerivation</varname> to process input arguments, as well
as the fact that it is easier to use (you can use the same attribute names
you see in your Nix code, instead of the ones generated (e.g.
<varname>buildInputs</varname> vs <varname>nativeBuildInputs</varname>,
and involves less typing.
</para>
</note>
</section>
<section xml:id="sec-pkg-overrideDerivation">
<title>&lt;pkg&gt;.overrideDerivation</title>
<warning>
<para>
You should prefer <varname>overrideAttrs</varname> in almost all cases,
see its documentation for the reasons why.
<varname>overrideDerivation</varname> is not deprecated and will continue
to work, but is less nice to use and does not have as many abilities as
<varname>overrideAttrs</varname>.
</para>
</warning>
<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>~/.config/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.
</para>
<para>
Example usage:
<programlisting>mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
name = "sed-4.2.2-pre";
src = fetchurl {
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
};
patches = [];
});</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.
</para>
<para>
The argument <varname>oldAttrs</varname> is used to refer to the attribute
set of 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">
<title>lib.makeOverridable</title>
<para>
The function <varname>lib.makeOverridable</varname> is used to make the
result of a function easily customizable. This utility only makes sense for
functions that accept an argument set and return an attribute set.
</para>
<para>
Example usage:
<programlisting>f = { a, b }: { result = a+b; }
c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
</para>
<para>
The variable <varname>c</varname> is the value of the <varname>f</varname>
function applied with some default arguments. Hence the value of
<varname>c.result</varname> is <literal>3</literal>, in this example.
</para>
<para>
The variable <varname>c</varname> however also has some additional
functions, like <link linkend="sec-pkg-override">c.override</link> which
can be used to override the default arguments. In this example the value of
<varname>(c.override { a = 4; }).result</varname> is 6.
</para>
</section>
</section>
<section xml:id="sec-generators">
<title>Generators</title>
<para>
Generators are functions that create file formats from nix data structures,
e.g. for configuration files. There are generators available for:
<literal>INI</literal>, <literal>JSON</literal> and <literal>YAML</literal>
</para>
<para>
All generators follow a similar call interface: <code>generatorName
configFunctions data</code>, where <literal>configFunctions</literal> is an
attrset of user-defined functions that format nested parts of the content.
They each have common defaults, so often they do not need to be set
manually. An example is <code>mkSectionName ? (name: libStr.escape [ "[" "]"
] name)</code> from the <literal>INI</literal> generator. It receives the
name of a section and sanitizes it. The default
<literal>mkSectionName</literal> escapes <literal>[</literal> and
<literal>]</literal> with a backslash.
</para>
<para>
Generators can be fine-tuned to produce exactly the file format required by
your application/service. One example is an INI-file format which uses
<literal>: </literal> as separator, the strings
<literal>"yes"</literal>/<literal>"no"</literal> as boolean values and
requires all string values to be quoted:
</para>
<programlisting>
with lib;
let
customToINI = generators.toINI {
# specifies how to format a key/value pair
mkKeyValue = generators.mkKeyValueDefault {
# specifies the generated string for a subset of nix values
mkValueString = v:
if v == true then ''"yes"''
else if v == false then ''"no"''
else if isString v then ''"${v}"''
# and delegats all other values to the default generator
else generators.mkValueStringDefault {} v;
} ":";
};
# the INI file can now be given as plain old nix values
in customToINI {
main = {
pushinfo = true;
autopush = false;
host = "localhost";
port = 42;
};
mergetool = {
merge = "diff3";
};
}
</programlisting>
<para>
This will produce the following INI file as nix string:
</para>
<programlisting>
[main]
autopush:"no"
host:"localhost"
port:42
pushinfo:"yes"
str\:ange:"very::strange"
[mergetool]
merge:"diff3"
</programlisting>
<note>
<para>
Nix store paths can be converted to strings by enclosing a derivation
attribute like so: <code>"${drv}"</code>.
</para>
</note>
<para>
Detailed documentation for each generator can be found in
<literal>lib/generators.nix</literal>.
</para>
</section>
<section xml:id="sec-debug">
<title>Debugging Nix Expressions</title>
<para>
Nix is a unityped, dynamic language, this means every value can potentially
appear anywhere. Since it is also non-strict, evaluation order and what
ultimately is evaluated might surprise you. Therefore it is important to be
able to debug nix expressions.
</para>
<para>
In the <literal>lib/debug.nix</literal> file you will find a number of
functions that help (pretty-)printing values while evaluation is runnnig.
You can even specify how deep these values should be printed recursively,
and transform them on the fly. Please consult the docstrings in
<literal>lib/debug.nix</literal> for usage information.
</para>
</section>
<section xml:id="sec-fhs-environments">
<title>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 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 temporary lightweight environments which are destroyed after all
child processes exit, without root user rights requirement. Accepted
arguments are:
</para>
<variablelist>
<varlistentry>
<term>
<literal>name</literal>
</term>
<listitem>
<para>
Environment name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<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>
</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>
</varlistentry>
<varlistentry>
<term>
<literal>extraBuildCommands</literal>
</term>
<listitem>
<para>
Additional commands to be executed for finalizing the directory
structure.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>extraBuildCommandsMulti</literal>
</term>
<listitem>
<para>
Like <literal>extraBuildCommands</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>
One can create a simple environment using a <literal>shell.nix</literal>
like that:
</para>
<programlisting><![CDATA[
{ pkgs ? import <nixpkgs> {} }:
(pkgs.buildFHSUserEnv {
name = "simple-x11-env";
targetPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]) ++ (with pkgs.xorg;
[ libX11
libXcursor
libXrandr
]);
multiPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]);
runScript = "bash";
}).env
]]></programlisting>
<para>
Running <literal>nix-shell</literal> would then drop you into a shell with
these libraries and binaries available. You can use this to run
closed-source applications which expect FHS structure without hassles:
simply change <literal>runScript</literal> to the application path, e.g.
<filename>./bin/start.sh</filename> -- relative paths are supported.
</para>
</section>
<section xml:id="sec-pkgs-dockerTools">
<title>pkgs.dockerTools</title>
<para>
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
manipulating Docker images according to the
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#docker-image-specification-v120">
Docker Image Specification v1.2.0 </link>. Docker itself is not used to
perform any of the operations done by these functions.
</para>
<warning>
<para>
The <varname>dockerTools</varname> API is unstable and may be subject to
backwards-incompatible changes in the future.
</para>
</warning>
<section xml:id="ssec-pkgs-dockerTools-buildImage">
<title>buildImage</title>
<para>
This function is analogous to the <command>docker build</command> command,
in that can used to build a Docker-compatible repository tarball containing
a single image with one or multiple layers. As such, the result is suitable
for being loaded in Docker with <command>docker load</command>.
</para>
<para>
The parameters of <varname>buildImage</varname> with relative example
values are described below:
</para>
<example xml:id='ex-dockerTools-buildImage'>
<title>Docker build</title>
<programlisting>
buildImage {
name = "redis"; <co xml:id='ex-dockerTools-buildImage-1' />
tag = "latest"; <co xml:id='ex-dockerTools-buildImage-2' />
fromImage = someBaseImage; <co xml:id='ex-dockerTools-buildImage-3' />
fromImageName = null; <co xml:id='ex-dockerTools-buildImage-4' />
fromImageTag = "latest"; <co xml:id='ex-dockerTools-buildImage-5' />
contents = pkgs.redis; <co xml:id='ex-dockerTools-buildImage-6' />
runAsRoot = '' <co xml:id='ex-dockerTools-buildImage-runAsRoot' />
#!${stdenv.shell}
mkdir -p /data
'';
config = { <co xml:id='ex-dockerTools-buildImage-8' />
Cmd = [ "/bin/redis-server" ];
WorkingDir = "/data";
Volumes = {
"/data" = {};
};
};
}
</programlisting>
</example>
<para>
The above example will build a Docker image <literal>redis/latest</literal>
from the given base image. Loading and running this image in Docker results
in <literal>redis-server</literal> being started automatically.
</para>
<calloutlist>
<callout arearefs='ex-dockerTools-buildImage-1'>
<para>
<varname>name</varname> specifies the name of the resulting image. This
is the only required argument for <varname>buildImage</varname>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-2'>
<para>
<varname>tag</varname> specifies the tag of the resulting image. By
default it's <literal>null</literal>, which indicates that the nix output hash will be used as tag.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-3'>
<para>
<varname>fromImage</varname> is the repository tarball containing the
base image. It must be a valid Docker image, such as exported by
<command>docker save</command>. By default it's <literal>null</literal>,
which can be seen as equivalent to <literal>FROM scratch</literal> of a
<filename>Dockerfile</filename>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-4'>
<para>
<varname>fromImageName</varname> can be used to further specify the base
image within the repository, in case it contains multiple images. By
default it's <literal>null</literal>, in which case
<varname>buildImage</varname> will peek the first image available in the
repository.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-5'>
<para>
<varname>fromImageTag</varname> can be used to further specify the tag of
the base image within the repository, in case an image contains multiple
tags. By default it's <literal>null</literal>, in which case
<varname>buildImage</varname> will peek the first tag available for the
base image.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-6'>
<para>
<varname>contents</varname> is a derivation that will be copied in the
new layer of the resulting image. This can be similarly seen as
<command>ADD contents/ /</command> in a <filename>Dockerfile</filename>.
By default it's <literal>null</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-runAsRoot'>
<para>
<varname>runAsRoot</varname> is a bash script that will run as root in an
environment that overlays the existing layers of the base image with the
new resulting layer, including the previously copied
<varname>contents</varname> derivation. This can be similarly seen as
<command>RUN ...</command> in a <filename>Dockerfile</filename>.
<note>
<para>
Using this parameter requires the <literal>kvm</literal> device to be
available.
</para>
</note>
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-8'>
<para>
<varname>config</varname> is used to specify the configuration of the
containers that will be started off the built image in Docker. The
available options are listed in the
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
Docker Image Specification v1.2.0 </link>.
</para>
</callout>
</calloutlist>
<para>
After the new layer has been created, its closure (to which
<varname>contents</varname>, <varname>config</varname> and
<varname>runAsRoot</varname> contribute) will be copied in the layer
itself. Only new dependencies that are not already in the existing layers
will be copied.
</para>
<para>
At the end of the process, only one new single layer will be produced and
added to the resulting image.
</para>
<para>
The resulting repository will only list the single image
<varname>image/tag</varname>. In the case of
<xref linkend='ex-dockerTools-buildImage'/> it would be
<varname>redis/latest</varname>.
</para>
<para>
It is possible to inspect the arguments with which an image was built using
its <varname>buildArgs</varname> attribute.
</para>
<note>
<para>
If you see errors similar to <literal>getProtocolByName: does not exist
(no such protocol name: tcp)</literal> you may need to add
<literal>pkgs.iana-etc</literal> to <varname>contents</varname>.
</para>
</note>
<note>
<para>
If you see errors similar to <literal>Error_Protocol ("certificate has
unknown CA",True,UnknownCa)</literal> you may need to add
<literal>pkgs.cacert</literal> to <varname>contents</varname>.
</para>
</note>
</section>
<section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry">
<title>pullImage</title>
<para>
This function is analogous to the <command>docker pull</command> command,
in that can be used to pull a Docker image from a Docker registry. By
default <link xlink:href="https://hub.docker.com/">Docker Hub</link> is
used to pull images.
</para>
<para>
Its parameters are described in the example below:
</para>
<example xml:id='ex-dockerTools-pullImage'>
<title>Docker pull</title>
<programlisting>
pullImage {
imageName = "nixos/nix"; <co xml:id='ex-dockerTools-pullImage-1' />
imageDigest = "sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b"; <co xml:id='ex-dockerTools-pullImage-2' />
finalImageTag = "1.11"; <co xml:id='ex-dockerTools-pullImage-3' />
sha256 = "0mqjy3zq2v6rrhizgb9nvhczl87lcfphq9601wcprdika2jz7qh8"; <co xml:id='ex-dockerTools-pullImage-4' />
os = "linux"; <co xml:id='ex-dockerTools-pullImage-5' />
arch = "x86_64"; <co xml:id='ex-dockerTools-pullImage-6' />
}
</programlisting>
</example>
<calloutlist>
<callout arearefs='ex-dockerTools-pullImage-1'>
<para>
<varname>imageName</varname> specifies the name of the image to be
downloaded, which can also include the registry namespace (e.g.
<literal>nixos</literal>). This argument is required.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-2'>
<para>
<varname>imageDigest</varname> specifies the digest of the image to be
downloaded. Skopeo can be used to get the digest of an image, with its
<varname>inspect</varname> subcommand. Since a given <varname>imageName</varname>
may transparently refer to a manifest list of images which support
multiple architectures and/or operating systems, supply the `--override-os`
and `--override-arch` arguments to specify exactly which image you
want. By default it will match the OS and architecture of the host the
command is run on.
<programlisting>
$ nix-shell --packages skopeo jq --command "skopeo --override-os linux --override-arch x86_64 inspect docker://docker.io/nixos/nix:1.11 | jq -r '.Digest'"
sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b
</programlisting>
This argument is required.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-3'>
<para>
<varname>finalImageTag</varname>, if specified, this is the tag of the
image to be created. Note it is never used to fetch the image since we
prefer to rely on the immutable digest ID. By default it's
<literal>latest</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-4'>
<para>
<varname>sha256</varname> is the checksum of the whole fetched image.
This argument is required.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-5'>
<para>
<varname>os</varname>, if specified, is the operating system of the fetched image.
By default it's <literal>linux</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-6'>
<para>
<varname>arch</varname>, if specified, is the cpu architecture of the fetched image.
By default it's <literal>x86_64</literal>.
</para>
</callout>
</calloutlist>
</section>
<section xml:id="ssec-pkgs-dockerTools-exportImage">
<title>exportImage</title>
<para>
This function is analogous to the <command>docker export</command> command,
in that can used to flatten a Docker image that contains multiple layers.
It is in fact the result of the merge of all the layers of the image. As
such, the result is suitable for being imported in Docker with
<command>docker import</command>.
</para>
<note>
<para>
Using this function requires the <literal>kvm</literal> device to be
available.
</para>
</note>
<para>
The parameters of <varname>exportImage</varname> are the following:
</para>
<example xml:id='ex-dockerTools-exportImage'>
<title>Docker export</title>
<programlisting>
exportImage {
fromImage = someLayeredImage;
fromImageName = null;
fromImageTag = null;
name = someLayeredImage.name;
}
</programlisting>
</example>
<para>
The parameters relative to the base image have the same synopsis as
described in <xref linkend='ssec-pkgs-dockerTools-buildImage'/>, except
that <varname>fromImage</varname> is the only required argument in this
case.
</para>
<para>
The <varname>name</varname> argument is the name of the derivation output,
which defaults to <varname>fromImage.name</varname>.
</para>
</section>
<section xml:id="ssec-pkgs-dockerTools-shadowSetup">
<title>shadowSetup</title>
<para>
This constant string is a helper for setting up the base files for managing
users and groups, only if such files don't exist already. It is suitable
for being used in a <varname>runAsRoot</varname>
<xref linkend='ex-dockerTools-buildImage-runAsRoot'/> script for cases like
in the example below:
</para>
<example xml:id='ex-dockerTools-shadowSetup'>
<title>Shadow base files</title>
<programlisting>
buildImage {
name = "shadow-basic";
runAsRoot = ''
#!${stdenv.shell}
${shadowSetup}
groupadd -r redis
useradd -r -g redis redis
mkdir /data
chown redis:redis /data
'';
}
</programlisting>
</example>
<para>
Creating base files like <literal>/etc/passwd</literal> or
<literal>/etc/login.defs</literal> are necessary for shadow-utils to
manipulate users and groups.
</para>
</section>
</section>
<xi:include href="functions/library.xml" />
<xi:include href="functions/overrides.xml" />
<xi:include href="functions/generators.xml" />
<xi:include href="functions/debug.xml" />
<xi:include href="functions/fetchers.xml" />
<xi:include href="functions/trivial-builders.xml" />
<xi:include href="functions/fhs-environments.xml" />
<xi:include href="functions/shell.xml" />
<xi:include href="functions/dockertools.xml" />
<xi:include href="functions/appimagetools.xml" />
<xi:include href="functions/prefer-remote-fetch.xml" />
<xi:include href="functions/nix-gitignore.xml" />
</chapter>

View File

@ -0,0 +1,118 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-pkgs-appimageTools">
<title>pkgs.appimageTools</title>
<para>
<varname>pkgs.appimageTools</varname> is a set of functions for extracting
and wrapping <link xlink:href="https://appimage.org/">AppImage</link> files.
They are meant to be used if traditional packaging from source is infeasible,
or it would take too long. To quickly run an AppImage file,
<literal>pkgs.appimage-run</literal> can be used as well.
</para>
<warning>
<para>
The <varname>appimageTools</varname> API is unstable and may be subject to
backwards-incompatible changes in the future.
</para>
</warning>
<section xml:id="ssec-pkgs-appimageTools-formats">
<title>AppImage formats</title>
<para>
There are different formats for AppImages, see
<link xlink:href="https://github.com/AppImage/AppImageSpec/blob/74ad9ca2f94bf864a4a0dac1f369dd4f00bd1c28/draft.md#image-format">the
specification</link> for details.
</para>
<itemizedlist>
<listitem>
<para>
Type 1 images are ISO 9660 files that are also ELF executables.
</para>
</listitem>
<listitem>
<para>
Type 2 images are ELF executables with an appended filesystem.
</para>
</listitem>
</itemizedlist>
<para>
They can be told apart with <command>file -k</command>:
</para>
<screen>
<prompt>$ </prompt>file -k type1.AppImage
type1.AppImage: ELF 64-bit LSB executable, x86-64, version 1 (SYSV) ISO 9660 CD-ROM filesystem data 'AppImage' (Lepton 3.x), scale 0-0,
spot sensor temperature 0.000000, unit celsius, color scheme 0, calibration: offset 0.000000, slope 0.000000, dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=d629f6099d2344ad82818172add1d38c5e11bc6d, stripped\012- data
<prompt>$ </prompt>file -k type2.AppImage
type2.AppImage: ELF 64-bit LSB executable, x86-64, version 1 (SYSV) (Lepton 3.x), scale 232-60668, spot sensor temperature -4.187500, color scheme 15, show scale bar, calibration: offset -0.000000, slope 0.000000 (Lepton 2.x), scale 4111-45000, spot sensor temperature 412442.250000, color scheme 3, minimum point enabled, calibration: offset -75402534979642766821519867692934234112.000000, slope 5815371847733706829839455140374904832.000000, dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=79dcc4e55a61c293c5e19edbd8d65b202842579f, stripped\012- data
</screen>
<para>
Note how the type 1 AppImage is described as an <literal>ISO 9660 CD-ROM
filesystem</literal>, and the type 2 AppImage is not.
</para>
</section>
<section xml:id="ssec-pkgs-appimageTools-wrapping">
<title>Wrapping</title>
<para>
Depending on the type of AppImage you're wrapping, you'll have to use
<varname>wrapType1</varname> or <varname>wrapType2</varname>.
</para>
<programlisting>
appimageTools.wrapType2 { # or wrapType1
name = "patchwork"; <co xml:id='ex-appimageTools-wrapping-1' />
src = fetchurl { <co xml:id='ex-appimageTools-wrapping-2' />
url = https://github.com/ssbc/patchwork/releases/download/v3.11.4/Patchwork-3.11.4-linux-x86_64.AppImage;
sha256 = "1blsprpkvm0ws9b96gb36f0rbf8f5jgmw4x6dsb1kswr4ysf591s";
};
extraPkgs = pkgs: with pkgs; [ ]; <co xml:id='ex-appimageTools-wrapping-3' />
}</programlisting>
<calloutlist>
<callout arearefs='ex-appimageTools-wrapping-1'>
<para>
<varname>name</varname> specifies the name of the resulting image.
</para>
</callout>
<callout arearefs='ex-appimageTools-wrapping-2'>
<para>
<varname>src</varname> specifies the AppImage file to extract.
</para>
</callout>
<callout arearefs='ex-appimageTools-wrapping-2'>
<para>
<varname>extraPkgs</varname> allows you to pass a function to include
additional packages inside the FHS environment your AppImage is going to
run in. There are a few ways to learn which dependencies an application
needs:
<itemizedlist>
<listitem>
<para>
Looking through the extracted AppImage files, reading its scripts and
running <command>patchelf</command> and <command>ldd</command> on its
executables. This can also be done in <command>appimage-run</command>,
by setting <command>APPIMAGE_DEBUG_EXEC=bash</command>.
</para>
</listitem>
<listitem>
<para>
Running <command>strace -vfefile</command> on the wrapped executable,
looking for libraries that can't be found.
</para>
</listitem>
</itemizedlist>
</para>
</callout>
</calloutlist>
</section>
</section>

21
doc/functions/debug.xml Normal file
View File

@ -0,0 +1,21 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-debug">
<title>Debugging Nix Expressions</title>
<para>
Nix is a unityped, dynamic language, this means every value can potentially
appear anywhere. Since it is also non-strict, evaluation order and what
ultimately is evaluated might surprise you. Therefore it is important to be
able to debug nix expressions.
</para>
<para>
In the <literal>lib/debug.nix</literal> file you will find a number of
functions that help (pretty-)printing values while evaluation is runnnig. You
can even specify how deep these values should be printed recursively, and
transform them on the fly. Please consult the docstrings in
<literal>lib/debug.nix</literal> for usage information.
</para>
</section>

View File

@ -0,0 +1,590 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-pkgs-dockerTools">
<title>pkgs.dockerTools</title>
<para>
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
manipulating Docker images according to the
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#docker-image-specification-v120">
Docker Image Specification v1.2.0 </link>. Docker itself is not used to
perform any of the operations done by these functions.
</para>
<warning>
<para>
The <varname>dockerTools</varname> API is unstable and may be subject to
backwards-incompatible changes in the future.
</para>
</warning>
<section xml:id="ssec-pkgs-dockerTools-buildImage">
<title>buildImage</title>
<para>
This function is analogous to the <command>docker build</command> command,
in that it can be used to build a Docker-compatible repository tarball
containing a single image with one or multiple layers. As such, the result
is suitable for being loaded in Docker with <command>docker load</command>.
</para>
<para>
The parameters of <varname>buildImage</varname> with relative example values
are described below:
</para>
<example xml:id='ex-dockerTools-buildImage'>
<title>Docker build</title>
<programlisting>
buildImage {
name = "redis"; <co xml:id='ex-dockerTools-buildImage-1' />
tag = "latest"; <co xml:id='ex-dockerTools-buildImage-2' />
fromImage = someBaseImage; <co xml:id='ex-dockerTools-buildImage-3' />
fromImageName = null; <co xml:id='ex-dockerTools-buildImage-4' />
fromImageTag = "latest"; <co xml:id='ex-dockerTools-buildImage-5' />
contents = pkgs.redis; <co xml:id='ex-dockerTools-buildImage-6' />
runAsRoot = '' <co xml:id='ex-dockerTools-buildImage-runAsRoot' />
#!${pkgs.runtimeShell}
mkdir -p /data
'';
config = { <co xml:id='ex-dockerTools-buildImage-8' />
Cmd = [ "/bin/redis-server" ];
WorkingDir = "/data";
Volumes = {
"/data" = {};
};
};
}
</programlisting>
</example>
<para>
The above example will build a Docker image <literal>redis/latest</literal>
from the given base image. Loading and running this image in Docker results
in <literal>redis-server</literal> being started automatically.
</para>
<calloutlist>
<callout arearefs='ex-dockerTools-buildImage-1'>
<para>
<varname>name</varname> specifies the name of the resulting image. This is
the only required argument for <varname>buildImage</varname>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-2'>
<para>
<varname>tag</varname> specifies the tag of the resulting image. By
default it's <literal>null</literal>, which indicates that the nix output
hash will be used as tag.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-3'>
<para>
<varname>fromImage</varname> is the repository tarball containing the base
image. It must be a valid Docker image, such as exported by
<command>docker save</command>. By default it's <literal>null</literal>,
which can be seen as equivalent to <literal>FROM scratch</literal> of a
<filename>Dockerfile</filename>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-4'>
<para>
<varname>fromImageName</varname> can be used to further specify the base
image within the repository, in case it contains multiple images. By
default it's <literal>null</literal>, in which case
<varname>buildImage</varname> will peek the first image available in the
repository.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-5'>
<para>
<varname>fromImageTag</varname> can be used to further specify the tag of
the base image within the repository, in case an image contains multiple
tags. By default it's <literal>null</literal>, in which case
<varname>buildImage</varname> will peek the first tag available for the
base image.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-6'>
<para>
<varname>contents</varname> is a derivation that will be copied in the new
layer of the resulting image. This can be similarly seen as <command>ADD
contents/ /</command> in a <filename>Dockerfile</filename>. By default
it's <literal>null</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-runAsRoot'>
<para>
<varname>runAsRoot</varname> is a bash script that will run as root in an
environment that overlays the existing layers of the base image with the
new resulting layer, including the previously copied
<varname>contents</varname> derivation. This can be similarly seen as
<command>RUN ...</command> in a <filename>Dockerfile</filename>.
<note>
<para>
Using this parameter requires the <literal>kvm</literal> device to be
available.
</para>
</note>
</para>
</callout>
<callout arearefs='ex-dockerTools-buildImage-8'>
<para>
<varname>config</varname> is used to specify the configuration of the
containers that will be started off the built image in Docker. The
available options are listed in the
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
Docker Image Specification v1.2.0 </link>.
</para>
</callout>
</calloutlist>
<para>
After the new layer has been created, its closure (to which
<varname>contents</varname>, <varname>config</varname> and
<varname>runAsRoot</varname> contribute) will be copied in the layer itself.
Only new dependencies that are not already in the existing layers will be
copied.
</para>
<para>
At the end of the process, only one new single layer will be produced and
added to the resulting image.
</para>
<para>
The resulting repository will only list the single image
<varname>image/tag</varname>. In the case of
<xref linkend='ex-dockerTools-buildImage'/> it would be
<varname>redis/latest</varname>.
</para>
<para>
It is possible to inspect the arguments with which an image was built using
its <varname>buildArgs</varname> attribute.
</para>
<note>
<para>
If you see errors similar to <literal>getProtocolByName: does not exist (no
such protocol name: tcp)</literal> you may need to add
<literal>pkgs.iana-etc</literal> to <varname>contents</varname>.
</para>
</note>
<note>
<para>
If you see errors similar to <literal>Error_Protocol ("certificate has
unknown CA",True,UnknownCa)</literal> you may need to add
<literal>pkgs.cacert</literal> to <varname>contents</varname>.
</para>
</note>
<example xml:id="example-pkgs-dockerTools-buildImage-creation-date">
<title>Impurely Defining a Docker Layer's Creation Date</title>
<para>
By default <function>buildImage</function> will use a static date of one
second past the UNIX Epoch. This allows <function>buildImage</function> to
produce binary reproducible images. When listing images with
<command>docker images</command>, the newly created images will be listed
like this:
</para>
<screen><![CDATA[
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest 08c791c7846e 48 years ago 25.2MB
]]></screen>
<para>
You can break binary reproducibility but have a sorted, meaningful
<literal>CREATED</literal> column by setting <literal>created</literal> to
<literal>now</literal>.
</para>
<programlisting><![CDATA[
pkgs.dockerTools.buildImage {
name = "hello";
tag = "latest";
created = "now";
contents = pkgs.hello;
config.Cmd = [ "/bin/hello" ];
}
]]></programlisting>
<para>
and now the Docker CLI will display a reasonable date and sort the images
as expected:
<screen><![CDATA[
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest de2bf4786de6 About a minute ago 25.2MB
]]></screen>
however, the produced images will not be binary reproducible.
</para>
</example>
</section>
<section xml:id="ssec-pkgs-dockerTools-buildLayeredImage">
<title>buildLayeredImage</title>
<para>
Create a Docker image with many of the store paths being on their own layer
to improve sharing between images.
</para>
<variablelist>
<varlistentry>
<term>
<varname>name</varname>
</term>
<listitem>
<para>
The name of the resulting image.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>tag</varname> <emphasis>optional</emphasis>
</term>
<listitem>
<para>
Tag of the generated image.
</para>
<para>
<emphasis>Default:</emphasis> the output path's hash
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>contents</varname> <emphasis>optional</emphasis>
</term>
<listitem>
<para>
Top level paths in the container. Either a single derivation, or a list
of derivations.
</para>
<para>
<emphasis>Default:</emphasis> <literal>[]</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>config</varname> <emphasis>optional</emphasis>
</term>
<listitem>
<para>
Run-time configuration of the container. A full list of the options are
available at in the
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
Docker Image Specification v1.2.0 </link>.
</para>
<para>
<emphasis>Default:</emphasis> <literal>{}</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>created</varname> <emphasis>optional</emphasis>
</term>
<listitem>
<para>
Date and time the layers were created. Follows the same
<literal>now</literal> exception supported by
<literal>buildImage</literal>.
</para>
<para>
<emphasis>Default:</emphasis> <literal>1970-01-01T00:00:01Z</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>maxLayers</varname> <emphasis>optional</emphasis>
</term>
<listitem>
<para>
Maximum number of layers to create.
</para>
<para>
<emphasis>Default:</emphasis> <literal>24</literal>
</para>
</listitem>
</varlistentry>
</variablelist>
<section xml:id="dockerTools-buildLayeredImage-arg-contents">
<title>Behavior of <varname>contents</varname> in the final image</title>
<para>
Each path directly listed in <varname>contents</varname> will have a
symlink in the root of the image.
</para>
<para>
For example:
<programlisting><![CDATA[
pkgs.dockerTools.buildLayeredImage {
name = "hello";
contents = [ pkgs.hello ];
}
]]></programlisting>
will create symlinks for all the paths in the <literal>hello</literal>
package:
<screen><![CDATA[
/bin/hello -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/bin/hello
/share/info/hello.info -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/share/info/hello.info
/share/locale/bg/LC_MESSAGES/hello.mo -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/share/locale/bg/LC_MESSAGES/hello.mo
]]></screen>
</para>
</section>
<section xml:id="dockerTools-buildLayeredImage-arg-config">
<title>Automatic inclusion of <varname>config</varname> references</title>
<para>
The closure of <varname>config</varname> is automatically included in the
closure of the final image.
</para>
<para>
This allows you to make very simple Docker images with very little code.
This container will start up and run <command>hello</command>:
<programlisting><![CDATA[
pkgs.dockerTools.buildLayeredImage {
name = "hello";
config.Cmd = [ "${pkgs.hello}/bin/hello" ];
}
]]></programlisting>
</para>
</section>
<section xml:id="dockerTools-buildLayeredImage-arg-maxLayers">
<title>Adjusting <varname>maxLayers</varname></title>
<para>
Increasing the <varname>maxLayers</varname> increases the number of layers
which have a chance to be shared between different images.
</para>
<para>
Modern Docker installations support up to 128 layers, however older
versions support as few as 42.
</para>
<para>
If the produced image will not be extended by other Docker builds, it is
safe to set <varname>maxLayers</varname> to <literal>128</literal>. However
it will be impossible to extend the image further.
</para>
<para>
The first (<literal>maxLayers-2</literal>) most "popular" paths will have
their own individual layers, then layer #<literal>maxLayers-1</literal>
will contain all the remaining "unpopular" paths, and finally layer
#<literal>maxLayers</literal> will contain the Image configuration.
</para>
<para>
Docker's Layers are not inherently ordered, they are content-addressable
and are not explicitly layered until they are composed in to an Image.
</para>
</section>
</section>
<section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry">
<title>pullImage</title>
<para>
This function is analogous to the <command>docker pull</command> command, in
that it can be used to pull a Docker image from a Docker registry. By
default <link xlink:href="https://hub.docker.com/">Docker Hub</link> is used
to pull images.
</para>
<para>
Its parameters are described in the example below:
</para>
<example xml:id='ex-dockerTools-pullImage'>
<title>Docker pull</title>
<programlisting>
pullImage {
imageName = "nixos/nix"; <co xml:id='ex-dockerTools-pullImage-1' />
imageDigest = "sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b"; <co xml:id='ex-dockerTools-pullImage-2' />
finalImageName = "nix"; <co xml:id='ex-dockerTools-pullImage-3' />
finalImageTag = "1.11"; <co xml:id='ex-dockerTools-pullImage-4' />
sha256 = "0mqjy3zq2v6rrhizgb9nvhczl87lcfphq9601wcprdika2jz7qh8"; <co xml:id='ex-dockerTools-pullImage-5' />
os = "linux"; <co xml:id='ex-dockerTools-pullImage-6' />
arch = "x86_64"; <co xml:id='ex-dockerTools-pullImage-7' />
}
</programlisting>
</example>
<calloutlist>
<callout arearefs='ex-dockerTools-pullImage-1'>
<para>
<varname>imageName</varname> specifies the name of the image to be
downloaded, which can also include the registry namespace (e.g.
<literal>nixos</literal>). This argument is required.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-2'>
<para>
<varname>imageDigest</varname> specifies the digest of the image to be
downloaded. This argument is required.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-3'>
<para>
<varname>finalImageName</varname>, if specified, this is the name of the
image to be created. Note it is never used to fetch the image since we
prefer to rely on the immutable digest ID. By default it's equal to
<varname>imageName</varname>.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-4'>
<para>
<varname>finalImageTag</varname>, if specified, this is the tag of the
image to be created. Note it is never used to fetch the image since we
prefer to rely on the immutable digest ID. By default it's
<literal>latest</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-5'>
<para>
<varname>sha256</varname> is the checksum of the whole fetched image. This
argument is required.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-6'>
<para>
<varname>os</varname>, if specified, is the operating system of the
fetched image. By default it's <literal>linux</literal>.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-7'>
<para>
<varname>arch</varname>, if specified, is the cpu architecture of the
fetched image. By default it's <literal>x86_64</literal>.
</para>
</callout>
</calloutlist>
<para>
<literal>nix-prefetch-docker</literal> command can be used to get required
image parameters:
<programlisting>
$ nix run nixpkgs.nix-prefetch-docker -c nix-prefetch-docker --image-name mysql --image-tag 5
</programlisting>
Since a given <varname>imageName</varname> may transparently refer to a
manifest list of images which support multiple architectures and/or
operating systems, you can supply the <option>--os</option> and
<option>--arch</option> arguments to specify exactly which image you want.
By default it will match the OS and architecture of the host the command is
run on.
<programlisting>
$ nix-prefetch-docker --image-name mysql --image-tag 5 --arch x86_64 --os linux
</programlisting>
Desired image name and tag can be set using
<option>--final-image-name</option> and <option>--final-image-tag</option>
arguments:
<programlisting>
$ nix-prefetch-docker --image-name mysql --image-tag 5 --final-image-name eu.gcr.io/my-project/mysql --final-image-tag prod
</programlisting>
</para>
</section>
<section xml:id="ssec-pkgs-dockerTools-exportImage">
<title>exportImage</title>
<para>
This function is analogous to the <command>docker export</command> command,
in that it can be used to flatten a Docker image that contains multiple
layers. It is in fact the result of the merge of all the layers of the
image. As such, the result is suitable for being imported in Docker with
<command>docker import</command>.
</para>
<note>
<para>
Using this function requires the <literal>kvm</literal> device to be
available.
</para>
</note>
<para>
The parameters of <varname>exportImage</varname> are the following:
</para>
<example xml:id='ex-dockerTools-exportImage'>
<title>Docker export</title>
<programlisting>
exportImage {
fromImage = someLayeredImage;
fromImageName = null;
fromImageTag = null;
name = someLayeredImage.name;
}
</programlisting>
</example>
<para>
The parameters relative to the base image have the same synopsis as
described in <xref linkend='ssec-pkgs-dockerTools-buildImage'/>, except that
<varname>fromImage</varname> is the only required argument in this case.
</para>
<para>
The <varname>name</varname> argument is the name of the derivation output,
which defaults to <varname>fromImage.name</varname>.
</para>
</section>
<section xml:id="ssec-pkgs-dockerTools-shadowSetup">
<title>shadowSetup</title>
<para>
This constant string is a helper for setting up the base files for managing
users and groups, only if such files don't exist already. It is suitable for
being used in a <varname>runAsRoot</varname>
<xref linkend='ex-dockerTools-buildImage-runAsRoot'/> script for cases like
in the example below:
</para>
<example xml:id='ex-dockerTools-shadowSetup'>
<title>Shadow base files</title>
<programlisting>
buildImage {
name = "shadow-basic";
runAsRoot = ''
#!${pkgs.runtimeShell}
${shadowSetup}
groupadd -r redis
useradd -r -g redis redis
mkdir /data
chown redis:redis /data
'';
}
</programlisting>
</example>
<para>
Creating base files like <literal>/etc/passwd</literal> or
<literal>/etc/login.defs</literal> is necessary for shadow-utils to
manipulate users and groups.
</para>
</section>
</section>

194
doc/functions/fetchers.xml Normal file
View File

@ -0,0 +1,194 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-pkgs-fetchers">
<title>Fetcher functions</title>
<para>
When using Nix, you will frequently need to download source code and other
files from the internet. Nixpkgs comes with a few helper functions that allow
you to fetch fixed-output derivations in a structured way.
</para>
<para>
The two fetcher primitives are <function>fetchurl</function> and
<function>fetchzip</function>. Both of these have two required arguments, a
URL and a hash. The hash is typically <literal>sha256</literal>, although
many more hash algorithms are supported. Nixpkgs contributors are currently
recommended to use <literal>sha256</literal>. This hash will be used by Nix
to identify your source. A typical usage of fetchurl is provided below.
</para>
<programlisting><![CDATA[
{ stdenv, fetchurl }:
stdenv.mkDerivation {
name = "hello";
src = fetchurl {
url = "http://www.example.org/hello.tar.gz";
sha256 = "1111111111111111111111111111111111111111111111111111";
};
}
]]></programlisting>
<para>
The main difference between <function>fetchurl</function> and
<function>fetchzip</function> is in how they store the contents.
<function>fetchurl</function> will store the unaltered contents of the URL
within the Nix store. <function>fetchzip</function> on the other hand will
decompress the archive for you, making files and directories directly
accessible in the future. <function>fetchzip</function> can only be used with
archives. Despite the name, <function>fetchzip</function> is not limited to
.zip files and can also be used with any tarball.
</para>
<para>
<function>fetchpatch</function> works very similarly to
<function>fetchurl</function> with the same arguments expected. It expects
patch files as a source and and performs normalization on them before
computing the checksum. For example it will remove comments or other unstable
parts that are sometimes added by version control systems and can change over
time.
</para>
<para>
Other fetcher functions allow you to add source code directly from a VCS such
as subversion or git. These are mostly straightforward names based on the
name of the command used with the VCS system. Because they give you a working
repository, they act most like <function>fetchzip</function>.
</para>
<variablelist>
<varlistentry>
<term>
<literal>fetchsvn</literal>
</term>
<listitem>
<para>
Used with Subversion. Expects <literal>url</literal> to a Subversion
directory, <literal>rev</literal>, and <literal>sha256</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchgit</literal>
</term>
<listitem>
<para>
Used with Git. Expects <literal>url</literal> to a Git repo,
<literal>rev</literal>, and <literal>sha256</literal>.
<literal>rev</literal> in this case can be full the git commit id (SHA1
hash) or a tag name like <literal>refs/tags/v1.0</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchfossil</literal>
</term>
<listitem>
<para>
Used with Fossil. Expects <literal>url</literal> to a Fossil archive,
<literal>rev</literal>, and <literal>sha256</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchcvs</literal>
</term>
<listitem>
<para>
Used with CVS. Expects <literal>cvsRoot</literal>, <literal>tag</literal>,
and <literal>sha256</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchhg</literal>
</term>
<listitem>
<para>
Used with Mercurial. Expects <literal>url</literal>,
<literal>rev</literal>, and <literal>sha256</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
A number of fetcher functions wrap part of <function>fetchurl</function> and
<function>fetchzip</function>. They are mainly convenience functions intended
for commonly used destinations of source code in Nixpkgs. These wrapper
fetchers are listed below.
</para>
<variablelist>
<varlistentry>
<term>
<literal>fetchFromGitHub</literal>
</term>
<listitem>
<para>
<function>fetchFromGitHub</function> expects four arguments.
<literal>owner</literal> is a string corresponding to the GitHub user or
organization that controls this repository. <literal>repo</literal>
corresponds to the name of the software repository. These are located at
the top of every GitHub HTML page as
<literal>owner</literal>/<literal>repo</literal>. <literal>rev</literal>
corresponds to the Git commit hash or tag (e.g <literal>v1.0</literal>)
that will be downloaded from Git. Finally, <literal>sha256</literal>
corresponds to the hash of the extracted directory. Again, other hash
algorithms are also available but <literal>sha256</literal> is currently
preferred.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromGitLab</literal>
</term>
<listitem>
<para>
This is used with GitLab repositories. The arguments expected are very
similar to fetchFromGitHub above.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromBitbucket</literal>
</term>
<listitem>
<para>
This is used with BitBucket repositories. The arguments expected are very
similar to fetchFromGitHub above.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromSavannah</literal>
</term>
<listitem>
<para>
This is used with Savannah repositories. The arguments expected are very
similar to fetchFromGitHub above.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromRepoOrCz</literal>
</term>
<listitem>
<para>
This is used with repo.or.cz repositories. The arguments expected are very
similar to fetchFromGitHub above.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>

View File

@ -0,0 +1,142 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-fhs-environments">
<title>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 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
temporary lightweight environments which are destroyed after all child
processes exit, without root user rights requirement. Accepted arguments are:
</para>
<variablelist>
<varlistentry>
<term>
<literal>name</literal>
</term>
<listitem>
<para>
Environment name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<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>
</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>
</varlistentry>
<varlistentry>
<term>
<literal>extraBuildCommands</literal>
</term>
<listitem>
<para>
Additional commands to be executed for finalizing the directory structure.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>extraBuildCommandsMulti</literal>
</term>
<listitem>
<para>
Like <literal>extraBuildCommands</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>
One can create a simple environment using a <literal>shell.nix</literal> like
that:
</para>
<programlisting><![CDATA[
{ pkgs ? import <nixpkgs> {} }:
(pkgs.buildFHSUserEnv {
name = "simple-x11-env";
targetPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]) ++ (with pkgs.xorg;
[ libX11
libXcursor
libXrandr
]);
multiPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]);
runScript = "bash";
}).env
]]></programlisting>
<para>
Running <literal>nix-shell</literal> would then drop you into a shell with
these libraries and binaries available. You can use this to run closed-source
applications which expect FHS structure without hassles: simply change
<literal>runScript</literal> to the application path, e.g.
<filename>./bin/start.sh</filename> -- relative paths are supported.
</para>
</section>

View File

@ -0,0 +1,89 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-generators">
<title>Generators</title>
<para>
Generators are functions that create file formats from nix data structures,
e.g. for configuration files. There are generators available for:
<literal>INI</literal>, <literal>JSON</literal> and <literal>YAML</literal>
</para>
<para>
All generators follow a similar call interface: <code>generatorName
configFunctions data</code>, where <literal>configFunctions</literal> is an
attrset of user-defined functions that format nested parts of the content.
They each have common defaults, so often they do not need to be set manually.
An example is <code>mkSectionName ? (name: libStr.escape [ "[" "]" ]
name)</code> from the <literal>INI</literal> generator. It receives the name
of a section and sanitizes it. The default <literal>mkSectionName</literal>
escapes <literal>[</literal> and <literal>]</literal> with a backslash.
</para>
<para>
Generators can be fine-tuned to produce exactly the file format required by
your application/service. One example is an INI-file format which uses
<literal>: </literal> as separator, the strings
<literal>"yes"</literal>/<literal>"no"</literal> as boolean values and
requires all string values to be quoted:
</para>
<programlisting>
with lib;
let
customToINI = generators.toINI {
# specifies how to format a key/value pair
mkKeyValue = generators.mkKeyValueDefault {
# specifies the generated string for a subset of nix values
mkValueString = v:
if v == true then ''"yes"''
else if v == false then ''"no"''
else if isString v then ''"${v}"''
# and delegats all other values to the default generator
else generators.mkValueStringDefault {} v;
} ":";
};
# the INI file can now be given as plain old nix values
in customToINI {
main = {
pushinfo = true;
autopush = false;
host = "localhost";
port = 42;
};
mergetool = {
merge = "diff3";
};
}
</programlisting>
<para>
This will produce the following INI file as nix string:
</para>
<programlisting>
[main]
autopush:"no"
host:"localhost"
port:42
pushinfo:"yes"
str\:ange:"very::strange"
[mergetool]
merge:"diff3"
</programlisting>
<note>
<para>
Nix store paths can be converted to strings by enclosing a derivation
attribute like so: <code>"${drv}"</code>.
</para>
</note>
<para>
Detailed documentation for each generator can be found in
<literal>lib/generators.nix</literal>.
</para>
</section>

29
doc/functions/library.xml Normal file
View File

@ -0,0 +1,29 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-functions-library">
<title>Nixpkgs Library Functions</title>
<para>
Nixpkgs provides a standard library at <varname>pkgs.lib</varname>, or
through <code>import &lt;nixpkgs/lib&gt;</code>.
</para>
<xi:include href="./library/asserts.xml" />
<xi:include href="./library/attrsets.xml" />
<!-- These docs are generated via nixdoc. To add another generated
library function file to this list, the file
`lib-function-docs.nix` must also be updated. -->
<xi:include href="./library/generated/strings.xml" />
<xi:include href="./library/generated/trivial.xml" />
<xi:include href="./library/generated/lists.xml" />
<xi:include href="./library/generated/debug.xml" />
<xi:include href="./library/generated/options.xml" />
</section>

View File

@ -0,0 +1,117 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-functions-library-asserts">
<title>Assert functions</title>
<section xml:id="function-library-lib.asserts.assertMsg">
<title><function>lib.asserts.assertMsg</function></title>
<subtitle><literal>assertMsg :: Bool -> String -> Bool</literal>
</subtitle>
<xi:include href="./locations.xml" xpointer="lib.asserts.assertMsg" />
<para>
Print a trace message if <literal>pred</literal> is false.
</para>
<para>
Intended to be used to augment asserts with helpful error messages.
</para>
<variablelist>
<varlistentry>
<term>
<varname>pred</varname>
</term>
<listitem>
<para>
Condition under which the <varname>msg</varname> should
<emphasis>not</emphasis> be printed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>msg</varname>
</term>
<listitem>
<para>
Message to print.
</para>
</listitem>
</varlistentry>
</variablelist>
<example xml:id="function-library-lib.asserts.assertMsg-example-false">
<title>Printing when the predicate is false</title>
<programlisting><![CDATA[
assert lib.asserts.assertMsg ("foo" == "bar") "foo is not bar, silly"
stderr> trace: foo is not bar, silly
stderr> assert failed
]]></programlisting>
</example>
</section>
<section xml:id="function-library-lib.asserts.assertOneOf">
<title><function>lib.asserts.assertOneOf</function></title>
<subtitle><literal>assertOneOf :: String -> String ->
StringList -> Bool</literal>
</subtitle>
<xi:include href="./locations.xml" xpointer="lib.asserts.assertOneOf" />
<para>
Specialized <function>asserts.assertMsg</function> for checking if
<varname>val</varname> is one of the elements of <varname>xs</varname>.
Useful for checking enums.
</para>
<variablelist>
<varlistentry>
<term>
<varname>name</varname>
</term>
<listitem>
<para>
The name of the variable the user entered <varname>val</varname> into,
for inclusion in the error message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>val</varname>
</term>
<listitem>
<para>
The value of what the user provided, to be compared against the values in
<varname>xs</varname>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>xs</varname>
</term>
<listitem>
<para>
The list of valid values.
</para>
</listitem>
</varlistentry>
</variablelist>
<example xml:id="function-library-lib.asserts.assertOneOf-example">
<title>Ensuring a user provided a possible value</title>
<programlisting><![CDATA[
let sslLibrary = "bearssl";
in lib.asserts.assertOneOf "sslLibrary" sslLibrary [ "openssl" "bearssl" ];
=> false
stderr> trace: sslLibrary must be one of "openssl", "libressl", but is: "bearssl"
]]></programlisting>
</example>
</section>
</section>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-pkgs-nix-gitignore">
<title>pkgs.nix-gitignore</title>
<para>
<function>pkgs.nix-gitignore</function> is a function that acts similarly to
<literal>builtins.filterSource</literal> but also allows filtering with the
help of the gitignore format.
</para>
<section xml:id="sec-pkgs-nix-gitignore-usage">
<title>Usage</title>
<para>
<literal>pkgs.nix-gitignore</literal> exports a number of functions, but
you'll most likely need either <literal>gitignoreSource</literal> or
<literal>gitignoreSourcePure</literal>. As their first argument, they both
accept either 1. a file with gitignore lines or 2. a string with gitignore
lines, or 3. a list of either of the two. They will be concatenated into a
single big string.
</para>
<programlisting><![CDATA[
{ pkgs ? import <nixpkgs> {} }:
nix-gitignore.gitignoreSource [] ./source
# Simplest version
nix-gitignore.gitignoreSource "supplemental-ignores\n" ./source
# This one reads the ./source/.gitignore and concats the auxiliary ignores
nix-gitignore.gitignoreSourcePure "ignore-this\nignore-that\n" ./source
# Use this string as gitignore, don't read ./source/.gitignore.
nix-gitignore.gitignoreSourcePure ["ignore-this\nignore-that\n", ~/.gitignore] ./source
# It also accepts a list (of strings and paths) that will be concatenated
# once the paths are turned to strings via readFile.
]]></programlisting>
<para>
These functions are derived from the <literal>Filter</literal> functions by
setting the first filter argument to <literal>(_: _: true)</literal>:
</para>
<programlisting><![CDATA[
gitignoreSourcePure = gitignoreFilterSourcePure (_: _: true);
gitignoreSource = gitignoreFilterSource (_: _: true);
]]></programlisting>
<para>
Those filter functions accept the same arguments the
<literal>builtins.filterSource</literal> function would pass to its filters,
thus <literal>fn: gitignoreFilterSourcePure fn ""</literal> should be
extensionally equivalent to <literal>filterSource</literal>. The file is
blacklisted iff it's blacklisted by either your filter or the
gitignoreFilter.
</para>
<para>
If you want to make your own filter from scratch, you may use
</para>
<programlisting><![CDATA[
gitignoreFilter = ign: root: filterPattern (gitignoreToPatterns ign) root;
]]></programlisting>
</section>
<section xml:id="sec-pkgs-nix-gitignore-usage-recursive">
<title>gitignore files in subdirectories</title>
<para>
If you wish to use a filter that would search for .gitignore files in
subdirectories, just like git does by default, use this function:
</para>
<programlisting><![CDATA[
gitignoreFilterRecursiveSource = filter: patterns: root:
# OR
gitignoreRecursiveSource = gitignoreFilterSourcePure (_: _: true);
]]></programlisting>
</section>
</section>

212
doc/functions/overrides.xml Normal file
View File

@ -0,0 +1,212 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-overrides">
<title>Overriding</title>
<para>
Sometimes one wants to override parts of <literal>nixpkgs</literal>, e.g.
derivation attributes, the results of derivations.
</para>
<para>
These functions are used to make changes to packages, returning only single
packages. <link xlink:href="#chap-overlays">Overlays</link>, on the other
hand, can be used to combine the overridden packages across the entire
package set of Nixpkgs.
</para>
<section xml:id="sec-pkg-override">
<title>&lt;pkg&gt;.override</title>
<para>
The function <varname>override</varname> is usually available for all the
derivations in the nixpkgs expression (<varname>pkgs</varname>).
</para>
<para>
It is used to override the arguments passed to a function.
</para>
<para>
Example usages:
<programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
<!-- TODO: move below programlisting to a new section about extending and overlays
and reference it
-->
<programlisting>
import pkgs.path { overlays = [ (self: super: {
foo = super.foo.override { barSupport = true ; };
})]};
</programlisting>
<programlisting>
mypkg = pkgs.callPackage ./mypkg.nix {
mydep = pkgs.mydep.override { ... };
}
</programlisting>
</para>
<para>
In the first example, <varname>pkgs.foo</varname> is the result of a
function call with some default arguments, usually a derivation. Using
<varname>pkgs.foo.override</varname> will call the same function with the
given new arguments.
</para>
</section>
<section xml:id="sec-pkg-overrideAttrs">
<title>&lt;pkg&gt;.overrideAttrs</title>
<para>
The function <varname>overrideAttrs</varname> allows overriding the
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
producing a new derivation based on the original one. This function is
available on all derivations produced by the
<varname>stdenv.mkDerivation</varname> function, which is most packages in
the nixpkgs expression <varname>pkgs</varname>.
</para>
<para>
Example usage:
<programlisting>
helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
separateDebugInfo = true;
});
</programlisting>
</para>
<para>
In the above example, the <varname>separateDebugInfo</varname> attribute is
overridden to be true, thus building debug info for
<varname>helloWithDebug</varname>, while all other attributes will be
retained from the original <varname>hello</varname> package.
</para>
<para>
The argument <varname>oldAttrs</varname> is conventionally used to refer to
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
</para>
<note>
<para>
Note that <varname>separateDebugInfo</varname> is processed only by the
<varname>stdenv.mkDerivation</varname> function, not the generated, raw Nix
derivation. Thus, using <varname>overrideDerivation</varname> will not work
in this case, as it overrides only the attributes of the final derivation.
It is for this reason that <varname>overrideAttrs</varname> should be
preferred in (almost) all cases to <varname>overrideDerivation</varname>,
i.e. to allow using <varname>stdenv.mkDerivation</varname> to process input
arguments, as well as the fact that it is easier to use (you can use the
same attribute names you see in your Nix code, instead of the ones
generated (e.g. <varname>buildInputs</varname> vs
<varname>nativeBuildInputs</varname>), and it involves less typing).
</para>
</note>
</section>
<section xml:id="sec-pkg-overrideDerivation">
<title>&lt;pkg&gt;.overrideDerivation</title>
<warning>
<para>
You should prefer <varname>overrideAttrs</varname> in almost all cases, see
its documentation for the reasons why.
<varname>overrideDerivation</varname> is not deprecated and will continue
to work, but is less nice to use and does not have as many abilities as
<varname>overrideAttrs</varname>.
</para>
</warning>
<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>~/.config/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.
</para>
<para>
Example usage:
<programlisting>
mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
name = "sed-4.2.2-pre";
src = fetchurl {
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
};
patches = [];
});
</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.
</para>
<para>
The argument <varname>oldAttrs</varname> is used to refer to the attribute
set of 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">
<title>lib.makeOverridable</title>
<para>
The function <varname>lib.makeOverridable</varname> is used to make the
result of a function easily customizable. This utility only makes sense for
functions that accept an argument set and return an attribute set.
</para>
<para>
Example usage:
<programlisting>
f = { a, b }: { result = a+b; };
c = lib.makeOverridable f { a = 1; b = 2; };
</programlisting>
</para>
<para>
The variable <varname>c</varname> is the value of the <varname>f</varname>
function applied with some default arguments. Hence the value of
<varname>c.result</varname> is <literal>3</literal>, in this example.
</para>
<para>
The variable <varname>c</varname> however also has some additional
functions, like <link linkend="sec-pkg-override">c.override</link> which can
be used to override the default arguments. In this example the value of
<varname>(c.override { a = 4; }).result</varname> is 6.
</para>
</section>
</section>

View File

@ -0,0 +1,25 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/xinclude"
xml:id="sec-prefer-remote-fetch">
<title>prefer-remote-fetch overlay</title>
<para>
<function>prefer-remote-fetch</function> is an overlay that download sources
on remote builder. This is useful when the evaluating machine has a slow
upload while the builder can fetch faster directly from the source. To use
it, put the following snippet as a new overlay:
<programlisting>
self: super:
(super.prefer-remote-fetch self super)
</programlisting>
A full configuration example for that sets the overlay up for your own
account, could look like this
<programlisting>
$ mkdir ~/.config/nixpkgs/overlays/
$ cat &gt; ~/.config/nixpkgs/overlays/prefer-remote-fetch.nix &lt;&lt;EOF
self: super: super.prefer-remote-fetch self super
EOF
</programlisting>
</para>
</section>

26
doc/functions/shell.xml Normal file
View File

@ -0,0 +1,26 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-pkgs-mkShell">
<title>pkgs.mkShell</title>
<para>
<function>pkgs.mkShell</function> is a special kind of derivation that is
only useful when using it combined with <command>nix-shell</command>. It will
in fact fail to instantiate when invoked with <command>nix-build</command>.
</para>
<section xml:id="sec-pkgs-mkShell-usage">
<title>Usage</title>
<programlisting><![CDATA[
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# this will make all the build inputs from hello and gnutar
# available to the shell environment
inputsFrom = with pkgs; [ hello gnutar ];
buildInputs = [ pkgs.gnumake ];
}
]]></programlisting>
</section>
</section>

View File

@ -0,0 +1,113 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-trivial-builders">
<title>Trivial builders</title>
<para>
Nixpkgs provides a couple of functions that help with building derivations.
The most important one, <function>stdenv.mkDerivation</function>, has already
been documented above. The following functions wrap
<function>stdenv.mkDerivation</function>, making it easier to use in certain
cases.
</para>
<variablelist>
<varlistentry>
<term>
<literal>runCommand</literal>
</term>
<listitem>
<para>
This takes three arguments, <literal>name</literal>,
<literal>env</literal>, and <literal>buildCommand</literal>.
<literal>name</literal> is just the name that Nix will append to the store
path in the same way that <literal>stdenv.mkDerivation</literal> uses its
<literal>name</literal> attribute. <literal>env</literal> is an attribute
set specifying environment variables that will be set for this derivation.
These attributes are then passed to the wrapped
<literal>stdenv.mkDerivation</literal>. <literal>buildCommand</literal>
specifies the commands that will be run to create this derivation. Note
that you will need to create <literal>$out</literal> for Nix to register
the command as successful.
</para>
<para>
An example of using <literal>runCommand</literal> is provided below.
</para>
<programlisting>
(import &lt;nixpkgs&gt; {}).runCommand "my-example" {} ''
echo My example command is running
mkdir $out
echo I can write data to the Nix store > $out/message
echo I can also run basic commands like:
echo ls
ls
echo whoami
whoami
echo date
date
''
</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>runCommandCC</literal>
</term>
<listitem>
<para>
This works just like <literal>runCommand</literal>. The only difference is
that it also provides a C compiler in <literal>buildCommand</literal>s
environment. To minimize your dependencies, you should only use this if
you are sure you will need a C compiler as part of running your command.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>writeTextFile</literal>, <literal>writeText</literal>, <literal>writeTextDir</literal>, <literal>writeScript</literal>, <literal>writeScriptBin</literal>
</term>
<listitem>
<para>
These functions write <literal>text</literal> to the Nix store. This is
useful for creating scripts from Nix expressions.
<literal>writeTextFile</literal> takes an attribute set and expects two
arguments, <literal>name</literal> and <literal>text</literal>.
<literal>name</literal> corresponds to the name used in the Nix store
path. <literal>text</literal> will be the contents of the file. You can
also set <literal>executable</literal> to true to make this file have the
executable bit set.
</para>
<para>
Many more commands wrap <literal>writeTextFile</literal> including
<literal>writeText</literal>, <literal>writeTextDir</literal>,
<literal>writeScript</literal>, and <literal>writeScriptBin</literal>.
These are convenience functions over <literal>writeTextFile</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>symlinkJoin</literal>
</term>
<listitem>
<para>
This can be used to put many derivations into the same directory
structure. It works by creating a new derivation and adding symlinks to
each of the paths listed. It expects two arguments,
<literal>name</literal>, and <literal>paths</literal>.
<literal>name</literal> is the name used in the Nix store path for the
created derivation. <literal>paths</literal> is a list of paths that will
be symlinked. These paths can be to Nix store derivations or any other
subdirectory contained within.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>

View File

@ -0,0 +1,240 @@
---
title: Android
author: Sander van der Burg
date: 2018-11-18
---
# Android
The Android build environment provides three major features and a number of
supporting features.
Deploying an Android SDK installation with plugins
--------------------------------------------------
The first use case is deploying the SDK with a desired set of plugins or subsets
of an SDK.
```nix
with import <nixpkgs> {};
let
androidComposition = androidenv.composeAndroidPackages {
toolsVersion = "25.2.5";
platformToolsVersion = "27.0.1";
buildToolsVersions = [ "27.0.3" ];
includeEmulator = false;
emulatorVersion = "27.2.0";
platformVersions = [ "24" ];
includeSources = false;
includeDocs = false;
includeSystemImages = false;
systemImageTypes = [ "default" ];
abiVersions = [ "armeabi-v7a" ];
lldbVersions = [ "2.0.2558144" ];
cmakeVersions = [ "3.6.4111459" ];
includeNDK = false;
ndkVersion = "16.1.4479499";
useGoogleAPIs = false;
useGoogleTVAddOns = false;
includeExtras = [
"extras;google;gcm"
];
};
in
androidComposition.androidsdk
```
The above function invocation states that we want an Android SDK with the above
specified plugin versions. By default, most plugins are disabled. Notable
exceptions are the tools, platform-tools and build-tools sub packages.
The following parameters are supported:
* `toolsVersion`, specifies the version of the tools package to use
* `platformsToolsVersion` specifies the version of the `platform-tools` plugin
* `buildToolsVersion` specifies the versions of the `build-tools` plugins to
use.
* `includeEmulator` specifies whether to deploy the emulator package (`false`
by default). When enabled, the version of the emulator to deploy can be
specified by setting the `emulatorVersion` parameter.
* `includeDocs` specifies whether the documentation catalog should be included.
* `lldbVersions` specifies what LLDB versions should be deployed.
* `cmakeVersions` specifies which CMake versions should be deployed.
* `includeNDK` specifies that the Android NDK bundle should be included.
Defaults to: `false`.
* `ndkVersion` specifies the NDK version that we want to use.
* `includeExtras` is an array of identifier strings referring to arbitrary
add-on packages that should be installed.
* `platformVersions` specifies which platform SDK versions should be included.
For each platform version that has been specified, we can apply the following
options:
* `includeSystemImages` specifies whether a system image for each platform SDK
should be included.
* `includeSources` specifies whether the sources for each SDK version should be
included.
* `useGoogleAPIs` specifies that for each selected platform version the
Google API should be included.
* `useGoogleTVAddOns` specifies that for each selected platform version the
Google TV add-on should be included.
For each requested system image we can specify the following options:
* `systemImageTypes` specifies what kind of system images should be included.
Defaults to: `default`.
* `abiVersions` specifies what kind of ABI version of each system image should
be included. Defaults to: `armeabi-v7a`.
Most of the function arguments have reasonable default settings.
When building the above expression with:
```bash
$ nix-build
```
The Android SDK gets deployed with all desired plugin versions.
We can also deploy subsets of the Android SDK. For example, to only the the
`platform-tools` package, you can evaluate the following expression:
```nix
with import <nixpkgs> {};
let
androidComposition = androidenv.composeAndroidPackages {
# ...
};
in
androidComposition.platform-tools
```
Using predefine Android package compositions
--------------------------------------------
In addition to composing an Android package set manually, it is also possible
to use a predefined composition that contains all basic packages for a specific
Android version, such as version 9.0 (API-level 28).
The following Nix expression can be used to deploy the entire SDK with all basic
plugins:
```nix
with import <nixpkgs> {};
androidenv.androidPkgs_9_0.androidsdk
```
It is also possible to use one plugin only:
```nix
with import <nixpkgs> {};
androidenv.androidPkgs_9_0.platform-tools
```
Building an Android application
-------------------------------
In addition to the SDK, it is also possible to build an Ant-based Android
project and automatically deploy all the Android plugins that a project
requires.
```nix
with import <nixpkgs> {};
androidenv.buildApp {
name = "MyAndroidApp";
src = ./myappsources;
release = true;
# If release is set to true, you need to specify the following parameters
keyStore = ./keystore;
keyAlias = "myfirstapp";
keyStorePassword = "mykeystore";
keyAliasPassword = "myfirstapp";
# Any Android SDK parameters that install all the relevant plugins that a
# build requires
platformVersions = [ "24" ];
# When we include the NDK, then ndk-build is invoked before Ant gets invoked
includeNDK = true;
}
```
Aside from the app-specific build parameters (`name`, `src`, `release` and
keystore parameters), the `buildApp {}` function supports all the function
parameters that the SDK composition function (the function shown in the
previous section) supports.
This build function is particularly useful when it is desired to use
[Hydra](http://nixos.org/hydra): the Nix-based continuous integration solution
to build Android apps. An Android APK gets exposed as a build product and can be
installed on any Android device with a web browser by navigating to the build
result page.
Spawning emulator instances
---------------------------
For testing purposes, it can also be quite convenient to automatically generate
scripts that spawn emulator instances with all desired configuration settings.
An emulator spawn script can be configured by invoking the `emulateApp {}`
function:
```nix
with import <nixpkgs> {};
androidenv.emulateApp {
name = "emulate-MyAndroidApp";
platformVersion = "24";
abiVersion = "armeabi-v7a"; # mips, x86 or x86_64
systemImageType = "default";
useGoogleAPIs = false;
}
```
It is also possible to specify an APK to deploy inside the emulator
and the package and activity names to launch it:
```nix
with import <nixpkgs> {};
androidenv.emulateApp {
name = "emulate-MyAndroidApp";
platformVersion = "24";
abiVersion = "armeabi-v7a"; # mips, x86 or x86_64
systemImageType = "default";
useGoogleAPIs = false;
app = ./MyApp.apk;
package = "MyApp";
activity = "MainActivity";
}
```
In addition to prebuilt APKs, you can also bind the APK parameter to a
`buildApp {}` function invocation shown in the previous example.
Querying the available versions of each plugin
----------------------------------------------
When using any of the previously shown functions, it may be a bit inconvenient
to find out what options are supported, since the Android SDK provides many
plugins.
A shell script in the `pkgs/development/mobile/androidenv/` sub directory can be used to retrieve all
possible options:
```bash
sh ./querypackages.sh packages build-tools
```
The above command-line instruction queries all build-tools versions in the
generated `packages.nix` expression.
Updating the generated expressions
----------------------------------
Most of the Nix expressions are generated from XML files that the Android
package manager uses. To update the expressions run the `generate.sh` script
that is stored in the `pkgs/development/mobile/androidenv/` sub directory:
```bash
sh ./generate.sh
```

View File

@ -11,10 +11,9 @@
</para>
<para>
Some libraries require OCaml and sometimes also Camlp5 or findlib. The exact
versions that were used to build Coq are saved in the
<literal>coq.ocaml</literal> and <literal>coq.camlp5</literal> and
<literal>coq.findlib</literal> attributes.
Some extensions (plugins) might require OCaml and sometimes other OCaml
packages. The <literal>coq.ocamlPackages</literal> attribute can be used to
depend on the same package set Coq was built against.
</para>
<para>

View File

@ -3,12 +3,91 @@
xml:id="sec-language-go">
<title>Go</title>
<para>
The function <varname>buildGoPackage</varname> builds standard Go programs.
</para>
<section xml:id="ssec-go-modules">
<title>Go modules</title>
<example xml:id='ex-buildGoPackage'>
<title>buildGoPackage</title>
<para>
The function <varname> buildGoModule </varname> builds Go programs managed
with Go modules. It builds a
<link xlink:href="https://github.com/golang/go/wiki/Modules">Go
modules</link> through a two phase build:
<itemizedlist>
<listitem>
<para>
An intermediate fetcher derivation. This derivation will be used to fetch
all of the dependencies of the Go module.
</para>
</listitem>
<listitem>
<para>
A final derivation will use the output of the intermediate derivation to
build the binaries and produce the final output.
</para>
</listitem>
</itemizedlist>
</para>
<example xml:id='ex-buildGoModule'>
<title>buildGoModule</title>
<programlisting>
pet = buildGoModule rec {
name = "pet-${version}";
version = "0.3.4";
src = fetchFromGitHub {
owner = "knqyf263";
repo = "pet";
rev = "v${version}";
sha256 = "0m2fzpqxk7hrbxsgqplkg7h2p7gv6s1miymv3gvw0cz039skag0s";
};
modSha256 = "1879j77k96684wi554rkjxydrj8g3hpp0kvxz03sd8dmwr3lh83j"; <co xml:id='ex-buildGoModule-1' />
subPackages = [ "." ]; <co xml:id='ex-buildGoModule-2' />
meta = with lib; {
description = "Simple command-line snippet manager, written in Go";
homepage = https://github.com/knqyf263/pet;
license = licenses.mit;
maintainers = with maintainers; [ kalbasit ];
platforms = platforms.linux ++ platforms.darwin;
};
}
</programlisting>
</example>
<para>
<xref linkend='ex-buildGoModule'/> is an example expression using
buildGoModule, the following arguments are of special significance to the
function:
<calloutlist>
<callout arearefs='ex-buildGoModule-1'>
<para>
<varname>modSha256</varname> is the hash of the output of the
intermediate fetcher derivation.
</para>
</callout>
<callout arearefs='ex-buildGoModule-2'>
<para>
<varname>subPackages</varname> limits the builder from building child
packages that have not been listed. If <varname>subPackages</varname> is
not specified, all child packages will be built.
</para>
</callout>
</calloutlist>
</para>
</section>
<section xml:id="ssec-go-legacy">
<title>Go legacy</title>
<para>
The function <varname> buildGoPackage </varname> builds legacy Go programs,
not supporting Go modules.
</para>
<example xml:id='ex-buildGoPackage'>
<title>buildGoPackage</title>
<programlisting>
deis = buildGoPackage rec {
name = "deis-${version}";
@ -29,56 +108,56 @@ deis = buildGoPackage rec {
buildFlags = "--tags release"; <co xml:id='ex-buildGoPackage-4' />
}
</programlisting>
</example>
</example>
<para>
<xref linkend='ex-buildGoPackage'/> is an example expression using
buildGoPackage, the following arguments are of special significance to the
function:
<calloutlist>
<callout arearefs='ex-buildGoPackage-1'>
<para>
<varname>goPackagePath</varname> specifies the package's canonical Go
import path.
</para>
</callout>
<callout arearefs='ex-buildGoPackage-2'>
<para>
<varname>subPackages</varname> limits the builder from building child
packages that have not been listed. If <varname>subPackages</varname> is
not specified, all child packages will be built.
</para>
<para>
In this example only <literal>github.com/deis/deis/client</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.
</para>
</callout>
<callout arearefs='ex-buildGoPackage-4'>
<para>
<varname>buildFlags</varname> is a list of flags passed to the go build
command.
</para>
</callout>
</calloutlist>
</para>
<para>
<xref linkend='ex-buildGoPackage'/> is an example expression using
buildGoPackage, the following arguments are of special significance to the
function:
<calloutlist>
<callout arearefs='ex-buildGoPackage-1'>
<para>
<varname>goPackagePath</varname> specifies the package's canonical Go
import path.
</para>
</callout>
<callout arearefs='ex-buildGoPackage-2'>
<para>
<varname>subPackages</varname> limits the builder from building child
packages that have not been listed. If <varname>subPackages</varname> is
not specified, all child packages will be built.
</para>
<para>
In this example only <literal>github.com/deis/deis/client</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.
</para>
</callout>
<callout arearefs='ex-buildGoPackage-4'>
<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>
<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>
<example xml:id='ex-goDeps'>
<title>deps.nix</title>
<programlisting>
[ <co xml:id='ex-goDeps-1' />
{
@ -101,60 +180,62 @@ deis = buildGoPackage rec {
}
]
</programlisting>
</example>
</example>
<para>
<calloutlist>
<callout arearefs='ex-goDeps-1'>
<para>
<varname>goDeps</varname> is a list of Go dependencies.
</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.
</para>
</callout>
</calloutlist>
</para>
<para>
<calloutlist>
<callout arearefs='ex-goDeps-1'>
<para>
<varname>goDeps</varname> is a list of Go dependencies.
</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.
</para>
</callout>
</calloutlist>
</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/kamilchm/go2nix">go2nix</link>. It can
produce complete derivation and <varname>goDeps</varname> file for Go
programs.
</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:
<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:
<screen>
$ nix-build -A deis.bin
</screen>
or build all outputs with:
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>.
</para>
<varname>bin</varname> output will be installed by default with
<varname>nix-env -i</varname> or <varname>systemPackages</varname>.
</para>
<para>
You may use Go packages installed into the active Nix profiles by adding the
following to your ~/.bashrc:
<para>
You may use Go packages installed into the active Nix profiles by adding the
following to your ~/.bashrc:
<screen>
for p in $NIX_PROFILES; do
GOPATH="$p/share/go:$GOPATH"
done
</screen>
</para>
</para>
</section>
</section>

View File

@ -55,7 +55,7 @@ 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].
create a development environment](#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
@ -127,7 +127,7 @@ Also, the attributes `haskell.compiler.ghcXYC` and
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
[How to install Haskell packages](#how-to-install-haskell-packages) how you can install those programs into your
user profile:
```shell
nix-env -f "<nixpkgs>" -iA haskellPackages.ghc haskellPackages.cabal-install
@ -162,7 +162,7 @@ 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].
See [How to build a Haskell project using Stack](#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
@ -352,9 +352,9 @@ you want them to come from. Add the following to `configuration.nix`.
```nix
services.hoogle = {
enable = true;
packages = (hpkgs: with hpkgs; [text cryptonite]);
haskellPackages = pkgs.haskellPackages;
enable = true;
packages = (hpkgs: with hpkgs; [text cryptonite]);
haskellPackages = pkgs.haskellPackages;
};
```
@ -366,7 +366,7 @@ 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.
```shell
git clone --recursive http://github.com/yesodweb/wai
git clone --recursive https://github.com/yesodweb/wai
cd wai
stack --nix build
```
@ -935,7 +935,7 @@ The implementation can be found in the
[integer-gmp](http://hackage.haskell.org/package/integer-gmp) package.
A potential problem with this is that GMP is licensed under the
[GNU Lesser General Public License (LGPL)](http://www.gnu.org/copyleft/lesser.html),
[GNU Lesser General Public License (LGPL)](https://www.gnu.org/copyleft/lesser.html),
a kind of "copyleft" license. According to the terms of the LGPL, paragraph 5,
you may distribute a program that is designed to be compiled and dynamically
linked with the library under the terms of your choice (i.e., commercially) but

View File

@ -1,39 +1,115 @@
Idris packages
==============
# Idris packages
This directory contains build rules for idris packages. In addition,
it contains several functions to build and compose those packages.
Everything is exposed to the user via the `idrisPackages` attribute.
## Installing Idris
callPackage
------------
The easiest way to get a working idris version is to install the `idris` attribute:
This is like the normal nixpkgs callPackage function, specialized to
idris packages.
```
$ # On NixOS
$ nix-env -i nixos.idris
$ # On non-NixOS
$ nix-env -i nixpkgs.idris
```
builtins
---------
This however only provides the `prelude` and `base` libraries. To install additional libraries:
This is a list of all of the libraries that come packaged with Idris
itself.
```
$ nix-env -iE 'pkgs: pkgs.idrisPackages.with-packages (with pkgs.idrisPackages; [ contrib pruviloj ])'
```
build-idris-package
--------------------
To see all available Idris packages:
```
$ # On NixOS
$ nix-env -qaPA nixos.idrisPackages
$ # On non-NixOS
$ nix-env -qaPA nixpkgs.idrisPackages
```
A function to build an idris package. Its sole argument is a set like
you might pass to `stdenv.mkDerivation`, except `build-idris-package`
sets several attributes for you. See `build-idris-package.nix` for
details.
Similarly, entering a `nix-shell`:
```
$ nix-shell -p 'idrisPackages.with-packages (with idrisPackages; [ contrib pruviloj ])'
```
build-builtin-package
----------------------
## Starting Idris with library support
A version of `build-idris-package` specialized to builtin libraries.
Mostly for internal use.
To have access to these libraries in idris, call it with an argument `-p <library name>` for each library:
with-packages
-------------
```
$ nix-shell -p 'idrisPackages.with-packages (with idrisPackages; [ contrib pruviloj ])'
[nix-shell:~]$ idris -p contrib -p pruviloj
```
Bundle idris together with a list of packages. Because idris currently
only supports a single directory in its library path, you must include
all desired libraries here, including `prelude` and `base`.
A listing of all available packages the Idris binary has access to is available via `--listlibs`:
```
$ idris --listlibs
00prelude-idx.ibc
pruviloj
base
contrib
prelude
00pruviloj-idx.ibc
00base-idx.ibc
00contrib-idx.ibc
```
## Building an Idris project with Nix
As an example of how a Nix expression for an Idris package can be created, here is the one for `idrisPackages.yaml`:
```nix
{ build-idris-package
, fetchFromGitHub
, contrib
, lightyear
, lib
}:
build-idris-package {
name = "yaml";
version = "2018-01-25";
# This is the .ipkg file that should be built, defaults to the package name
# In this case it should build `Yaml.ipkg` instead of `yaml.ipkg`
# This is only necessary because the yaml packages ipkg file is
# different from its package name here.
ipkgName = "Yaml";
# Idris dependencies to provide for the build
idrisDeps = [ contrib lightyear ];
src = fetchFromGitHub {
owner = "Heather";
repo = "Idris.Yaml";
rev = "5afa51ffc839844862b8316faba3bafa15656db4";
sha256 = "1g4pi0swmg214kndj85hj50ccmckni7piprsxfdzdfhg87s0avw7";
};
meta = {
description = "Idris YAML lib";
homepage = https://github.com/Heather/Idris.Yaml;
license = lib.licenses.mit;
maintainers = [ lib.maintainers.brainrape ];
};
}
```
Assuming this file is saved as `yaml.nix`, it's buildable using
```
$ nix-build -E '(import <nixpkgs> {}).idrisPackages.callPackage ./yaml.nix {}'
```
Or it's possible to use
```nix
with import <nixpkgs> {};
{
yaml = idrisPackages.callPackage ./yaml.nix {};
}
```
in another file (say `default.nix`) to be able to build it with
```
$ nix-build -A yaml
```

View File

@ -10,15 +10,18 @@
Nixpkgs to easily build packages for other programming languages, such as
Perl or Haskell. These are described in this chapter.
</para>
<xi:include href="android.section.xml" />
<xi:include href="beam.xml" />
<xi:include href="bower.xml" />
<xi:include href="coq.xml" />
<xi:include href="go.xml" />
<xi:include href="haskell.section.xml" />
<xi:include href="idris.section.xml" />
<xi:include href="ios.section.xml" />
<xi:include href="java.xml" />
<xi:include href="lua.xml" />
<xi:include href="node.section.xml" />
<xi:include href="ocaml.xml" />
<xi:include href="perl.xml" />
<xi:include href="python.section.xml" />
<xi:include href="qt.xml" />
@ -26,6 +29,7 @@
<xi:include href="ruby.xml" />
<xi:include href="rust.section.xml" />
<xi:include href="texlive.xml" />
<xi:include href="titanium.section.xml" />
<xi:include href="vim.section.xml" />
<xi:include href="emscripten.section.xml" />
</chapter>

View File

@ -0,0 +1,219 @@
---
title: iOS
author: Sander van der Burg
date: 2018-11-18
---
# iOS
This component is basically a wrapper/workaround that makes it possible to
expose an Xcode installation as a Nix package by means of symlinking to the
relevant executables on the host system.
Since Xcode can't be packaged with Nix, nor we can publish it as a Nix package
(because of its license) this is basically the only integration strategy
making it possible to do iOS application builds that integrate with other
components of the Nix ecosystem
The primary objective of this project is to use the Nix expression language to
specify how iOS apps can be built from source code, and to automatically spawn
iOS simulator instances for testing.
This component also makes it possible to use [Hydra](http://nixos.org/hydra),
the Nix-based continuous integration server to regularly build iOS apps and to
do wireless ad-hoc installations of enterprise IPAs on iOS devices through
Hydra.
The Xcode build environment implements a number of features.
Deploying a proxy component wrapper exposing Xcode
--------------------------------------------------
The first use case is deploying a Nix package that provides symlinks to the Xcode
installation on the host system. This package can be used as a build input to
any build function implemented in the Nix expression language that requires
Xcode.
```nix
let
pkgs = import <nixpkgs> {};
xcodeenv = import ./xcodeenv {
inherit (pkgs) stdenv;
};
in
xcodeenv.composeXcodeWrapper {
version = "9.2";
xcodeBaseDir = "/Applications/Xcode.app";
}
```
By deploying the above expression with `nix-build` and inspecting its content
you will notice that several Xcode-related executables are exposed as a Nix
package:
```bash
$ ls result/bin
lrwxr-xr-x 1 sander staff 94 1 jan 1970 Simulator -> /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator
lrwxr-xr-x 1 sander staff 17 1 jan 1970 codesign -> /usr/bin/codesign
lrwxr-xr-x 1 sander staff 17 1 jan 1970 security -> /usr/bin/security
lrwxr-xr-x 1 sander staff 21 1 jan 1970 xcode-select -> /usr/bin/xcode-select
lrwxr-xr-x 1 sander staff 61 1 jan 1970 xcodebuild -> /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
lrwxr-xr-x 1 sander staff 14 1 jan 1970 xcrun -> /usr/bin/xcrun
```
Building an iOS application
---------------------------
We can build an iOS app executable for the simulator, or an IPA/xcarchive file
for release purposes, e.g. ad-hoc, enterprise or store installations, by
executing the `xcodeenv.buildApp {}` function:
```nix
let
pkgs = import <nixpkgs> {};
xcodeenv = import ./xcodeenv {
inherit (pkgs) stdenv;
};
in
xcodeenv.buildApp {
name = "MyApp";
src = ./myappsources;
sdkVersion = "11.2";
target = null; # Corresponds to the name of the app by default
configuration = null; # Release for release builds, Debug for debug builds
scheme = null; # -scheme will correspond to the app name by default
sdk = null; # null will set it to 'iphonesimulator` for simulator builds or `iphoneos` to real builds
xcodeFlags = "";
release = true;
certificateFile = ./mycertificate.p12;
certificatePassword = "secret";
provisioningProfile = ./myprovisioning.profile;
signMethod = "ad-hoc"; # 'enterprise' or 'store'
generateIPA = true;
generateXCArchive = false;
enableWirelessDistribution = true;
installURL = "/installipa.php";
bundleId = "mycompany.myapp";
appVersion = "1.0";
# Supports all xcodewrapper parameters as well
xcodeBaseDir = "/Applications/Xcode.app";
}
```
The above function takes a variety of parameters:
* The `name` and `src` parameters are mandatory and specify the name of the app
and the location where the source code resides
* `sdkVersion` specifies which version of the iOS SDK to use.
It also possile to adjust the `xcodebuild` parameters. This is only needed in
rare circumstances. In most cases the default values should suffice:
* Specifies which `xcodebuild` target to build. By default it takes the target
that has the same name as the app.
* The `configuration` parameter can be overridden if desired. By default, it
will do a debug build for the simulator and a release build for real devices.
* The `scheme` parameter specifies which `-scheme` parameter to propagate to
`xcodebuild`. By default, it corresponds to the app name.
* The `sdk` parameter specifies which SDK to use. By default, it picks
`iphonesimulator` for simulator builds and `iphoneos` for release builds.
* The `xcodeFlags` parameter specifies arbitrary command line parameters that
should be propagated to `xcodebuild`.
By default, builds are carried out for the iOS simulator. To do release builds
(builds for real iOS devices), you must set the `release` parameter to `true`.
In addition, you need to set the following parameters:
* `certificateFile` refers to a P12 certificate file.
* `certificatePassword` specifies the password of the P12 certificate.
* `provisioningProfile` refers to the provision profile needed to sign the app
* `signMethod` should refer to `ad-hoc` for signing the app with an ad-hoc
certificate, `enterprise` for enterprise certificates and `app-store` for App
store certificates.
* `generateIPA` specifies that we want to produce an IPA file (this is probably
what you want)
* `generateXCArchive` specifies thet we want to produce an xcarchive file.
When building IPA files on Hydra and when it is desired to allow iOS devices to
install IPAs by browsing to the Hydra build products page, you can enable the
`enableWirelessDistribution` parameter.
When enabled, you need to configure the following options:
* The `installURL` parameter refers to the URL of a PHP script that composes the
`itms-services://` URL allowing iOS devices to install the IPA file.
* `bundleId` refers to the bundle ID value of the app
* `appVersion` refers to the app's version number
To use wireless adhoc distributions, you must also install the corresponding
PHP script on a web server (see section: 'Installing the PHP script for wireless
ad hoc installations from Hydra' for more information).
In addition to the build parameters, you can also specify any parameters that
the `xcodeenv.composeXcodeWrapper {}` function takes. For example, the
`xcodeBaseDir` parameter can be overridden to refer to a different Xcode
version.
Spawning simulator instances
----------------------------
In addition to building iOS apps, we can also automatically spawn simulator
instances:
```nix
let
pkgs = import <nixpkgs> {};
xcodeenv = import ./xcodeenv {
inherit (pkgs) stdenv;
};
in
xcode.simulateApp {
name = "simulate";
# Supports all xcodewrapper parameters as well
xcodeBaseDir = "/Applications/Xcode.app";
}
```
The above expression produces a script that starts the simulator from the
provided Xcode installation. The script can be started as follows:
```bash
./result/bin/run-test-simulator
```
By default, the script will show an overview of UDID for all available simulator
instances and asks you to pick one. You can also provide a UDID as a
command-line parameter to launch an instance automatically:
```bash
./result/bin/run-test-simulator 5C93129D-CF39-4B1A-955F-15180C3BD4B8
```
You can also extend the simulator script to automatically deploy and launch an
app in the requested simulator instance:
```nix
let
pkgs = import <nixpkgs> {};
xcodeenv = import ./xcodeenv {
inherit (pkgs) stdenv;
};
in
xcode.simulateApp {
name = "simulate";
bundleId = "mycompany.myapp";
app = xcode.buildApp {
# ...
};
# Supports all xcodewrapper parameters as well
xcodeBaseDir = "/Applications/Xcode.app";
}
```
By providing the result of an `xcode.buildApp {}` function and configuring the
app bundle id, the app gets deployed automatically and started.

View File

@ -16,18 +16,17 @@ stdenv.mkDerivation {
}
</programlisting>
Note that <varname>jdk</varname> is an alias for the OpenJDK (self-built
where available, or pre-built via Zulu).
Platforms with OpenJDK not (yet) in Nixpkgs (<literal>Aarch32</literal>,
<literal>Aarch64</literal>) point to the (unfree)
<literal>oraclejdk</literal>.
</para>
where available, or pre-built via Zulu). Platforms with OpenJDK not (yet) in
Nixpkgs (<literal>Aarch32</literal>, <literal>Aarch64</literal>) point to the
(unfree) <literal>oraclejdk</literal>.
</para>
<para>
JAR files that are intended to be used by other packages should be installed
in <filename>$out/share/java</filename>. JDKs have a stdenv setup hook
that add any JARs in the <filename>share/java</filename> directories of the
build inputs to the <envar>CLASSPATH</envar> environment variable. For
instance, if the package <literal>libfoo</literal> installs a JAR named
in <filename>$out/share/java</filename>. JDKs have a stdenv setup hook that
add any JARs in the <filename>share/java</filename> directories of the build
inputs to the <envar>CLASSPATH</envar> environment variable. For instance, if
the package <literal>libfoo</literal> installs a JAR named
<filename>foo.jar</filename> in its <filename>share/java</filename>
directory, and another package declares the attribute
<programlisting>
@ -61,18 +60,17 @@ installPhase =
<literal>${jre}/bin/java</literal> instead of
<literal>${jdk}/bin/java</literal>, you prevent your package from depending
on the JDK at runtime.
</para>
</para>
<para>
<para>
Note all JDKs passthru <literal>home</literal>, so if your application
requires environment variables like <envar>JAVA_HOME</envar> being set, that
can be done in a generic fashion with the <literal>--set</literal> argument
of <literal>makeWrapper</literal>:
<programlisting>
--set JAVA_HOME ${jdk.home}
</programlisting>
</para>
</para>
<para>
It is possible to use a different Java compiler than <command>javac</command>

View File

@ -14,7 +14,7 @@ project.
The package set also provides support for multiple Node.js versions. The policy
is that a new package should be added to the collection for the latest stable LTS
release (which is currently 6.x), unless there is an explicit reason to support
release (which is currently 10.x), unless there is an explicit reason to support
a different release.
If your package uses native addons, you need to examine what kind of native
@ -26,7 +26,7 @@ build system it uses. Here are some examples:
After you have identified the correct system, you need to override your package
expression while adding in build system as a build input. For example, `dat`
requires `node-gyp-build`, so we override its expression in `default-v6.nix`:
requires `node-gyp-build`, so we override its expression in `default-v10.nix`:
```nix
dat = nodePackages.dat.override (oldAttrs: {
@ -36,14 +36,14 @@ dat = nodePackages.dat.override (oldAttrs: {
To add a package from NPM to nixpkgs:
1. Modify `pkgs/development/node-packages/node-packages-v6.json` to add, update
or remove package entries. (Or `pkgs/development/node-packages/node-packages-v4.json`
for packages depending on Node.js 4.x)
1. Modify `pkgs/development/node-packages/node-packages-v10.json` to add, update
or remove package entries. (Or `pkgs/development/node-packages/node-packages-v8.json`
for packages depending on Node.js 8.x)
2. Run the script: `(cd pkgs/development/node-packages && ./generate.sh)`.
3. Build your new package to test your changes:
`cd /path/to/nixpkgs && nix-build -A nodePackages.<new-or-updated-package>`.
To build against a specific Node.js version (e.g. 4.x):
`nix-build -A nodePackages_4_x.<new-or-updated-package>`
To build against a specific Node.js version (e.g. 10.x):
`nix-build -A nodePackages_10_x.<new-or-updated-package>`
4. Add and commit all modified and generated files.
For more information about the generation process, consult the

View File

@ -0,0 +1,97 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-ocaml">
<title>OCaml</title>
<para>
OCaml libraries should be installed in
<literal>$(out)/lib/ocaml/${ocaml.version}/site-lib/</literal>. Such
directories are automatically added to the <literal>$OCAMLPATH</literal>
environment variable when building another package that depends on them or
when opening a <literal>nix-shell</literal>.
</para>
<para>
Given that most of the OCaml ecosystem is now built with dune, nixpkgs
includes a convenience build support function called
<literal>buildDunePackage</literal> that will build an OCaml package using
dune, OCaml and findlib and any additional dependencies provided as
<literal>buildInputs</literal> or <literal>propagatedBuildInputs</literal>.
</para>
<para>
Here is a simple package example. It defines an (optional) attribute
<literal>minimumOCamlVersion</literal> that will be used to throw a
descriptive evaluation error if building with an older OCaml is attempted. It
uses the <literal>fetchFromGitHub</literal> fetcher to get its source. It
sets the <literal>doCheck</literal> (optional) attribute to
<literal>true</literal> which means that tests will be run with <literal>dune
runtest -p angstrom</literal> after the build (<literal>dune build -p
angstrom</literal>) is complete. It uses <literal>alcotest</literal> as a
build input (because it is needed to run the tests) and
<literal>bigstringaf</literal> and <literal>result</literal> as propagated
build inputs (thus they will also be available to libraries depending on this
library). The library will be installed using the
<literal>angstrom.install</literal> file that dune generates.
</para>
<programlisting>
{ stdenv, fetchFromGitHub, buildDunePackage, alcotest, result, bigstringaf }:
buildDunePackage rec {
pname = "angstrom";
version = "0.10.0";
minimumOCamlVersion = "4.03";
src = fetchFromGitHub {
owner = "inhabitedtype";
repo = pname;
rev = version;
sha256 = "0lh6024yf9ds0nh9i93r9m6p5psi8nvrqxl5x7jwl13zb0r9xfpw";
};
buildInputs = [ alcotest ];
propagatedBuildInputs = [ bigstringaf result ];
doCheck = true;
meta = {
homepage = https://github.com/inhabitedtype/angstrom;
description = "OCaml parser combinators built for speed and memory efficiency";
license = stdenv.lib.licenses.bsd3;
maintainers = with stdenv.lib.maintainers; [ sternenseemann ];
};
}
</programlisting>
<para>
Here is a second example, this time using a source archive generated with
<literal>dune-release</literal>. It is a good idea to use this archive when
it is available as it will usually contain substituted variables such as a
<literal>%%VERSION%%</literal> field. This library does not depend on any
other OCaml library and no tests are run after building it.
</para>
<programlisting>
{ stdenv, fetchurl, buildDunePackage }:
buildDunePackage rec {
pname = "wtf8";
version = "1.0.1";
minimumOCamlVersion = "4.01";
src = fetchurl {
url = "https://github.com/flowtype/ocaml-${pname}/releases/download/v${version}/${pname}-${version}.tbz";
sha256 = "1msg3vycd3k8qqj61sc23qks541cxpb97vrnrvrhjnqxsqnh6ygq";
};
meta = with stdenv.lib; {
homepage = https://github.com/flowtype/ocaml-wtf8;
description = "WTF-8 is a superset of UTF-8 that allows unpaired surrogates.";
license = licenses.mit;
maintainers = [ maintainers.eqyiel ];
};
}
</programlisting>
</section>

View File

@ -186,25 +186,24 @@ building Python libraries is `buildPythonPackage`. Let's see how we can build th
`toolz` package.
```nix
{ # ...
{ lib, buildPythonPackage, fetchPypi }:
toolz = buildPythonPackage rec {
pname = "toolz";
version = "0.7.4";
buildPythonPackage rec {
pname = "toolz";
version = "0.7.4";
src = fetchPypi {
inherit pname version;
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
};
src = fetchPypi {
inherit pname version;
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
};
doCheck = false;
doCheck = false;
meta = {
homepage = "https://github.com/pytoolz/toolz/";
description = "List processing tools and functional utilities";
license = licenses.bsd3;
maintainers = with maintainers; [ fridh ];
};
meta = with lib; {
homepage = https://github.com/pytoolz/toolz;
description = "List processing tools and functional utilities";
license = licenses.bsd3;
maintainers = with maintainers; [ fridh ];
};
}
```
@ -267,43 +266,43 @@ that we introduced with the `let` expression.
#### Handling dependencies
Our example, `toolz`, does not 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.
Our example, `toolz`, does not 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 and passed to `checkInputs`.
The following example shows which arguments are given to `buildPythonPackage` in
order to build [`datashape`](https://github.com/blaze/datashape).
```nix
{ # ...
{ lib, buildPythonPackage, fetchPypi, numpy, multipledispatch, dateutil, pytest }:
datashape = buildPythonPackage rec {
pname = "datashape";
version = "0.4.7";
buildPythonPackage rec {
pname = "datashape";
version = "0.4.7";
src = fetchPypi {
inherit pname version;
sha256 = "14b2ef766d4c9652ab813182e866f493475e65e558bed0822e38bf07bba1a278";
};
src = fetchPypi {
inherit pname version;
sha256 = "14b2ef766d4c9652ab813182e866f493475e65e558bed0822e38bf07bba1a278";
};
checkInputs = with self; [ pytest ];
propagatedBuildInputs = with self; [ numpy multipledispatch dateutil ];
checkInputs = [ pytest ];
propagatedBuildInputs = [ numpy multipledispatch dateutil ];
meta = {
homepage = https://github.com/ContinuumIO/datashape;
description = "A data description language";
license = licenses.bsd2;
maintainers = with maintainers; [ fridh ];
};
meta = with lib; {
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
`dateutil`. Furthermore, we have one `checkInputs`, i.e. `pytest`. `pytest` is a
test runner and is only used during the `checkPhase` and is therefore not added
to `propagatedBuildInputs`.
@ -313,25 +312,24 @@ Python bindings to `libxml2` and `libxslt`. These libraries are only required
when building the bindings and are therefore added as `buildInputs`.
```nix
{ # ...
{ lib, pkgs, buildPythonPackage, fetchPypi }:
lxml = buildPythonPackage rec {
pname = "lxml";
version = "3.4.4";
buildPythonPackage rec {
pname = "lxml";
version = "3.4.4";
src = fetchPypi {
inherit pname version;
sha256 = "16a0fa97hym9ysdk3rmqz32xdjqmy4w34ld3rm3jf5viqjx65lxk";
};
src = fetchPypi {
inherit pname version;
sha256 = "16a0fa97hym9ysdk3rmqz32xdjqmy4w34ld3rm3jf5viqjx65lxk";
};
buildInputs = with self; [ pkgs.libxml2 pkgs.libxslt ];
buildInputs = [ pkgs.libxml2 pkgs.libxslt ];
meta = {
description = "Pythonic binding for the libxml2 and libxslt libraries";
homepage = https://lxml.de;
license = licenses.bsd3;
maintainers = with maintainers; [ sjourdois ];
};
meta = with lib; {
description = "Pythonic binding for the libxml2 and libxslt libraries";
homepage = https://lxml.de;
license = licenses.bsd3;
maintainers = with maintainers; [ sjourdois ];
};
}
```
@ -347,35 +345,34 @@ find each of them in a different folder, and therefore we have to set `LDFLAGS`
and `CFLAGS`.
```nix
{ # ...
{ lib, pkgs, buildPythonPackage, fetchPypi, numpy, scipy }:
pyfftw = buildPythonPackage rec {
pname = "pyFFTW";
version = "0.9.2";
buildPythonPackage rec {
pname = "pyFFTW";
version = "0.9.2";
src = fetchPypi {
inherit pname version;
sha256 = "f6bbb6afa93085409ab24885a1a3cdb8909f095a142f4d49e346f2bd1b789074";
};
src = fetchPypi {
inherit pname version;
sha256 = "f6bbb6afa93085409ab24885a1a3cdb8909f095a142f4d49e346f2bd1b789074";
};
buildInputs = [ pkgs.fftw pkgs.fftwFloat pkgs.fftwLongDouble];
buildInputs = [ pkgs.fftw pkgs.fftwFloat pkgs.fftwLongDouble];
propagatedBuildInputs = with self; [ numpy scipy ];
propagatedBuildInputs = [ numpy scipy ];
# Tests cannot import pyfftw. pyfftw works fine though.
doCheck = false;
# Tests cannot import pyfftw. pyfftw works fine though.
doCheck = false;
preConfigure = ''
export LDFLAGS="-L${pkgs.fftw.dev}/lib -L${pkgs.fftwFloat.out}/lib -L${pkgs.fftwLongDouble.out}/lib"
export CFLAGS="-I${pkgs.fftw.dev}/include -I${pkgs.fftwFloat.dev}/include -I${pkgs.fftwLongDouble.dev}/include"
'';
preConfigure = ''
export LDFLAGS="-L${pkgs.fftw.dev}/lib -L${pkgs.fftwFloat.out}/lib -L${pkgs.fftwLongDouble.out}/lib"
export 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 ];
maintainers = with maintainers; [ fridh ];
};
meta = with lib; {
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 ];
maintainers = with maintainers; [ fridh ];
};
}
```
@ -403,7 +400,7 @@ Indeed, we can just add any package we like to have in our environment to `propa
```nix
with import <nixpkgs> {};
with pkgs.python35Packages;
with python35Packages;
buildPythonPackage rec {
name = "mypackage";
@ -436,7 +433,7 @@ 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
{ lib, pkgs, buildPythonPackage }:
{ lib, buildPythonPackage }:
buildPythonPackage rec {
pname = "toolz";
@ -448,7 +445,7 @@ buildPythonPackage rec {
};
meta = with lib; {
homepage = "http://github.com/pytoolz/toolz/";
homepage = "https://github.com/pytoolz/toolz/";
description = "List processing tools and functional utilities";
license = licenses.bsd3;
maintainers = with maintainers; [ fridh ];
@ -456,18 +453,17 @@ buildPythonPackage rec {
}
```
It takes two arguments, `pkgs` and `buildPythonPackage`.
It takes an argument `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;
toolz = callPackage /path/to/toolz/release.nix {
buildPythonPackage = python35Packages.buildPythonPackage;
};
in pkgs.python35.withPackages (ps: [ ps.numpy toolz ])
in python35.withPackages (ps: [ ps.numpy toolz ])
).env
```
@ -478,18 +474,18 @@ 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.7, 3.4, 3.5, 3.6 and 3.7 of the CPython interpreter are available as
respectively `python27`, `python34`, `python35` and `python36`. The PyPy interpreter
is available as `pypy`. The aliases `python2` and `python3` correspond to respectively `python27` and
`python35`. The default interpreter, `python`, maps to `python2`.
The Nix expressions for the interpreters can be found in
`pkgs/development/interpreters/python`.
Versions 2.7, 3.5, 3.6 and 3.7 of the CPython interpreter are available as
respectively `python27`, `python35`, `python36` and `python37`. The aliases
`python2` and `python3` correspond to respectively `python27` and
`python37`. The default interpreter, `python`, maps to `python2`. The PyPy
interpreters compatible with Python 2.7 and 3 are available as `pypy27` and
`pypy3`, with aliases `pypy2` mapping to `pypy27` and `pypy` mapping to
`pypy2`. The Nix expressions for the interpreters can be
found in `pkgs/development/interpreters/python`.
All packages depending on any Python interpreter get appended
`out/{python.sitePackages}` to `$PYTHONPATH` if such directory
@ -508,13 +504,13 @@ Each interpreter has the following attributes:
- `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, e.g. `python3.4`.
- `executable`. Name of the interpreter executable, e.g. `python3.7`.
- `pkgs`. Set of Python packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`.
### Building packages and applications
Python libraries and applications that use `setuptools` or
`distutils` are typically build with respectively the `buildPythonPackage` and
`distutils` are typically built with respectively the `buildPythonPackage` and
`buildPythonApplication` functions. These two functions also support installing a `wheel`.
All Python packages reside in `pkgs/top-level/python-packages.nix` and all
@ -530,7 +526,6 @@ attribute set is created for each available Python interpreter. The available
sets are
* `pkgs.python27Packages`
* `pkgs.python34Packages`
* `pkgs.python35Packages`
* `pkgs.python36Packages`
* `pkgs.python37Packages`
@ -539,7 +534,7 @@ sets are
and the aliases
* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
* `pkgs.python3Packages` pointing to `pkgs.python36Packages`
* `pkgs.python3Packages` pointing to `pkgs.python37Packages`
* `pkgs.pythonPackages` pointing to `pkgs.python2Packages`
#### `buildPythonPackage` function
@ -549,31 +544,31 @@ The `buildPythonPackage` function is implemented in
The following is an example:
```nix
{ lib, buildPythonPackage, fetchPypi, hypothesis, setuptools_scm, attrs, py, setuptools, six, pluggy }:
buildPythonPackage rec {
version = "3.3.1";
pname = "pytest";
preCheck = ''
# don't test bash builtins
rm testing/test_argcomplete.py
'';
version = "3.3.1";
src = fetchPypi {
inherit pname version;
sha256 = "cf8436dc59d8695346fcd3ab296de46425ecab00d64096cebe79fb51ecb2eb93";
};
postPatch = ''
# don't test bash builtins
rm testing/test_argcomplete.py
'';
checkInputs = [ hypothesis ];
buildInputs = [ setuptools_scm ];
nativeBuildInputs = [ setuptools_scm ];
propagatedBuildInputs = [ attrs py setuptools six pluggy ];
meta = with stdenv.lib; {
meta = with lib; {
maintainers = with maintainers; [ domenkozar lovek323 madjar lsix ];
description = "Framework for writing tests";
};
}
```
The `buildPythonPackage` mainly does four things:
@ -586,11 +581,6 @@ The `buildPythonPackage` mainly does four things:
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 is (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 `checkInputs`.
@ -602,11 +592,10 @@ as the interpreter unless overridden otherwise.
All parameters from `stdenv.mkDerivation` function are still supported. The following are specific to `buildPythonPackage`:
* `catchConflicts ? true`: 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`.
* `disabled` ? false: If `true`, package is not build for the particular Python interpreter version.
* `dontWrapPythonPrograms ? false`: Skip wrapping of python programs.
* `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 ? "setuptools"`: Format of the source. Valid options are `"setuptools"`, `"flit"`, `"wheel"`, and `"other"`. `"setuptools"` is for when the source has a `setup.py` and `setuptools` is used to build a wheel, `flit`, in case `flit` should be used to build a wheel, and `wheel` in case a wheel is provided. Use `other` when a custom `buildPhase` and/or `installPhase` is needed.
* `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 ? "setuptools"`: Format of the source. Valid options are `"setuptools"`, `"pyproject"`, `"flit"`, `"wheel"`, and `"other"`. `"setuptools"` is for when the source has a `setup.py` and `setuptools` is used to build a wheel, `flit`, in case `flit` should be used to build a wheel, and `wheel` in case a wheel is provided. Use `other` when a custom `buildPhase` and/or `installPhase` is needed.
* `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"]`.
* `namePrefix`: Prepends text to `${name}` parameter. In case of libraries, this defaults to `"python3.5-"` for Python 3.5, etc., and in case of applications to `""`.
* `pythonPath ? []`: List of packages to be added into `$PYTHONPATH`. Packages in `pythonPath` are not propagated (contrary to `propagatedBuildInputs`).
@ -615,6 +604,14 @@ All parameters from `stdenv.mkDerivation` function are still supported. The foll
* `removeBinByteCode ? true`: Remove bytecode from `/bin`. Bytecode is only created when the filenames end with `.py`.
* `setupPyBuildFlags ? []`: List of flags passed to `setup.py build_ext` command.
The `stdenv.mkDerivation` function accepts various parameters for describing build inputs (see "Specifying dependencies"). The following are of special
interest for Python packages, either because these are primarily used, or because their behaviour is different:
* `nativeBuildInputs ? []`: Build-time only dependencies. Typically executables as well as the items listed in `setup_requires`.
* `buildInputs ? []`: Build and/or run-time dependencies that need to be be compiled for the host machine. Typically non-Python libraries which are being linked.
* `checkInputs ? []`: Dependencies needed for running the `checkPhase`. These are added to `nativeBuildInputs` when `doCheck = true`. Items listed in `tests_require` go here.
* `propagatedBuildInputs ? []`: Aside from propagating dependencies, `buildPythonPackage` also injects code into and wraps executables with the paths included in this list. Items listed in `install_requires` go here.
##### Overriding Python packages
The `buildPythonPackage` function has a `overridePythonAttrs` method that
@ -645,9 +642,48 @@ in python.withPackages(ps: [ps.blaze])).env
#### `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 this is irrelevant for applications, the prefix is omitted.
The `buildPythonApplication` function is practically the same as
`buildPythonPackage`. The main purpose of this function is to build a Python
package where one is interested only in the executables, and not importable
modules. For that reason, when adding this package to a `python.buildEnv`, the
modules won't be made available.
Another difference is that `buildPythonPackage` by default prefixes the names of
the packages with the version of the interpreter. Because this is irrelevant for
applications, the prefix is omitted.
When packaging a python application with `buildPythonApplication`, it should be
called with `callPackage` and passed `python` or `pythonPackages` (possibly
specifying an interpreter version), like this:
```nix
{ lib, python3Packages }:
python3Packages.buildPythonApplication rec {
pname = "luigi";
version = "2.7.9";
src = python3Packages.fetchPypi {
inherit pname version;
sha256 = "035w8gqql36zlan0xjrzz9j4lh9hs0qrsgnbyw07qs7lnkvbdv9x";
};
propagatedBuildInputs = with python3Packages; [ tornado_4 python-daemon ];
meta = with lib; {
...
};
}
```
This is then added to `all-packages.nix` just as any other application would be.
```nix
luigi = callPackage ../applications/networking/cluster/luigi { };
```
Since the package is an application, a consumer doesn't need to care about
python versions or modules, which is why they don't go in `pythonPackages`.
#### `toPythonApplication` function
@ -688,7 +724,7 @@ Saving the following as `default.nix`
with import <nixpkgs> {};
python.buildEnv.override {
extraLibs = [ pkgs.pythonPackages.pyramid ];
extraLibs = [ pythonPackages.pyramid ];
ignoreCollisions = true;
}
```
@ -770,11 +806,12 @@ Given a `default.nix`:
```nix
with import <nixpkgs> {};
buildPythonPackage { name = "myproject";
pythonPackages.buildPythonPackage {
name = "myproject";
buildInputs = with pythonPackages; [ pyramid ];
buildInputs = with pkgs.pythonPackages; [ pyramid ];
src = ./.; }
src = ./.;
}
```
Running `nix-shell` with no arguments should give you
@ -799,7 +836,7 @@ community to help save time. No tool is preferred at the moment.
### Deterministic builds
Python 2.7, 3.5 and 3.6 are now built deterministically and 3.4 mostly.
The Python interpreters are now built deterministically.
Minor modifications had to be made to the interpreters in order to generate
deterministic bytecode. This has security implications and is relevant for
those using Python in a `nix-shell`.
@ -835,7 +872,6 @@ example of such a situation is when `py.test` is used.
'';
}
```
- Unicode issues can typically be fixed by including `glibcLocales` in `buildInputs` and exporting `LC_ALL=en_US.utf-8`.
- Tests that attempt to access `$HOME` can be fixed by using the following work-around before running tests (e.g. `preCheck`): `export HOME=$(mktemp -d)`
## FAQ
@ -961,10 +997,13 @@ Create this `default.nix` file, together with a `requirements.txt` and simply ex
```nix
with import <nixpkgs> {};
with pkgs.python27Packages;
with python27Packages;
stdenv.mkDerivation {
name = "impurePythonEnv";
src = null;
buildInputs = [
# these packages are required for virtualenv and pip to work:
#
@ -984,14 +1023,15 @@ stdenv.mkDerivation {
libxslt
libzip
stdenv
zlib ];
src = null;
zlib
];
shellHook = ''
# set SOURCE_DATE_EPOCH so that we can use python wheels
SOURCE_DATE_EPOCH=$(date +%s)
virtualenv --no-setuptools venv
export PATH=$PWD/venv/bin:$PATH
pip install -r requirements.txt
# set SOURCE_DATE_EPOCH so that we can use python wheels
SOURCE_DATE_EPOCH=$(date +%s)
virtualenv --no-setuptools venv
export PATH=$PWD/venv/bin:$PATH
pip install -r requirements.txt
'';
}
```
@ -1041,8 +1081,7 @@ To modify only a Python package set instead of a whole Python derivation, use th
Use the following overlay template:
```nix
self: super:
{
self: super: {
python = super.python.override {
packageOverrides = python-self: python-super: {
zerobin = python-super.zerobin.overrideAttrs (oldAttrs: {
@ -1057,6 +1096,42 @@ self: super:
}
```
### How to use Intel's MKL with numpy and scipy?
A `site.cfg` is created that configures BLAS based on the `blas` parameter
of the `numpy` derivation. By passing in `mkl`, `numpy` and packages depending
on `numpy` will be built with `mkl`.
The following is an overlay that configures `numpy` to use `mkl`:
```nix
self: super: {
python37 = super.python37.override {
packageOverrides = python-self: python-super: {
numpy = python-super.numpy.override {
blas = super.pkgs.mkl;
};
};
};
}
```
`mkl` requires an `openmp` implementation when running with multiple processors.
By default, `mkl` will use Intel's `iomp` implementation if no other is
specified, but this is a runtime-only dependency and binary compatible with the
LLVM implementation. To use that one instead, Intel recommends users set it with
`LD_PRELOAD`.
Note that `mkl` is only available on `x86_64-{linux,darwin}` platforms;
moreover, Hydra is not building and distributing pre-compiled binaries using it.
### What inputs do `setup_requires`, `install_requires` and `tests_require` map to?
In a `setup.py` or `setup.cfg` it is common to declare dependencies:
* `setup_requires` corresponds to `nativeBuildInputs`
* `install_requires` corresponds to `propagatedBuildInputs`
* `tests_require` corresponds to `checkInputs`
## Contributing
### Contributing guidelines
@ -1068,4 +1143,5 @@ Following rules are desired to be respected:
* Make sure libraries build for all Python interpreters.
* By default we enable tests. Make sure the tests are found and, in the case of libraries, are passing for all interpreters. If certain tests fail they can be disabled individually. Try to avoid disabling the tests altogether. In any case, when you disable tests, leave a comment explaining why.
* Commit names of Python libraries should reflect that they are Python libraries, so write for example `pythonPackages.numpy: 1.11 -> 1.12`.
* Attribute names in `python-packages.nix` should be normalized according to [PEP 0503](https://www.python.org/dev/peps/pep-0503/#normalized-names).
This means that characters should be converted to lowercase and `.` and `_` should be replaced by a single `-` (foo-bar-baz instead of Foo__Bar.baz )

View File

@ -50,6 +50,17 @@ bundlerEnv rec {
future updates can be run easily.
</para>
<para>
Updating Ruby packages can then be done like this:
</para>
<screen>
<![CDATA[$ cd pkgs/servers/monitoring/sensu
$ nix-shell -p bundler --run 'bundle lock --update'
$ nix-shell -p bundix --run 'bundix'
]]>
</screen>
<para>
For tools written in Ruby - i.e. where the desire is to install a package and
then execute e.g. <command>rake</command> at the command line, there is an

View File

@ -64,9 +64,6 @@ When the `Cargo.lock`, provided by upstream, is not in sync with the
added in `cargoPatches` will also be prepended to the patches in `patches` at
build-time.
To install crates with nix there is also an experimental project called
[nixcrates](https://github.com/fractalide/nixcrates).
## Compiling Rust crates using Nix instead of Cargo
### Simple operation
@ -93,8 +90,8 @@ Now, the file produced by the call to `carnix`, called `hello.nix`, looks like:
```
# Generated by carnix 0.6.5: carnix -o hello.nix --src ./. Cargo.lock --standalone
{ lib, buildPlatform, buildRustCrate, fetchgit }:
let kernel = buildPlatform.parsed.kernel.name;
{ lib, stdenv, buildRustCrate, fetchgit }:
let kernel = stdenv.buildPlatform.parsed.kernel.name;
# ... (content skipped)
in
rec {
@ -122,8 +119,8 @@ following nix file:
```
# Generated by carnix 0.6.5: carnix -o hello.nix --src ./. Cargo.lock --standalone
{ lib, buildPlatform, buildRustCrate, fetchgit }:
let kernel = buildPlatform.parsed.kernel.name;
{ lib, stdenv, buildRustCrate, fetchgit }:
let kernel = stdenv.buildPlatform.parsed.kernel.name;
# ... (content skipped)
in
rec {
@ -306,11 +303,15 @@ with import <nixpkgs> {};
stdenv.mkDerivation {
name = "rust-env";
buildInputs = [
nativeBuildInputs = [
rustc cargo
# Example Additional Dependencies
pkgconfig openssl
# Example Build-time Additional Dependencies
pkgconfig
];
buildInputs = [
# Example Run-time Additional Dependencies
openssl
];
# Set Environment Variables

View File

@ -8,7 +8,7 @@
under attribute <varname>texlive</varname>.
</para>
<section>
<section xml:id="sec-language-texlive-users-guide">
<title>User's guide</title>
<itemizedlist>
@ -49,12 +49,12 @@ texlive.combine {
</listitem>
<listitem>
<para>
You can list packages e.g. by <command>nix-repl</command>.
<programlisting>
$ nix-repl
nix-repl> :l &lt;nixpkgs>
nix-repl> texlive.collection-&lt;TAB>
</programlisting>
You can list packages e.g. by <command>nix repl</command>.
<programlisting><![CDATA[
$ nix repl
nix-repl> :l <nixpkgs>
nix-repl> texlive.collection-<TAB>
]]></programlisting>
</para>
</listitem>
<listitem>
@ -68,7 +68,7 @@ nix-repl> texlive.collection-&lt;TAB>
</itemizedlist>
</section>
<section>
<section xml:id="sec-language-texlive-known-problems">
<title>Known problems</title>
<itemizedlist>

View File

@ -0,0 +1,115 @@
---
title: Titanium
author: Sander van der Burg
date: 2018-11-18
---
# Titanium
The Nixpkgs repository contains facilities to deploy a variety of versions of
the [Titanium SDK](https://www.appcelerator.com) versions, a cross-platform
mobile app development framework using JavaScript as an implementation language,
and includes a function abstraction making it possible to build Titanium
applications for Android and iOS devices from source code.
Not all Titanium features supported -- currently, it can only be used to build
Android and iOS apps.
Building a Titanium app
-----------------------
We can build a Titanium app from source for Android or iOS and for debugging or
release purposes by invoking the `titaniumenv.buildApp {}` function:
```nix
titaniumenv.buildApp {
name = "myapp";
src = ./myappsource;
preBuild = "";
target = "android"; # or 'iphone'
tiVersion = "7.1.0.GA";
release = true;
androidsdkArgs = {
platformVersions = [ "25" "26" ];
};
androidKeyStore = ./keystore;
androidKeyAlias = "myfirstapp";
androidKeyStorePassword = "secret";
xcodeBaseDir = "/Applications/Xcode.app";
xcodewrapperArgs = {
version = "9.3";
};
iosMobileProvisioningProfile = ./myprovisioning.profile;
iosCertificateName = "My Company";
iosCertificate = ./mycertificate.p12;
iosCertificatePassword = "secret";
iosVersion = "11.3";
iosBuildStore = false;
enableWirelessDistribution = true;
installURL = "/installipa.php";
}
```
The `titaniumenv.buildApp {}` function takes the following parameters:
* The `name` parameter refers to the name in the Nix store.
* The `src` parameter refers to the source code location of the app that needs
to be built.
* `preRebuild` contains optional build instructions that are carried out before
the build starts.
* `target` indicates for which device the app must be built. Currently only
'android' and 'iphone' (for iOS) are supported.
* `tiVersion` can be used to optionally override the requested Titanium version
in `tiapp.xml`. If not specified, it will use the version in `tiapp.xml`.
* `release` should be set to true when building an app for submission to the
Google Playstore or Apple Appstore. Otherwise, it should be false.
When the `target` has been set to `android`, we can configure the following
parameters:
* The `androidSdkArgs` parameter refers to an attribute set that propagates all
parameters to the `androidenv.composeAndroidPackages {}` function. This can
be used to install all relevant Android plugins that may be needed to perform
the Android build. If no parameters are given, it will deploy the platform
SDKs for API-levels 25 and 26 by default.
When the `release` parameter has been set to true, you need to provide
parameters to sign the app:
* `androidKeyStore` is the path to the keystore file
* `androidKeyAlias` is the key alias
* `androidKeyStorePassword` refers to the password to open the keystore file.
When the `target` has been set to `iphone`, we can configure the following
parameters:
* The `xcodeBaseDir` parameter refers to the location where Xcode has been
installed. When none value is given, the above value is the default.
* The `xcodewrapperArgs` parameter passes arbitrary parameters to the
`xcodeenv.composeXcodeWrapper {}` function. This can, for example, be used
to adjust the default version of Xcode.
When `release` has been set to true, you also need to provide the following
parameters:
* `iosMobileProvisioningProfile` refers to a mobile provisioning profile needed
for signing.
* `iosCertificateName` refers to the company name in the P12 certificate.
* `iosCertificate` refers to the path to the P12 file.
* `iosCertificatePassword` contains the password to open the P12 file.
* `iosVersion` refers to the iOS SDK version to use. It defaults to the latest
version.
* `iosBuildStore` should be set to `true` when building for the Apple Appstore
submission. For enterprise or ad-hoc builds it should be set to `false`.
When `enableWirelessDistribution` has been enabled, you must also provide the
path of the PHP script (`installURL`) (that is included with the iOS build
environment) to enable wireless ad-hoc installations.
Emulating or simulating the app
-------------------------------
It is also possible to simulate the correspond iOS simulator build by using
`xcodeenv.simulateApp {}` and emulate an Android APK by using
`androidenv.emulateApp {}`.

View File

@ -5,11 +5,17 @@ date: 2016-06-25
---
# User's Guide to Vim Plugins/Addons/Bundles/Scripts in Nixpkgs
You'll get a vim(-your-suffix) in PATH also loading the plugins you want.
Both Neovim and Vim can be configured to include your favorite plugins
and additional libraries.
Loading can be deferred; see examples.
Vim packages, VAM (=vim-addon-manager) and Pathogen are supported to load
packages.
At the moment we support three different methods for managing plugins:
- Vim packages (*recommend*)
- VAM (=vim-addon-manager)
- Pathogen
- vim-plug
## Custom configuration
@ -17,6 +23,7 @@ Adding custom .vimrc lines can be done using the following code:
```
vim_configurable.customize {
# `name` specifies the name of the executable and package
name = "vim-with-plugins";
vimrcConfig.customRC = ''
@ -25,9 +32,38 @@ vim_configurable.customize {
}
```
## Vim packages
This configuration is used when vim is invoked with the command specified as name, in this case `vim-with-plugins`.
To store you plugins in Vim packages the following example can be used:
For Neovim the `configure` argument can be overridden to achieve the same:
```
neovim.override {
configure = {
customRC = ''
# here your custom configuration goes!
'';
};
}
```
If you want to use `neovim-qt` as a graphical editor, you can configure it by overriding neovim in an overlay
or passing it an overridden neovimn:
```
neovim-qt.override {
neovim = neovim.override {
configure = {
customRC = ''
# your custom configuration
'';
};
};
}
```
## Managing plugins with Vim packages
To store you plugins in Vim packages (the native vim plugin manager, see `:help packages`) the following example can be used:
```
vim_configurable.customize {
@ -35,16 +71,88 @@ vim_configurable.customize {
# loaded on launch
start = [ youcompleteme fugitive ];
# manually loadable by calling `:packadd $plugin-name`
# however, if a vim plugin has a dependency that is not explicitly listed in
# opt that dependency will always be added to start to avoid confusion.
opt = [ phpCompletion elm-vim ];
# To automatically load a plugin when opening a filetype, add vimrc lines like:
# autocmd FileType php :packadd phpCompletion
}
};
};
}
```
## VAM
`myVimPackage` is an arbitrary name for the generated package. You can choose any name you like.
For Neovim the syntax is:
### dependencies by Vim plugins
```
neovim.override {
configure = {
customRC = ''
# here your custom configuration goes!
'';
packages.myVimPackage = with pkgs.vimPlugins; {
# see examples below how to use custom packages
start = [ ];
# If a vim plugin has a dependency that is not explicitly listed in
# opt that dependency will always be added to start to avoid confusion.
opt = [ ];
};
};
}
```
The resulting package can be added to `packageOverrides` in `~/.nixpkgs/config.nix` to make it installable:
```
{
packageOverrides = pkgs: with pkgs; {
myVim = vim_configurable.customize {
# `name` specifies the name of the executable and package
name = "vim-with-plugins";
# add here code from the example section
};
myNeovim = neovim.override {
configure = {
# add here code from the example section
};
};
};
}
```
After that you can install your special grafted `myVim` or `myNeovim` packages.
## Managing plugins with vim-plug
To use [vim-plug](https://github.com/junegunn/vim-plug) to manage your Vim
plugins the following example can be used:
```
vim_configurable.customize {
vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; {
# loaded on launch
plug.plugins = [ youcompleteme fugitive phpCompletion elm-vim ];
};
}
```
For Neovim the syntax is:
```
neovim.override {
configure = {
customRC = ''
# here your custom configuration goes!
'';
plug.plugins = with pkgs.vimPlugins; [
vim-go
];
};
}
```
## Managing plugins with VAM
### Handling dependencies of Vim plugins
VAM introduced .json files supporting dependencies without versioning
assuming that "using latest version" is ok most of the time.
@ -125,11 +233,23 @@ Sample output2:
]
## Adding new plugins to nixpkgs
In `pkgs/misc/vim-plugins/vim-plugin-names` we store the plugin names
for all vim plugins we automatically generate plugins for.
The format of this file `github username/github repository`:
For example https://github.com/scrooloose/nerdtree becomes `scrooloose/nerdtree`.
After adding your plugin to this file run the `./update.py` in the same folder.
This will updated a file called `generated.nix` and make your plugin accessible in the
`vimPlugins` attribute set (`vimPlugins.nerdtree` in our example).
If additional steps to the build process of the plugin are required, add an
override to the `pkgs/misc/vim-plugins/default.nix` in the same directory.
## Important repositories
- [vim-pi](https://bitbucket.org/vimcommunity/vim-pi) is a plugin repository
from VAM plugin manager meant to be used by others as well used by
- [vim2nix](http://github.com/MarcWeber/vim-addon-vim2nix) which generates the
- [vim2nix](https://github.com/MarcWeber/vim-addon-vim2nix) which generates the
.nix code

26
doc/lib-function-docs.nix Normal file
View File

@ -0,0 +1,26 @@
# Generates the documentation for library functons via nixdoc. To add
# another library function file to this list, the include list in the
# file `doc/functions/library.xml` must also be updated.
{ pkgs ? import ./.. {}, locationsXml }:
with pkgs; stdenv.mkDerivation {
name = "nixpkgs-lib-docs";
src = ./../lib;
buildInputs = [ nixdoc ];
installPhase = ''
function docgen {
nixdoc -c "$1" -d "$2" -f "../lib/$1.nix" > "$out/$1.xml"
}
mkdir -p $out
ln -s ${locationsXml} $out/locations.xml
docgen strings 'String manipulation functions'
docgen trivial 'Miscellaneous functions'
docgen lists 'List manipulation functions'
docgen debug 'Debugging functions'
docgen options 'NixOS / nixpkgs option handling'
'';
}

View File

@ -0,0 +1,85 @@
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
let
revision = pkgs.lib.trivial.revisionWithDefault (nixpkgs.revision or "master");
libDefPos = set:
builtins.map
(name: {
name = name;
location = builtins.unsafeGetAttrPos name set;
})
(builtins.attrNames set);
libset = toplib:
builtins.map
(subsetname: {
subsetname = subsetname;
functions = libDefPos toplib."${subsetname}";
})
(builtins.filter
(name: builtins.isAttrs toplib."${name}")
(builtins.attrNames toplib));
nixpkgsLib = pkgs.lib;
flattenedLibSubset = { subsetname, functions }:
builtins.map
(fn: {
name = "lib.${subsetname}.${fn.name}";
value = fn.location;
})
functions;
locatedlibsets = libs: builtins.map flattenedLibSubset (libset libs);
removeFilenamePrefix = prefix: filename:
let
prefixLen = (builtins.stringLength prefix) + 1; # +1 to remove the leading /
filenameLen = builtins.stringLength filename;
substr = builtins.substring prefixLen filenameLen filename;
in substr;
removeNixpkgs = removeFilenamePrefix (builtins.toString pkgs.path);
liblocations =
builtins.filter
(elem: elem.value != null)
(nixpkgsLib.lists.flatten
(locatedlibsets nixpkgsLib));
fnLocationRelative = { name, value }:
{
inherit name;
value = value // { file = removeNixpkgs value.file; };
};
relativeLocs = (builtins.map fnLocationRelative liblocations);
sanitizeId = builtins.replaceStrings
[ "'" ]
[ "-prime" ];
urlPrefix = "https://github.com/NixOS/nixpkgs/blob/${revision}";
xmlstrings = (nixpkgsLib.strings.concatMapStrings
({ name, value }:
''
<section><title>${name}</title>
<para xml:id="${sanitizeId name}">
Located at
<link
xlink:href="${urlPrefix}/${value.file}#L${builtins.toString value.line}">${value.file}:${builtins.toString value.line}</link>
in <literal>&lt;nixpkgs&gt;</literal>.
</para>
</section>
'')
relativeLocs);
in pkgs.writeText
"locations.xml"
''
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="5">
<title>All the locations for every lib function</title>
<para>This file is only for inclusion by other files.</para>
${xmlstrings}
</section>
''

View File

@ -14,7 +14,7 @@ meta = with stdenv.lib; {
GNU Hello is a program that prints "Hello, world!" when you run it.
It is fully customizable.
'';
homepage = http://www.gnu.org/software/hello/manual/;
homepage = https://www.gnu.org/software/hello/manual/;
license = licenses.gpl3Plus;
maintainers = [ maintainers.eelco ];
platforms = platforms.all;
@ -35,7 +35,7 @@ $ nix-env -qa hello --json
"hello": {
"meta": {
"description": "A program that produces a familiar, friendly greeting",
"homepage": "http://www.gnu.org/software/hello/manual/",
"homepage": "https://www.gnu.org/software/hello/manual/",
"license": {
"fullName": "GNU General Public License version 3 or later",
"shortName": "GPLv3+",
@ -135,7 +135,7 @@ hello-2.3 A program that produces a familiar, friendly greeting
<listitem>
<para>
The packages homepage. Example:
<literal>http://www.gnu.org/software/hello/manual/</literal>
<literal>https://www.gnu.org/software/hello/manual/</literal>
</para>
</listitem>
</varlistentry>
@ -146,7 +146,7 @@ hello-2.3 A program that produces a familiar, friendly greeting
<listitem>
<para>
The page where a link to the current version can be found. Example:
<literal>http://ftp.gnu.org/gnu/hello/</literal>
<literal>https://ftp.gnu.org/gnu/hello/</literal>
</para>
</listitem>
</varlistentry>
@ -250,6 +250,60 @@ meta.platforms = stdenv.lib.platforms.linux;
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>tests</varname>
</term>
<listitem>
<warning>
<para>
This attribute is special in that it is not actually under the
<literal>meta</literal> attribute set but rather under the
<literal>passthru</literal> attribute set. This is due to a current
limitation of Nix, and will change as soon as Nixpkgs will be able to
depend on a new enough version of Nix. See
<link xlink:href="https://github.com/NixOS/nix/issues/2532">the relevant
issue</link> for more details.
</para>
</warning>
<para>
An attribute set with as values tests. A test is a derivation, which
builds successfully when the test passes, and fails to build otherwise. A
derivation that is a test needs to have <literal>meta.timeout</literal>
defined.
</para>
<para>
The NixOS tests are available as <literal>nixosTests</literal> in
parameters of derivations. For instance, the OpenSMTPD derivation
includes lines similar to:
<programlisting>
{ /* ... */, nixosTests }:
{
# ...
passthru.tests = {
basic-functionality-and-dovecot-integration = nixosTests.opensmtpd;
};
}
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>timeout</varname>
</term>
<listitem>
<para>
A timeout (in seconds) for building the derivation. If the derivation
takes longer than this time to build, it can fail due to breaking the
timeout. However, all computers do not have the same computing power,
hence some builders may decide to apply a multiplicative factor to this
value. When filling this value in, try to keep it approximately
consistent with other values already present in
<literal>nixpkgs</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>hydraPlatforms</varname>

View File

@ -6,13 +6,13 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-multiple-output">
<title>Multiple-output packages</title>
<section>
<section xml:id="sec-multiple-outputs-introduction">
<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
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.
@ -38,7 +38,7 @@
</para>
</note>
</section>
<section>
<section xml:id="sec-multiple-outputs-installing">
<title>Installing a split package</title>
<para>
@ -84,7 +84,7 @@
</listitem>
</itemizedlist>
</section>
<section>
<section xml:id="sec-multiple-outputs-using-split-packages">
<title>Using a split package</title>
<para>
@ -101,8 +101,15 @@
contain <varname>$outputBin</varname> and <varname>$outputLib</varname> are
also added. (See <xref linkend="multiple-output-file-type-groups" />.)
</para>
<para>
In some cases it may be desirable to combine different outputs under a
single store path. A function <literal>symlinkJoin</literal> can be used to
do this. (Note that it may negate some closure size benefits of using a
multiple-output package.)
</para>
</section>
<section>
<section xml:id="sec-multiple-outputs-">
<title>Writing a split derivation</title>
<para>
@ -283,7 +290,7 @@
</variablelist>
</section>
<section>
<section xml:id="sec-multiple-outputs-caveats">
<title>Common caveats</title>
<itemizedlist>

View File

@ -78,7 +78,7 @@ Step 2: build kernel headers for the target architecture
---
{stdenv, fetchurl}:
assert stdenv.system == "i686-linux";
assert stdenv.buildPlatform.system == "i686-linux";
stdenv.mkDerivation {
name = "linux-headers-2.6.13.1-arm";

View File

@ -3,9 +3,9 @@
xml:id="chap-overlays">
<title>Overlays</title>
<para>
This chapter describes how to extend and change Nixpkgs packages using
overlays. Overlays are used to add layers in the fix-point used by Nixpkgs to
compose the set of all packages.
This chapter describes how to extend and change Nixpkgs using overlays.
Overlays are used to add layers in the fixed-point used by Nixpkgs to compose
the set of all packages.
</para>
<para>
Nixpkgs can be configured with a list of overlays, which are applied in
@ -17,91 +17,122 @@
<title>Installing overlays</title>
<para>
The list of overlays is determined as follows.
The list of overlays can be set either explicitly in a Nix expression, or
through <literal>&lt;nixpkgs-overlays></literal> or user configuration
files.
</para>
<para>
If the <varname>overlays</varname> argument is not provided explicitly, we
look for overlays in a path. The path is determined as follows:
<orderedlist>
<listitem>
<para>
First, if an <varname>overlays</varname> argument to the nixpkgs function
itself is given, then that is used.
</para>
<para>
This can be passed explicitly when importing nipxkgs, for example
<literal>import &lt;nixpkgs> { overlays = [ overlay1 overlay2 ];
}</literal>.
</para>
</listitem>
<listitem>
<para>
Otherwise, if the Nix path entry <literal>&lt;nixpkgs-overlays></literal>
exists, we look for overlays at that path, as described below.
</para>
<para>
See the section on <literal>NIX_PATH</literal> in the Nix manual for more
details on how to set a value for
<literal>&lt;nixpkgs-overlays>.</literal>
</para>
</listitem>
<listitem>
<para>
If one of <filename>~/.config/nixpkgs/overlays.nix</filename> and
<filename>~/.config/nixpkgs/overlays/</filename> exists, then we look for
overlays at that path, as described below. It is an error if both exist.
</para>
</listitem>
</orderedlist>
</para>
<section xml:id="sec-overlays-argument">
<title>Set overlays in NixOS or Nix expressions</title>
<para>
If we are looking for overlays at a path, then there are two cases:
<itemizedlist>
<listitem>
<para>
If the path is a file, then the file is imported as a Nix expression and
used as the list of overlays.
</para>
</listitem>
<listitem>
<para>
If the path is a directory, then we take the content of the directory,
order it lexicographically, and attempt to interpret each as an overlay
by:
<itemizedlist>
<listitem>
<para>
Importing the file, if it is a <literal>.nix</literal> file.
</para>
</listitem>
<listitem>
<para>
Importing a top-level <filename>default.nix</filename> file, if it is
a directory.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
<para>
On a NixOS system the value of the <literal>nixpkgs.overlays</literal>
option, if present, is passed to the system Nixpkgs directly as an
argument. Note that this does not affect the overlays for non-NixOS
operations (e.g. <literal>nix-env</literal>), which are
<link xlink:href="#sec-overlays-lookup">looked</link> up independently.
</para>
<para>
On a NixOS system the value of the <literal>nixpkgs.overlays</literal>
option, if present, is passed to the system Nixpkgs directly as an argument.
Note that this does not affect the overlays for non-NixOS operations (e.g.
<literal>nix-env</literal>), which are looked up independently.
</para>
<para>
The list of overlays can be passed explicitly when importing nixpkgs, for
example <literal>import &lt;nixpkgs> { overlays = [ overlay1 overlay2 ];
}</literal>.
</para>
<para>
The <filename>overlays.nix</filename> option therefore provides a convenient
way to use the same overlays for a NixOS system configuration and user
configuration: the same file can be used as
<filename>overlays.nix</filename> and imported as the value of
<literal>nixpkgs.overlays</literal>.
</para>
<para>
Further overlays can be added by calling the <literal>pkgs.extend</literal>
or <literal>pkgs.appendOverlays</literal>, although it is often preferable
to avoid these functions, because they recompute the Nixpkgs fixpoint,
which is somewhat expensive to do.
</para>
</section>
<section xml:id="sec-overlays-lookup">
<title>Install overlays via configuration lookup</title>
<para>
The list of overlays is determined as follows.
</para>
<para>
<orderedlist>
<listitem>
<para>
First, if an
<link xlink:href="#sec-overlays-argument"><varname>overlays</varname>
argument</link> to the Nixpkgs function itself is given, then that is
used and no path lookup will be performed.
</para>
</listitem>
<listitem>
<para>
Otherwise, if the Nix path entry
<literal>&lt;nixpkgs-overlays></literal> exists, we look for overlays at
that path, as described below.
</para>
<para>
See the section on <literal>NIX_PATH</literal> in the Nix manual for
more details on how to set a value for
<literal>&lt;nixpkgs-overlays>.</literal>
</para>
</listitem>
<listitem>
<para>
If one of <filename>~/.config/nixpkgs/overlays.nix</filename> and
<filename>~/.config/nixpkgs/overlays/</filename> exists, then we look
for overlays at that path, as described below. It is an error if both
exist.
</para>
</listitem>
</orderedlist>
</para>
<para>
If we are looking for overlays at a path, then there are two cases:
<itemizedlist>
<listitem>
<para>
If the path is a file, then the file is imported as a Nix expression and
used as the list of overlays.
</para>
</listitem>
<listitem>
<para>
If the path is a directory, then we take the content of the directory,
order it lexicographically, and attempt to interpret each as an overlay
by:
<itemizedlist>
<listitem>
<para>
Importing the file, if it is a <literal>.nix</literal> file.
</para>
</listitem>
<listitem>
<para>
Importing a top-level <filename>default.nix</filename> file, if it is
a directory.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
<para>
Because overlays that are set in NixOS configuration do not affect
non-NixOS operations such as <literal>nix-env</literal>, the
<filename>overlays.nix</filename> option provides a convenient way to use
the same overlays for a NixOS system configuration and user configuration:
the same file can be used as <filename>overlays.nix</filename> and imported
as the value of <literal>nixpkgs.overlays</literal>.
</para>
<!-- TODO: Example of sharing overlays between NixOS configuration
and configuration lookup. Also reference the example
from the sec-overlays-argument paragraph about NixOS.
-->
</section>
</section>
<!--============================================================-->
<section xml:id="sec-overlays-definition">

View File

@ -181,7 +181,7 @@ $ cat $(PRINT_PATH=1 nix-prefetch-url $i | tail -n 1) \
</section>
<!--============================================================-->
<!--
<section>
<section xml:id="sec-package-notes-gnome">
<title>Gnome</title>
<para>* Expression is auto-generated</para>
<para>* How to update</para>
@ -189,7 +189,7 @@ $ cat $(PRINT_PATH=1 nix-prefetch-url $i | tail -n 1) \
-->
<!--============================================================-->
<!--
<section>
<section xml:id="sec-package-notes-gcc">
<title>GCC</title>
<para></para>
</section>
@ -205,7 +205,7 @@ $ cat $(PRINT_PATH=1 nix-prefetch-url $i | tail -n 1) \
<para>
Nixpkgs provides a number of packages that will install Eclipse in its
various forms, these range from the bare-bones Eclipse Platform to the more
various forms. These range from the bare-bones Eclipse Platform to the more
fully featured Eclipse SDK or Scala-IDE packages and multiple version are
often available. It is possible to list available Eclipse packages by
issuing the command:
@ -311,17 +311,18 @@ packageOverrides = pkgs: {
<title>Elm</title>
<para>
The Nix expressions for Elm reside in
<filename>pkgs/development/compilers/elm</filename>. They are generated
automatically by <command>update-elm.rb</command> script. One should specify
versions of Elm packages inside the script, clear the
<filename>packages</filename> directory and run the script from inside it.
<literal>elm-reactor</literal> is special because it also has Elm package
dependencies. The process is not automated very much for now -- you should
get the <literal>elm-reactor</literal> source tree (e.g. with
<command>nix-shell</command>) and run <command>elm2nix.rb</command> inside
it. Place the resulting <filename>package.nix</filename> file into
<filename>packages/elm-reactor-elm.nix</filename>.
To start a development environment do <command>nix-shell -p elmPackages.elm elmPackages.elm-format</command>
</para>
<para>
To update Elm compiler, see
<filename>nixpkgs/pkgs/development/compilers/elm/README.md</filename>.
</para>
<para>
To package Elm applications,
<link xlink:href="https://github.com/hercules-ci/elm2nix#elm2nix">read about
elm2nix</link>.
</para>
</section>
<section xml:id="sec-shell-helpers">
@ -413,11 +414,9 @@ packageOverrides = pkgs: {
in your <filename>/etc/nixos/configuration.nix</filename>. You'll also need
<programlisting>hardware.pulseaudio.support32Bit = true;</programlisting>
if you are using PulseAudio - this will enable 32bit ALSA apps integration.
To use the Steam controller, you need to add
<programlisting>services.udev.extraRules = ''
SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", MODE="0666"
KERNEL=="uinput", MODE="0660", GROUP="users", OPTIONS+="static_node=uinput"
'';</programlisting>
To use the Steam controller or other Steam supported controllers such as
the DualShock 4 or Nintendo Switch Pro, you need to add
<programlisting>hardware.steam-hardware.enable = true;</programlisting>
to your configuration.
</para>
</section>
@ -643,15 +642,15 @@ cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
required dependencies manually - but it's tedious and there is always a
possibility that an unwanted dependency will sneak in through some other
package. To completely override such a package you can use
<varname>overrideScope</varname>.
<varname>overrideScope'</varname>.
</para>
<screen>
overrides = super: self: rec {
overrides = self: super: rec {
haskell-mode = self.melpaPackages.haskell-mode;
...
};
((emacsPackagesNgGen emacs).overrideScope overrides).emacsWithPackages (p: with p; [
((emacsPackagesNgGen emacs).overrideScope' overrides).emacsWithPackages (p: with p; [
# here both these package will use haskell-mode of our own choice
ghc-mod
dante
@ -671,6 +670,9 @@ overrides = super: self: rec {
plugins = with availablePlugins; [ python perl ];
}
}</programlisting>
If the <literal>configure</literal> function returns an attrset without the
<literal>plugins</literal> attribute, <literal>availablePlugins</literal>
will be used automatically.
</para>
<para>
@ -680,10 +682,10 @@ overrides = super: self: rec {
</para>
<para>
The python plugin allows the addition of extra libraries. For instance, the
<literal>inotify.py</literal> script in weechat-scripts requires D-Bus or
libnotify, and the <literal>fish.py</literal> script requires pycrypto. To
use these scripts, use the <literal>python</literal> plugin's
The python and perl plugins allows the addition of extra libraries. For
instance, the <literal>inotify.py</literal> script in weechat-scripts
requires D-Bus or libnotify, and the <literal>fish.py</literal> script
requires pycrypto. To use these scripts, use the plugin's
<literal>withPackages</literal> attribute:
<programlisting>weechat.override { configure = {availablePlugins, ...}: {
plugins = with availablePlugins; [
@ -704,45 +706,110 @@ overrides = super: self: rec {
}; }
</programlisting>
</para>
<para>
WeeChat allows to set defaults on startup using the
<literal>--run-command</literal>. The <literal>configure</literal> method
can be used to pass commands to the program:
<programlisting>weechat.override {
configure = { availablePlugins, ... }: {
init = ''
/set foo bar
/server add freenode chat.freenode.org
'';
};
}</programlisting>
Further values can be added to the list of commands when running
<literal>weechat --run-command "your-commands"</literal>.
</para>
<para>
Additionally it's possible to specify scripts to be loaded when starting
<literal>weechat</literal>. These will be loaded before the commands from
<literal>init</literal>:
<programlisting>weechat.override {
configure = { availablePlugins, ... }: {
scripts = with pkgs.weechatScripts; [
weechat-xmpp weechat-matrix-bridge wee-slack
];
init = ''
/set plugins.var.python.jabber.key "val"
'':
};
}</programlisting>
</para>
<para>
In <literal>nixpkgs</literal> there's a subpackage which contains
derivations for WeeChat scripts. Such derivations expect a
<literal>passthru.scripts</literal> attribute which contains a list of all
scripts inside the store path. Furthermore all scripts have to live in
<literal>$out/share</literal>. An exemplary derivation looks like this:
<programlisting>{ stdenv, fetchurl }:
stdenv.mkDerivation {
name = "exemplary-weechat-script";
src = fetchurl {
url = "https://scripts.tld/your-scripts.tar.gz";
sha256 = "...";
};
passthru.scripts = [ "foo.py" "bar.lua" ];
installPhase = ''
mkdir $out/share
cp foo.py $out/share
cp bar.lua $out/share
'';
}</programlisting>
</para>
</section>
<section xml:id="sec-citrix">
<title>Citrix Receiver</title>
<para>
The <link xlink:href="https://www.citrix.com/products/receiver/">Citrix Receiver</link> is a remote
desktop viewer which provides access to
<link xlink:href="https://www.citrix.com/products/xenapp-xendesktop/">XenDesktop</link> installations.
The <link xlink:href="https://www.citrix.com/products/receiver/">Citrix
Receiver</link> is a remote desktop viewer which provides access to
<link xlink:href="https://www.citrix.com/products/xenapp-xendesktop/">XenDesktop</link>
installations.
</para>
<section xml:id="sec-citrix-base">
<title>Basic usage</title>
<para>
The tarball archive needs to be downloaded manually as the licenses agreements of the vendor
need to be accepted first. This is available at the
<link xlink:href="https://www.citrix.com/downloads/citrix-receiver/">download page at citrix.com</link>.
Then run <literal>nix-prefetch-url file://$PWD/linuxx64-$version.tar.gz</literal>.
With the archive available in the store the package can be built and installed with Nix.
The tarball archive needs to be downloaded manually as the licenses
agreements of the vendor need to be accepted first. This is available at
the
<link xlink:href="https://www.citrix.com/downloads/citrix-receiver/">download
page at citrix.com</link>. Then run <literal>nix-prefetch-url
file://$PWD/linuxx64-$version.tar.gz</literal>. With the archive available
in the store the package can be built and installed with Nix.
</para>
<para>
<emphasis>Note: it's recommended to install <literal>Citrix Receiver</literal> using
<literal>nix-env -i</literal> or globally to ensure that the <literal>.desktop</literal> files
are installed properly into <literal>$XDG_CONFIG_DIRS</literal>. Otherwise it won't
be possible to open <literal>.ica</literal> files
automatically from the browser to start a Citrix connection.</emphasis>
<emphasis>Note: it's recommended to install <literal>Citrix
Receiver</literal> using <literal>nix-env -i</literal> or globally to
ensure that the <literal>.desktop</literal> files are installed properly
into <literal>$XDG_CONFIG_DIRS</literal>. Otherwise it won't be possible to
open <literal>.ica</literal> files automatically from the browser to start
a Citrix connection.</emphasis>
</para>
</section>
<section xml:id="sec-citrix-custom-certs">
<title>Custom certificates</title>
<para>
The <literal>Citrix Receiver</literal> in <literal>nixpkgs</literal> trusts several certificates
<link xlink:href="https://curl.haxx.se/docs/caextract.html">from the Mozilla database</link> by default.
However several companies using Citrix might require their own corporate certificate. On distros with imperative
The <literal>Citrix Receiver</literal> in <literal>nixpkgs</literal> trusts
several certificates
<link xlink:href="https://curl.haxx.se/docs/caextract.html">from the
Mozilla database</link> by default. However several companies using Citrix
might require their own corporate certificate. On distros with imperative
packaging these certs can be stored easily in
<link xlink:href="https://developer-docs.citrix.com/projects/receiver-for-linux-command-reference/en/13.7/"><literal>$ICAROOT</literal></link>,
however this directory is a store path in <literal>nixpkgs</literal>. In order to work around this issue the package provides a simple
mechanism to add custom certificates without rebuilding the entire package using <literal>symlinkJoin</literal>:
however this directory is a store path in <literal>nixpkgs</literal>. In
order to work around this issue the package provides a simple mechanism to
add custom certificates without rebuilding the entire package using
<literal>symlinkJoin</literal>:
<programlisting>
<![CDATA[with import <nixpkgs> { config.allowUnfree = true; };
let extraCerts = [ ./custom-cert-1.pem ./custom-cert-2.pem /* ... */ ]; in
@ -753,4 +820,102 @@ citrix_receiver.override {
</para>
</section>
</section>
<section xml:id="sec-ibus-typing-booster">
<title>ibus-engines.typing-booster</title>
<para>
This package is an ibus-based completion method to speed up typing.
</para>
<section xml:id="sec-ibus-typing-booster-activate">
<title>Activating the engine</title>
<para>
IBus needs to be configured accordingly to activate
<literal>typing-booster</literal>. The configuration depends on the desktop
manager in use. For detailed instructions, please refer to the
<link xlink:href="https://mike-fabian.github.io/ibus-typing-booster/documentation.html">upstream
docs</link>.
</para>
<para>
On NixOS you need to explicitly enable <literal>ibus</literal> with given
engines before customizing your desktop to use
<literal>typing-booster</literal>. This can be achieved using the
<literal>ibus</literal> module:
<programlisting>{ pkgs, ... }: {
i18n.inputMethod = {
enabled = "ibus";
ibus.engines = with pkgs.ibus-engines; [ typing-booster ];
};
}</programlisting>
</para>
</section>
<section xml:id="sec-ibus-typing-booster-customize-hunspell">
<title>Using custom hunspell dictionaries</title>
<para>
The IBus engine is based on <literal>hunspell</literal> to support
completion in many languages. By default the dictionaries
<literal>de-de</literal>, <literal>en-us</literal>,
<literal>es-es</literal>, <literal>it-it</literal>,
<literal>sv-se</literal> and <literal>sv-fi</literal> are in use. To add
another dictionary, the package can be overridden like this:
<programlisting>ibus-engines.typing-booster.override {
langs = [ "de-at" "en-gb" ];
}</programlisting>
</para>
<para>
<emphasis>Note: each language passed to <literal>langs</literal> must be an
attribute name in <literal>pkgs.hunspellDicts</literal>.</emphasis>
</para>
</section>
<section xml:id="sec-ibus-typing-booster-emoji-picker">
<title>Built-in emoji picker</title>
<para>
The <literal>ibus-engines.typing-booster</literal> package contains a
program named <literal>emoji-picker</literal>. To display all emojis
correctly, a special font such as <literal>noto-fonts-emoji</literal> is
needed:
</para>
<para>
On NixOS it can be installed using the following expression:
<programlisting>{ pkgs, ... }: {
fonts.fonts = with pkgs; [ noto-fonts-emoji ];
}</programlisting>
</para>
</section>
</section>
<section xml:id="dlib">
<title>DLib</title>
<para>
<link xlink:href="http://dlib.net/">DLib</link> is a modern, C++-based toolkit which
provides several machine learning algorithms.
</para>
<section xml:id="compiling-without-avx-support">
<title>Compiling without AVX support</title>
<para>
Especially older CPUs don't support
<link xlink:href="https://en.wikipedia.org/wiki/Advanced_Vector_Extensions">AVX</link>
(<abbrev>Advanced Vector Extensions</abbrev>) instructions that are used by DLib to
optimize their algorithms.
</para>
<para>
On the affected hardware errors like <literal>Illegal instruction</literal> will occur.
In those cases AVX support needs to be disabled:
<programlisting>self: super: {
dlib = super.dlib.override { avxSupport = false; };
}</programlisting>
</para>
</section>
</section>
</chapter>

View File

@ -6,13 +6,13 @@
<title>Darwin (macOS)</title>
<para>
Some common issues when packaging software for darwin:
Some common issues when packaging software for Darwin:
</para>
<itemizedlist>
<listitem>
<para>
The darwin <literal>stdenv</literal> uses clang instead of gcc. When
The Darwin <literal>stdenv</literal> uses clang instead of gcc. When
referring to the compiler <varname>$CC</varname> or <command>cc</command>
will work in both cases. Some builds hardcode gcc/g++ in their build
scripts, that can usually be fixed with using something like
@ -29,10 +29,9 @@
}
</programlisting>
</listitem>
<listitem>
<para>
On darwin libraries are linked using absolute paths, libraries are
On Darwin, libraries are linked using absolute paths, libraries are
resolved by their <literal>install_name</literal> at link time. Sometimes
packages won't set this correctly causing the library lookups to fail at
runtime. This can be fixed by adding extra linker flags or by running
@ -47,19 +46,19 @@
}
</programlisting>
</listitem>
<listitem>
<para>
Even if the libraries are linked using absolute paths and resolved via
their <literal>install_name</literal> correctly, tests can sometimes fail
to run binaries. This happens because the <varname>checkPhase</varname>
to run binaries. This happens because the <varname>checkPhase</varname>
runs before the libraries are installed.
</para>
<para>
This can usually be solved by running the tests after the
<varname>installPhase</varname> or alternatively by using
<varname>DYLD_LIBRARY_PATH</varname>. More information about this variable
can be found in the <citerefentry><refentrytitle>dyld</refentrytitle>
can be found in the <citerefentry>
<refentrytitle>dyld</refentrytitle>
<manvolnum>1</manvolnum></citerefentry> manpage.
</para>
<programlisting>
@ -77,7 +76,6 @@
}
</programlisting>
</listitem>
<listitem>
<para>
Some packages assume xcode is available and use <command>xcrun</command>
@ -98,8 +96,8 @@
</programlisting>
<para>
The package <literal>xcbuild</literal> can be used to build projects that
really depend on Xcode, however projects that build some kind of graphical
interface won't work without using Xcode in an impure way.
really depend on Xcode. However, this replacement is not 100% compatible
with Xcode and can occasionally cause issues.
</para>
</listitem>
</itemizedlist>

View File

@ -147,9 +147,9 @@ $ git add pkgs/development/libraries/libfoo/default.nix</screen>
</listitem>
<listitem>
<para>
You can use <command>nix-prefetch-url</command> (or similar
nix-prefetch-git, etc) <replaceable>url</replaceable> to get the
SHA-256 hash of source distributions. There are similar commands as
You can use <command>nix-prefetch-url</command>
<replaceable>url</replaceable> to get the SHA-256 hash of source
distributions. There are similar commands as
<command>nix-prefetch-git</command> and
<command>nix-prefetch-hg</command> available in
<literal>nix-prefetch-scripts</literal> package.

View File

@ -2,7 +2,7 @@
<article xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Nixpkgs Release Notes</title>
<section>
<section xml:id="release-notes-0.14">
<title>Release 0.14 (June 4, 2012)</title>
<para>
@ -17,7 +17,7 @@
packages by numerous contributors. For details, see the commit logs.
</para>
</section>
<section>
<section xml:id="release-notes-0.13">
<title>Release 0.13 (February 5, 2010)</title>
<para>
@ -51,7 +51,7 @@
</itemizedlist>
</para>
</section>
<section>
<section xml:id="release-notes-0.12">
<title>Release 0.12 (April 24, 2009)</title>
<para>
@ -145,7 +145,7 @@
<literal>nix-dev</literal> mailing list.
</para>
</section>
<section>
<section xml:id="release-notes-0.11">
<title>Release 0.11 (September 11, 2007)</title>
<para>
@ -344,7 +344,7 @@ export NIX_MIRRORS_sourceforge=http://osdn.dl.sourceforge.net/sourceforge/</prog
Bravenboer, Michael Raskin, Wouter den Breejen and Yury G. Kudryashov.
</para>
</section>
<section>
<section xml:id="release-notes-0.10">
<title>Release 0.10 (October 12, 2006)</title>
<note>
@ -547,7 +547,7 @@ stdenv.mkDerivation {
Bravenboer, Merijn de Jonge, Rob Vermaas and Roy van den Broek.
</para>
</section>
<section>
<section xml:id="release-notes-0.9">
<title>Release 0.9 (January 31, 2006)</title>
<para>
@ -676,7 +676,7 @@ stdenv.mkDerivation {
Martin Bravenboer, Rob Vermaas and Roy van den Broek.
</para>
</section>
<section>
<section xml:id="release-notes-0.8">
<title>Release 0.8 (April 11, 2005)</title>
<para>
@ -700,7 +700,7 @@ stdenv.mkDerivation {
</itemizedlist>
</para>
</section>
<section>
<section xml:id="release-notes-0.7">
<title>Release 0.7 (March 14, 2005)</title>
<itemizedlist>

View File

@ -6,31 +6,33 @@
<title>Reviewing contributions</title>
<warning>
<para>
The following section is a draft, and the policy for reviewing is still being
discussed in issues such as <link
The following section is a draft, and the policy for reviewing is still
being discussed in issues such as
<link
xlink:href="https://github.com/NixOS/nixpkgs/issues/11166">#11166
</link> and <link
</link> and
<link
xlink:href="https://github.com/NixOS/nixpkgs/issues/20836">#20836
</link>.
</para>
</warning>
<para>
The nixpkgs project receives a fairly high number of contributions via
GitHub pull-requests. Reviewing and approving these is an important task and
a way to contribute to the project.
The Nixpkgs project receives a fairly high number of contributions via GitHub
pull requests. Reviewing and approving these is an important task and a way
to contribute to the project.
</para>
<para>
The high change rate of nixpkgs makes any pull request that remains open for
The high change rate of Nixpkgs makes any pull request that remains open for
too long subject to conflicts that will require extra work from the submitter
or the merger. Reviewing pull requests in a timely manner and being
responsive to the comments is the key to avoid these. GitHub provides sort
filters that can be used to see the
responsive to the comments is the key to avoid this issue. GitHub provides
sort filters that can be used to see the
<link
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc">most
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc">most
recently</link> and the
<link
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc">least
recently</link> updated pull-requests. We highly encourage looking at
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc">least
recently</link> updated pull requests. We highly encourage looking at
<link xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+review%3Anone+status%3Asuccess+-label%3A%222.status%3A+work-in-progress%22+no%3Aproject+no%3Aassignee+no%3Amilestone">
this list of ready to merge, unreviewed pull requests</link>.
</para>
@ -40,13 +42,13 @@
to respect every community member and their work.
</para>
<para>
GitHub provides reactions as a simple and quick way to provide
feedback to pull-requests or any comments. The thumb-down reaction should be
used with care and if possible accompanied with some explanation so the
submitter has directions to improve their contribution.
GitHub provides reactions as a simple and quick way to provide feedback to
pull requests or any comments. The thumb-down reaction should be used with
care and if possible accompanied with some explanation so the submitter has
directions to improve their contribution.
</para>
<para>
Pull-request reviews should include a list of what has been reviewed in a
pull request reviews should include a list of what has been reviewed in a
comment, so other reviewers and mergers can know the state of the review.
</para>
<para>
@ -54,12 +56,12 @@
meant as examples. Their usage is optional and the reviewer is free to adapt
them to their liking.
</para>
<section>
<section xml:id="reviewing-contributions-package-updates">
<title>Package updates</title>
<para>
A package update is the most trivial and common type of pull-request. These
pull-requests mainly consist of updating the version part of the package
A package update is the most trivial and common type of pull request. These
pull requests mainly consist of updating the version part of the package
name and the source hash.
</para>
@ -75,7 +77,7 @@
<itemizedlist>
<listitem>
<para>
Add labels to the pull-request. (Requires commit rights)
Add labels to the pull request. (Requires commit rights)
</para>
<itemizedlist>
<listitem>
@ -117,8 +119,8 @@
<itemizedlist>
<listitem>
<para>
License can change with version updates, so it should be checked to match
the upstream license.
License can change with version updates, so it should be checked to
match the upstream license.
</para>
</listitem>
<listitem>
@ -142,9 +144,9 @@
<itemizedlist>
<listitem>
<para>
Pull-requests are often targeted to the master or staging branch, and
building the pull-request locally when it is submitted can trigger
many source builds.
pull requests are often targeted to the master or staging branch, and
building the pull request locally when it is submitted can trigger many
source builds.
</para>
<para>
It is possible to rebase the changes on nixos-unstable or
@ -172,14 +174,14 @@ $ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD <co
</callout>
<callout arearefs='reviewing-rebase-3'>
<para>
Fetching the pull-request changes, <varname>PRNUMBER</varname> is the
number at the end of the pull-request title and
<varname>BASEBRANCH</varname> the base branch of the pull-request.
Fetching the pull request changes, <varname>PRNUMBER</varname> is the
number at the end of the pull request title and
<varname>BASEBRANCH</varname> the base branch of the pull request.
</para>
</callout>
<callout arearefs='reviewing-rebase-4'>
<para>
Rebasing the pull-request changes to the nixos-unstable branch.
Rebasing the pull request changes to the nixos-unstable branch.
</para>
</callout>
</calloutlist>
@ -187,14 +189,15 @@ $ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD <co
</listitem>
<listitem>
<para>
The <link xlink:href="https://github.com/madjar/nox">nox</link> tool can
be used to review a pull-request content in a single command. It doesn't
rebase on a channel branch so it might trigger multiple source builds.
The
<link xlink:href="https://github.com/Mic92/nix-review">nix-review</link>
tool can be used to review a pull request content in a single command.
<varname>PRNUMBER</varname> should be replaced by the number at the end
of the pull-request title.
of the pull request title. You can also provide the full github pull
request url.
</para>
<screen>
$ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
$ nix-shell -p nix-review --run "nix-review pr PRNUMBER"
</screen>
</listitem>
</itemizedlist>
@ -206,7 +209,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</listitem>
</itemizedlist>
<example>
<example xml:id="reviewing-contributions-sample-package-update">
<title>Sample template for a package update review</title>
<screen>
##### Reviewed points
@ -224,11 +227,11 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</screen>
</example>
</section>
<section>
<section xml:id="reviewing-contributions-new-packages">
<title>New packages</title>
<para>
New packages are a common type of pull-requests. These pull requests
New packages are a common type of pull requests. These pull requests
consists in adding a new nix-expression for a package.
</para>
@ -239,7 +242,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
<itemizedlist>
<listitem>
<para>
Add labels to the pull-request. (Requires commit rights)
Add labels to the pull request. (Requires commit rights)
</para>
<itemizedlist>
<listitem>
@ -277,7 +280,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</listitem>
<listitem>
<para>
A maintainer must be set, this can be the package submitter or a
A maintainer must be set. This can be the package submitter or a
community member that accepts to take maintainership of the package.
</para>
</listitem>
@ -318,7 +321,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</listitem>
</itemizedlist>
<example>
<example xml:id="reviewing-contributions-sample-new-package">
<title>Sample template for a new package review</title>
<screen>
##### Reviewed points
@ -344,7 +347,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</screen>
</example>
</section>
<section>
<section xml:id="reviewing-contributions-module-updates">
<title>Module updates</title>
<para>
@ -359,7 +362,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
<itemizedlist>
<listitem>
<para>
Add labels to the pull-request. (Requires commit rights)
Add labels to the pull request. (Requires commit rights)
</para>
<itemizedlist>
<listitem>
@ -441,7 +444,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</listitem>
</itemizedlist>
<example>
<example xml:id="reviewing-contributions-sample-module-update">
<title>Sample template for a module update review</title>
<screen>
##### Reviewed points
@ -462,7 +465,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</screen>
</example>
</section>
<section>
<section xml:id="reviewing-contributions-new-modules">
<title>New modules</title>
<para>
@ -472,7 +475,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
<itemizedlist>
<listitem>
<para>
Add labels to the pull-request. (Requires commit rights)
Add labels to the pull request. (Requires commit rights)
</para>
<itemizedlist>
<listitem>
@ -540,7 +543,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</listitem>
</itemizedlist>
<example>
<example xml:id="reviewing-contributions-sample-new-module">
<title>Sample template for a new module review</title>
<screen>
##### Reviewed points
@ -562,7 +565,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
</screen>
</example>
</section>
<section>
<section xml:id="reviewing-contributions-other-submissions">
<title>Other submissions</title>
<para>
@ -574,7 +577,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
like to be a long-term reviewer for related submissions, please contact the
current reviewers for that topic. They will give you information about the
reviewing process. The main reviewers for a topic can be hard to find as
there is no list, but checking past pull-requests to see who reviewed or
there is no list, but checking past pull requests to see who reviewed or
git-blaming the code to see who committed to that topic can give some hints.
</para>
@ -583,8 +586,8 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
pull requests fitting this category.
</para>
</section>
<section>
<title>Merging pull-requests</title>
<section xml:id="reviewing-contributions--merging-pull-requests">
<title>Merging pull requests</title>
<para>
It is possible for community members that have enough knowledge and
@ -605,10 +608,12 @@ policy.
-->
<para>
In a case a contributor leaves definitively the Nix community, he should
create an issue or notify the mailing list with references of packages and
modules he maintains so the maintainership can be taken over by other
contributors.
In a case a contributor definitively leaves the Nix community, they should
create an issue or post on
<link
xlink:href="https://discourse.nixos.org">Discourse</link> with
references of packages and modules they maintain so the maintainership can
be taken over by other contributors.
</para>
</section>
</chapter>

View File

@ -1,5 +1,5 @@
{ pkgs ? import ../. {} }:
(import ./default.nix).overrideAttrs (x: {
(import ./default.nix {}).overrideAttrs (x: {
buildInputs = x.buildInputs ++ [ pkgs.xmloscopy pkgs.ruby ];
})

View File

@ -1,22 +0,0 @@
---
title: pkgs.mkShell
author: zimbatm
date: 2017-10-30
---
# mkShell
pkgs.mkShell is a special kind of derivation that is only useful when using
it combined with nix-shell. It will in fact fail to instantiate when invoked
with nix-build.
## Usage
```nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# this will make all the build inputs from hello and gnutar available to the shell environment
inputsFrom = with pkgs; [ hello gnutar ];
buildInputs = [ pkgs.gnumake ];
}
```

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@
body
{
font-family: "Nimbus Sans L", sans-serif;
font-size: 1em;
background: white;
margin: 2em 1em 2em 1em;
}
@ -28,6 +29,25 @@ h2 /* chapters, appendices, subtitle */
font-size: 180%;
}
div.book
{
text-align: center;
}
div.book > div
{
/*
* based on https://medium.com/@zkareemz/golden-ratio-62b3b6d4282a
* we do 70 characters per line to fit code listings better
* 70 * (font-size / 1.618)
* expression for emacs:
* (* 70 (/ 1 1.618))
*/
max-width: 43.2em;
text-align: left;
margin: auto;
}
/* Extra space between chapters, appendices. */
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
{
@ -102,8 +122,8 @@ pre.screen, pre.programlisting
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
margin-left: 0.5em;
margin-right: 0.5em;
background: #f4f4f8;
font-family: monospace;

View File

@ -2,7 +2,7 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-submitting-changes">
<title>Submitting changes</title>
<section>
<section xml:id="submitting-changes-making-patches">
<title>Making patches</title>
<itemizedlist>
@ -205,7 +205,7 @@ Additional information.
</listitem>
</itemizedlist>
</section>
<section>
<section xml:id="submitting-changes-submitting-changes">
<title>Submitting changes</title>
<itemizedlist>
@ -253,7 +253,7 @@ Additional information.
</listitem>
</itemizedlist>
</section>
<section>
<section xml:id="submitting-changes-pull-request-template">
<title>Pull Request Template</title>
<para>
@ -269,7 +269,7 @@ Additional information.
below:
</para>
<section>
<section xml:id="submitting-changes-tested-with-sandbox">
<title>Tested using sandboxing</title>
<para>
@ -322,7 +322,7 @@ Additional information.
</para>
</section>
<section>
<section xml:id="submitting-changes-platform-diversity">
<title>Built on platform(s)</title>
<para>
@ -334,7 +334,7 @@ Additional information.
</para>
</section>
<section>
<section xml:id="submitting-changes-nixos-tests">
<title>Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)</title>
<para>
@ -350,30 +350,29 @@ Additional information.
</para>
</section>
<section>
<title>Tested compilation of all pkgs that depend on this change using <command>nox-review</command></title>
<section xml:id="submitting-changes-tested-compilation">
<title>Tested compilation of all pkgs that depend on this change using <command>nix-review</command></title>
<para>
If you are updating a package's version, you can use nox to make sure all
packages that depend on the updated package still compile correctly. This
can be done using the nox utility. The <command>nox-review</command>
utility can look for and build all dependencies either based on uncommited
changes with the <literal>wip</literal> option or specifying a github pull
request number.
</para>
<para>
review uncommitted changes:
<screen>nix-shell -p nox --run "nox-review wip"</screen>
If you are updating a package's version, you can use nix-review to make
sure all packages that depend on the updated package still compile
correctly. The <command>nix-review</command> utility can look for and build
all dependencies either based on uncommited changes with the
<literal>wip</literal> option or specifying a github pull request number.
</para>
<para>
review changes from pull request number 12345:
<screen>nix-shell -p nox --run "nox-review pr 12345"</screen>
<screen>nix-shell -p nix-review --run "nix-review pr 12345"</screen>
</para>
<para>
review uncommitted changes:
<screen>nix-shell -p nix-review --run "nix-review wip"</screen>
</para>
</section>
<section>
<section xml:id="submitting-changes-tested-execution">
<title>Tested execution of all binary files (usually in <filename>./result/bin/</filename>)</title>
<para>
@ -387,8 +386,8 @@ Additional information.
</para>
</section>
<section>
<title>Meets nixpkgs contribution standards</title>
<section xml:id="submitting-changes-contribution-standards">
<title>Meets Nixpkgs contribution standards</title>
<para>
The last checkbox is fits
@ -402,7 +401,7 @@ Additional information.
</para>
</section>
</section>
<section>
<section xml:id="submitting-changes-hotfixing-pull-requests">
<title>Hotfixing pull requests</title>
<itemizedlist>
@ -430,7 +429,7 @@ Additional information.
</listitem>
</itemizedlist>
</section>
<section>
<section xml:id="submitting-changes-commit-policy">
<title>Commit policy</title>
<itemizedlist>
@ -456,7 +455,7 @@ Additional information.
</listitem>
</itemizedlist>
<section>
<section xml:id="submitting-changes-master-branch">
<title>Master branch</title>
<itemizedlist>
@ -468,7 +467,7 @@ Additional information.
</itemizedlist>
</section>
<section>
<section xml:id="submitting-changes-staging-branch">
<title>Staging branch</title>
<itemizedlist>
@ -493,7 +492,7 @@ Additional information.
</itemizedlist>
</section>
<section>
<section xml:id="submitting-changes-stable-release-branches">
<title>Stable release branches</title>
<itemizedlist>

44
lib/asserts.nix Normal file
View File

@ -0,0 +1,44 @@
{ lib }:
rec {
/* Print a trace message if pred is false.
Intended to be used to augment asserts with helpful error messages.
Example:
assertMsg false "nope"
=> false
stderr> trace: nope
assert (assertMsg ("foo" == "bar") "foo is not bar, silly"); ""
stderr> trace: foo is not bar, silly
stderr> assert failed at
Type:
assertMsg :: Bool -> String -> Bool
*/
# TODO(Profpatsch): add tests that check stderr
assertMsg = pred: msg:
if pred
then true
else builtins.trace msg false;
/* Specialized `assertMsg` for checking if val is one of the elements
of a list. Useful for checking enums.
Example:
let sslLibrary = "libressl"
in assertOneOf "sslLibrary" sslLibrary [ "openssl" "bearssl" ]
=> false
stderr> trace: sslLibrary must be one of "openssl", "bearssl", but is: "libressl"
Type:
assertOneOf :: String -> ComparableVal -> List ComparableVal -> Bool
*/
assertOneOf = name: val: xs: assertMsg
(lib.elem val xs)
"${name} must be one of ${
lib.generators.toPretty {} xs}, but is: ${
lib.generators.toPretty {} val}";
}

View File

@ -94,6 +94,15 @@ rec {
attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs);
/* Given a set of attribute names, return the set of the corresponding
attributes from the given set.
Example:
getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; }
=> { a = 1; b = 2; }
*/
getAttrs = names: attrs: genAttrs names (name: attrs.${name});
/* Collect each attribute named `attr' from a list of attribute
sets. Sets that don't contain the named attribute are ignored.
@ -145,7 +154,7 @@ rec {
foldAttrs = op: nul: list_of_attrs:
fold (n: a:
fold (name: o:
o // (listToAttrs [{inherit name; value = op n.${name} (a.${name} or nul); }])
o // { ${name} = op n.${name} (a.${name} or nul); }
) a (attrNames n)
) {} list_of_attrs;
@ -435,12 +444,15 @@ rec {
useful for deep-overriding.
Example:
x = { a = { b = 4; c = 3; }; }
overrideExisting x { a = { b = 6; d = 2; }; }
=> { a = { b = 6; d = 2; }; }
overrideExisting {} { a = 1; }
=> {}
overrideExisting { b = 2; } { a = 1; }
=> { b = 2; }
overrideExisting { a = 3; b = 2; } { a = 1; }
=> { a = 1; b = 2; }
*/
overrideExisting = old: new:
old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] old.${attr} new)) (attrNames old));
mapAttrs (name: value: new.${name} or value) old;
/* Get a package output.
If no output is found, fallback to `.out` and then to the default.

View File

@ -1,113 +0,0 @@
{lib, pkgs}:
let inherit (lib) nvs; in
{
# composableDerivation basically mixes these features:
# - fix function
# - mergeAttrBy
# - provides shortcuts for "options" such as "--enable-foo" and adding
# buildInputs, see php example
#
# It predates styles which are common today, such as
# * the config attr
# * mkDerivation.override feature
# * overrideDerivation (lib/customization.nix)
#
# Some of the most more important usage examples (which could be rewritten if it was important):
# * php
# * postgis
# * vim_configurable
#
# A minimal example illustrating most features would look like this:
# let base = composableDerivation { (fixed: let inherit (fixed.fixed) name in {
# src = fetchurl {
# }
# buildInputs = [A];
# preConfigre = "echo ${name}";
# # attention, "name" attr is missing, thus you cannot instantiate "base".
# }
# in {
# # These all add name attribute, thus you can instantiate those:
# v1 = base.merge ({ name = "foo-add-B"; buildInputs = [B]; }); // B gets merged into buildInputs
# v2 = base.merge ({ name = "mix-in-pre-configure-lines" preConfigre = ""; });
# v3 = base.replace ({ name = "foo-no-A-only-B;" buildInputs = [B]; });
# }
#
# So yes, you can think about it being something like nixos modules, and
# you'd be merging "features" in one at a time using .merge or .replace
# Thanks Shea for telling me that I rethink the documentation ..
#
# issues:
# * its complicated to understand
# * some "features" such as exact merge behaviour are buried in mergeAttrBy
# and defaultOverridableDelayableArgs assuming the default behaviour does
# the right thing in the common case
# * Eelco once said using such fix style functions are slow to evaluate
# * Too quick & dirty. Hard to understand for others. The benefit was that
# you were able to create a kernel builder like base derivation and replace
# / add patches the way you want without having to declare function arguments
#
# nice features:
# declaring "optional features" is modular. For instance:
# flags.curl = {
# configureFlags = ["--with-curl=${curl.dev}" "--with-curlwrappers"];
# buildInputs = [curl openssl];
# };
# flags.other = { .. }
# (Example taken from PHP)
#
# alternative styles / related features:
# * Eg see function supporting building the kernel
# * versionedDerivation (discussion about this is still going on - or ended)
# * composedArgsAndFun
# * mkDerivation.override
# * overrideDerivation
# * using { .., *Support ? false }: like configurable options.
# To find those examples use grep
#
# To sum up: It exists for historical reasons - and for most commonly used
# tasks the alternatives should be used
#
# If you have questions about this code ping Marc Weber.
composableDerivation = {
mkDerivation ? pkgs.stdenv.mkDerivation,
# list of functions to be applied before defaultOverridableDelayableArgs removes removeAttrs names
# prepareDerivationArgs handles derivation configurations
applyPreTidy ? [ lib.prepareDerivationArgs ],
# consider adding addtional elements by derivation.merge { removeAttrs = ["elem"]; };
removeAttrs ? ["cfg" "flags"]
}: (lib.defaultOverridableDelayableArgs ( a: mkDerivation a)
{
inherit applyPreTidy removeAttrs;
}).merge;
# some utility functions
# use this function to generate flag attrs for prepareDerivationArgs
# E nable D isable F eature
edf = {name, feat ? name, enable ? {}, disable ? {} , value ? ""}:
nvs name {
set = {
configureFlags = ["--enable-${feat}${if value == "" then "" else "="}${value}"];
} // enable;
unset = {
configureFlags = ["--disable-${feat}"];
} // disable;
};
# same for --with and --without-
# W ith or W ithout F eature
wwf = {name, feat ? name, enable ? {}, disable ? {}, value ? ""}:
nvs name {
set = enable // {
configureFlags = ["--with-${feat}${if value == "" then "" else "="}${value}"]
++ lib.maybeAttr "configureFlags" [] enable;
};
unset = disable // {
configureFlags = ["--without-${feat}"]
++ lib.maybeAttr "configureFlags" [] disable;
};
};
}

View File

@ -121,7 +121,7 @@ rec {
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
origArgs = auto // args;
pkgs = f origArgs;
mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
mkAttrOverridable = name: _: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
in lib.mapAttrs mkAttrOverridable pkgs;
@ -185,7 +185,7 @@ rec {
/* Make a set of packages with a common scope. All packages called
with the provided `callPackage' will be evaluated with the same
arguments. Any package in the set may depend on any other. The
`overrideScope' function allows subsequent modification of the package
`overrideScope'` function allows subsequent modification of the package
set in a consistent way, i.e. all packages in the set will be
called with the overridden packages. The package sets may be
hierarchical: the packages in the set are called with the scope
@ -195,10 +195,10 @@ rec {
let self = f self // {
newScope = scope: newScope (self // scope);
callPackage = self.newScope {};
# TODO(@Ericson2314): Haromonize argument order of `g` with everything else
overrideScope = g:
makeScope newScope
(lib.fixedPoints.extends (lib.flip g) f);
overrideScope = g: lib.warn
"`overrideScope` (from `lib.makeScope`) is deprecated. Do `overrideScope' (self: super: { })` instead of `overrideScope (super: self: { })`. All other overrides have the parameters in that order, including other definitions of `overrideScope`. This was the only definition violating the pattern."
(makeScope newScope (lib.fixedPoints.extends (lib.flip g) f));
overrideScope' = g: makeScope newScope (lib.fixedPoints.extends g f);
packages = f;
};
in self;

View File

@ -23,27 +23,54 @@ rec {
# -- TRACING --
/* Trace msg, but only if pred is true.
/* Conditionally trace the supplied message, based on a predicate.
Type: traceIf :: bool -> string -> a -> a
Example:
traceIf true "hello" 3
trace: hello
=> 3
*/
traceIf = pred: msg: x: if pred then trace msg x else x;
traceIf =
# Predicate to check
pred:
# Message that should be traced
msg:
# Value to return
x: if pred then trace msg x else x;
/* Trace the value and also return it.
/* Trace the supplied value after applying a function to it, and
return the original value.
Type: traceValFn :: (a -> b) -> a -> a
Example:
traceValFn (v: "mystring ${v}") "foo"
trace: mystring foo
=> "foo"
*/
traceValFn = f: x: trace (f x) x;
traceValFn =
# Function to apply
f:
# Value to trace and return
x: trace (f x) x;
/* Trace the supplied value and return it.
Type: traceVal :: a -> a
Example:
traceVal 42
# trace: 42
=> 42
*/
traceVal = traceValFn id;
/* `builtins.trace`, but the value is `builtins.deepSeq`ed first.
Type: traceSeq :: a -> b -> b
Example:
trace { a.b.c = 3; } null
trace: { a = <CODE>; }
@ -52,7 +79,11 @@ rec {
trace: { a = { b = { c = 3; }; }; }
=> null
*/
traceSeq = x: y: trace (builtins.deepSeq x x) y;
traceSeq =
# The value to trace
x:
# The value to return
y: trace (builtins.deepSeq x x) y;
/* Like `traceSeq`, but only evaluate down to depth n.
This is very useful because lots of `traceSeq` usages
@ -76,27 +107,49 @@ rec {
in trace (generators.toPretty { allowPrettyValues = true; }
(modify depth snip x)) y;
/* A combination of `traceVal` and `traceSeq` */
traceValSeqFn = f: v: traceValFn f (builtins.deepSeq v v);
/* A combination of `traceVal` and `traceSeq` that applies a
provided function to the value to be traced after `deepSeq`ing
it.
*/
traceValSeqFn =
# Function to apply
f:
# Value to trace
v: traceValFn f (builtins.deepSeq v v);
/* A combination of `traceVal` and `traceSeq`. */
traceValSeq = traceValSeqFn id;
/* A combination of `traceVal` and `traceSeqN` that applies a
provided function to the value to be traced. */
traceValSeqNFn =
# Function to apply
f:
depth:
# Value to trace
v: traceSeqN depth (f v) v;
/* A combination of `traceVal` and `traceSeqN`. */
traceValSeqNFn = f: depth: v: traceSeqN depth (f v) v;
traceValSeqN = traceValSeqNFn id;
# -- TESTING --
/* Evaluate a set of tests. A test is an attribute set {expr,
expected}, denoting an expression and its expected result. The
result is a list of failed tests, each represented as {name,
expected, actual}, denoting the attribute name of the failing
test and its expected and actual results. Used for regression
testing of the functions in lib; see tests.nix for an example.
Only tests having names starting with "test" are run.
Add attr { tests = ["testName"]; } to run these test only
/* Evaluate a set of tests. A test is an attribute set `{expr,
expected}`, denoting an expression and its expected result. The
result is a list of failed tests, each represented as `{name,
expected, actual}`, denoting the attribute name of the failing
test and its expected and actual results.
Used for regression testing of the functions in lib; see
tests.nix for an example. Only tests having names starting with
"test" are run.
Add attr { tests = ["testName"]; } to run these tests only.
*/
runTests = tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test:
runTests =
# Tests to run
tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test:
let testsToRun = if tests ? tests then tests.tests else [];
in if (substring 0 4 name == "test" || elem name testsToRun)
&& ((testsToRun == []) || elem name tests.tests)
@ -105,8 +158,11 @@ rec {
then [ { inherit name; expected = test.expected; result = test.expr; } ]
else [] ) tests));
# create a test assuming that list elements are true
# usage: { testX = allTrue [ true ]; }
/* Create a test assuming that list elements are `true`.
Example:
{ testX = allTrue [ true ]; }
*/
testAllTrue = expr: { inherit expr; expected = map (x: true) expr; };

View File

@ -38,10 +38,11 @@ let
systems = callLibs ./systems;
# misc
asserts = callLibs ./asserts.nix;
debug = callLibs ./debug.nix;
generators = callLibs ./generators.nix;
misc = callLibs ./deprecated.nix;
# domain-specific
fetchers = callLibs ./fetchers.nix;
@ -58,13 +59,12 @@ let
stringLength sub substring tail;
inherit (trivial) id const concat or and bitAnd bitOr bitXor bitNot
boolToString mergeAttrs flip mapNullable inNixShell min max
importJSON warn info nixpkgsVersion version mod compare
importJSON warn info showWarnings nixpkgsVersion version mod compare
splitByAndCompare functionArgs setFunctionArgs isFunction;
inherit (fixedPoints) fix fix' extends composeExtensions
inherit (fixedPoints) fix fix' converge extends composeExtensions
makeExtensible makeExtensibleWithCustomName;
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
getAttrFromPath attrVals attrValues catAttrs filterAttrs
getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
genAttrs isDerivation toDerivation optionalAttrs
@ -80,8 +80,8 @@ let
inherit (strings) concatStrings concatMapStrings concatImapStrings
intersperse concatStringsSep concatMapStringsSep
concatImapStringsSep makeSearchPath makeSearchPathOutput
makeLibraryPath makeBinPath makePerlPath makeFullPerlPath optionalString
hasPrefix hasSuffix stringToCharacters stringAsChars escape
makeLibraryPath makeBinPath optionalString
hasInfix hasPrefix hasSuffix stringToCharacters stringAsChars escape
escapeShellArg escapeShellArgs replaceChars lowerChars
upperChars toLower toUpper addContextFrom splitString
removePrefix removeSuffix versionOlder versionAtLeast getVersion
@ -94,7 +94,7 @@ let
callPackageWith callPackagesWith extendDerivation hydraJob
makeScope;
inherit (meta) addMetaAttrs dontDistribute setName updateName
appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
hiPrioSet;
inherit (sources) pathType pathIsDirectory cleanSourceFilter
cleanSource sourceByRegex sourceFilesBySuffices
@ -117,20 +117,22 @@ let
unknownModule mkOption;
inherit (types) isType setType defaultTypeMerge defaultFunctor
isOptionType mkOptionType;
inherit (asserts)
assertMsg assertOneOf;
inherit (debug) addErrorContextToAttrs traceIf traceVal traceValFn
traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal
traceShowValMarked showVal traceCall traceCall2 traceCall3
traceValIfNot runTests testAllTrue traceCallXml attrNamesToStr;
inherit (misc) maybeEnv defaultMergeArg defaultMerge foldArgs
defaultOverridableDelayableArgs composedArgsAndFun
maybeAttrNullable maybeAttr ifEnable checkFlag getValue
checkReqs uniqList uniqListExt condConcat lazyGenericClosure
innerModifySumArgs modifySumArgs innerClosePropagation
closePropagation mapAttrsFlatten nvs setAttr setAttrMerge
mergeAttrsWithFunc mergeAttrsConcatenateValues
mergeAttrsNoOverride mergeAttrByFunc mergeAttrsByFuncDefaults
mergeAttrsByFuncDefaultsClean mergeAttrBy prepareDerivationArgs
nixType imap overridableDelayableArgs;
mergeAttrsByFuncDefaultsClean mergeAttrBy
fakeSha256 fakeSha512
nixType imap;
});
in lib

View File

@ -35,74 +35,6 @@ rec {
withStdOverrides;
# predecessors: proposed replacement for applyAndFun (which has a bug cause it merges twice)
# the naming "overridableDelayableArgs" tries to express that you can
# - override attr values which have been supplied earlier
# - use attr values before they have been supplied by accessing the fix point
# name "fixed"
# f: the (delayed overridden) arguments are applied to this
#
# initial: initial attrs arguments and settings. see defaultOverridableDelayableArgs
#
# returns: f applied to the arguments // special attributes attrs
# a) merge: merge applied args with new args. Wether an argument is overridden depends on the merge settings
# b) replace: this let's you replace and remove names no matter which merge function has been set
#
# examples: see test cases "res" below;
overridableDelayableArgs =
f: # the function applied to the arguments
initial: # you pass attrs, the functions below are passing a function taking the fix argument
let
takeFixed = if lib.isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument
tidy = args:
let # apply all functions given in "applyPreTidy" in sequence
applyPreTidyFun = fold ( n: a: x: n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
in removeAttrs (applyPreTidyFun args) ( ["applyPreTidy"] ++ (maybeAttr "removeAttrs" [] args) ); # tidy up args before applying them
fun = n: x:
let newArgs = fixed:
let args = takeFixed fixed;
mergeFun = args.${n};
in if isAttrs x then (mergeFun args x)
else assert lib.isFunction x;
mergeFun args (x ( args // { inherit fixed; }));
in overridableDelayableArgs f newArgs;
in
(f (tidy (lib.fix takeFixed))) // {
merge = fun "mergeFun";
replace = fun "keepFun";
};
defaultOverridableDelayableArgs = f:
let defaults = {
mergeFun = mergeAttrByFunc; # default merge function. merge strategie (concatenate lists, strings) is given by mergeAttrBy
keepFun = a: b: { inherit (a) removeAttrs mergeFun keepFun mergeAttrBy; } // b; # even when using replace preserve these values
applyPreTidy = []; # list of functions applied to args before args are tidied up (usage case : prepareDerivationArgs)
mergeAttrBy = mergeAttrBy // {
applyPreTidy = a: b: a ++ b;
removeAttrs = a: b: a ++ b;
};
removeAttrs = ["mergeFun" "keepFun" "mergeAttrBy" "removeAttrs" "fixed" ]; # before applying the arguments to the function make sure these names are gone
};
in (overridableDelayableArgs f defaults).merge;
# rec { # an example of how composedArgsAndFun can be used
# a = composedArgsAndFun (x: x) { a = ["2"]; meta = { d = "bar";}; };
# # meta.d will be lost ! It's your task to preserve it (eg using a merge function)
# b = a.passthru.function { a = [ "3" ]; meta = { d2 = "bar2";}; };
# # instead of passing/ overriding values you can use a merge function:
# c = b.passthru.function ( x: { a = x.a ++ ["4"]; }); # consider using (maybeAttr "a" [] x)
# }
# result:
# {
# a = { a = ["2"]; meta = { d = "bar"; }; passthru = { function = .. }; };
# b = { a = ["3"]; meta = { d2 = "bar2"; }; passthru = { function = .. }; };
# c = { a = ["3" "4"]; meta = { d2 = "bar2"; }; passthru = { function = .. }; };
# # c2 is equal to c
# }
composedArgsAndFun = f: foldArgs defaultMerge f {};
# shortcut for attrByPath ["name"] default attrs
maybeAttrNullable = maybeAttr;
@ -285,7 +217,7 @@ rec {
# };
# will result in
# { mergeAttrsBy = [...]; buildInputs = [ a b c d ]; }
# is used by prepareDerivationArgs, defaultOverridableDelayableArgs and can be used when composing using
# is used by defaultOverridableDelayableArgs and can be used when composing using
# foldArgs, composedArgsAndFun or applyAndFun. Example: composableDerivation in all-packages.nix
mergeAttrByFunc = x: y:
let
@ -318,58 +250,6 @@ rec {
// listToAttrs (map (n: nameValuePair n (a: b: "${a}\n${b}") ) [ "preConfigure" "postInstall" ])
;
# prepareDerivationArgs tries to make writing configurable derivations easier
# example:
# prepareDerivationArgs {
# mergeAttrBy = {
# myScript = x: y: x ++ "\n" ++ y;
# };
# cfg = {
# readlineSupport = true;
# };
# flags = {
# readline = {
# set = {
# configureFlags = [ "--with-compiler=${compiler}" ];
# buildInputs = [ compiler ];
# pass = { inherit compiler; READLINE=1; };
# assertion = compiler.dllSupport;
# myScript = "foo";
# };
# unset = { configureFlags = ["--without-compiler"]; };
# };
# };
# src = ...
# buildPhase = '' ... '';
# name = ...
# myScript = "bar";
# };
# if you don't have need for unset you can omit the surrounding set = { .. } attr
# all attrs except flags cfg and mergeAttrBy will be merged with the
# additional data from flags depending on config settings
# It's used in composableDerivation in all-packages.nix. It's also used
# heavily in the new python and libs implementation
#
# should we check for misspelled cfg options?
# TODO use args.mergeFun here as well?
prepareDerivationArgs = args:
let args2 = { cfg = {}; flags = {}; } // args;
flagName = name: "${name}Support";
cfgWithDefaults = (listToAttrs (map (n: nameValuePair (flagName n) false) (attrNames args2.flags)))
// args2.cfg;
opts = attrValues (mapAttrs (a: v:
let v2 = if v ? set || v ? unset then v else { set = v; };
n = if cfgWithDefaults.${flagName a} then "set" else "unset";
attr = maybeAttr n {} v2; in
if (maybeAttr "assertion" true attr)
then attr
else throw "assertion of flag ${a} of derivation ${args.name} failed"
) args2.flags );
in removeAttrs
(mergeAttrsByFuncDefaults ([args] ++ opts ++ [{ passthru = cfgWithDefaults; }]))
["flags" "cfg" "mergeAttrBy" ];
nixType = x:
if isAttrs x then
if x ? outPath then "derivation"
@ -390,4 +270,8 @@ rec {
starting at zero.
*/
imap = imap1;
# Fake hashes. Can be used as hash placeholders, when computing hash ahead isn't trivial
fakeSha256 = "0000000000000000000000000000000000000000000000000000000000000000";
fakeSha512 = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
}

View File

@ -24,6 +24,19 @@ rec {
# for a concrete example.
fix' = f: let x = f x // { __unfix__ = f; }; in x;
# Return the fixpoint that `f` converges to when called recursively, starting
# with the input `x`.
#
# nix-repl> converge (x: x / 2) 16
# 0
converge = f: x:
let
x' = f x;
in
if x' == x
then x
else converge f x';
# Modify the contents of an explicitly recursive attribute set in a way that
# honors `self`-references. This is accomplished with a function
#
@ -41,6 +54,18 @@ rec {
# think of it as an infix operator `g extends f` that mimics the syntax from
# Java. It may seem counter-intuitive to have the "base class" as the second
# argument, but it's nice this way if several uses of `extends` are cascaded.
#
# To get a better understanding how `extends` turns a function with a fix
# point (the package set we start with) into a new function with a different fix
# point (the desired packages set) lets just see, how `extends g f`
# unfolds with `g` and `f` defined above:
#
# extends g f = self: let super = f self; in super // g self super;
# = self: let super = { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }; in super // g self super
# = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; } // g self { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }
# = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; } // { foo = "foo" + " + "; }
# = self: { foo = "foo + "; bar = "bar"; foobar = self.foo + self.bar; }
#
extends = f: rattrs: self: let super = rattrs self; in super // f self super;
# Compose two extending functions of the type expected by 'extends'

View File

@ -143,6 +143,7 @@ rec {
}@args: v: with builtins;
let isPath = v: typeOf v == "path";
in if isInt v then toString v
else if isFloat v then "~${toString v}"
else if isString v then ''"${libStr.escape [''"''] v}"''
else if true == v then "true"
else if false == v then "false"

View File

@ -1,57 +1,21 @@
{ lib
# we pass the kernel version here to keep a nice syntax `whenOlder "4.13"`
# kernelVersion, e.g., config.boot.kernelPackages.version
, version
, mkValuePreprocess ? null
}:
{ lib, version }:
with lib;
rec {
# Common patterns
when = cond: opt: if cond then opt else null;
whenAtLeast = ver: when (versionAtLeast version ver);
whenOlder = ver: when (versionOlder version ver);
whenBetween = verLow: verHigh: when (versionAtLeast version verLow && versionOlder version verHigh);
# Common patterns/legacy
whenAtLeast = ver: mkIf (versionAtLeast version ver);
whenOlder = ver: mkIf (versionOlder version ver);
# range is (inclusive, exclusive)
whenBetween = verLow: verHigh: mkIf (versionAtLeast version verLow && versionOlder version verHigh);
# Keeping these around in case we decide to change this horrible implementation :)
option = x: if x == null then null else "?${x}";
yes = "y";
no = "n";
module = "m";
option = x:
x // { optional = true; };
mkValue = val:
let
isNumber = c: elem c ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"];
in
if val == "" then "\"\""
else if val == yes || val == module || val == no then val
else if all isNumber (stringToCharacters val) then val
else if substring 0 2 val == "0x" then val
else val; # FIXME: fix quoting one day
yes = { tristate = "y"; };
no = { tristate = "n"; };
module = { tristate = "m"; };
freeform = x: { freeform = x; };
# generate nix intermediate kernel config file of the form
#
# VIRTIO_MMIO m
# VIRTIO_BLK y
# VIRTIO_CONSOLE n
# NET_9P_VIRTIO? y
#
# Use mkValuePreprocess to preprocess option values, aka mark 'modules' as
# 'yes' or vice-versa
# Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158
# returns a string, expr should be an attribute set
generateNixKConf = exprs: mkValuePreprocess:
let
mkConfigLine = key: rawval:
let
val = if builtins.isFunction mkValuePreprocess then mkValuePreprocess rawval else rawval;
in
if val == null
then ""
else if hasPrefix "?" val
then "${key}? ${mkValue (removePrefix "?" val)}\n"
else "${key} ${mkValue val}\n";
mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg);
in mkConf exprs;
}

View File

@ -13,6 +13,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
* add it to this list. The URL mentioned above is a good source for inspiration.
*/
abstyles = spdx {
spdxId = "Abstyles";
fullName = "Abstyles License";
};
afl21 = spdx {
spdxId = "AFL-2.1";
fullName = "Academic Free License v2.1";
@ -24,13 +29,13 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
};
agpl3 = spdx {
spdxId = "AGPL-3.0";
fullName = "GNU Affero General Public License v3.0";
spdxId = "AGPL-3.0-only";
fullName = "GNU Affero General Public License v3.0 only";
};
agpl3Plus = {
agpl3Plus = spdx {
spdxId = "AGPL-3.0-or-later";
fullName = "GNU Affero General Public License v3.0 or later";
inherit (agpl3) url;
};
amazonsl = {
@ -42,6 +47,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
amd = {
fullName = "AMD License Agreement";
url = http://developer.amd.com/amd-license-agreement/;
free = false;
};
apsl20 = spdx {
@ -99,14 +105,10 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = ''BSD 4-clause "Original" or "Old" License'';
};
bsl10 = {
fullName = "Business Source License 1.0";
url = https://mariadb.com/bsl10;
};
bsl11 = {
fullName = "Business Source License 1.1";
url = https://mariadb.com/bsl11;
free = false;
};
clArtistic = spdx {
@ -143,6 +145,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
free = false;
};
cc-by-nc-30 = spdx {
spdxId = "CC-BY-NC-3.0";
fullName = "Creative Commons Attribution Non Commercial 3.0 Unported";
free = false;
};
cc-by-nc-40 = spdx {
spdxId = "CC-BY-NC-4.0";
fullName = "Creative Commons Attribution Non Commercial 4.0 International";
@ -264,13 +272,23 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
};
fdl12 = spdx {
spdxId = "GFDL-1.2";
fullName = "GNU Free Documentation License v1.2";
spdxId = "GFDL-1.2-only";
fullName = "GNU Free Documentation License v1.2 only";
};
fdl12Plus = spdx {
spdxId = "GFDL-1.2-or-later";
fullName = "GNU Free Documentation License v1.2 or later";
};
fdl13 = spdx {
spdxId = "GFDL-1.3";
fullName = "GNU Free Documentation License v1.3";
spdxId = "GFDL-1.3-only";
fullName = "GNU Free Documentation License v1.3 only";
};
fdl13Plus = spdx {
spdxId = "GFDL-1.3-or-later";
fullName = "GNU Free Documentation License v1.3 or later";
};
ffsl = {
@ -295,20 +313,25 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
};
gpl1 = spdx {
spdxId = "GPL-1.0";
spdxId = "GPL-1.0-only";
fullName = "GNU General Public License v1.0 only";
};
gpl1Plus = spdx {
spdxId = "GPL-1.0+";
spdxId = "GPL-1.0-or-later";
fullName = "GNU General Public License v1.0 or later";
};
gpl2 = spdx {
spdxId = "GPL-2.0";
spdxId = "GPL-2.0-only";
fullName = "GNU General Public License v2.0 only";
};
gpl2Classpath = spdx {
spdxId = "GPL-2.0-with-classpath-exception";
fullName = "GNU General Public License v2.0 only (with Classpath exception)";
};
gpl2ClasspathPlus = {
fullName = "GNU General Public License v2.0 or later (with Classpath exception)";
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
@ -320,17 +343,17 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
};
gpl2Plus = spdx {
spdxId = "GPL-2.0+";
spdxId = "GPL-2.0-or-later";
fullName = "GNU General Public License v2.0 or later";
};
gpl3 = spdx {
spdxId = "GPL-3.0";
spdxId = "GPL-3.0-only";
fullName = "GNU General Public License v3.0 only";
};
gpl3Plus = spdx {
spdxId = "GPL-3.0+";
spdxId = "GPL-3.0-or-later";
fullName = "GNU General Public License v3.0 or later";
};
@ -355,6 +378,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "Independent JPEG Group License";
};
imagemagick = spdx {
fullName = "ImageMagick License";
spdxId = "imagemagick";
};
inria-compcert = {
fullName = "INRIA Non-Commercial License Agreement for the CompCert verified compiler";
url = "http://compcert.inria.fr/doc/LICENSE";
@ -382,33 +410,45 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "ISC License";
};
# Proprietary binaries; free to redistribute without modification.
issl = {
fullName = "Intel Simplified Software License";
url = https://software.intel.com/en-us/license/intel-simplified-software-license;
free = false;
};
jasper = spdx {
spdxId = "JasPer-2.0";
fullName = "JasPer License";
};
lgpl2 = spdx {
spdxId = "LGPL-2.0";
spdxId = "LGPL-2.0-only";
fullName = "GNU Library General Public License v2 only";
};
lgpl2Plus = spdx {
spdxId = "LGPL-2.0+";
spdxId = "LGPL-2.0-or-later";
fullName = "GNU Library General Public License v2 or later";
};
lgpl21 = spdx {
spdxId = "LGPL-2.1";
spdxId = "LGPL-2.1-only";
fullName = "GNU Library General Public License v2.1 only";
};
lgpl21Plus = spdx {
spdxId = "LGPL-2.1+";
spdxId = "LGPL-2.1-or-later";
fullName = "GNU Library General Public License v2.1 or later";
};
lgpl3 = spdx {
spdxId = "LGPL-3.0";
spdxId = "LGPL-3.0-only";
fullName = "GNU Lesser General Public License v3.0 only";
};
lgpl3Plus = spdx {
spdxId = "LGPL-3.0+";
spdxId = "LGPL-3.0-or-later";
fullName = "GNU Lesser General Public License v3.0 or later";
};
@ -417,6 +457,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "libpng License";
};
libpng2 = {
fullName = "libpng License v2"; # 1.6.36+
url = "http://www.libpng.org/pub/png/src/libpng-LICENSE.txt";
};
libtiff = spdx {
spdxId = "libtiff";
fullName = "libtiff License";
@ -480,6 +525,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
free = false;
};
nasa13 = spdx {
spdxId = "NASA-1.3";
fullName = "NASA Open Source Agreement 1.3";
free = false;
};
ncsa = spdx {
spdxId = "NCSA";
fullName = "University of Illinois/NCSA Open Source License";
@ -495,6 +546,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "Non-Profit Open Software License 3.0";
};
ocamlpro_nc = {
fullName = "OCamlPro Non Commercial license version 1";
url = "https://alt-ergo.ocamlpro.com/http/alt-ergo-2.2.0/OCamlPro-Non-Commercial-License.pdf";
free = false;
};
ofl = spdx {
spdxId = "OFL-1.1";
fullName = "SIL Open Font License 1.1";
@ -510,6 +567,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "OpenSSL License";
};
osl2 = spdx {
spdxId = "OSL-2.0";
fullName = "Open Software License 2.0";
};
osl21 = spdx {
spdxId = "OSL-2.1";
fullName = "Open Software License 2.1";
@ -546,6 +608,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "Public Domain";
};
purdueBsd = {
fullName = " Purdue BSD-Style License"; # also know as lsof license
url = https://enterprise.dejacode.com/licenses/public/purdue-bsd;
};
qpl = spdx {
spdxId = "QPL-1.0";
fullName = "Q Public License 1.0";
@ -561,6 +628,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "Ruby License";
};
sendmail = spdx {
spdxId = "Sendmail";
fullName = "Sendmail License";
};
sgi-b-20 = spdx {
spdxId = "SGI-B-2.0";
fullName = "SGI Free Software License B v2.0";
@ -650,7 +722,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
};
wxWindows = spdx {
spdxId = "WXwindows";
spdxId = "wxWindows";
fullName = "wxWindows Library Licence, Version 3.1";
};

View File

@ -1,4 +1,5 @@
# General list operations.
{ lib }:
with lib.trivial;
let
@ -6,23 +7,25 @@ let
in
rec {
inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
inherit (builtins) head tail length isList elemAt concatLists filter elem genList map;
/* Create a list consisting of a single element. `singleton x' is
sometimes more convenient with respect to indentation than `[x]'
/* 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.
Type: singleton :: a -> [a]
Example:
singleton "foo"
=> [ "foo" ]
*/
singleton = x: [x];
/* right fold a binary function `op' between successive elements of
`list' with `nul' as the starting value, i.e.,
`foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'.
Type:
foldr :: (a -> b -> b) -> b -> [a] -> b
/* right fold a binary function `op` between successive elements of
`list` with `nul' as the starting value, i.e.,
`foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))`.
Type: foldr :: (a -> b -> b) -> b -> [a] -> b
Example:
concat = foldr (a: b: a + b) "z"
@ -42,16 +45,15 @@ rec {
else op (elemAt list n) (fold' (n + 1));
in fold' 0;
/* `fold' is an alias of `foldr' for historic reasons */
/* `fold` is an alias of `foldr` for historic reasons */
# FIXME(Profpatsch): deprecate?
fold = foldr;
/* left fold, like `foldr', but from the left:
/* left fold, like `foldr`, but from the left:
`foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)`.
Type:
foldl :: (b -> a -> b) -> b -> [a] -> b
Type: foldl :: (b -> a -> b) -> b -> [a] -> b
Example:
lconcat = foldl (a: b: a + b) "z"
@ -70,16 +72,20 @@ rec {
else op (foldl' (n - 1)) (elemAt list n);
in foldl' (length list - 1);
/* Strict version of `foldl'.
/* 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.)
Type: foldl' :: (b -> a -> b) -> b -> [a] -> b
*/
foldl' = builtins.foldl' or foldl;
/* Map with index starting from 0
Type: imap0 :: (int -> a -> b) -> [a] -> [b]
Example:
imap0 (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-0" "b-1" ]
@ -88,6 +94,8 @@ rec {
/* Map with index starting from 1
Type: imap1 :: (int -> a -> b) -> [a] -> [b]
Example:
imap1 (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-1" "b-2" ]
@ -96,6 +104,8 @@ rec {
/* Map and concatenate the result.
Type: concatMap :: (a -> [b]) -> [a] -> [b]
Example:
concatMap (x: [x] ++ ["z"]) ["a" "b"]
=> [ "a" "z" "b" "z" ]
@ -118,15 +128,21 @@ rec {
/* Remove elements equal to 'e' from a list. Useful for buildInputs.
Type: remove :: a -> [a] -> [a]
Example:
remove 3 [ 1 3 4 3 ]
=> [ 1 4 ]
*/
remove = e: filter (x: x != e);
remove =
# Element to remove from the list
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.
predicate, returns `default` if no such element exists, or
`multiple` if there are multiple matching elements.
Type: findSingle :: (a -> bool) -> a -> a -> [a] -> a
Example:
findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ]
@ -136,14 +152,24 @@ rec {
findSingle (x: x == 3) "none" "multiple" [ 1 9 ]
=> "none"
*/
findSingle = pred: default: multiple: list:
findSingle =
# Predicate
pred:
# Default value to return if element was not found.
default:
# Default value to return if more than one element was found
multiple:
# Input list
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.
predicate or return `default` if no such element exists.
Type: findFirst :: (a -> bool) -> a -> [a] -> a
Example:
findFirst (x: x > 3) 7 [ 1 6 4 ]
@ -151,12 +177,20 @@ rec {
findFirst (x: x > 9) 7 [ 1 6 4 ]
=> 7
*/
findFirst = pred: default: list:
findFirst =
# Predicate
pred:
# Default value to return
default:
# Input list
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'.
/* Return true if function `pred` returns true for at least one
element of `list`.
Type: any :: (a -> bool) -> [a] -> bool
Example:
any isString [ 1 "a" { } ]
@ -166,8 +200,10 @@ rec {
*/
any = builtins.any or (pred: foldr (x: y: if pred x then true else y) false);
/* Return true iff function `pred' returns true for all elements of
`list'.
/* Return true if function `pred` returns true for all elements of
`list`.
Type: all :: (a -> bool) -> [a] -> bool
Example:
all (x: x < 3) [ 1 2 ]
@ -177,19 +213,25 @@ rec {
*/
all = builtins.all or (pred: foldr (x: y: if pred x then y else false) true);
/* Count how many times function `pred' returns true for the elements
of `list'.
/* Count how many elements of `list` match the supplied predicate
function.
Type: count :: (a -> bool) -> [a] -> int
Example:
count (x: x == 3) [ 3 2 3 4 6 ]
=> 2
*/
count = pred: foldl' (c: x: if pred x then c + 1 else c) 0;
count =
# Predicate
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').
Type: optional :: bool -> a -> [a]
Example:
optional true "foo"
=> [ "foo" ]
@ -200,13 +242,19 @@ rec {
/* Return a list or an empty list, depending on a boolean value.
Type: optionals :: bool -> [a] -> [a]
Example:
optionals true [ 2 3 ]
=> [ 2 3 ]
optionals false [ 2 3 ]
=> [ ]
*/
optionals = cond: elems: if cond then elems else [];
optionals =
# Condition
cond:
# List to return if condition is true
elems: if cond then elems else [];
/* If argument is a list, return it; else, wrap it in a singleton
@ -223,20 +271,28 @@ rec {
/* Return a list of integers from `first' up to and including `last'.
Type: range :: int -> int -> [int]
Example:
range 2 4
=> [ 2 3 4 ]
range 3 2
=> [ ]
*/
range = first: last:
range =
# First integer in the range
first:
# Last integer in the range
last:
if first > last then
[]
else
genList (n: first + n) (last - first + 1);
/* Splits the elements of a list in two lists, `right' and
`wrong', depending on the evaluation of a predicate.
/* Splits the elements of a list in two lists, `right` and
`wrong`, depending on the evaluation of a predicate.
Type: (a -> bool) -> [a] -> { right :: [a], wrong :: [a] }
Example:
partition (x: x > 2) [ 5 1 2 3 4 ]
@ -252,7 +308,7 @@ rec {
/* Splits the elements of a list into many lists, using the return value of a predicate.
Predicate should return a string which becomes keys of attrset `groupBy' returns.
`groupBy'' allows to customise the combining function and initial value
`groupBy'` allows to customise the combining function and initial value
Example:
groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
@ -268,10 +324,6 @@ rec {
xfce = [ { name = "xfce"; script = "xfce4-session &"; } ];
}
groupBy' allows to customise the combining function and initial value
Example:
groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
=> { true = 12; false = 3; }
*/
@ -289,17 +341,27 @@ rec {
the merging stops at the shortest. How both lists are merged is defined
by the first argument.
Type: zipListsWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Example:
zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
=> ["he" "lo"]
*/
zipListsWith = f: fst: snd:
zipListsWith =
# Function to zip elements of both lists
f:
# First list
fst:
# Second list
snd:
genList
(n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd));
/* Merges two lists of the same size together. If the sizes aren't the same
the merging stops at the shortest.
Type: zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}]
Example:
zipLists [ 1 2 ] [ "a" "b" ]
=> [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]
@ -308,6 +370,8 @@ rec {
/* Reverse the order of the elements of a list.
Type: reverseList :: [a] -> [a]
Example:
reverseList [ "b" "o" "j" ]
@ -321,8 +385,7 @@ rec {
`before a b == true` means that `b` depends on `a` (there's an
edge from `b` to `a`).
Examples:
Example:
listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ]
== { minimal = "/"; # minimal element
visited = [ "/home/user" ]; # seen elements (in reverse order)
@ -336,7 +399,6 @@ rec {
rest = [ "/home" "other" ]; # everything else
*/
listDfs = stopOnCycles: before: list:
let
dfs' = us: visited: rest:
@ -361,7 +423,7 @@ rec {
`before a b == true` means that `b` should be after `a`
in the result.
Examples:
Example:
toposort hasPrefix [ "/home/user" "other" "/" "/home" ]
== { result = [ "/" "/home" "/home/user" "other" ]; }
@ -376,7 +438,6 @@ rec {
toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; }
*/
toposort = before: list:
let
dfsthis = listDfs true before list;
@ -467,26 +528,38 @@ rec {
/* Return the first (at most) N elements of a list.
Type: take :: int -> [a] -> [a]
Example:
take 2 [ "a" "b" "c" "d" ]
=> [ "a" "b" ]
take 2 [ ]
=> [ ]
*/
take = count: sublist 0 count;
take =
# Number of elements to take
count: sublist 0 count;
/* Remove the first (at most) N elements of a list.
Type: drop :: int -> [a] -> [a]
Example:
drop 2 [ "a" "b" "c" "d" ]
=> [ "c" "d" ]
drop 2 [ ]
=> [ ]
*/
drop = count: list: sublist count (length list) list;
drop =
# Number of elements to drop
count:
# Input list
list: sublist count (length list) list;
/* Return a list consisting of at most count elements of list,
starting at index start.
/* Return a list consisting of at most `count` elements of `list`,
starting at index `start`.
Type: sublist :: int -> int -> [a] -> [a]
Example:
sublist 1 3 [ "a" "b" "c" "d" "e" ]
@ -494,7 +567,13 @@ rec {
sublist 1 3 [ ]
=> [ ]
*/
sublist = start: count: list:
sublist =
# Index at which to start the sublist
start:
# Number of elements to take
count:
# Input list
list:
let len = length list; in
genList
(n: elemAt list (n + start))
@ -504,23 +583,34 @@ rec {
/* Return the last element of a list.
This function throws an error if the list is empty.
Type: last :: [a] -> a
Example:
last [ 1 2 3 ]
=> 3
*/
last = list:
assert list != []; elemAt list (length list - 1);
assert lib.assertMsg (list != []) "lists.last: list must not be empty!";
elemAt list (length list - 1);
/* Return all elements but the last
/* Return all elements but the last.
This function throws an error if the list is empty.
Type: init :: [a] -> [a]
Example:
init [ 1 2 3 ]
=> [ 1 2 ]
*/
init = list: assert list != []; take (length list - 1) list;
init = list:
assert lib.assertMsg (list != []) "lists.init: list must not be empty!";
take (length list - 1) list;
/* return the image of the cross product of some lists by a function
/* Return the image of the cross product of some lists by a function.
Example:
crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]]
@ -531,8 +621,9 @@ rec {
/* Remove duplicate elements from the list. O(n^2) complexity.
Example:
Type: unique :: [a] -> [a]
Example:
unique [ 3 2 3 4 ]
=> [ 3 2 4 ]
*/
@ -542,8 +633,7 @@ rec {
else
let
x = head list;
xs = unique (drop 1 list);
in [x] ++ remove x xs;
in [x] ++ unique (remove x list);
/* Intersects list 'e' and another list. O(nm) complexity.

View File

@ -41,16 +41,18 @@ rec {
let x = builtins.parseDrvName name; in "${x.name}-${suffix}-${x.version}");
/* Apply a function to each derivation and only to derivations in an attrset
/* Apply a function to each derivation and only to derivations in an attrset.
*/
mapDerivationAttrset = f: set: lib.mapAttrs (name: pkg: if lib.isDerivation pkg then (f pkg) else pkg) set;
/* Set the nix-env priority of the package.
*/
setPrio = priority: addMetaAttrs { inherit priority; };
/* Decrease the nix-env priority of the package, i.e., other
versions/variants of the package will be preferred.
*/
lowPrio = drv: addMetaAttrs { priority = 10; } drv;
lowPrio = setPrio 10;
/* Apply lowPrio to an attrset with derivations
*/
@ -60,8 +62,7 @@ rec {
/* Increase the nix-env priority of the package, i.e., this
version/variant of the package will be preferred.
*/
hiPrio = drv: addMetaAttrs { priority = -10; } drv;
hiPrio = setPrio (-10);
/* Apply hiPrio to an attrset with derivations
*/

View File

@ -1,2 +1,2 @@
# Expose the minimum required version for evaluating Nixpkgs
"1.11"
"2.0"

View File

@ -192,29 +192,55 @@ rec {
(concatMap (m: map (config: { inherit (m) file; inherit config; }) (pushDownProperties m.config)) modules);
mergeModules' = prefix: options: configs:
listToAttrs (map (name: {
let
/* byName is like foldAttrs, but will look for attributes to merge in the
specified attribute name.
byName "foo" (module: value: ["module.hidden=${module.hidden},value=${value}"])
[
{
hidden="baz";
foo={qux="bar"; gla="flop";};
}
{
hidden="fli";
foo={qux="gne"; gli="flip";};
}
]
===>
{
gla = [ "module.hidden=baz,value=flop" ];
gli = [ "module.hidden=fli,value=flip" ];
qux = [ "module.hidden=baz,value=bar" "module.hidden=fli,value=gne" ];
}
*/
byName = attr: f: modules:
foldl' (acc: module:
acc // (mapAttrs (n: v:
(acc.${n} or []) ++ f module v
) module.${attr}
)
) {} modules;
# an attrset 'name' => list of submodules that declare name.
declsByName = byName "options" (module: option:
[{ inherit (module) file; options = option; }]
) options;
# an attrset 'name' => list of submodules that define name.
defnsByName = byName "config" (module: value:
map (config: { inherit (module) file; inherit config; }) (pushDownProperties value)
) configs;
# extract the definitions for each loc
defnsByName' = byName "config" (module: value:
[{ inherit (module) file; inherit value; }]
) configs;
in
(flip mapAttrs declsByName (name: decls:
# We're descending into attribute name.
inherit name;
value =
let
loc = prefix ++ [name];
# Get all submodules that declare name.
decls = concatMap (m:
if m.options ? ${name}
then [ { inherit (m) file; options = m.options.${name}; } ]
else []
) options;
# Get all submodules that define name.
defns = concatMap (m:
if m.config ? ${name}
then map (config: { inherit (m) file; inherit config; })
(pushDownProperties m.config.${name})
else []
) configs;
defns = defnsByName.${name} or [];
defns' = defnsByName'.${name} or [];
nrOptions = count (m: isOption m.options) decls;
# Extract the definitions for this loc
defns' = map (m: { inherit (m) file; value = m.config.${name}; })
(filter (m: m.config ? ${name}) configs);
in
if nrOptions == length decls then
let opt = fixupOptionType loc (mergeOptionDecls loc decls);
@ -226,8 +252,8 @@ rec {
in
throw "The option `${showOption loc}' in `${firstOption.file}' is a prefix of options in `${firstNonOption.file}'."
else
mergeModules' loc decls defns;
}) (concatMap (m: attrNames m.options) options))
mergeModules' loc decls defns
))
// { _definedNames = map (m: { inherit (m) file; names = attrNames m.config; }) configs; };
/* Merge multiple option declarations into a single declaration. In
@ -338,7 +364,6 @@ rec {
values = defs''';
inherit (defs'') highestPrio;
};
defsFinal = defsFinal'.values;
# Type-check the remaining definitions, and merge them.
@ -426,8 +451,7 @@ rec {
filterOverrides' = defs:
let
defaultPrio = 100;
getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPrio;
getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPriority;
highestPrio = foldl' (prio: def: min (getPrio def) prio) 9999 defs;
strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def;
in {
@ -510,6 +534,8 @@ rec {
mkBefore = mkOrder 500;
mkAfter = mkOrder 1500;
# The default priority for things that don't have a priority specified.
defaultPriority = 100;
# Convenient property used to transfer all definitions and their
# properties from one option to another. This property is useful for
@ -532,8 +558,20 @@ rec {
#
mkAliasDefinitions = mkAliasAndWrapDefinitions id;
mkAliasAndWrapDefinitions = wrap: option:
mkIf (isOption option && option.isDefined) (wrap (mkMerge option.definitions));
mkAliasIfDef option (wrap (mkMerge option.definitions));
# Similar to mkAliasAndWrapDefinitions but copies over the priority from the
# option as well.
#
# If a priority is not set, it assumes a priority of defaultPriority.
mkAliasAndWrapDefsWithPriority = wrap: option:
let
prio = option.highestPrio or defaultPriority;
defsWithPrio = map (mkOverride prio) option.definitions;
in mkAliasIfDef option (wrap (mkMerge defsWithPrio));
mkAliasIfDef = option:
mkIf (isOption option && option.isDefined);
/* Compatibility. */
fixMergeModules = modules: args: evalModules { inherit modules args; check = false; };
@ -572,6 +610,9 @@ rec {
forwards any definitions of boot.copyKernels to
boot.loader.grub.copyKernels while printing a warning.
This also copies over the priority from the aliased option to the
non-aliased option.
*/
mkRenamedOptionModule = from: to: doRename {
inherit from to;
@ -666,7 +707,7 @@ rec {
use = id;
};
doRename = { from, to, visible, warn, use }:
doRename = { from, to, visible, warn, use, withPriority ? true }:
{ config, options, ... }:
let
fromOpt = getAttrFromPath from options;
@ -684,7 +725,9 @@ rec {
warnings = optional (warn && fromOpt.isDefined)
"The option `${showOption from}' defined in ${showFiles fromOpt.files} has been renamed to `${showOption to}'.";
}
(mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
(if withPriority
then mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt
else mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
];
};

View File

@ -8,33 +8,72 @@ with lib.strings;
rec {
/* Returns true when the given argument is an option
Type: isOption :: a -> bool
Example:
isOption 1 // => false
isOption (mkOption {}) // => true
*/
isOption = lib.isType "option";
/* Creates an Option attribute set. mkOption accepts an attribute set with the following keys:
All keys default to `null` when not given.
Example:
mkOption { } // => { _type = "option"; }
mkOption { defaultText = "foo"; } // => { _type = "option"; defaultText = "foo"; }
*/
mkOption =
{ default ? null # Default value used when no definition is given in the configuration.
, defaultText ? null # Textual representation of the default, for in the manual.
, example ? null # Example value used in the manual.
, description ? null # String describing the option.
, relatedPackages ? null # Related packages used in the manual (see `genRelatedPackages` in ../nixos/doc/manual/default.nix).
, type ? null # Option type, providing type-checking and value merging.
, apply ? null # Function that converts the option value to something else.
, internal ? null # Whether the option is for NixOS developers only.
, visible ? null # Whether the option shows up in the manual.
, readOnly ? null # Whether the option can be set only once
, options ? null # Obsolete, used by types.optionSet.
{
# Default value used when no definition is given in the configuration.
default ? null,
# Textual representation of the default, for the manual.
defaultText ? null,
# Example value used in the manual.
example ? null,
# String describing the option.
description ? null,
# Related packages used in the manual (see `genRelatedPackages` in ../nixos/doc/manual/default.nix).
relatedPackages ? null,
# Option type, providing type-checking and value merging.
type ? null,
# Function that converts the option value to something else.
apply ? null,
# Whether the option is for NixOS developers only.
internal ? null,
# Whether the option shows up in the manual.
visible ? null,
# Whether the option can be set only once
readOnly ? null,
# Deprecated, used by types.optionSet.
options ? null
} @ attrs:
attrs // { _type = "option"; };
mkEnableOption = name: mkOption {
/* Creates an Option attribute set for a boolean value option i.e an
option to be toggled on or off:
Example:
mkEnableOption "foo"
=> { _type = "option"; default = false; description = "Whether to enable foo."; example = true; type = { ... }; }
*/
mkEnableOption =
# Name for the created option
name: mkOption {
default = false;
example = true;
description = "Whether to enable ${name}.";
type = lib.types.bool;
};
# This option accept anything, but it does not produce any result. This
# is useful for sharing a module across different module sets without
# having to implement similar features as long as the value of the options
# are not expected.
/* This option accepts anything, but it does not produce any result.
This is useful for sharing a module across different module sets
without having to implement similar features as long as the
values of the options are not accessed. */
mkSinkUndeclaredOptions = attrs: mkOption ({
internal = true;
visible = false;
@ -74,7 +113,24 @@ rec {
else
val) (head defs).value defs;
/* Extracts values of all "value" keys of the given list.
Type: getValues :: [ { value :: a } ] -> [a]
Example:
getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ]
getValues [ ] // => [ ]
*/
getValues = map (x: x.value);
/* Extracts values of all "file" keys of the given list
Type: getFiles :: [ { file :: a } ] -> [a]
Example:
getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
getFiles [ ] // => [ ]
*/
getFiles = map (x: x.file);
# Generate documentation template from the list of option declaration like
@ -87,7 +143,7 @@ rec {
docOption = rec {
loc = opt.loc;
name = showOption opt.loc;
description = opt.description or (throw "Option `${name}' has no description.");
description = opt.description or (lib.warn "Option `${name}' has no description." "This option has no description.");
declarations = filter (x: x != unknownModule) opt.declarations;
internal = opt.internal or false;
visible = opt.visible or true;
@ -107,10 +163,13 @@ rec {
/* This function recursively removes all derivation attributes from
`x' except for the `name' attribute. This is to make the
generation of `options.xml' much more efficient: the XML
representation of derivations is very large (on the order of
megabytes) and is not actually used by the manual generator. */
`x` except for the `name` attribute.
This is to make the generation of `options.xml` much more
efficient: the XML representation of derivations is very large
(on the order of megabytes) and is not actually used by the
manual generator.
*/
scrubOptionValue = x:
if isDerivation x then
{ type = "derivation"; drvPath = x.name; outPath = x.name; name = x.name; }
@ -119,20 +178,21 @@ rec {
else x;
/* For use in the example option attribute. It causes the given
text to be included verbatim in documentation. This is necessary
for example values that are not simple values, e.g.,
functions. */
/* For use in the `example` option attribute. It causes the given
text to be included verbatim in documentation. This is necessary
for example values that are not simple values, e.g., functions.
*/
literalExample = text: { _type = "literalExample"; inherit text; };
# Helper functions.
/* Helper functions. */
/* Convert an option, described as a list of the option parts in to a
safe, human readable version.
# Convert an option, described as a list of the option parts in to a
# safe, human readable version. ie:
#
# (showOption ["foo" "bar" "baz"]) == "foo.bar.baz"
# (showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux"
Example:
(showOption ["foo" "bar" "baz"]) == "foo.bar.baz"
(showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux"
*/
showOption = parts: let
escapeOptionPart = part:
let

View File

@ -12,8 +12,8 @@ rec {
# Bring in a path as a source, filtering out all Subversion and CVS
# directories, as well as backup files (*~).
cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! (
# Filter out Subversion and CVS directories.
(type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
# Filter out version control software files/directories
(baseName == ".git" || type == "directory" && (baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
# Filter out editor backup / swap files.
lib.hasSuffix "~" baseName ||
builtins.match "^\\.sw[a-z]$" baseName != null ||
@ -26,6 +26,10 @@ rec {
(type == "symlink" && lib.hasPrefix "result" baseName)
);
# Filters a source tree removing version control files and directories using cleanSourceWith
#
# Example:
# cleanSource ./.
cleanSource = src: cleanSourceWith { filter = cleanSourceFilter; inherit src; };
# Like `builtins.filterSource`, except it will compose with itself,
@ -69,7 +73,7 @@ rec {
# Get the commit id of a git repo
# Example: commitIdFromGitRepo <nixpkgs/.git>
commitIdFromGitRepo =
let readCommitFromFile = path: file:
let readCommitFromFile = file: path:
with builtins;
let fileName = toString path + "/" + file;
packedRefsName = toString path + "/packed-refs";
@ -81,7 +85,7 @@ rec {
matchRef = match "^ref: (.*)$" fileContent;
in if isNull matchRef
then fileContent
else readCommitFromFile path (lib.head matchRef)
else readCommitFromFile (lib.head matchRef) path
# 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
@ -92,7 +96,7 @@ rec {
then throw ("Could not find " + file + " in " + packedRefsName)
else lib.head matchRef
else throw ("Not a .git directory: " + path);
in lib.flip readCommitFromFile "HEAD";
in readCommitFromFile "HEAD";
pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir);

View File

@ -12,6 +12,8 @@ rec {
/* Concatenate a list of strings.
Type: concatStrings :: [string] -> string
Example:
concatStrings ["foo" "bar"]
=> "foobar"
@ -20,15 +22,19 @@ rec {
/* Map a function over a list and concatenate the resulting strings.
Type: concatMapStrings :: (a -> string) -> [a] -> string
Example:
concatMapStrings (x: "a" + x) ["foo" "bar"]
=> "afooabar"
*/
concatMapStrings = f: list: concatStrings (map f list);
/* Like `concatMapStrings' except that the f functions also gets the
/* Like `concatMapStrings` except that the f functions also gets the
position as a parameter.
Type: concatImapStrings :: (int -> a -> string) -> [a] -> string
Example:
concatImapStrings (pos: x: "${toString pos}-${x}") ["foo" "bar"]
=> "1-foo2-bar"
@ -37,17 +43,25 @@ rec {
/* Place an element between each element of a list
Type: intersperse :: a -> [a] -> [a]
Example:
intersperse "/" ["usr" "local" "bin"]
=> ["usr" "/" "local" "/" "bin"].
*/
intersperse = separator: list:
intersperse =
# Separator to add between elements
separator:
# Input list
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
Type: concatStringsSep :: string -> [string] -> string
Example:
concatStringsSep "/" ["usr" "local" "bin"]
=> "usr/local/bin"
@ -55,43 +69,77 @@ rec {
concatStringsSep = builtins.concatStringsSep or (separator: list:
concatStrings (intersperse separator list));
/* First maps over the list and then concatenates it.
/* Maps a function over a list of strings and then concatenates the
result with the specified separator interspersed between
elements.
Type: concatMapStringsSep :: string -> (string -> string) -> [string] -> string
Example:
concatMapStringsSep "-" (x: toUpper x) ["foo" "bar" "baz"]
=> "FOO-BAR-BAZ"
*/
concatMapStringsSep = sep: f: list: concatStringsSep sep (map f list);
concatMapStringsSep =
# Separator to add between elements
sep:
# Function to map over the list
f:
# List of input strings
list: concatStringsSep sep (map f list);
/* First imaps over the list and then concatenates it.
/* Same as `concatMapStringsSep`, but the mapping function
additionally receives the position of its argument.
Type: concatIMapStringsSep :: string -> (int -> string -> string) -> [string] -> string
Example:
concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ]
=> "6-3-2"
*/
concatImapStringsSep = sep: f: list: concatStringsSep sep (lib.imap1 f list);
concatImapStringsSep =
# Separator to add between elements
sep:
# Function that receives elements and their positions
f:
# List of input strings
list: concatStringsSep sep (lib.imap1 f list);
/* Construct a Unix-style search path consisting of each `subDir"
directory of the given list of packages.
/* Construct a Unix-style, colon-separated search path consisting of
the given `subDir` appended to each of the given paths.
Type: makeSearchPath :: string -> [string] -> string
Example:
makeSearchPath "bin" ["/root" "/usr" "/usr/local"]
=> "/root/bin:/usr/bin:/usr/local/bin"
makeSearchPath "bin" ["/"]
=> "//bin"
makeSearchPath "bin" [""]
=> "/bin"
*/
makeSearchPath = subDir: packages:
concatStringsSep ":" (map (path: path + "/" + subDir) (builtins.filter (x: x != null) packages));
makeSearchPath =
# Directory name to append
subDir:
# List of base paths
paths:
concatStringsSep ":" (map (path: path + "/" + subDir) (builtins.filter (x: x != null) paths));
/* Construct a Unix-style search path, using given package output.
If no output is found, fallback to `.out` and then to the default.
/* Construct a Unix-style search path by appending the given
`subDir` to the specified `output` of each of the packages. If no
output by the given name is found, fallback to `.out` and then to
the default.
Type: string -> string -> [package] -> string
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);
makeSearchPathOutput =
# Package output to use
output:
# Directory name to append
subDir:
# List of packages
pkgs: makeSearchPath subDir (map (lib.getOutput output) pkgs);
/* Construct a library search path (such as RPATH) containing the
libraries for a set of packages
@ -114,64 +162,80 @@ rec {
*/
makeBinPath = makeSearchPathOutput "bin" "bin";
/* Construct a perl search path (such as $PERL5LIB)
FIXME(zimbatm): this should be moved in perl-specific code
Example:
pkgs = import <nixpkgs> { }
makePerlPath [ pkgs.perlPackages.libnet ]
=> "/nix/store/n0m1fk9c960d8wlrs62sncnadygqqc6y-perl-Net-SMTP-1.25/lib/perl5/site_perl"
*/
makePerlPath = makeSearchPathOutput "lib" "lib/perl5/site_perl";
/* Construct a perl search path recursively including all dependencies (such as $PERL5LIB)
Example:
pkgs = import <nixpkgs> { }
makeFullPerlPath [ pkgs.perlPackages.CGI ]
=> "/nix/store/fddivfrdc1xql02h9q500fpnqy12c74n-perl-CGI-4.38/lib/perl5/site_perl:/nix/store/8hsvdalmsxqkjg0c5ifigpf31vc4vsy2-perl-HTML-Parser-3.72/lib/perl5/site_perl:/nix/store/zhc7wh0xl8hz3y3f71nhlw1559iyvzld-perl-HTML-Tagset-3.20/lib/perl5/site_perl"
*/
makeFullPerlPath = deps: makePerlPath (lib.misc.closePropagation deps);
/* Depending on the boolean `cond', return either the given string
or the empty string. Useful to concatenate against a bigger string.
Type: optionalString :: bool -> string -> string
Example:
optionalString true "some-string"
=> "some-string"
optionalString false "some-string"
=> ""
*/
optionalString = cond: string: if cond then string else "";
optionalString =
# Condition
cond:
# String to return if condition is true
string: if cond then string else "";
/* Determine whether a string has given prefix.
Type: hasPrefix :: string -> string -> bool
Example:
hasPrefix "foo" "foobar"
=> true
hasPrefix "foo" "barfoo"
=> false
*/
hasPrefix = pref: str:
substring 0 (stringLength pref) str == pref;
hasPrefix =
# Prefix to check for
pref:
# Input string
str: substring 0 (stringLength pref) str == pref;
/* Determine whether a string has given suffix.
Type: hasSuffix :: string -> string -> bool
Example:
hasSuffix "foo" "foobar"
=> false
hasSuffix "foo" "barfoo"
=> true
*/
hasSuffix = suffix: content:
hasSuffix =
# Suffix to check for
suffix:
# Input string
content:
let
lenContent = stringLength content;
lenSuffix = stringLength suffix;
in lenContent >= lenSuffix &&
substring (lenContent - lenSuffix) lenContent content == suffix;
/* Determine whether a string contains the given infix
Type: hasInfix :: string -> string -> bool
Example:
hasInfix "bc" "abcd"
=> true
hasInfix "ab" "abcd"
=> true
hasInfix "cd" "abcd"
=> true
hasInfix "foo" "abcd"
=> false
*/
hasInfix = infix: content:
let
drop = x: substring 1 (stringLength x) x;
in hasPrefix infix content
|| content != "" && hasInfix infix (drop content);
/* 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
@ -180,6 +244,8 @@ rec {
Also note that Nix treats strings as a list of bytes and thus doesn't
handle unicode.
Type: stringtoCharacters :: string -> [string]
Example:
stringToCharacters ""
=> [ ]
@ -194,18 +260,25 @@ rec {
/* Manipulate a string character by character and replace them by
strings before concatenating the results.
Type: stringAsChars :: (string -> string) -> string -> string
Example:
stringAsChars (x: if x == "a" then "i" else x) "nax"
=> "nix"
*/
stringAsChars = f: s:
concatStrings (
stringAsChars =
# Function to map over each individual character
f:
# Input string
s: concatStrings (
map f (stringToCharacters s)
);
/* Escape occurrence of the elements of list in string by
/* Escape occurrence of the elements of `list` in `string` by
prefixing it with a backslash.
Type: escape :: [string] -> string -> string
Example:
escape ["(" ")"] "(foo)"
=> "\\(foo\\)"
@ -214,6 +287,8 @@ rec {
/* Quote string to be used safely within the Bourne shell.
Type: escapeShellArg :: string -> string
Example:
escapeShellArg "esc'ape\nme"
=> "'esc'\\''ape\nme'"
@ -222,6 +297,8 @@ rec {
/* Quote all arguments to be safely passed to the Bourne shell.
Type: escapeShellArgs :: [string] -> string
Example:
escapeShellArgs ["one" "two three" "four'five"]
=> "'one' 'two three' 'four'\\''five'"
@ -230,13 +307,15 @@ rec {
/* Turn a string into a Nix expression representing that string
Type: string -> string
Example:
escapeNixString "hello\${}\n"
=> "\"hello\\\${}\\n\""
*/
escapeNixString = s: escape ["$"] (builtins.toJSON s);
/* Obsolete - use replaceStrings instead. */
# Obsolete - use replaceStrings instead.
replaceChars = builtins.replaceStrings or (
del: new: s:
let
@ -256,6 +335,8 @@ rec {
/* Converts an ASCII string to lower-case.
Type: toLower :: string -> string
Example:
toLower "HOME"
=> "home"
@ -264,6 +345,8 @@ rec {
/* Converts an ASCII string to upper-case.
Type: toUpper :: string -> string
Example:
toUpper "home"
=> "HOME"
@ -273,7 +356,7 @@ rec {
/* 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
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.
@ -319,8 +402,9 @@ rec {
in
recurse 0 0;
/* Return the suffix of the second argument if the first argument matches
its prefix.
/* Return a string without the specified prefix, if the prefix matches.
Type: string -> string -> string
Example:
removePrefix "foo." "foo.bar.baz"
@ -328,18 +412,23 @@ rec {
removePrefix "xxx" "foo.bar.baz"
=> "foo.bar.baz"
*/
removePrefix = pre: s:
removePrefix =
# Prefix to remove if it matches
prefix:
# Input string
str:
let
preLen = stringLength pre;
sLen = stringLength s;
preLen = stringLength prefix;
sLen = stringLength str;
in
if hasPrefix pre s then
substring preLen (sLen - preLen) s
if hasPrefix prefix str then
substring preLen (sLen - preLen) str
else
s;
str;
/* Return the prefix of the second argument if the first argument matches
its suffix.
/* Return a string without the specified suffix, if the suffix matches.
Type: string -> string -> string
Example:
removeSuffix "front" "homefront"
@ -347,17 +436,21 @@ rec {
removeSuffix "xxx" "homefront"
=> "homefront"
*/
removeSuffix = suf: s:
removeSuffix =
# Suffix to remove if it matches
suffix:
# Input string
str:
let
sufLen = stringLength suf;
sLen = stringLength s;
sufLen = stringLength suffix;
sLen = stringLength str;
in
if sufLen <= sLen && suf == substring (sLen - sufLen) sufLen s then
substring 0 (sLen - sufLen) s
if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then
substring 0 (sLen - sufLen) str
else
s;
str;
/* Return true iff string v1 denotes a version older than v2.
/* Return true if string v1 denotes a version older than v2.
Example:
versionOlder "1.1" "1.2"
@ -367,7 +460,7 @@ rec {
*/
versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1;
/* Return true iff string v1 denotes a version equal to or newer than v2.
/* Return true if string v1 denotes a version equal to or newer than v2.
Example:
versionAtLeast "1.1" "1.0"
@ -410,7 +503,7 @@ rec {
components = splitString "/" url;
filename = lib.last components;
name = builtins.head (splitString sep filename);
in assert name != filename; name;
in assert name != filename; name;
/* Create an --{enable,disable}-<feat> string that can be passed to
standard GNU Autoconf scripts.
@ -459,6 +552,11 @@ rec {
/* Create a fixed width string with additional prefix to match
required width.
This function will fail if the input string is longer than the
requested length.
Type: fixedWidthString :: int -> string -> string
Example:
fixedWidthString 5 "0" (toString 15)
=> "00015"
@ -468,7 +566,10 @@ rec {
strw = lib.stringLength str;
reqWidth = width - (lib.stringLength filler);
in
assert strw <= width;
assert lib.assertMsg (strw <= width)
"fixedWidthString: requested string length (${
toString width}) must not be shorter than actual length (${
toString strw})";
if strw == width then str else filler + fixedWidthString reqWidth filler str;
/* Format a number adding leading zeroes up to fixed width.
@ -499,12 +600,16 @@ rec {
=> false
*/
isStorePath = x:
isCoercibleToString x
&& builtins.substring 0 1 (toString x) == "/"
&& dirOf (builtins.toPath x) == builtins.storeDir;
if isCoercibleToString x then
let str = toString x; in
builtins.substring 0 1 str == "/"
&& dirOf str == builtins.storeDir
else
false;
/* Convert string to int
Obviously, it is a bit hacky to use fromJSON that way.
/* Parse a string string as an int.
Type: string -> int
Example:
toInt "1337"
@ -514,17 +619,18 @@ rec {
toInt "3.14"
=> error: floating point JSON numbers are not supported
*/
# Obviously, it is a bit hacky to use fromJSON this 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.
/* 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
NOTE: This function is not performant and should be avoided.
Example:
readPathsFromFile /prefix
@ -537,16 +643,17 @@ rec {
*/
readPathsFromFile = rootPath: file:
let
root = toString rootPath;
lines = lib.splitString "\n" (builtins.readFile file);
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
relativePaths = removeComments lines;
absolutePaths = builtins.map (path: builtins.toPath (root + "/" + path)) relativePaths;
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
in
absolutePaths;
/* Read the contents of a file removing the trailing \n
Type: fileContents :: path -> string
Example:
$ echo "1.0" > ./version

View File

@ -24,14 +24,20 @@ rec {
config = parse.tripleFromSystem final.parsed;
# Just a guess, based on `system`
platform = platforms.selectBySystem final.system;
# Determine whether we are compatible with the provided CPU
isCompatible = platform: parse.isCompatible final.parsed.cpu platform.parsed.cpu;
# Derived meta-data
libc =
/**/ if final.isDarwin then "libSystem"
else if final.isMinGW then "msvcrt"
else if final.isWasi then "wasilibc"
else if final.isMusl then "musl"
else if final.isUClibc then "uclibc"
else if final.isAndroid then "bionic"
else if final.isLinux /* default */ then "glibc"
else if final.isMsp430 then "newlib"
else if final.isAvr then "avrlibc"
else if final.isNetBSD then "nblibc"
# TODO(@Ericson2314) think more about other operating systems
else "native/impure";
extensions = {
@ -46,6 +52,73 @@ rec {
# Misc boolean options
useAndroidPrebuilt = false;
useiOSPrebuilt = false;
# Output from uname
uname = {
# uname -s
system = {
"linux" = "Linux";
"windows" = "Windows";
"darwin" = "Darwin";
"netbsd" = "NetBSD";
"freebsd" = "FreeBSD";
"openbsd" = "OpenBSD";
"wasi" = "Wasi";
}.${final.parsed.kernel.name} or null;
# uname -p
processor = final.parsed.cpu.name;
# uname -r
release = null;
};
kernelArch =
if final.isAarch32 then "arm"
else if final.isAarch64 then "arm64"
else if final.isx86_32 then "x86"
else if final.isx86_64 then "ia64"
else final.parsed.cpu.name;
qemuArch =
if final.isArm then "arm"
else if final.isx86_64 then "x86_64"
else if final.isx86 then "i386"
else {
"powerpc" = "ppc";
"powerpcle" = "ppc";
"powerpc64" = "ppc64";
"powerpc64le" = "ppc64le";
}.${final.parsed.cpu.name} or final.parsed.cpu.name;
emulator = pkgs: let
qemu-user = pkgs.qemu.override {
smartcardSupport = false;
spiceSupport = false;
openGLSupport = false;
virglSupport = false;
vncSupport = false;
gtkSupport = false;
sdlSupport = false;
pulseSupport = false;
smbdSupport = false;
seccompSupport = false;
hostCpuTargets = ["${final.qemuArch}-linux-user"];
};
wine-name = "wine${toString final.parsed.cpu.bits}";
wine = (pkgs.winePackagesFor wine-name).minimal;
in
if final.parsed.kernel.name == pkgs.stdenv.hostPlatform.parsed.kernel.name &&
pkgs.stdenv.hostPlatform.isCompatible final
then "${pkgs.runtimeShell} -c '\"$@\"' --"
else if final.isWindows
then "${wine}/bin/${wine-name}"
else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux
then "${qemu-user}/bin/qemu-${final.qemuArch}"
else if final.isWasi
then "${pkgs.wasmtime}/bin/wasmtime"
else throw "Don't know how to run ${final.config} executables.";
} // mapAttrs (n: v: v final.parsed) inspect.predicates
// args;
in assert final.useAndroidPrebuilt -> final.isAndroid;

View File

@ -15,6 +15,10 @@ let
"x86_64-cygwin" "x86_64-darwin" "x86_64-freebsd" "x86_64-linux"
"x86_64-netbsd" "x86_64-openbsd" "x86_64-solaris"
"x86_64-windows" "i686-windows"
"wasm64-wasi" "wasm32-wasi"
];
allParsed = map parse.mkSystemFromString all;
@ -36,13 +40,15 @@ in rec {
cygwin = filterDoubles predicates.isCygwin;
darwin = filterDoubles predicates.isDarwin;
freebsd = filterDoubles predicates.isFreeBSD;
# Should be better, but MinGW is unclear, and HURD is bit-rotted.
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; });
# Should be better, but MinGW is unclear.
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabi; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; });
illumos = filterDoubles predicates.isSunOS;
linux = filterDoubles predicates.isLinux;
netbsd = filterDoubles predicates.isNetBSD;
openbsd = filterDoubles predicates.isOpenBSD;
unix = filterDoubles predicates.isUnix;
wasi = filterDoubles predicates.isWasi;
windows = filterDoubles predicates.isWindows;
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "powerpc64le-linux"];
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "armv7a-linux" "aarch64-linux" "powerpc64le-linux"];
}

View File

@ -2,7 +2,14 @@
# `crossSystem`. They are put here for user convenience, but also used by cross
# tests and linux cross stdenv building, so handle with care!
{ lib }:
let platforms = import ./platforms.nix { inherit lib; }; in
let
platforms = import ./platforms.nix { inherit lib; };
riscv = bits: {
config = "riscv${bits}-unknown-linux-gnu";
platform = platforms.riscv-multiplatform bits;
};
in
rec {
#
@ -28,7 +35,7 @@ rec {
};
armv7l-hf-multiplatform = rec {
config = "armv7a-unknown-linux-gnueabihf";
config = "armv7l-unknown-linux-gnueabihf";
platform = platforms.armv7l-hf-multiplatform;
};
@ -37,18 +44,10 @@ rec {
platform = platforms.aarch64-multiplatform;
};
armv5te-android-prebuilt = rec {
config = "armv5tel-unknown-linux-androideabi";
sdkVer = "21";
ndkVer = "10e";
platform = platforms.armv5te-android;
useAndroidPrebuilt = true;
};
armv7a-android-prebuilt = rec {
config = "armv7a-unknown-linux-androideabi";
sdkVer = "24";
ndkVer = "17";
ndkVer = "18b";
platform = platforms.armv7a-android;
useAndroidPrebuilt = true;
};
@ -56,7 +55,7 @@ rec {
aarch64-android-prebuilt = rec {
config = "aarch64-unknown-linux-android";
sdkVer = "24";
ndkVer = "17";
ndkVer = "18b";
platform = platforms.aarch64-multiplatform;
useAndroidPrebuilt = true;
};
@ -92,13 +91,56 @@ rec {
musl64 = { config = "x86_64-unknown-linux-musl"; };
musl32 = { config = "i686-unknown-linux-musl"; };
riscv = bits: {
config = "riscv${bits}-unknown-linux-gnu";
platform = platforms.riscv-multiplatform bits;
};
riscv64 = riscv "64";
riscv32 = riscv "32";
msp430 = {
config = "msp430-elf";
libc = "newlib";
};
avr = {
config = "avr";
};
arm-embedded = {
config = "arm-none-eabi";
libc = "newlib";
};
armhf-embedded = {
config = "arm-none-eabihf";
libc = "newlib";
};
aarch64-embedded = {
config = "aarch64-none-elf";
libc = "newlib";
};
aarch64be-embedded = {
config = "aarch64_be-none-elf";
libc = "newlib";
};
ppc-embedded = {
config = "powerpc-none-eabi";
libc = "newlib";
};
ppcle-embedded = {
config = "powerpcle-none-eabi";
libc = "newlib";
};
i686-embedded = {
config = "i686-elf";
libc = "newlib";
};
x86_64-embedded = {
config = "x86_64-elf";
libc = "newlib";
};
#
# Darwin
@ -162,4 +204,21 @@ rec {
libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
platform = {};
};
# BSDs
amd64-netbsd = {
config = "x86_64-unknown-netbsd";
libc = "nblibc";
};
#
# WASM
#
wasi32 = {
config = "wasm32-unknown-wasi";
useLLVM = true;
};
}

View File

@ -20,7 +20,7 @@ in rec {
cygwin = [ patterns.isCygwin ];
darwin = [ patterns.isDarwin ];
freebsd = [ patterns.isFreeBSD ];
# Should be better, but MinGW is unclear, and HURD is bit-rotted.
# Should be better, but MinGW is unclear.
gnu = [
{ kernel = parse.kernels.linux; abi = abis.gnu; }
{ kernel = parse.kernels.linux; abi = abis.gnueabi; }
@ -32,6 +32,7 @@ in rec {
openbsd = [ patterns.isOpenBSD ];
unix = patterns.isUnix; # Actually a list
windows = [ patterns.isWindows ];
wasi = [ patterns.isWasi ];
inherit (lib.systems.doubles) mesaPlatforms;
}

View File

@ -9,7 +9,8 @@ let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis
rec {
patterns = rec {
isi686 = { cpu = cpuTypes.i686; };
isx86_64 = { cpu = cpuTypes.x86_64; };
isx86_32 = { cpu = { family = "x86"; bits = 32; }; };
isx86_64 = { cpu = { family = "x86"; bits = 64; }; };
isPowerPC = { cpu = cpuTypes.powerpc; };
isPower = { cpu = { family = "power"; }; };
isx86 = { cpu = { family = "x86"; }; };
@ -19,6 +20,9 @@ rec {
isRiscV = { cpu = { family = "riscv"; }; };
isSparc = { cpu = { family = "sparc"; }; };
isWasm = { cpu = { family = "wasm"; }; };
isMsp430 = { cpu = { family = "msp430"; }; };
isAvr = { cpu = { family = "avr"; }; };
isAlpha = { cpu = { family = "alpha"; }; };
is32bit = { cpu = { bits = 32; }; };
is64bit = { cpu = { bits = 64; }; };
@ -27,19 +31,19 @@ rec {
isBSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
isDarwin = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
isUnix = [ isBSD isDarwin isLinux isSunOS isHurd isCygwin ];
isUnix = [ isBSD isDarwin isLinux isSunOS isCygwin ];
isMacOS = { kernel = kernels.macos; };
isiOS = { kernel = kernels.ios; };
isLinux = { kernel = kernels.linux; };
isSunOS = { kernel = kernels.solaris; };
isFreeBSD = { kernel = kernels.freebsd; };
isHurd = { kernel = kernels.hurd; };
isNetBSD = { kernel = kernels.netbsd; };
isOpenBSD = { kernel = kernels.openbsd; };
isWindows = { kernel = kernels.windows; };
isCygwin = { kernel = kernels.windows; abi = abis.cygnus; };
isMinGW = { kernel = kernels.windows; abi = abis.gnu; };
isWasi = { kernel = kernels.wasi; };
isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];

View File

@ -69,20 +69,24 @@ rec {
cpuTypes = with significantBytes; setTypes types.openCpuType {
arm = { bits = 32; significantByte = littleEndian; family = "arm"; };
armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; };
armv6m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; };
armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; };
armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
armv7r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
armv7m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
armv8a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; };
armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; arch = "armv5t"; };
armv6m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6-m"; };
armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6"; };
armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-a"; };
armv7r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-r"; };
armv7m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-m"; };
armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7"; };
armv8a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-m"; };
aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
i386 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i386"; };
i486 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i486"; };
i586 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i586"; };
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i686"; };
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; arch = "x86-64"; };
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
@ -92,6 +96,7 @@ rec {
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
powerpc64 = { bits = 64; significantByte = bigEndian; family = "power"; };
powerpc64le = { bits = 64; significantByte = littleEndian; family = "power"; };
powerpcle = { bits = 32; significantByte = littleEndian; family = "power"; };
riscv32 = { bits = 32; significantByte = littleEndian; family = "riscv"; };
riscv64 = { bits = 64; significantByte = littleEndian; family = "riscv"; };
@ -101,8 +106,93 @@ rec {
wasm32 = { bits = 32; significantByte = littleEndian; family = "wasm"; };
wasm64 = { bits = 64; significantByte = littleEndian; family = "wasm"; };
alpha = { bits = 64; significantByte = littleEndian; family = "alpha"; };
msp430 = { bits = 16; significantByte = littleEndian; family = "msp430"; };
avr = { bits = 8; family = "avr"; };
};
# Determine where two CPUs are compatible with each other. That is,
# can we run code built for system b on system a? For that to
# happen, then the set of all possible possible programs that system
# b accepts must be a subset of the set of all programs that system
# a accepts. This compatibility relation forms a category where each
# CPU is an object and each arrow from a to b represents
# compatibility. CPUs with multiple modes of Endianness are
# isomorphic while all CPUs are endomorphic because any program
# built for a CPU can run on that CPU.
isCompatible = a: b: with cpuTypes; lib.any lib.id [
# x86
(b == i386 && isCompatible a i486)
(b == i486 && isCompatible a i586)
(b == i586 && isCompatible a i686)
# XXX: Not true in some cases. Like in WSL mode.
(b == i686 && isCompatible a x86_64)
# ARMv4
(b == arm && isCompatible a armv5tel)
# ARMv5
(b == armv5tel && isCompatible a armv6l)
# ARMv6
(b == armv6l && isCompatible a armv6m)
(b == armv6m && isCompatible a armv7l)
# ARMv7
(b == armv7l && isCompatible a armv7a)
(b == armv7l && isCompatible a armv7r)
(b == armv7l && isCompatible a armv7m)
(b == armv7a && isCompatible a armv8a)
(b == armv7r && isCompatible a armv8a)
(b == armv7m && isCompatible a armv8a)
(b == armv7a && isCompatible a armv8r)
(b == armv7r && isCompatible a armv8r)
(b == armv7m && isCompatible a armv8r)
(b == armv7a && isCompatible a armv8m)
(b == armv7r && isCompatible a armv8m)
(b == armv7m && isCompatible a armv8m)
# ARMv8
(b == armv8r && isCompatible a armv8a)
(b == armv8m && isCompatible a armv8a)
# XXX: not always true! Some arm64 cpus dont support arm32 mode.
(b == aarch64 && a == armv8a)
(b == armv8a && isCompatible a aarch64)
(b == aarch64 && a == aarch64_be)
(b == aarch64_be && isCompatible a aarch64)
# PowerPC
(b == powerpc && isCompatible a powerpc64)
(b == powerpcle && isCompatible a powerpc)
(b == powerpc && a == powerpcle)
(b == powerpc64le && isCompatible a powerpc64)
(b == powerpc64 && a == powerpc64le)
# MIPS
(b == mips && isCompatible a mips64)
(b == mips && a == mipsel)
(b == mipsel && isCompatible a mips)
(b == mips64 && a == mips64el)
(b == mips64el && isCompatible a mips64)
# RISCV
(b == riscv32 && isCompatible a riscv64)
# SPARC
(b == sparc && isCompatible a sparc64)
# WASM
(b == wasm32 && isCompatible a wasm64)
# identity
(b == a)
];
################################################################################
types.openVendor = mkOptionType {
@ -117,6 +207,7 @@ rec {
apple = {};
pc = {};
none = {};
unknown = {};
};
@ -135,6 +226,7 @@ rec {
elf = {};
macho = {};
pe = {};
wasm = {};
unknown = {};
};
@ -172,12 +264,12 @@ rec {
macos = { execFormat = macho; families = { inherit darwin; }; name = "darwin"; };
ios = { execFormat = macho; families = { inherit darwin; }; };
freebsd = { execFormat = elf; families = { inherit bsd; }; };
hurd = { execFormat = elf; families = { }; };
linux = { execFormat = elf; families = { }; };
netbsd = { execFormat = elf; families = { inherit bsd; }; };
none = { execFormat = unknown; families = { }; };
openbsd = { execFormat = elf; families = { inherit bsd; }; };
solaris = { execFormat = elf; families = { }; };
wasi = { execFormat = wasm; families = { }; };
windows = { execFormat = pe; families = { }; };
} // { # aliases
# 'darwin' is the kernel for all of them. We choose macOS by default.
@ -200,7 +292,15 @@ rec {
abis = setTypes types.openAbi {
cygnus = {};
msvc = {};
eabi = {};
# Note: eabi is specific to ARM and PowerPC.
# On PowerPC, this corresponds to PPCEABI.
# On ARM, this corresponds to ARMEABI.
eabi = { float = "soft"; };
eabihf = { float = "hard"; };
# Other architectures should use ELF in embedded situations.
elf = {};
androideabi = {};
android = {
@ -256,11 +356,20 @@ rec {
setType "system" components;
mkSkeletonFromList = l: {
"1" = if elemAt l 0 == "avr"
then { cpu = elemAt l 0; kernel = "none"; abi = "unknown"; }
else throw "Target specification with 1 components is ambiguous";
"2" = # We only do 2-part hacks for things Nix already supports
if elemAt l 1 == "cygwin"
then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; }
else if elemAt l 1 == "gnu"
then { cpu = elemAt l 0; kernel = "hurd"; abi = "gnu"; }
# MSVC ought to be the default ABI so this case isn't needed. But then it
# becomes difficult to handle the gnu* variants for Aarch32 correctly for
# minGW. So it's easier to make gnu* the default for the MinGW, but
# hack-in MSVC for the non-MinGW case right here.
else if elemAt l 1 == "windows"
then { cpu = elemAt l 0; kernel = "windows"; abi = "msvc"; }
else if (elemAt l 1) == "elf"
then { cpu = elemAt l 0; vendor = "unknown"; kernel = "none"; abi = elemAt l 1; }
else { cpu = elemAt l 0; kernel = elemAt l 1; };
"3" = # Awkwards hacks, beware!
if elemAt l 1 == "apple"
@ -268,9 +377,13 @@ rec {
else if (elemAt l 1 == "linux") || (elemAt l 2 == "gnu")
then { cpu = elemAt l 0; kernel = elemAt l 1; abi = elemAt l 2; }
else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; }
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; }
else if (elemAt l 2 == "wasi")
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "wasi"; }
else if hasPrefix "netbsd" (elemAt l 2)
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"])
then { cpu = elemAt l 0; vendor = "unknown"; kernel = elemAt l 1; abi = elemAt l 2; }
else throw "Target specification with 3 components is ambiguous";
"4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; };
}.${toString (length l)}
@ -302,13 +415,12 @@ rec {
else getKernel args.kernel;
abi =
/**/ if args ? abi then getAbi args.abi
else if isLinux parsed then
else if isLinux parsed || isWindows parsed then
if isAarch32 parsed then
if lib.versionAtLeast (parsed.cpu.version or "0") "6"
then abis.gnueabihf
else abis.gnueabi
else abis.gnu
else if isWindows parsed then abis.gnu
else abis.unknown;
};

View File

@ -253,22 +253,11 @@ rec {
kernelTarget = "zImage";
};
# https://developer.android.com/ndk/guides/abis#armeabi
armv5te-android = {
name = "armeabi";
gcc = {
arch = "armv5te";
float = "soft";
float-abi = "soft";
};
};
# https://developer.android.com/ndk/guides/abis#v7a
armv7a-android = {
name = "armeabi-v7a";
gcc = {
arch = "armv7-a";
float = "hard";
float-abi = "softfp";
fpu = "vfpv3-d16";
};
@ -467,10 +456,13 @@ rec {
};
selectBySystem = system: {
"i486-linux" = pc32;
"i586-linux" = pc32;
"i686-linux" = pc32;
"x86_64-linux" = pc64;
"armv5tel-linux" = sheevaplug;
"armv6l-linux" = raspberrypi;
"armv7a-linux" = armv7l-hf-multiplatform;
"armv7l-linux" = armv7l-hf-multiplatform;
"aarch64-linux" = aarch64-multiplatform;
"mipsel-linux" = fuloong2f_n32;

7
lib/tests/check-eval.nix Normal file
View File

@ -0,0 +1,7 @@
# Throws an error if any of our lib tests fail.
let tests = [ "misc" "systems" ];
all = builtins.concatLists (map (f: import (./. + "/${f}.nix")) tests);
in if all == []
then null
else throw (builtins.toJSON all)

View File

@ -112,7 +112,7 @@ runTests {
storePathAppendix = isStorePath
"${goodPath}/bin/python";
nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
asPath = isStorePath (builtins.toPath goodPath);
asPath = isStorePath (/. + goodPath);
otherPath = isStorePath "/something/else";
otherVals = {
attrset = isStorePath {};
@ -236,6 +236,20 @@ runTests {
};
};
testOverrideExistingEmpty = {
expr = overrideExisting {} { a = 1; };
expected = {};
};
testOverrideExistingDisjoint = {
expr = overrideExisting { b = 2; } { a = 1; };
expected = { b = 2; };
};
testOverrideExistingOverride = {
expr = overrideExisting { a = 3; b = 2; } { a = 1; };
expected = { a = 1; b = 2; };
};
# GENERATORS
# these tests assume attributes are converted to lists
@ -355,9 +369,10 @@ runTests {
testToPretty = {
expr = mapAttrs (const (generators.toPretty {})) rec {
int = 42;
float = 0.1337;
bool = true;
string = ''fno"rd'';
path = /. + "/foo"; # toPath returns a string
path = /. + "/foo";
null_ = null;
function = x: x;
functionArgs = { arg ? 4, foo }: arg;
@ -367,6 +382,7 @@ runTests {
};
expected = rec {
int = "42";
float = "~0.133700";
bool = "true";
string = ''"fno\"rd"'';
path = "/foo";
@ -385,42 +401,4 @@ runTests {
expected = "«foo»";
};
# MISC
testOverridableDelayableArgsTest = {
expr =
let res1 = defaultOverridableDelayableArgs id {};
res2 = defaultOverridableDelayableArgs id { a = 7; };
res3 = let x = defaultOverridableDelayableArgs id { a = 7; };
in (x.merge) { b = 10; };
res4 = let x = defaultOverridableDelayableArgs id { a = 7; };
in (x.merge) ( x: { b = 10; });
res5 = let x = defaultOverridableDelayableArgs id { a = 7; };
in (x.merge) ( x: { a = builtins.add x.a 3; });
res6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = builtins.add; }; };
y = x.merge {};
in (y.merge) { a = 10; };
resRem7 = res6.replace (a: removeAttrs a ["a"]);
# fixed tests (delayed args): (when using them add some comments, please)
resFixed1 =
let x = defaultOverridableDelayableArgs id ( x: { a = 7; c = x.fixed.b; });
y = x.merge (x: { name = "name-${builtins.toString x.fixed.c}"; });
in (y.merge) { b = 10; };
strip = attrs: removeAttrs attrs ["merge" "replace"];
in all id
[ ((strip res1) == { })
((strip res2) == { a = 7; })
((strip res3) == { a = 7; b = 10; })
((strip res4) == { a = 7; b = 10; })
((strip res5) == { a = 10; })
((strip res6) == { a = 17; })
((strip resRem7) == {})
((strip resFixed1) == { a = 7; b = 10; c =10; name = "name-10"; })
];
expected = true;
};
}

View File

@ -149,6 +149,12 @@ checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-long-list.ni
# Check loaOf with many merges of lists.
checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-many-list-merges.nix
# Check mkAliasOptionModule.
checkConfigOutput "true" config.enable ./alias-with-priority.nix
checkConfigOutput "true" config.enableAlias ./alias-with-priority.nix
checkConfigOutput "false" config.enable ./alias-with-priority-can-override.nix
checkConfigOutput "false" config.enableAlias ./alias-with-priority-can-override.nix
cat <<EOF
====== module tests ======
$pass Pass

View File

@ -0,0 +1,55 @@
# This is a test to show that mkAliasOptionModule sets the priority correctly
# for aliased options.
#
# This test shows that an alias with a high priority is able to override
# a non-aliased option.
{ config, lib, ... }:
with lib;
{
options = {
# A simple boolean option that can be enabled or disabled.
enable = lib.mkOption {
type = types.nullOr types.bool;
default = null;
example = true;
description = ''
Some descriptive text
'';
};
# mkAliasOptionModule sets warnings, so this has to be defined.
warnings = mkOption {
internal = true;
default = [];
type = types.listOf types.str;
example = [ "The `foo' service is deprecated and will go away soon!" ];
description = ''
This option allows modules to show warnings to users during
the evaluation of the system configuration.
'';
};
};
imports = [
# Create an alias for the "enable" option.
(mkAliasOptionModule [ "enableAlias" ] [ "enable" ])
# Disable the aliased option with a high priority so it
# should override the next import.
( { config, lib, ... }:
{
enableAlias = lib.mkForce false;
}
)
# Enable the normal (non-aliased) option.
( { config, lib, ... }:
{
enable = true;
}
)
];
}

View File

@ -0,0 +1,55 @@
# This is a test to show that mkAliasOptionModule sets the priority correctly
# for aliased options.
#
# This test shows that an alias with a low priority is able to be overridden
# with a non-aliased option.
{ config, lib, ... }:
with lib;
{
options = {
# A simple boolean option that can be enabled or disabled.
enable = lib.mkOption {
type = types.nullOr types.bool;
default = null;
example = true;
description = ''
Some descriptive text
'';
};
# mkAliasOptionModule sets warnings, so this has to be defined.
warnings = mkOption {
internal = true;
default = [];
type = types.listOf types.str;
example = [ "The `foo' service is deprecated and will go away soon!" ];
description = ''
This option allows modules to show warnings to users during
the evaluation of the system configuration.
'';
};
};
imports = [
# Create an alias for the "enable" option.
(mkAliasOptionModule [ "enableAlias" ] [ "enable" ])
# Disable the aliased option, but with a default (low) priority so it
# should be able to be overridden by the next import.
( { config, lib, ... }:
{
enableAlias = lib.mkDefault false;
}
)
# Enable the normal (non-aliased) option.
( { config, lib, ... }:
{
enable = true;
}
)
];
}

View File

@ -12,20 +12,21 @@ let
expected = lib.sort lib.lessThan y;
};
in with lib.systems.doubles; lib.runTests {
all = assertTrue (mseteq all (linux ++ darwin ++ cygwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
testall = mseteq all (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ wasi ++ windows);
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ]);
i686 = assertTrue (mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" ]);
mips = assertTrue (mseteq mips [ "mipsel-linux" ]);
x86_64 = assertTrue (mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" ]);
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ];
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" ];
testmips = mseteq mips [ "mipsel-linux" ];
testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" ];
cygwin = assertTrue (mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ]);
darwin = assertTrue (mseteq darwin [ "x86_64-darwin" ]);
freebsd = assertTrue (mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ]);
gnu = assertTrue (mseteq gnu (linux /* ++ hurd ++ kfreebsd ++ ... */));
illumos = assertTrue (mseteq illumos [ "x86_64-solaris" ]);
linux = assertTrue (mseteq linux [ "i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mipsel-linux" ]);
netbsd = assertTrue (mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ]);
openbsd = assertTrue (mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ]);
unix = assertTrue (mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
testcygwin = mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ];
testdarwin = mseteq darwin [ "x86_64-darwin" ];
testfreebsd = mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ];
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
testillumos = mseteq illumos [ "x86_64-solaris" ];
testlinux = mseteq linux [ "i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mipsel-linux" ];
testnetbsd = mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ];
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
testunix = mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ cygwin);
}

View File

@ -9,23 +9,37 @@ rec {
Type: id :: a -> a
*/
id = x: x;
id =
# The value to return
x: x;
/* The constant function
Ignores the second argument.
Or: Construct a function that always returns a static value.
Ignores the second argument. If called with only one argument,
constructs a function that always returns a static value.
Type: const :: a -> b -> a
Example:
let f = const 5; in f 10
=> 5
*/
const = x: y: x;
const =
# Value to return
x:
# Value to ignore
y: x;
## Named versions corresponding to some builtin operators.
/* Concatenate two lists */
/* Concatenate two lists
Type: concat :: [a] -> [a] -> [a]
Example:
concat [ 1 2 ] [ 3 4 ]
=> [ 1 2 3 4 ]
*/
concat = x: y: x ++ y;
/* boolean or */
@ -36,44 +50,57 @@ rec {
/* bitwise and */
bitAnd = builtins.bitAnd
or import ./zip-int-bits.nix
(a: b: if a==1 && b==1 then 1 else 0);
or (import ./zip-int-bits.nix
(a: b: if a==1 && b==1 then 1 else 0));
/* bitwise or */
bitOr = builtins.bitOr
or import ./zip-int-bits.nix
(a: b: if a==1 || b==1 then 1 else 0);
or (import ./zip-int-bits.nix
(a: b: if a==1 || b==1 then 1 else 0));
/* bitwise xor */
bitXor = builtins.bitXor
or import ./zip-int-bits.nix
(a: b: if a!=b then 1 else 0);
or (import ./zip-int-bits.nix
(a: b: if a!=b then 1 else 0));
/* bitwise not */
bitNot = builtins.sub (-1);
/* Convert a boolean to a string.
Note that toString on a bool returns "1" and "".
This function uses the strings "true" and "false" to represent
boolean values. Calling `toString` on a bool instead returns "1"
and "" (sic!).
Type: boolToString :: bool -> string
*/
boolToString = b: if b then "true" else "false";
/* Merge two attribute sets shallowly, right side trumps left
mergeAttrs :: attrs -> attrs -> attrs
Example:
mergeAttrs { a = 1; b = 2; } { b = 3; c = 4; }
=> { a = 1; b = 3; c = 4; }
*/
mergeAttrs = x: y: x // y;
mergeAttrs =
# Left attribute set
x:
# Right attribute set (higher precedence for equal keys)
y: x // y;
/* Flip the order of the arguments of a binary function.
Type: flip :: (a -> b -> c) -> (b -> a -> c)
Example:
flip concat [1] [2]
=> [ 2 1 ]
*/
flip = f: a: b: f b a;
/* Apply function if argument is non-null.
/* Apply function if the supplied argument is non-null.
Example:
mapNullable (x: x+1) null
@ -81,7 +108,11 @@ rec {
mapNullable (x: x+1) 22
=> 23
*/
mapNullable = f: a: if isNull a then a else f a;
mapNullable =
# Function to call
f:
# Argument to check for null before passing it to `f`
a: if isNull a then a else f a;
# Pull in some builtins not included elsewhere.
inherit (builtins)
@ -92,29 +123,58 @@ rec {
## nixpks version strings
# The current full nixpkgs version number.
/* Returns the current full nixpkgs version number. */
version = release + versionSuffix;
# The current nixpkgs version number as string.
/* Returns the current nixpkgs release number as string. */
release = lib.strings.fileContents ../.version;
# The current nixpkgs version suffix as string.
/* Returns the current nixpkgs release code name.
On each release the first letter is bumped and a new animal is chosen
starting with that new letter.
*/
codeName = "Loris";
/* Returns the current nixpkgs version suffix as string. */
versionSuffix =
let suffixFile = ../.version-suffix;
in if pathExists suffixFile
then lib.strings.fileContents suffixFile
else "pre-git";
/* Attempts to return the the current revision of nixpkgs and
returns the supplied default value otherwise.
Type: revisionWithDefault :: string -> string
*/
revisionWithDefault =
# Default value to return if revision can not be determined
default:
let
revisionFile = "${toString ./..}/.git-revision";
gitRepo = "${toString ./..}/.git";
in if lib.pathIsDirectory gitRepo
then lib.commitIdFromGitRepo gitRepo
else if lib.pathExists revisionFile then lib.fileContents revisionFile
else default;
nixpkgsVersion = builtins.trace "`lib.nixpkgsVersion` is deprecated, use `lib.version` instead!" version;
# Whether we're being called by nix-shell.
/* Determine whether the function is being called from inside a Nix
shell.
Type: inNixShell :: bool
*/
inNixShell = builtins.getEnv "IN_NIX_SHELL" != "";
## Integer operations
# Return minimum/maximum of two numbers.
/* Return minimum of two numbers. */
min = x: y: if x < y then x else y;
/* Return maximum of two numbers. */
max = x: y: if x > y then x else y;
/* Integer modulus
@ -148,8 +208,9 @@ rec {
second subtype, compare elements of a single subtype with `yes`
and `no` respectively.
Example:
Type: (a -> bool) -> (a -> a -> int) -> (a -> a -> int) -> (a -> a -> int)
Example:
let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in
cmp "a" "z" => -1
@ -160,34 +221,48 @@ rec {
# while
compare "fooa" "a" => 1
*/
splitByAndCompare = p: yes: no: a: b:
splitByAndCompare =
# Predicate
p:
# Comparison function if predicate holds for both values
yes:
# Comparison function if predicate holds for neither value
no:
# First value to compare
a:
# Second value to compare
b:
if p a
then if p b then yes a b else -1
else if p b then 1 else no a b;
/* Reads a JSON file. */
/* Reads a JSON file.
Type :: path -> any
*/
importJSON = path:
builtins.fromJSON (builtins.readFile path);
## Warnings and asserts
## Warnings
/* 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.
# 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.
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}";
warn = msg: builtins.trace "warning: ${msg}";
info = msg: builtins.trace "INFO: ${msg}";
showWarnings = warnings: res: lib.fold (w: x: warn w x) res warnings;
## Function annotations

View File

@ -119,7 +119,9 @@ rec {
let
betweenDesc = lowest: highest:
"${toString lowest} and ${toString highest} (both inclusive)";
between = lowest: highest: assert lowest <= highest;
between = lowest: highest:
assert lib.assertMsg (lowest <= highest)
"ints.between: lowest must be smaller than highest";
addCheck int (x: x >= lowest && x <= highest) // {
name = "intBetween";
description = "integer between ${betweenDesc lowest highest}";
@ -167,6 +169,9 @@ rec {
# s32 = sign 32 4294967296;
};
# Alias of u16 for a port number
port = ints.u16;
float = mkOptionType rec {
name = "float";
description = "floating point number";
@ -192,7 +197,10 @@ rec {
# separator between the values).
separatedString = sep: mkOptionType rec {
name = "separatedString";
description = "string";
description = if sep == ""
then "Concatenated string" # for types.string.
else "strings concatenated with ${builtins.toJSON sep}"
;
check = isString;
merge = loc: defs: concatStringsSep sep (getValues defs);
functor = (defaultFunctor name) // {
@ -276,8 +284,7 @@ rec {
(mergeDefinitions (loc ++ [name]) elemType defs).optionalValue
)
# Push down position info.
(map (def: listToAttrs (mapAttrsToList (n: def':
{ name = n; value = { inherit (def) file; value = def'; }; }) def.value)) defs)));
(map (def: mapAttrs (n: v: { inherit (def) file; value = v; }) def.value) defs)));
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]);
getSubModules = elemType.getSubModules;
substSubModules = m: attrsOf (elemType.substSubModules m);
@ -439,7 +446,9 @@ rec {
# Either value of type `finalType` or `coercedType`, the latter is
# converted to `finalType` using `coerceFunc`.
coercedTo = coercedType: coerceFunc: finalType:
assert coercedType.getSubModules == null;
assert lib.assertMsg (coercedType.getSubModules == null)
"coercedTo: coercedType must not have submodules (its a ${
coercedType.description})";
mkOptionType rec {
name = "coercedTo";
description = "${finalType.description} or ${coercedType.description} convertible to it";
@ -464,7 +473,6 @@ rec {
name = builtins.trace "types.optionSet is deprecated; use types.submodule instead" "optionSet";
description = "option set";
};
# Augment the given type with an additional type check function.
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
#! /usr/bin/env nix-shell
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.FileSlurp nixUnstable nixUnstable.perl-bindings
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.FileSlurp perlPackages.JSON perlPackages.LWPProtocolHttps nixUnstable nixUnstable.perl-bindings
# This command uploads tarballs to tarballs.nixos.org, the
# content-addressed cache used by fetchurl as a fallback for when
@ -101,8 +101,8 @@ sub uploadFile {
my ($name, $dest) = @_;
#print STDERR "linking $name to $dest...\n";
$bucket->add_key($name, "", {
'x-amz-website-redirect-location' => "/" . $dest,
'x-amz-acl' => "public-read"
'x-amz-website-redirect-location' => "/" . $dest,
'x-amz-acl' => "public-read"
})
or die "failed to create redirect from $name to $dest\n";
$cache{$name} = 1;
@ -116,8 +116,8 @@ sub uploadFile {
# Upload the file as sha512/<hash-in-base-16>.
print STDERR "uploading $fn to $mainKey...\n";
$bucket->add_key_filename($mainKey, $fn, {
'x-amz-meta-original-name' => $name,
'x-amz-acl' => "public-read"
'x-amz-meta-original-name' => $name,
'x-amz-acl' => "public-read"
})
or die "failed to upload $fn to $mainKey\n";
$cache{$mainKey} = 1;

View File

@ -0,0 +1,11 @@
#! /bin/sh
if [[ -z "$VERBOSE" ]]; then
echo "You may set VERBOSE=1 to see debug output or to any other non-empty string to make this script completely silent"
fi
unset HOME NIXPKGS_CONFIG # Force empty config
# With the default heap size (380MB), nix-instantiate fails:
# Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS
export GC_INITIAL_HEAP_SIZE=${GC_INITIAL_HEAP_SIZE:-2000000000} # 2GB
nix-instantiate --strict --eval-only --xml --show-trace "$(dirname "$0")"/eval-release.nix 2>&1 > /dev/null

View File

@ -14,12 +14,13 @@ fi
tmp=$(mktemp -d)
pushd $tmp >/dev/null
wget -nH -r -c --no-parent "${WGET_ARGS[@]}" >/dev/null
wget -nH -r -c --no-parent "${WGET_ARGS[@]}" -A '*.tar.xz.sha256' -A '*.mirrorlist' >/dev/null
find -type f -name '*.mirrorlist' -delete
csv=$(mktemp)
find . -type f | while read src; do
# Sanitize file name
filename=$(basename "$src" | tr '@' '_')
filename=$(gawk '{ print $2 }' "$src" | tr '@' '_')
nameVersion="${filename%.tar.*}"
name=$(echo "$nameVersion" | sed -e 's,-[[:digit:]].*,,' | sed -e 's,-opensource-src$,,' | sed -e 's,-everywhere-src$,,')
version=$(echo "$nameVersion" | sed -e 's,^\([[:alpha:]][[:alnum:]]*-\)\+,,')
@ -38,8 +39,8 @@ gawk -F , "{ print \$1 }" $csv | sort | uniq | while read name; do
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")
url="$(dirname "${src:2}")/$filename"
sha256=$(gawk '{ print $1 }' "$src")
cat >>"$SRCS" <<EOF
$name = {
version = "$latestVersion";

View File

@ -31,7 +31,7 @@ let
if !canEval x then []
else if isDerivation x then optional (canEval x.drvPath) x
else if isList x then concatLists (map derivationsIn' x)
else if isAttrs x then concatLists (mapAttrsToList (n: v: derivationsIn' v) x)
else if isAttrs x then concatLists (mapAttrsToList (n: v: addErrorContext "while finding tarballs in '${n}':" (derivationsIn' v)) x)
else [ ];
keyDrv = drv: if canEval drv.drvPath then { key = drv.drvPath; value = drv; } else { };

Some files were not shown because too many files have changed in this diff Show More