Merge branch 'master' into texmacsDarwin
This commit is contained in:
commit
12f14a0909
16
.gitattributes
vendored
Normal file
16
.gitattributes
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
**/deps.nix linguist-generated
|
||||||
|
**/node-packages.nix linguist-generated
|
||||||
|
|
||||||
|
pkgs/applications/editors/emacs-modes/*-generated.nix linguist-generated
|
||||||
|
pkgs/development/r-modules/*-packages.nix linguist-generated
|
||||||
|
pkgs/development/haskell-modules/hackage-packages.nix linguist-generated
|
||||||
|
pkgs/development/beam-modules/hex-packages.nix linguist-generated
|
||||||
|
|
||||||
|
doc/** linguist-documentation
|
||||||
|
doc/default.nix linguist-documentation=false
|
||||||
|
|
||||||
|
nixos/doc/** linguist-documentation
|
||||||
|
nixos/doc/default.nix linguist-documentation=false
|
||||||
|
|
||||||
|
nixos/modules/module-list.nix merge=union
|
||||||
|
pkgs/top-level/all-packages.nix merge=union
|
25
.github/CODEOWNERS
vendored
25
.github/CODEOWNERS
vendored
@ -10,18 +10,19 @@
|
|||||||
# This file
|
# This file
|
||||||
/.github/CODEOWNERS @edolstra
|
/.github/CODEOWNERS @edolstra
|
||||||
|
|
||||||
# Boostraping and core infra
|
|
||||||
/pkgs/stdenv @edolstra
|
|
||||||
/pkgs/build-support/cc-wrapper @edolstra
|
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
/lib @edolstra @nbp
|
/lib @edolstra @nbp
|
||||||
|
/lib/systems @nbp @ericson2314
|
||||||
|
|
||||||
# Nixpkgs Internals
|
# Nixpkgs Internals
|
||||||
/default.nix @nbp
|
/default.nix @nbp
|
||||||
/pkgs/top-level/default.nix @nbp
|
/pkgs/top-level/default.nix @nbp @Ericson2314
|
||||||
/pkgs/top-level/impure.nix @nbp
|
/pkgs/top-level/impure.nix @nbp @Ericson2314
|
||||||
/pkgs/top-level/stage.nix @nbp
|
/pkgs/top-level/stage.nix @nbp @Ericson2314
|
||||||
|
/pkgs/stdenv
|
||||||
|
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej
|
||||||
|
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
|
||||||
|
/pkgs/build-support/setup-hooks @Ericson2314
|
||||||
|
|
||||||
# NixOS Internals
|
# NixOS Internals
|
||||||
/nixos/default.nix @nbp
|
/nixos/default.nix @nbp
|
||||||
@ -82,4 +83,10 @@
|
|||||||
/pkgs/applications/editors/eclipse @rycee
|
/pkgs/applications/editors/eclipse @rycee
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/issues/31401
|
# https://github.com/NixOS/nixpkgs/issues/31401
|
||||||
/lib/maintainers.nix @ghost
|
/lib/licenses.nix @ghost
|
||||||
|
|
||||||
|
# Qt / KDE
|
||||||
|
/pkgs/applications/kde @ttuegel
|
||||||
|
/pkgs/desktops/plasma-5 @ttuegel
|
||||||
|
/pkgs/development/libraries/kde-frameworks @ttuegel
|
||||||
|
/pkgs/development/libraries/qt-5 @ttuegel
|
||||||
|
2
COPYING
2
COPYING
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2003-2017 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
Copyright (c) 2003-2018 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
[<img src="http://nixos.org/logo/nixos-hires.png" width="500px" alt="logo" />](https://nixos.org/nixos)
|
[<img src="https://nixos.org/logo/nixos-hires.png" width="500px" alt="logo" />](https://nixos.org/nixos)
|
||||||
|
|
||||||
[](https://travis-ci.org/NixOS/nixpkgs)
|
|
||||||
[](https://www.codetriage.com/nixos/nixpkgs)
|
[](https://www.codetriage.com/nixos/nixpkgs)
|
||||||
|
|
||||||
Nixpkgs is a collection of packages for the [Nix](https://nixos.org/nix/) package
|
Nixpkgs is a collection of packages for the [Nix](https://nixos.org/nix/) package
|
||||||
manager. It is periodically built and tested by the [hydra](http://hydra.nixos.org/)
|
manager. It is periodically built and tested by the [Hydra](https://hydra.nixos.org/)
|
||||||
build daemon as so-called channels. To get channel information via git, add
|
build daemon as so-called channels. To get channel information via git, add
|
||||||
[nixpkgs-channels](https://github.com/NixOS/nixpkgs-channels.git) as a remote:
|
[nixpkgs-channels](https://github.com/NixOS/nixpkgs-channels.git) as a remote:
|
||||||
|
|
||||||
@ -23,7 +22,7 @@ release and `nixos-unstable` for the latest successful build of master:
|
|||||||
|
|
||||||
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](https://nixos.org/nixos/) Linux distribution source code is located inside
|
||||||
`nixos/` folder.
|
`nixos/` folder.
|
||||||
|
|
||||||
* [NixOS installation instructions](https://nixos.org/nixos/manual/#ch-installation)
|
* [NixOS installation instructions](https://nixos.org/nixos/manual/#ch-installation)
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
tab settings so it’s asking for trouble.</para></listitem>
|
tab settings so it’s asking for trouble.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Use <literal>lowerCamelCase</literal> for variable
|
<listitem><para>Use <literal>lowerCamelCase</literal> for variable
|
||||||
names, not <literal>UpperCamelCase</literal>. TODO: naming of
|
names, not <literal>UpperCamelCase</literal>. Note, this rule does
|
||||||
attributes in
|
not apply to package attribute names, which instead follow the rules
|
||||||
<filename>all-packages.nix</filename>?</para></listitem>
|
in <xref linkend="sec-package-naming"/>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Function calls with attribute set arguments are
|
<listitem><para>Function calls with attribute set arguments are
|
||||||
written as
|
written as
|
||||||
@ -220,9 +220,10 @@ args.stdenv.mkDerivation (args // {
|
|||||||
|
|
||||||
<listitem><para>The variable name used for the instantiated package
|
<listitem><para>The variable name used for the instantiated package
|
||||||
in <filename>all-packages.nix</filename>, and when passing it as a
|
in <filename>all-packages.nix</filename>, and when passing it as a
|
||||||
dependency to other functions. This is what Nix expression authors
|
dependency to other functions. Typically this is called the
|
||||||
see. It can also be used when installing using <command>nix-env
|
<emphasis>package attribute name</emphasis>. This is what Nix
|
||||||
-iA</command>.</para></listitem>
|
expression authors see. It can also be used when installing using
|
||||||
|
<command>nix-env -iA</command>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>The filename for (the directory containing) the Nix
|
<listitem><para>The filename for (the directory containing) the Nix
|
||||||
expression.</para></listitem>
|
expression.</para></listitem>
|
||||||
@ -259,12 +260,12 @@ bound to the variable name <varname>e2fsprogs</varname> in
|
|||||||
Also append <literal>"unstable"</literal> to the name - e.g.,
|
Also append <literal>"unstable"</literal> to the name - e.g.,
|
||||||
<literal>"pkgname-unstable-2014-09-23"</literal>.</para></listitem>
|
<literal>"pkgname-unstable-2014-09-23"</literal>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Dashes in the package name should be preserved
|
<listitem><para>Dashes in the package name should be preserved in
|
||||||
in new variable names, rather than converted to underscores
|
new variable names, rather than converted to underscores or camel
|
||||||
(which was convention up to around 2013 and most names
|
cased — e.g., <varname>http-parser</varname> instead of
|
||||||
still have underscores instead of dashes) — e.g.,
|
<varname>http_parser</varname> or <varname>httpParser</varname>. The
|
||||||
<varname>http-parser</varname> instead of
|
hyphenated style is preferred in all three package
|
||||||
<varname>http_parser</varname>.</para></listitem>
|
names.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>If there are multiple versions of a package, this
|
<listitem><para>If there are multiple versions of a package, this
|
||||||
should be reflected in the variable names in
|
should be reflected in the variable names in
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The "target platform" attribute is, unlike the other two attributes, not actually fundamental to the process of building software.
|
The "target platform" attribute is, unlike the other two attributes, not actually fundamental to the process of building software.
|
||||||
Instead, it is only relevant for compatability with building certain specific compilers and build tools.
|
Instead, it is only relevant for compatibility with building certain specific compilers and build tools.
|
||||||
It can be safely ignored for all other packages.
|
It can be safely ignored for all other packages.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
@ -162,7 +162,7 @@
|
|||||||
<para>
|
<para>
|
||||||
A runtime dependency between 2 packages implies that between them both the host and target platforms match.
|
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":
|
This is directly implied by the meaning of "host platform" and "runtime dependency":
|
||||||
The package dependency exists while both packages are runnign on a single host platform.
|
The package dependency exists while both packages are running on a single host platform.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
A build time dependency, however, implies a shift in platforms between the depending package and the depended-on package.
|
A build time dependency, however, implies a shift in platforms between the depending package and the depended-on package.
|
||||||
@ -187,7 +187,7 @@
|
|||||||
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.
|
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.
|
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.
|
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 four attributes used for specifying dependencies as documented in <xref linkend="ssec-stdenv-attributes"/>.
|
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.
|
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.
|
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.
|
Because of this, a best-of-both-worlds solution is in the works with no splicing or explicit access of <varname>buildPackages</varname> needed.
|
||||||
@ -200,6 +200,45 @@
|
|||||||
</para></note>
|
</para></note>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Cross packagaing 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!
|
||||||
|
</para>
|
||||||
|
<qandaset>
|
||||||
|
<qandaentry>
|
||||||
|
<question><para>
|
||||||
|
What if my package's build system needs to build a C program to be run under the build environment?
|
||||||
|
</para></question>
|
||||||
|
<answer><para>
|
||||||
|
<programlisting>depsBuildBuild = [ buildPackages.stdenv.cc ];</programlisting>
|
||||||
|
Add it to your <function>mkDerivation</function> invocation.
|
||||||
|
</para></answer>
|
||||||
|
</qandaentry>
|
||||||
|
<qandaentry>
|
||||||
|
<question><para>
|
||||||
|
My package fails to find <command>ar</command>.
|
||||||
|
</para></question>
|
||||||
|
<answer><para>
|
||||||
|
Many packages assume that an unprefixed <command>ar</command> is available, but Nix doesn't provide one.
|
||||||
|
It only provides a prefixed one, just as it only does for all the other binutils programs.
|
||||||
|
It may be necessary to patch the package to fix the build system to use a prefixed `ar`.
|
||||||
|
</para></answer>
|
||||||
|
</qandaentry>
|
||||||
|
<qandaentry>
|
||||||
|
<question><para>
|
||||||
|
My package's testsuite needs to run host platform code.
|
||||||
|
</para></question>
|
||||||
|
<answer><para>
|
||||||
|
<programlisting>doCheck = stdenv.hostPlatform != stdenv.buildPlatfrom;</programlisting>
|
||||||
|
Add it to your <function>mkDerivation</function> invocation.
|
||||||
|
</para></answer>
|
||||||
|
</qandaentry>
|
||||||
|
</qandaset>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!--============================================================-->
|
<!--============================================================-->
|
||||||
@ -214,8 +253,19 @@
|
|||||||
or also with <varname>crossSystem</varname>, in which case packages run on the latter, but all building happens on the former.
|
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 defined in the previous section.
|
Both parameters take the same schema as the 3 (build, host, and target) platforms defined in the previous section.
|
||||||
As mentioned above, <literal>lib.systems.examples</literal> has some platforms which are used as arguments for these parameters in practice.
|
As mentioned above, <literal>lib.systems.examples</literal> has some platforms which are used as arguments for these parameters in practice.
|
||||||
You can use them programmatically, or on the command line like <command>nix-build <nixpkgs> --arg crossSystem '(import <nixpkgs/lib>).systems.examples.fooBarBaz'</command>.
|
You can use them programmatically, or on the command line: <programlisting>
|
||||||
|
nix-build <nixpkgs> --arg crossSystem '(import <nixpkgs/lib>).systems.examples.fooBarBaz' -A whatever</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
Eventually we would like to make these platform examples an unnecessary convenience so that <programlisting>
|
||||||
|
nix-build <nixpkgs> --arg crossSystem.config '<arch>-<os>-<vendor>-<abi>' -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 vaguely sane manner on the users behalf.
|
||||||
|
Issue <link xlink:href="https://github.com/NixOS/nixpkgs/issues/34274">#34274</link> tracks this inconvenience along with its root cause in crufty configuration options.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
<para>
|
<para>
|
||||||
While one is free to pass both parameters in full, there's a lot of logic to fill in missing fields.
|
While one is free to pass both parameters in full, there's a lot of logic to fill in missing fields.
|
||||||
As discussed in the previous section, only one of <varname>system</varname>, <varname>config</varname>, and <varname>parsed</varname> is needed to infer the other two.
|
As discussed in the previous section, only one of <varname>system</varname>, <varname>config</varname>, and <varname>parsed</varname> is needed to infer the other two.
|
||||||
|
@ -23,11 +23,12 @@ pkgs.stdenv.mkDerivation {
|
|||||||
|
|
||||||
buildCommand = let toDocbook = { useChapters ? false, inputFile, outputFile }:
|
buildCommand = let toDocbook = { useChapters ? false, inputFile, outputFile }:
|
||||||
let
|
let
|
||||||
extraHeader = ''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
|
extraHeader = lib.optionalString (!useChapters)
|
||||||
|
''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
|
||||||
in ''
|
in ''
|
||||||
{
|
{
|
||||||
pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--top-level-division=chapter"} \
|
pandoc '${inputFile}' -w docbook+smart ${lib.optionalString useChapters "--top-level-division=chapter"} \
|
||||||
--smart \
|
-f markdown+smart \
|
||||||
| sed -e 's|<ulink url=|<link xlink:href=|' \
|
| sed -e 's|<ulink url=|<link xlink:href=|' \
|
||||||
-e 's|</ulink>|</link>|' \
|
-e 's|</ulink>|</link>|' \
|
||||||
-e 's|<sect. id=|<section xml:id=|' \
|
-e 's|<sect. id=|<section xml:id=|' \
|
||||||
@ -48,6 +49,10 @@ pkgs.stdenv.mkDerivation {
|
|||||||
outputFile = "introduction.xml";
|
outputFile = "introduction.xml";
|
||||||
useChapters = true;
|
useChapters = true;
|
||||||
}
|
}
|
||||||
|
+ toDocbook {
|
||||||
|
inputFile = ./shell.md;
|
||||||
|
outputFile = "shell.xml";
|
||||||
|
}
|
||||||
+ toDocbook {
|
+ toDocbook {
|
||||||
inputFile = ./languages-frameworks/python.md;
|
inputFile = ./languages-frameworks/python.md;
|
||||||
outputFile = "./languages-frameworks/python.xml";
|
outputFile = "./languages-frameworks/python.xml";
|
||||||
@ -76,6 +81,10 @@ pkgs.stdenv.mkDerivation {
|
|||||||
inputFile = ./languages-frameworks/vim.md;
|
inputFile = ./languages-frameworks/vim.md;
|
||||||
outputFile = "./languages-frameworks/vim.xml";
|
outputFile = "./languages-frameworks/vim.xml";
|
||||||
}
|
}
|
||||||
|
+ toDocbook {
|
||||||
|
inputFile = ./languages-frameworks/emscripten.md;
|
||||||
|
outputFile = "./languages-frameworks/emscripten.xml";
|
||||||
|
}
|
||||||
+ ''
|
+ ''
|
||||||
echo ${lib.nixpkgsVersion} > .version
|
echo ${lib.nixpkgsVersion} > .version
|
||||||
|
|
||||||
|
@ -11,31 +11,53 @@
|
|||||||
in the Coq derivation.
|
in the Coq derivation.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Some libraries require OCaml and sometimes also Camlp5. The exact
|
Some libraries require OCaml and sometimes also Camlp5 or findlib.
|
||||||
versions that were used to build Coq are saved in the
|
The exact versions that were used to build Coq are saved in the
|
||||||
<literal>coq.ocaml</literal> and <literal>coq.camlp5</literal>
|
<literal>coq.ocaml</literal> and <literal>coq.camlp5</literal>
|
||||||
attributes.
|
and <literal>coq.findlib</literal> attributes.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Coq libraries may be compatible with some specific versions of Coq only.
|
||||||
|
The <literal>compatibleCoqVersions</literal> attribute is used to
|
||||||
|
precisely select those versions of Coq that are compatible with this
|
||||||
|
derivation.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Here is a simple package example. It is a pure Coq library, thus it
|
Here is a simple package example. It is a pure Coq library, thus it
|
||||||
only depends on Coq. Its <literal>makefile</literal> has been
|
depends on Coq. It builds on the Mathematical Components library, thus it
|
||||||
generated using <literal>coq_makefile</literal> so we only have to
|
also takes <literal>mathcomp</literal> as <literal>buildInputs</literal>.
|
||||||
|
Its <literal>Makefile</literal> has been generated using
|
||||||
|
<literal>coq_makefile</literal> so we only have to
|
||||||
set the <literal>$COQLIB</literal> variable at install time.
|
set the <literal>$COQLIB</literal> variable at install time.
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{stdenv, fetchurl, coq}:
|
{ stdenv, fetchFromGitHub, coq, mathcomp }:
|
||||||
stdenv.mkDerivation {
|
|
||||||
src = fetchurl {
|
stdenv.mkDerivation rec {
|
||||||
url = http://coq.inria.fr/pylons/contribs/files/Karatsuba/v8.4/Karatsuba.tar.gz;
|
name = "coq${coq.coq-version}-multinomials-${version}";
|
||||||
sha256 = "0ymfpv4v49k4fm63nq6gcl1hbnnxrvjjp7yzc4973n49b853c5b1";
|
version = "1.0";
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "math-comp";
|
||||||
|
repo = "multinomials";
|
||||||
|
rev = version;
|
||||||
|
sha256 = "1qmbxp1h81cy3imh627pznmng0kvv37k4hrwi2faa101s6bcx55m";
|
||||||
};
|
};
|
||||||
|
|
||||||
name = "coq-karatsuba";
|
|
||||||
|
|
||||||
buildInputs = [ coq ];
|
buildInputs = [ coq ];
|
||||||
|
propagatedBuildInputs = [ mathcomp ];
|
||||||
|
|
||||||
installFlags = "COQLIB=$(out)/lib/coq/${coq.coq-version}/";
|
installFlags = "COQLIB=$(out)/lib/coq/${coq.coq-version}/";
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "A Coq/SSReflect Library for Monoidal Rings and Multinomials";
|
||||||
|
inherit (src.meta) homepage;
|
||||||
|
license = stdenv.lib.licenses.cecill-b;
|
||||||
|
inherit (coq.meta) platforms;
|
||||||
|
};
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
compatibleCoqVersions = v: builtins.elem v [ "8.5" "8.6" "8.7" ];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
185
doc/languages-frameworks/emscripten.md
Normal file
185
doc/languages-frameworks/emscripten.md
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
# User's Guide to Emscripten in Nixpkgs
|
||||||
|
|
||||||
|
[Emscripten](https://github.com/kripken/emscripten): An LLVM-to-JavaScript Compiler
|
||||||
|
|
||||||
|
This section of the manual covers how to use `emscripten` in nixpkgs.
|
||||||
|
|
||||||
|
Minimal requirements:
|
||||||
|
|
||||||
|
* nix
|
||||||
|
* nixpkgs
|
||||||
|
|
||||||
|
Modes of use of `emscripten`:
|
||||||
|
|
||||||
|
* **Imperative usage** (on the command line):
|
||||||
|
|
||||||
|
If you want to work with `emcc`, `emconfigure` and `emmake` as you are used to from Ubuntu and similar distributions you can use these commands:
|
||||||
|
|
||||||
|
* `nix-env -i emscripten`
|
||||||
|
* `nix-shell -p emscripten`
|
||||||
|
|
||||||
|
* **Declarative usage**:
|
||||||
|
|
||||||
|
This mode is far more power full since this makes use of `nix` for dependency management of emscripten libraries and targets by using the `mkDerivation` which is implemented by `pkgs.emscriptenStdenv` and `pkgs.buildEmscriptenPackage`. The source for the packages is in `pkgs/top-level/emscripten-packages.nix` and the abstraction behind it in `pkgs/development/em-modules/generic/default.nix`.
|
||||||
|
* build and install all packages:
|
||||||
|
* `nix-env -iA emscriptenPackages`
|
||||||
|
|
||||||
|
* dev-shell for zlib implementation hacking:
|
||||||
|
* `nix-shell -A emscriptenPackages.zlib`
|
||||||
|
|
||||||
|
|
||||||
|
## Imperative usage
|
||||||
|
|
||||||
|
A few things to note:
|
||||||
|
|
||||||
|
* `export EMCC_DEBUG=2` is nice for debugging
|
||||||
|
* `~/.emscripten`, the build artifact cache sometimes creates issues and needs to be removed from time to time
|
||||||
|
|
||||||
|
|
||||||
|
## Declarative usage
|
||||||
|
|
||||||
|
Let's see two different examples from `pkgs/top-level/emscripten-packages.nix`:
|
||||||
|
|
||||||
|
* `pkgs.zlib.override`
|
||||||
|
* `pkgs.buildEmscriptenPackage`
|
||||||
|
|
||||||
|
Both are interesting concepts.
|
||||||
|
|
||||||
|
A special requirement of the `pkgs.buildEmscriptenPackage` is the `doCheck = true` is a default meaning that each emscriptenPackage requires a `checkPhase` implemented.
|
||||||
|
|
||||||
|
* Use `export EMCC_DEBUG=2` from within a emscriptenPackage's `phase` to get more detailed debug output what is going wrong.
|
||||||
|
* ~/.emscripten cache is requiring us to set `HOME=$TMPDIR` in individual phases. This makes compilation slower but also makes it more deterministic.
|
||||||
|
|
||||||
|
### Usage 1: pkgs.zlib.override
|
||||||
|
|
||||||
|
This example uses `zlib` from nixpkgs but instead of compiling **C** to **ELF** it compiles **C** to **JS** since we were using `pkgs.zlib.override` and changed stdenv to `pkgs.emscriptenStdenv`. A few adaptions and hacks were set in place to make it working. One advantage is that when `pkgs.zlib` is updated, it will automatically update this package as well. However, this can also be the downside...
|
||||||
|
|
||||||
|
See the `zlib` example:
|
||||||
|
|
||||||
|
zlib = (pkgs.zlib.override {
|
||||||
|
stdenv = pkgs.emscriptenStdenv;
|
||||||
|
}).overrideDerivation
|
||||||
|
(old: rec {
|
||||||
|
buildInputs = old.buildInputs ++ [ pkgconfig ];
|
||||||
|
# we need to reset this setting!
|
||||||
|
NIX_CFLAGS_COMPILE="";
|
||||||
|
configurePhase = ''
|
||||||
|
# FIXME: Some tests require writing at $HOME
|
||||||
|
HOME=$TMPDIR
|
||||||
|
runHook preConfigure
|
||||||
|
|
||||||
|
#export EMCC_DEBUG=2
|
||||||
|
emconfigure ./configure --prefix=$out --shared
|
||||||
|
|
||||||
|
runHook postConfigure
|
||||||
|
'';
|
||||||
|
dontStrip = true;
|
||||||
|
outputs = [ "out" ];
|
||||||
|
buildPhase = ''
|
||||||
|
emmake make
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
emmake make install
|
||||||
|
'';
|
||||||
|
checkPhase = ''
|
||||||
|
echo "================= testing zlib using node ================="
|
||||||
|
|
||||||
|
echo "Compiling a custom test"
|
||||||
|
set -x
|
||||||
|
emcc -O2 -s EMULATE_FUNCTION_POINTER_CASTS=1 test/example.c -DZ_SOLO \
|
||||||
|
libz.so.${old.version} -I . -o example.js
|
||||||
|
|
||||||
|
echo "Using node to execute the test"
|
||||||
|
${pkgs.nodejs}/bin/node ./example.js
|
||||||
|
|
||||||
|
set +x
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "test failed for some reason"
|
||||||
|
exit 1;
|
||||||
|
else
|
||||||
|
echo "it seems to work! very good."
|
||||||
|
fi
|
||||||
|
echo "================= /testing zlib using node ================="
|
||||||
|
'';
|
||||||
|
|
||||||
|
postPatch = pkgs.stdenv.lib.optionalString pkgs.stdenv.isDarwin ''
|
||||||
|
substituteInPlace configure \
|
||||||
|
--replace '/usr/bin/libtool' 'ar' \
|
||||||
|
--replace 'AR="libtool"' 'AR="ar"' \
|
||||||
|
--replace 'ARFLAGS="-o"' 'ARFLAGS="-r"'
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
### Usage 2: pkgs.buildEmscriptenPackage
|
||||||
|
|
||||||
|
This `xmlmirror` example features a emscriptenPackage which is defined completely from this context and no `pkgs.zlib.override` is used.
|
||||||
|
|
||||||
|
xmlmirror = pkgs.buildEmscriptenPackage rec {
|
||||||
|
name = "xmlmirror";
|
||||||
|
|
||||||
|
buildInputs = [ pkgconfig autoconf automake libtool gnumake libxml2 nodejs openjdk json_c ];
|
||||||
|
nativeBuildInputs = [ pkgconfig zlib ];
|
||||||
|
|
||||||
|
src = pkgs.fetchgit {
|
||||||
|
url = "https://gitlab.com/odfplugfest/xmlmirror.git";
|
||||||
|
rev = "4fd7e86f7c9526b8f4c1733e5c8b45175860a8fd";
|
||||||
|
sha256 = "1jasdqnbdnb83wbcnyrp32f36w3xwhwp0wq8lwwmhqagxrij1r4b";
|
||||||
|
};
|
||||||
|
|
||||||
|
configurePhase = ''
|
||||||
|
rm -f fastXmlLint.js*
|
||||||
|
# a fix for ERROR:root:For asm.js, TOTAL_MEMORY must be a multiple of 16MB, was 234217728
|
||||||
|
# https://gitlab.com/odfplugfest/xmlmirror/issues/8
|
||||||
|
sed -e "s/TOTAL_MEMORY=234217728/TOTAL_MEMORY=268435456/g" -i Makefile.emEnv
|
||||||
|
# https://github.com/kripken/emscripten/issues/6344
|
||||||
|
# https://gitlab.com/odfplugfest/xmlmirror/issues/9
|
||||||
|
sed -e "s/\$(JSONC_LDFLAGS) \$(ZLIB_LDFLAGS) \$(LIBXML20_LDFLAGS)/\$(JSONC_LDFLAGS) \$(LIBXML20_LDFLAGS) \$(ZLIB_LDFLAGS) /g" -i Makefile.emEnv
|
||||||
|
# https://gitlab.com/odfplugfest/xmlmirror/issues/11
|
||||||
|
sed -e "s/-o fastXmlLint.js/-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]' -o fastXmlLint.js/g" -i Makefile.emEnv
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
HOME=$TMPDIR
|
||||||
|
make -f Makefile.emEnv
|
||||||
|
'';
|
||||||
|
|
||||||
|
outputs = [ "out" "doc" ];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/share
|
||||||
|
mkdir -p $doc/share/${name}
|
||||||
|
|
||||||
|
cp Demo* $out/share
|
||||||
|
cp -R codemirror-5.12 $out/share
|
||||||
|
cp fastXmlLint.js* $out/share
|
||||||
|
cp *.xsd $out/share
|
||||||
|
cp *.js $out/share
|
||||||
|
cp *.xhtml $out/share
|
||||||
|
cp *.html $out/share
|
||||||
|
cp *.json $out/share
|
||||||
|
cp *.rng $out/share
|
||||||
|
cp README.md $doc/share/${name}
|
||||||
|
'';
|
||||||
|
checkPhase = ''
|
||||||
|
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
### Declarative debugging
|
||||||
|
|
||||||
|
Use `nix-shell -I nixpkgs=/some/dir/nixpkgs -A emscriptenPackages.libz` and from there you can go trough the individual steps. This makes it easy to build a good `unit test` or list the files of the project.
|
||||||
|
|
||||||
|
1. `nix-shell -I nixpkgs=/some/dir/nixpkgs -A emscriptenPackages.libz`
|
||||||
|
2. `cd /tmp/`
|
||||||
|
3. `unpackPhase`
|
||||||
|
4. cd libz-1.2.3
|
||||||
|
5. `configurePhase`
|
||||||
|
6. `buildPhase`
|
||||||
|
7. ... happy hacking...
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Using this toolchain makes it easy to leverage `nix` from NixOS, MacOSX or even Windows (WSL+ubuntu+nix). This toolchain is reproducible, behaves like the rest of the packages from nixpkgs and contains a set of well working examples to learn and adapt from.
|
||||||
|
|
||||||
|
If in trouble, ask the maintainers.
|
||||||
|
|
@ -48,7 +48,7 @@ trouble with packages like `3dmodels` and `4Blocks`, because these names are
|
|||||||
invalid identifiers in the Nix language. The issue of how to deal with these
|
invalid identifiers in the Nix language. The issue of how to deal with these
|
||||||
rare corner cases is currently unresolved.)
|
rare corner cases is currently unresolved.)
|
||||||
|
|
||||||
Haskell packages who's Nix name (second column) begins with a `haskell-` prefix
|
Haskell packages whose Nix name (second column) begins with a `haskell-` prefix
|
||||||
are packages that provide a library whereas packages without that prefix
|
are packages that provide a library whereas packages without that prefix
|
||||||
provide just executables. Libraries may provide executables too, though: the
|
provide just executables. Libraries may provide executables too, though: the
|
||||||
package `haskell-pandoc`, for example, installs both a library and an
|
package `haskell-pandoc`, for example, installs both a library and an
|
||||||
@ -334,14 +334,10 @@ navigate there.
|
|||||||
|
|
||||||
Finally, you can run
|
Finally, you can run
|
||||||
```shell
|
```shell
|
||||||
hoogle server -p 8080
|
hoogle server -p 8080 --local
|
||||||
```
|
```
|
||||||
and navigate to http://localhost:8080/ for your own local
|
and navigate to http://localhost:8080/ for your own local
|
||||||
[Hoogle](https://www.haskell.org/hoogle/). Note, however, that Firefox and
|
[Hoogle](https://www.haskell.org/hoogle/).
|
||||||
possibly other browsers disallow navigation from `http:` to `file:` URIs for
|
|
||||||
security reasons, which might be quite an inconvenience. See [this
|
|
||||||
page](http://kb.mozillazine.org/Links_to_local_pages_do_not_work) for
|
|
||||||
workarounds.
|
|
||||||
|
|
||||||
### How to build a Haskell project using Stack
|
### How to build a Haskell project using Stack
|
||||||
|
|
||||||
@ -581,8 +577,8 @@ nix-shell "<nixpkgs>" -A haskellPackages.bar.env
|
|||||||
Every Haskell package set takes a function called `overrides` that you can use
|
Every Haskell package set takes a function called `overrides` that you can use
|
||||||
to manipulate the package as much as you please. One useful application of this
|
to manipulate the package as much as you please. One useful application of this
|
||||||
feature is to replace the default `mkDerivation` function with one that enables
|
feature is to replace the default `mkDerivation` function with one that enables
|
||||||
library profiling for all packages. To accomplish that, add configure the
|
library profiling for all packages. To accomplish that add the following
|
||||||
following snippet in your `~/.config/nixpkgs/config.nix` file:
|
snippet to your `~/.config/nixpkgs/config.nix` file:
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
packageOverrides = super: let self = super.pkgs; in
|
packageOverrides = super: let self = super.pkgs; in
|
||||||
@ -693,9 +689,7 @@ might be necessary to purge the local caches that store data from those
|
|||||||
machines to disable these binary channels for the duration of the previous
|
machines to disable these binary channels for the duration of the previous
|
||||||
command, i.e. by running:
|
command, i.e. by running:
|
||||||
```shell
|
```shell
|
||||||
rm /nix/var/nix/binary-cache-v3.sqlite
|
rm ~/.cache/nix/binary-cache*.sqlite
|
||||||
rm /nix/var/nix/manifests/*
|
|
||||||
rm /nix/var/nix/channel-cache/*
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Builds on Darwin fail with `math.h` not found
|
### Builds on Darwin fail with `math.h` not found
|
||||||
@ -777,14 +771,14 @@ to find out the store path of the system's zlib library. Now, you can
|
|||||||
stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build
|
stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build
|
||||||
```
|
```
|
||||||
|
|
||||||
Typically, you'll need `--extra-include-dirs` as well. It's possible
|
Typically, you'll need `--extra-include-dirs` as well. It's possible
|
||||||
to add those flag to the project's `stack.yaml` or your user's
|
to add those flag to the project's `stack.yaml` or your user's
|
||||||
global `~/.stack/global/stack.yaml` file so that you don't have to
|
global `~/.stack/global/stack.yaml` file so that you don't have to
|
||||||
specify them manually every time. But again, you're likely better off
|
specify them manually every time. But again, you're likely better off
|
||||||
using Stack's Nix support instead.
|
using Stack's Nix support instead.
|
||||||
|
|
||||||
The same thing applies to `cabal configure`, of course, if you're
|
The same thing applies to `cabal configure`, of course, if you're
|
||||||
building with `cabal-install` instead of Stack.
|
building with `cabal-install` instead of Stack.
|
||||||
|
|
||||||
### Creating statically linked binaries
|
### Creating statically linked binaries
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ such as Perl or Haskell. These are described in this chapter.</para>
|
|||||||
<xi:include href="rust.xml" />
|
<xi:include href="rust.xml" />
|
||||||
<xi:include href="texlive.xml" />
|
<xi:include href="texlive.xml" />
|
||||||
<xi:include href="vim.xml" />
|
<xi:include href="vim.xml" />
|
||||||
|
<xi:include href="emscripten.xml" />
|
||||||
|
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -177,5 +177,19 @@ you need it.</para>
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="ssec-perl-cross-compilation"><title>Cross-compiling modules</title>
|
||||||
|
|
||||||
|
<para>Nixpkgs has experimental support for cross-compiling Perl
|
||||||
|
modules. In many cases, it will just work out of the box, even for
|
||||||
|
modules with native extensions. Sometimes, however, the Makefile.PL
|
||||||
|
for a module may (indirectly) import a native module. In that case,
|
||||||
|
you will need to make a stub for that module that will satisfy the
|
||||||
|
Makefile.PL and install it into
|
||||||
|
<filename>lib/perl5/site_perl/cross_perl/${perl.version}</filename>.
|
||||||
|
See the <varname>postInstall</varname> for <varname>DBI</varname> for
|
||||||
|
an example.</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ with
|
|||||||
```nix
|
```nix
|
||||||
with import <nixpkgs> {};
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
python35.withPackages (ps: [ps.numpy ps.toolz])
|
(python35.withPackages (ps: [ps.numpy ps.toolz])).env
|
||||||
```
|
```
|
||||||
Executing `nix-shell` gives you again a Nix shell from which you can run Python.
|
Executing `nix-shell` gives you again a Nix shell from which you can run Python.
|
||||||
|
|
||||||
@ -191,7 +191,6 @@ building Python libraries is `buildPythonPackage`. Let's see how we can build th
|
|||||||
toolz = buildPythonPackage rec {
|
toolz = buildPythonPackage rec {
|
||||||
pname = "toolz";
|
pname = "toolz";
|
||||||
version = "0.7.4";
|
version = "0.7.4";
|
||||||
name = "${pname}-${version}";
|
|
||||||
|
|
||||||
src = fetchPypi {
|
src = fetchPypi {
|
||||||
inherit pname version;
|
inherit pname version;
|
||||||
@ -237,7 +236,6 @@ with import <nixpkgs> {};
|
|||||||
my_toolz = python35.pkgs.buildPythonPackage rec {
|
my_toolz = python35.pkgs.buildPythonPackage rec {
|
||||||
pname = "toolz";
|
pname = "toolz";
|
||||||
version = "0.7.4";
|
version = "0.7.4";
|
||||||
name = "${pname}-${version}";
|
|
||||||
|
|
||||||
src = python35.pkgs.fetchPypi {
|
src = python35.pkgs.fetchPypi {
|
||||||
inherit pname version;
|
inherit pname version;
|
||||||
@ -283,15 +281,15 @@ order to build [`datashape`](https://github.com/blaze/datashape).
|
|||||||
{ # ...
|
{ # ...
|
||||||
|
|
||||||
datashape = buildPythonPackage rec {
|
datashape = buildPythonPackage rec {
|
||||||
name = "datashape-${version}";
|
pname = "datashape";
|
||||||
version = "0.4.7";
|
version = "0.4.7";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
src = fetchPypi {
|
||||||
url = "mirror://pypi/D/DataShape/${name}.tar.gz";
|
inherit pname version;
|
||||||
sha256 = "14b2ef766d4c9652ab813182e866f493475e65e558bed0822e38bf07bba1a278";
|
sha256 = "14b2ef766d4c9652ab813182e866f493475e65e558bed0822e38bf07bba1a278";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildInputs = with self; [ pytest ];
|
checkInputs = with self; [ pytest ];
|
||||||
propagatedBuildInputs = with self; [ numpy multipledispatch dateutil ];
|
propagatedBuildInputs = with self; [ numpy multipledispatch dateutil ];
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
@ -318,10 +316,11 @@ when building the bindings and are therefore added as `buildInputs`.
|
|||||||
{ # ...
|
{ # ...
|
||||||
|
|
||||||
lxml = buildPythonPackage rec {
|
lxml = buildPythonPackage rec {
|
||||||
name = "lxml-3.4.4";
|
pname = "lxml";
|
||||||
|
version = "3.4.4";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
src = fetchPypi {
|
||||||
url = "mirror://pypi/l/lxml/${name}.tar.gz";
|
inherit pname version;
|
||||||
sha256 = "16a0fa97hym9ysdk3rmqz32xdjqmy4w34ld3rm3jf5viqjx65lxk";
|
sha256 = "16a0fa97hym9ysdk3rmqz32xdjqmy4w34ld3rm3jf5viqjx65lxk";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -351,11 +350,11 @@ and `CFLAGS`.
|
|||||||
{ # ...
|
{ # ...
|
||||||
|
|
||||||
pyfftw = buildPythonPackage rec {
|
pyfftw = buildPythonPackage rec {
|
||||||
name = "pyfftw-${version}";
|
pname = "pyFFTW";
|
||||||
version = "0.9.2";
|
version = "0.9.2";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
src = fetchPypi {
|
||||||
url = "mirror://pypi/p/pyFFTW/pyFFTW-${version}.tar.gz";
|
inherit pname version;
|
||||||
sha256 = "f6bbb6afa93085409ab24885a1a3cdb8909f095a142f4d49e346f2bd1b789074";
|
sha256 = "f6bbb6afa93085409ab24885a1a3cdb8909f095a142f4d49e346f2bd1b789074";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -440,11 +439,11 @@ We first create a function that builds `toolz` in `~/path/to/toolz/release.nix`
|
|||||||
{ pkgs, buildPythonPackage }:
|
{ pkgs, buildPythonPackage }:
|
||||||
|
|
||||||
buildPythonPackage rec {
|
buildPythonPackage rec {
|
||||||
name = "toolz-${version}";
|
pname = "toolz";
|
||||||
version = "0.7.4";
|
version = "0.7.4";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
src = fetchPypi {
|
||||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
inherit pname version;
|
||||||
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -549,25 +548,31 @@ The `buildPythonPackage` function is implemented in
|
|||||||
|
|
||||||
The following is an example:
|
The following is an example:
|
||||||
```nix
|
```nix
|
||||||
{ # ...
|
|
||||||
|
|
||||||
twisted = buildPythonPackage {
|
buildPythonPackage rec {
|
||||||
name = "twisted-8.1.0";
|
version = "3.3.1";
|
||||||
|
pname = "pytest";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
preCheck = ''
|
||||||
url = http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2;
|
# don't test bash builtins
|
||||||
sha256 = "0q25zbr4xzknaghha72mq57kh53qw1bf8csgp63pm9sfi72qhirl";
|
rm testing/test_argcomplete.py
|
||||||
};
|
'';
|
||||||
|
|
||||||
propagatedBuildInputs = [ self.ZopeInterface ];
|
src = fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "cf8436dc59d8695346fcd3ab296de46425ecab00d64096cebe79fb51ecb2eb93";
|
||||||
|
};
|
||||||
|
|
||||||
meta = {
|
checkInputs = [ hypothesis ];
|
||||||
homepage = http://twistedmatrix.com/;
|
buildInputs = [ setuptools_scm ];
|
||||||
description = "Twisted, an event-driven networking engine written in Python";
|
propagatedBuildInputs = [ attrs py setuptools six pluggy ];
|
||||||
license = stdenv.lib.licenses.mit;
|
|
||||||
};
|
meta = with stdenv.lib; {
|
||||||
|
maintainers = with maintainers; [ domenkozar lovek323 madjar lsix ];
|
||||||
|
description = "Framework for writing tests";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The `buildPythonPackage` mainly does four things:
|
The `buildPythonPackage` mainly does four things:
|
||||||
@ -623,7 +628,6 @@ with import <nixpkgs> {};
|
|||||||
packageOverrides = self: super: {
|
packageOverrides = self: super: {
|
||||||
pandas = super.pandas.overridePythonAttrs(old: rec {
|
pandas = super.pandas.overridePythonAttrs(old: rec {
|
||||||
version = "0.19.1";
|
version = "0.19.1";
|
||||||
name = "pandas-${version}";
|
|
||||||
src = super.fetchPypi {
|
src = super.fetchPypi {
|
||||||
pname = "pandas";
|
pname = "pandas";
|
||||||
inherit version;
|
inherit version;
|
||||||
@ -867,8 +871,10 @@ Executing `python setup.py bdist_wheel` in a `nix-shell `fails with
|
|||||||
```
|
```
|
||||||
ValueError: ZIP does not support timestamps before 1980
|
ValueError: ZIP does not support timestamps before 1980
|
||||||
```
|
```
|
||||||
This is because files are included that depend on items in the Nix store which have a timestamp of, that is, it corresponds to January the 1st, 1970 at 00:00:00. And as the error informs you, ZIP does not support that.
|
|
||||||
The command `bdist_wheel` takes into account `SOURCE_DATE_EPOCH`, and `nix-shell` sets this to 1. By setting it to a value corresponding to 1980 or later, or by unsetting it, it is possible to build wheels.
|
This is because files from the Nix store (which have a timestamp of the UNIX epoch of January 1, 1970) are included in the .ZIP, but .ZIP archives follow the DOS convention of counting timestamps from 1980.
|
||||||
|
|
||||||
|
The command `bdist_wheel` reads the `SOURCE_DATE_EPOCH` environment variable, which `nix-shell` sets to 1. Unsetting this variable or giving it a value corresponding to 1980 or later enables building wheels.
|
||||||
|
|
||||||
Use 1980 as timestamp:
|
Use 1980 as timestamp:
|
||||||
```shell
|
```shell
|
||||||
@ -878,7 +884,7 @@ or the current time:
|
|||||||
```shell
|
```shell
|
||||||
nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
|
nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
|
||||||
```
|
```
|
||||||
or unset:
|
or unset `SOURCE_DATE_EPOCH`:
|
||||||
```shell
|
```shell
|
||||||
nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
|
nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
|
||||||
```
|
```
|
||||||
|
@ -9,17 +9,18 @@ date: 2017-03-05
|
|||||||
To install the rust compiler and cargo put
|
To install the rust compiler and cargo put
|
||||||
|
|
||||||
```
|
```
|
||||||
rust
|
rustc
|
||||||
|
cargo
|
||||||
```
|
```
|
||||||
|
|
||||||
into the `environment.systemPackages` or bring them into
|
into the `environment.systemPackages` or bring them into
|
||||||
scope with `nix-shell -p rust`.
|
scope with `nix-shell -p rustc cargo`.
|
||||||
|
|
||||||
For daily builds (beta and nightly) use either rustup from
|
For daily builds (beta and nightly) use either rustup from
|
||||||
nixpkgs or use the [Rust nightlies
|
nixpkgs or use the [Rust nightlies
|
||||||
overlay](#using-the-rust-nightlies-overlay).
|
overlay](#using-the-rust-nightlies-overlay).
|
||||||
|
|
||||||
## Packaging Rust applications
|
## Compiling Rust applications with Cargo
|
||||||
|
|
||||||
Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`:
|
Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`:
|
||||||
|
|
||||||
@ -55,6 +56,226 @@ checksum can be then take from the failed build.
|
|||||||
To install crates with nix there is also an experimental project called
|
To install crates with nix there is also an experimental project called
|
||||||
[nixcrates](https://github.com/fractalide/nixcrates).
|
[nixcrates](https://github.com/fractalide/nixcrates).
|
||||||
|
|
||||||
|
## Compiling Rust crates using Nix instead of Cargo
|
||||||
|
|
||||||
|
### Simple operation
|
||||||
|
|
||||||
|
When run, `cargo build` produces a file called `Cargo.lock`,
|
||||||
|
containing pinned versions of all dependencies. Nixpkgs contains a
|
||||||
|
tool called `carnix` (`nix-env -iA nixos.carnix`), which can be used
|
||||||
|
to turn a `Cargo.lock` into a Nix expression.
|
||||||
|
|
||||||
|
That Nix expression calls `rustc` directly (hence bypassing Cargo),
|
||||||
|
and can be used to compile a crate and all its dependencies. Here is
|
||||||
|
an example for a minimal `hello` crate:
|
||||||
|
|
||||||
|
|
||||||
|
$ cargo new hello
|
||||||
|
$ cd hello
|
||||||
|
$ cargo build
|
||||||
|
Compiling hello v0.1.0 (file:///tmp/hello)
|
||||||
|
Finished dev [unoptimized + debuginfo] target(s) in 0.20 secs
|
||||||
|
$ carnix -o hello.nix --src ./. Cargo.lock --standalone
|
||||||
|
$ nix-build hello.nix
|
||||||
|
|
||||||
|
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;
|
||||||
|
# ... (content skipped)
|
||||||
|
in
|
||||||
|
rec {
|
||||||
|
hello = f: hello_0_1_0 { features = hello_0_1_0_features { hello_0_1_0 = f; }; };
|
||||||
|
hello_0_1_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
|
||||||
|
crateName = "hello";
|
||||||
|
version = "0.1.0";
|
||||||
|
authors = [ "pe@pijul.org <pe@pijul.org>" ];
|
||||||
|
src = ./.;
|
||||||
|
inherit dependencies buildDependencies features;
|
||||||
|
};
|
||||||
|
hello_0_1_0 = { features?(hello_0_1_0_features {}) }: hello_0_1_0_ {};
|
||||||
|
hello_0_1_0_features = f: updateFeatures f (rec {
|
||||||
|
hello_0_1_0.default = (f.hello_0_1_0.default or true);
|
||||||
|
}) [ ];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In particular, note that the argument given as `--src` is copied
|
||||||
|
verbatim to the source. If we look at a more complicated
|
||||||
|
dependencies, for instance by adding a single line `libc="*"` to our
|
||||||
|
`Cargo.toml`, we first need to run `cargo build` to update the
|
||||||
|
`Cargo.lock`. Then, `carnix` needs to be run again, and produces the
|
||||||
|
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;
|
||||||
|
# ... (content skipped)
|
||||||
|
in
|
||||||
|
rec {
|
||||||
|
hello = f: hello_0_1_0 { features = hello_0_1_0_features { hello_0_1_0 = f; }; };
|
||||||
|
hello_0_1_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
|
||||||
|
crateName = "hello";
|
||||||
|
version = "0.1.0";
|
||||||
|
authors = [ "pe@pijul.org <pe@pijul.org>" ];
|
||||||
|
src = ./.;
|
||||||
|
inherit dependencies buildDependencies features;
|
||||||
|
};
|
||||||
|
libc_0_2_36_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
|
||||||
|
crateName = "libc";
|
||||||
|
version = "0.2.36";
|
||||||
|
authors = [ "The Rust Project Developers" ];
|
||||||
|
sha256 = "01633h4yfqm0s302fm0dlba469bx8y6cs4nqc8bqrmjqxfxn515l";
|
||||||
|
inherit dependencies buildDependencies features;
|
||||||
|
};
|
||||||
|
hello_0_1_0 = { features?(hello_0_1_0_features {}) }: hello_0_1_0_ {
|
||||||
|
dependencies = mapFeatures features ([ libc_0_2_36 ]);
|
||||||
|
};
|
||||||
|
hello_0_1_0_features = f: updateFeatures f (rec {
|
||||||
|
hello_0_1_0.default = (f.hello_0_1_0.default or true);
|
||||||
|
libc_0_2_36.default = true;
|
||||||
|
}) [ libc_0_2_36_features ];
|
||||||
|
libc_0_2_36 = { features?(libc_0_2_36_features {}) }: libc_0_2_36_ {
|
||||||
|
features = mkFeatures (features.libc_0_2_36 or {});
|
||||||
|
};
|
||||||
|
libc_0_2_36_features = f: updateFeatures f (rec {
|
||||||
|
libc_0_2_36.default = (f.libc_0_2_36.default or true);
|
||||||
|
libc_0_2_36.use_std =
|
||||||
|
(f.libc_0_2_36.use_std or false) ||
|
||||||
|
(f.libc_0_2_36.default or false) ||
|
||||||
|
(libc_0_2_36.default or false);
|
||||||
|
}) [];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, the `libc` crate has no `src` attribute, so `buildRustCrate`
|
||||||
|
will fetch it from [crates.io](https://crates.io). A `sha256`
|
||||||
|
attribute is still needed for Nix purity.
|
||||||
|
|
||||||
|
### Handling external dependencies
|
||||||
|
|
||||||
|
Some crates require external libraries. For crates from
|
||||||
|
[crates.io](https://crates.io), such libraries can be specified in
|
||||||
|
`defaultCrateOverrides` package in nixpkgs itself.
|
||||||
|
|
||||||
|
Starting from that file, one can add more overrides, to add features
|
||||||
|
or build inputs by overriding the hello crate in a seperate file.
|
||||||
|
|
||||||
|
```
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
((import ./hello.nix).hello {}).override {
|
||||||
|
crateOverrides = defaultCrateOverrides // {
|
||||||
|
hello = attrs: { buildInputs = [ openssl ]; };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, `crateOverrides` is expected to be a attribute set, where the
|
||||||
|
key is the crate name without version number and the value a function.
|
||||||
|
The function gets all attributes passed to `buildRustCrate` as first
|
||||||
|
argument and returns a set that contains all attribute that should be
|
||||||
|
overwritten.
|
||||||
|
|
||||||
|
For more complicated cases, such as when parts of the crate's
|
||||||
|
derivation depend on the the crate's version, the `attrs` argument of
|
||||||
|
the override above can be read, as in the following example, which
|
||||||
|
patches the derivation:
|
||||||
|
|
||||||
|
```
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
((import ./hello.nix).hello {}).override {
|
||||||
|
crateOverrides = defaultCrateOverrides // {
|
||||||
|
hello = attrs: lib.optionalAttrs (lib.versionAtLeast attrs.version "1.0") {
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace lib/zoneinfo.rs \
|
||||||
|
--replace "/usr/share/zoneinfo" "${tzdata}/share/zoneinfo"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Another situation is when we want to override a nested
|
||||||
|
dependency. This actually works in the exact same way, since the
|
||||||
|
`crateOverrides` parameter is forwarded to the crate's
|
||||||
|
dependencies. For instance, to override the build inputs for crate
|
||||||
|
`libc` in the example above, where `libc` is a dependency of the main
|
||||||
|
crate, we could do:
|
||||||
|
|
||||||
|
```
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
((import hello.nix).hello {}).override {
|
||||||
|
crateOverrides = defaultCrateOverrides // {
|
||||||
|
libc = attrs: { buildInputs = []; };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options and phases configuration
|
||||||
|
|
||||||
|
Actually, the overrides introduced in the previous section are more
|
||||||
|
general. A number of other parameters can be overridden:
|
||||||
|
|
||||||
|
- The version of rustc used to compile the crate:
|
||||||
|
|
||||||
|
```
|
||||||
|
(hello {}).override { rust = pkgs.rust; };
|
||||||
|
```
|
||||||
|
|
||||||
|
- Whether to build in release mode or debug mode (release mode by
|
||||||
|
default):
|
||||||
|
|
||||||
|
```
|
||||||
|
(hello {}).override { release = false; };
|
||||||
|
```
|
||||||
|
|
||||||
|
- Whether to print the commands sent to rustc when building
|
||||||
|
(equivalent to `--verbose` in cargo:
|
||||||
|
|
||||||
|
```
|
||||||
|
(hello {}).override { verbose = false; };
|
||||||
|
```
|
||||||
|
|
||||||
|
- Extra arguments to be passed to `rustc`:
|
||||||
|
|
||||||
|
```
|
||||||
|
(hello {}).override { extraRustcOpts = "-Z debuginfo=2"; };
|
||||||
|
```
|
||||||
|
|
||||||
|
- Phases, just like in any other derivation, can be specified using
|
||||||
|
the following attributes: `preUnpack`, `postUnpack`, `prePatch`,
|
||||||
|
`patches`, `postPatch`, `preConfigure` (in the case of a Rust crate,
|
||||||
|
this is run before calling the "build" script), `postConfigure`
|
||||||
|
(after the "build" script),`preBuild`, `postBuild`, `preInstall` and
|
||||||
|
`postInstall`. As an example, here is how to create a new module
|
||||||
|
before running the build script:
|
||||||
|
|
||||||
|
```
|
||||||
|
(hello {}).override {
|
||||||
|
preConfigure = ''
|
||||||
|
echo "pub const PATH=\"${hi.out}\";" >> src/path.rs"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
One can also supply features switches. For example, if we want to
|
||||||
|
compile `diesel_cli` only with the `postgres` feature, and no default
|
||||||
|
features, we would write:
|
||||||
|
|
||||||
|
```
|
||||||
|
(callPackage ./diesel.nix {}).diesel {
|
||||||
|
default = false;
|
||||||
|
postgres = true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `diesel.nix` is the file generated by Carnix, as explained above.
|
||||||
|
|
||||||
## Using the Rust nightlies overlay
|
## Using the Rust nightlies overlay
|
||||||
|
|
||||||
Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.
|
Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.
|
||||||
|
@ -39,6 +39,9 @@ nix-repl> :l <nixpkgs>
|
|||||||
nix-repl> texlive.collection-<TAB>
|
nix-repl> texlive.collection-<TAB>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
<listitem><para>
|
||||||
|
Note that the wrapper assumes that the result has a chance to be useful. For example, the core executables should be present, as well as some core data files. The supported way of ensuring this is by including some scheme, for example <varname>scheme-basic</varname>, into the combination.
|
||||||
|
</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ $ nix-env -qa hello --json
|
|||||||
"x86_64-linux",
|
"x86_64-linux",
|
||||||
"armv5tel-linux",
|
"armv5tel-linux",
|
||||||
"armv7l-linux",
|
"armv7l-linux",
|
||||||
"mips64el-linux",
|
"mips32-linux",
|
||||||
"x86_64-darwin",
|
"x86_64-darwin",
|
||||||
"i686-cygwin",
|
"i686-cygwin",
|
||||||
"i686-freebsd",
|
"i686-freebsd",
|
||||||
@ -174,7 +174,7 @@ meta-attributes</title>
|
|||||||
maintainers of this Nix expression. If
|
maintainers of this Nix expression. If
|
||||||
you would like to be a maintainer of a package, you may want to add
|
you would like to be a maintainer of a package, you may want to add
|
||||||
yourself to <link
|
yourself to <link
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/maintainers.nix"><filename>nixpkgs/lib/maintainers.nix</filename></link>
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/maintainers/maintainer-list.nix"><filename>nixpkgs/maintainers/maintainer-list.nix</filename></link>
|
||||||
and write something like <literal>[ stdenv.lib.maintainers.alice
|
and write something like <literal>[ stdenv.lib.maintainers.alice
|
||||||
stdenv.lib.maintainers.bob ]</literal>.</para></listitem>
|
stdenv.lib.maintainers.bob ]</literal>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
|
|
||||||
<varlistentry><term><varname>
|
<varlistentry><term><varname>
|
||||||
$outputDevdoc</varname></term><listitem><para>
|
$outputDevdoc</varname></term><listitem><para>
|
||||||
is for <emphasis>developer</emphasis> documentation. Currently we count gtk-doc in there. It goes to <varname>devdoc</varname> or is removed (!) by default. This is because e.g. gtk-doc tends to be rather large and completely unused by nixpkgs users.
|
is for <emphasis>developer</emphasis> documentation. Currently we count gtk-doc and devhelp books in there. It goes to <varname>devdoc</varname> or is removed (!) by default. This is because e.g. gtk-doc tends to be rather large and completely unused by nixpkgs users.
|
||||||
</para></listitem></varlistentry>
|
</para></listitem></varlistentry>
|
||||||
|
|
||||||
<varlistentry><term><varname>
|
<varlistentry><term><varname>
|
||||||
|
@ -660,6 +660,32 @@ cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
|
|||||||
passing <command>-q</command> to the Emacs command.
|
passing <command>-q</command> to the Emacs command.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Sometimes <varname>emacsWithPackages</varname> is not enough, as
|
||||||
|
this package set has some priorities imposed on packages (with
|
||||||
|
the lowest priority assigned to Melpa Unstable, and the highest for
|
||||||
|
packages manually defined in
|
||||||
|
<filename>pkgs/top-level/emacs-packages.nix</filename>). But you
|
||||||
|
can't control this priorities when some package is installed as a
|
||||||
|
dependency. You can override it on per-package-basis, providing all
|
||||||
|
the 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>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
overrides = super: self: rec {
|
||||||
|
haskell-mode = self.melpaPackages.haskell-mode;
|
||||||
|
...
|
||||||
|
};
|
||||||
|
((emacsPackagesNgGen emacs).overrideScope overrides).emacsWithPackages (p: with p; [
|
||||||
|
# here both these package will use haskell-mode of our own choice
|
||||||
|
ghc-mod
|
||||||
|
dante
|
||||||
|
])
|
||||||
|
</screen>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -667,11 +693,13 @@ cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
|
|||||||
<section xml:id="sec-weechat">
|
<section xml:id="sec-weechat">
|
||||||
<title>Weechat</title>
|
<title>Weechat</title>
|
||||||
<para>
|
<para>
|
||||||
Weechat can currently be configured to include your choice of plugins.
|
Weechat can be configured to include your choice of plugins, reducing its
|
||||||
To make use of this functionality, install an expression that overrides its configuration such as
|
closure size from the default configuration which includes all available
|
||||||
|
plugins. To make use of this functionality, install an expression that
|
||||||
|
overrides its configuration such as
|
||||||
<programlisting>weechat.override {configure = {availablePlugins, ...}: {
|
<programlisting>weechat.override {configure = {availablePlugins, ...}: {
|
||||||
plugins = with availablePlugins; [ python perl ];
|
plugins = with availablePlugins; [ python perl ];
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
|
@ -7,123 +7,123 @@
|
|||||||
<title>Reviewing contributions</title>
|
<title>Reviewing contributions</title>
|
||||||
|
|
||||||
<warning>
|
<warning>
|
||||||
<para>The following section is a draft and reviewing policy is still being
|
<para>The following section is a draft and reviewing policy is still being
|
||||||
discussed.</para>
|
discussed.</para>
|
||||||
</warning>
|
</warning>
|
||||||
|
|
||||||
<para>The nixpkgs projects receives a fairly high number of contributions via
|
<para>The nixpkgs projects receives a fairly high number of contributions via
|
||||||
GitHub pull-requests. Reviewing and approving these is an important task and a
|
GitHub pull-requests. Reviewing and approving these is an important task and a
|
||||||
way to contribute to the project.</para>
|
way to contribute to the project.</para>
|
||||||
|
|
||||||
<para>The high change rate of nixpkgs make any pull request that is open for
|
<para>The high change rate of nixpkgs make any pull request that is open for
|
||||||
long enough subject to conflicts that will require extra work from the
|
long enough subject to conflicts that will require extra work from the
|
||||||
submitter or the merger. Reviewing pull requests in a timely manner and being
|
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
|
responsive to the comments is the key to avoid these. GitHub provides sort
|
||||||
filters that can be used to see the <link
|
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
|
recently</link> and the <link
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc">least
|
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc">least
|
||||||
recently</link> updated pull-requests.</para>
|
recently</link> updated pull-requests.</para>
|
||||||
|
|
||||||
<para>When reviewing a pull request, please always be nice and polite.
|
<para>When reviewing a pull request, please always be nice and polite.
|
||||||
Controversial changes can lead to controversial opinions, but it is important
|
Controversial changes can lead to controversial opinions, but it is important
|
||||||
to respect every community members and their work.</para>
|
to respect every community members and their work.</para>
|
||||||
|
|
||||||
<para>GitHub provides reactions, they are a simple and quick way to provide
|
<para>GitHub provides reactions, they are a simple and quick way to provide
|
||||||
feedback to pull-requests or any comments. The thumb-down reaction should be
|
feedback to pull-requests or any comments. The thumb-down reaction should be
|
||||||
used with care and if possible accompanied with some explanations so the
|
used with care and if possible accompanied with some explanations so the
|
||||||
submitter has directions to improve his contribution.</para>
|
submitter has directions to improve his contribution.</para>
|
||||||
|
|
||||||
<para>Pull-requests reviews should include a list of what has been reviewed in a
|
<para>Pull-requests reviews should include a list of what has been reviewed in a
|
||||||
comment, so other reviewers and mergers can know the state of the
|
comment, so other reviewers and mergers can know the state of the
|
||||||
review.</para>
|
review.</para>
|
||||||
|
|
||||||
<para>All the review template samples provided in this section are generic and
|
<para>All the review template samples provided in this section are generic and
|
||||||
meant as examples. Their usage is optional and the reviewer is free to adapt
|
meant as examples. Their usage is optional and the reviewer is free to adapt
|
||||||
them to his liking.</para>
|
them to his liking.</para>
|
||||||
|
|
||||||
<section><title>Package updates</title>
|
<section><title>Package updates</title>
|
||||||
|
|
||||||
<para>A package update is the most trivial and common type of pull-request.
|
<para>A package update is the most trivial and common type of pull-request.
|
||||||
These pull-requests mainly consist in updating the version part of the package
|
These pull-requests mainly consist in updating the version part of the package
|
||||||
name and the source hash.</para>
|
name and the source hash.</para>
|
||||||
<para>It can happen that non trivial updates include patches or more complex
|
<para>It can happen that non trivial updates include patches or more complex
|
||||||
changes.</para>
|
changes.</para>
|
||||||
|
|
||||||
<para>Reviewing process:</para>
|
<para>Reviewing process:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||||
rights)</para>
|
rights)</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para><literal>8.has: package (update)</literal> and any topic
|
<listitem><para><literal>8.has: package (update)</literal> and any topic
|
||||||
label that fit the updated package.</para></listitem>
|
label that fit the updated package.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the package versioning is fitting the
|
<listitem><para>Ensure that the package versioning is fitting the
|
||||||
guidelines.</para></listitem>
|
guidelines.</para></listitem>
|
||||||
<listitem><para>Ensure that the commit text is fitting the
|
<listitem><para>Ensure that the commit text is fitting the
|
||||||
guidelines.</para></listitem>
|
guidelines.</para></listitem>
|
||||||
<listitem><para>Ensure that the package maintainers are notified.</para>
|
<listitem><para>Ensure that the package maintainers are notified.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>mention-bot usually notify GitHub users based on the
|
<listitem><para>mention-bot usually notify GitHub users based on the
|
||||||
submitted changes, but it can happen that it misses some of the
|
submitted changes, but it can happen that it misses some of the
|
||||||
package maintainers.</para></listitem>
|
package maintainers.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the meta field contains correct
|
<listitem><para>Ensure that the meta field contains correct
|
||||||
information.</para>
|
information.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>License can change with version updates, so it should be
|
<listitem><para>License can change with version updates, so it should be
|
||||||
checked to be fitting upstream license.</para></listitem>
|
checked to be fitting upstream license.</para></listitem>
|
||||||
<listitem><para>If the package has no maintainer, a maintainer must be
|
<listitem><para>If the package has no maintainer, a maintainer must be
|
||||||
set. This can be the update submitter or a community member that
|
set. This can be the update submitter or a community member that
|
||||||
accepts to take maintainership of the package.</para></listitem>
|
accepts to take maintainership of the package.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the code contains no typos.</para></listitem>
|
<listitem><para>Ensure that the code contains no typos.</para></listitem>
|
||||||
<listitem><para>Building the package locally.</para>
|
<listitem><para>Building the package locally.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Pull-requests are often targeted to the master or staging
|
<listitem><para>Pull-requests are often targeted to the master or staging
|
||||||
branch so building the pull-request locally as it is submitted can
|
branch so building the pull-request locally as it is submitted can
|
||||||
trigger a large amount of source builds.</para>
|
trigger a large amount of source builds.</para>
|
||||||
<para>It is possible to rebase the changes on nixos-unstable or
|
<para>It is possible to rebase the changes on nixos-unstable or
|
||||||
nixpkgs-unstable for easier review by running the following commands
|
nixpkgs-unstable for easier review by running the following commands
|
||||||
from a nixpkgs clone.
|
from a nixpkgs clone.
|
||||||
<screen>
|
<screen>
|
||||||
$ git remote add channels https://github.com/NixOS/nixpkgs-channels.git <co
|
$ git remote add channels https://github.com/NixOS/nixpkgs-channels.git <co
|
||||||
xml:id='reviewing-rebase-1' />
|
xml:id='reviewing-rebase-1' />
|
||||||
$ git fetch channels nixos-unstable <co xml:id='reviewing-rebase-2' />
|
$ git fetch channels nixos-unstable <co xml:id='reviewing-rebase-2' />
|
||||||
$ git fetch origin pull/PRNUMBER/head <co xml:id='reviewing-rebase-3' />
|
$ git fetch origin pull/PRNUMBER/head <co xml:id='reviewing-rebase-3' />
|
||||||
$ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD <co
|
$ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD <co
|
||||||
xml:id='reviewing-rebase-4' />
|
xml:id='reviewing-rebase-4' />
|
||||||
</screen>
|
</screen>
|
||||||
<calloutlist>
|
<calloutlist>
|
||||||
<callout arearefs='reviewing-rebase-1'>
|
<callout arearefs='reviewing-rebase-1'>
|
||||||
<para>This should be done only once to be able to fetch channel
|
<para>This should be done only once to be able to fetch channel
|
||||||
branches from the nixpkgs-channels repository.</para>
|
branches from the nixpkgs-channels repository.</para>
|
||||||
</callout>
|
</callout>
|
||||||
<callout arearefs='reviewing-rebase-2'>
|
<callout arearefs='reviewing-rebase-2'>
|
||||||
<para>Fetching the nixos-unstable branch.</para>
|
<para>Fetching the nixos-unstable branch.</para>
|
||||||
</callout>
|
</callout>
|
||||||
<callout arearefs='reviewing-rebase-3'>
|
<callout arearefs='reviewing-rebase-3'>
|
||||||
<para>Fetching the pull-request changes, <varname>PRNUMBER</varname>
|
<para>Fetching the pull-request changes, <varname>PRNUMBER</varname>
|
||||||
is the number at the end of the pull-request title and
|
is the number at the end of the pull-request title and
|
||||||
<varname>BASEBRANCH</varname> the base branch of the
|
<varname>BASEBRANCH</varname> the base branch of the
|
||||||
pull-request.</para>
|
pull-request.</para>
|
||||||
</callout>
|
</callout>
|
||||||
<callout arearefs='reviewing-rebase-3'>
|
<callout arearefs='reviewing-rebase-3'>
|
||||||
<para>Rebasing the pull-request changes to the nixos-unstable
|
<para>Rebasing the pull-request changes to the nixos-unstable
|
||||||
branch.</para>
|
branch.</para>
|
||||||
</callout>
|
</callout>
|
||||||
</calloutlist>
|
</calloutlist>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The <link xlink:href="https://github.com/madjar/nox">nox</link>
|
<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.
|
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
|
It doesn't rebase on a channel branch so it might trigger multiple
|
||||||
source builds. <varname>PRNUMBER</varname> should be replaced by the
|
source builds. <varname>PRNUMBER</varname> should be replaced by the
|
||||||
number at the end of the pull-request title.</para>
|
number at the end of the pull-request title.</para>
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
$ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||||
@ -153,42 +153,42 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
|||||||
|
|
||||||
<section><title>New packages</title>
|
<section><title>New packages</title>
|
||||||
|
|
||||||
<para>New packages are a common type of pull-requests. These pull requests
|
<para>New packages are a common type of pull-requests. These pull requests
|
||||||
consists in adding a new nix-expression for a package.</para>
|
consists in adding a new nix-expression for a package.</para>
|
||||||
|
|
||||||
<para>Reviewing process:</para>
|
<para>Reviewing process:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||||
rights)</para>
|
rights)</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para><literal>8.has: package (new)</literal> and any topic
|
<listitem><para><literal>8.has: package (new)</literal> and any topic
|
||||||
label that fit the new package.</para></listitem>
|
label that fit the new package.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the package versioning is fitting the
|
<listitem><para>Ensure that the package versioning is fitting the
|
||||||
guidelines.</para></listitem>
|
guidelines.</para></listitem>
|
||||||
<listitem><para>Ensure that the commit name is fitting the
|
<listitem><para>Ensure that the commit name is fitting the
|
||||||
guidelines.</para></listitem>
|
guidelines.</para></listitem>
|
||||||
<listitem><para>Ensure that the meta field contains correct
|
<listitem><para>Ensure that the meta field contains correct
|
||||||
information.</para>
|
information.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>License must be checked to be fitting upstream
|
<listitem><para>License must be checked to be fitting upstream
|
||||||
license.</para></listitem>
|
license.</para></listitem>
|
||||||
<listitem><para>Platforms should be set or the package will not get binary
|
<listitem><para>Platforms should be set or the package will not get binary
|
||||||
substitutes.</para></listitem>
|
substitutes.</para></listitem>
|
||||||
<listitem><para>A maintainer must be set, this can be the package
|
<listitem><para>A maintainer must be set, this can be the package
|
||||||
submitter or a community member that accepts to take maintainership of
|
submitter or a community member that accepts to take maintainership of
|
||||||
the package.</para></listitem>
|
the package.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the code contains no typos.</para></listitem>
|
<listitem><para>Ensure that the code contains no typos.</para></listitem>
|
||||||
<listitem><para>Ensure the package source.</para>
|
<listitem><para>Ensure the package source.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Mirrors urls should be used when
|
<listitem><para>Mirrors urls should be used when
|
||||||
available.</para></listitem>
|
available.</para></listitem>
|
||||||
<listitem><para>The most appropriate function should be used (e.g.
|
<listitem><para>The most appropriate function should be used (e.g.
|
||||||
packages from GitHub should use
|
packages from GitHub should use
|
||||||
<literal>fetchFromGitHub</literal>).</para></listitem>
|
<literal>fetchFromGitHub</literal>).</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -223,49 +223,49 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
|||||||
|
|
||||||
<section><title>Module updates</title>
|
<section><title>Module updates</title>
|
||||||
|
|
||||||
<para>Module updates are submissions changing modules in some ways. These often
|
<para>Module updates are submissions changing modules in some ways. These often
|
||||||
contains changes to the options or introduce new options.</para>
|
contains changes to the options or introduce new options.</para>
|
||||||
|
|
||||||
<para>Reviewing process</para>
|
<para>Reviewing process</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||||
rights)</para>
|
rights)</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para><literal>8.has: module (update)</literal> and any topic
|
<listitem><para><literal>8.has: module (update)</literal> and any topic
|
||||||
label that fit the module.</para></listitem>
|
label that fit the module.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the module maintainers are notified.</para>
|
<listitem><para>Ensure that the module maintainers are notified.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Mention-bot notify GitHub users based on the submitted
|
<listitem><para>Mention-bot notify GitHub users based on the submitted
|
||||||
changes, but it can happen that it miss some of the package
|
changes, but it can happen that it miss some of the package
|
||||||
maintainers.</para></listitem>
|
maintainers.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the module tests, if any, are
|
<listitem><para>Ensure that the module tests, if any, are
|
||||||
succeeding.</para></listitem>
|
succeeding.</para></listitem>
|
||||||
<listitem><para>Ensure that the introduced options are correct.</para>
|
<listitem><para>Ensure that the introduced options are correct.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Type should be appropriate (string related types differs
|
<listitem><para>Type should be appropriate (string related types differs
|
||||||
in their merging capabilities, <literal>optionSet</literal> and
|
in their merging capabilities, <literal>optionSet</literal> and
|
||||||
<literal>string</literal> types are deprecated).</para></listitem>
|
<literal>string</literal> types are deprecated).</para></listitem>
|
||||||
<listitem><para>Description, default and example should be
|
<listitem><para>Description, default and example should be
|
||||||
provided.</para></listitem>
|
provided.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that option changes are backward compatible.</para>
|
<listitem><para>Ensure that option changes are backward compatible.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para><literal>mkRenamedOptionModule</literal> and
|
<listitem><para><literal>mkRenamedOptionModule</literal> and
|
||||||
<literal>mkAliasOptionModule</literal> functions provide way to make
|
<literal>mkAliasOptionModule</literal> functions provide way to make
|
||||||
option changes backward compatible.</para></listitem>
|
option changes backward compatible.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that removed options are declared with
|
<listitem><para>Ensure that removed options are declared with
|
||||||
<literal>mkRemovedOptionModule</literal></para></listitem>
|
<literal>mkRemovedOptionModule</literal></para></listitem>
|
||||||
<listitem><para>Ensure that changes that are not backward compatible are
|
<listitem><para>Ensure that changes that are not backward compatible are
|
||||||
mentioned in release notes.</para></listitem>
|
mentioned in release notes.</para></listitem>
|
||||||
<listitem><para>Ensure that documentations affected by the change is
|
<listitem><para>Ensure that documentations affected by the change is
|
||||||
updated.</para></listitem>
|
updated.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
@ -294,37 +294,37 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
|||||||
<para>New modules submissions introduce a new module to NixOS.</para>
|
<para>New modules submissions introduce a new module to NixOS.</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Add labels to the pull-request. (Requires commit
|
<listitem><para>Add labels to the pull-request. (Requires commit
|
||||||
rights)</para>
|
rights)</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para><literal>8.has: module (new)</literal> and any topic label
|
<listitem><para><literal>8.has: module (new)</literal> and any topic label
|
||||||
that fit the module.</para></listitem>
|
that fit the module.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the module tests, if any, are
|
<listitem><para>Ensure that the module tests, if any, are
|
||||||
succeeding.</para></listitem>
|
succeeding.</para></listitem>
|
||||||
<listitem><para>Ensure that the introduced options are correct.</para>
|
<listitem><para>Ensure that the introduced options are correct.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Type should be appropriate (string related types differs
|
<listitem><para>Type should be appropriate (string related types differs
|
||||||
in their merging capabilities, <literal>optionSet</literal> and
|
in their merging capabilities, <literal>optionSet</literal> and
|
||||||
<literal>string</literal> types are deprecated).</para></listitem>
|
<literal>string</literal> types are deprecated).</para></listitem>
|
||||||
<listitem><para>Description, default and example should be
|
<listitem><para>Description, default and example should be
|
||||||
provided.</para></listitem>
|
provided.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that module <literal>meta</literal> field is
|
<listitem><para>Ensure that module <literal>meta</literal> field is
|
||||||
present</para>
|
present</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Maintainers should be declared in
|
<listitem><para>Maintainers should be declared in
|
||||||
<literal>meta.maintainers</literal>.</para></listitem>
|
<literal>meta.maintainers</literal>.</para></listitem>
|
||||||
<listitem><para>Module documentation should be declared with
|
<listitem><para>Module documentation should be declared with
|
||||||
<literal>meta.doc</literal>.</para></listitem>
|
<literal>meta.doc</literal>.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Ensure that the module respect other modules
|
<listitem><para>Ensure that the module respect other modules
|
||||||
functionality.</para>
|
functionality.</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>For example, enabling a module should not open firewall
|
<listitem><para>For example, enabling a module should not open firewall
|
||||||
ports by default.</para></listitem>
|
ports by default.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -340,7 +340,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
|||||||
- [ ] options have default
|
- [ ] options have default
|
||||||
- [ ] options have example
|
- [ ] options have example
|
||||||
- [ ] options have descriptions
|
- [ ] options have descriptions
|
||||||
- [ ] No unneeded package is added to system.environmentPackages
|
- [ ] No unneeded package is added to environment.systemPackages
|
||||||
- [ ] meta.maintainers is set
|
- [ ] meta.maintainers is set
|
||||||
- [ ] module documentation is declared in meta.doc
|
- [ ] module documentation is declared in meta.doc
|
||||||
|
|
||||||
@ -355,22 +355,22 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
|||||||
|
|
||||||
<para>Other type of submissions requires different reviewing steps.</para>
|
<para>Other type of submissions requires different reviewing steps.</para>
|
||||||
|
|
||||||
<para>If you consider having enough knowledge and experience in a topic and
|
<para>If you consider having enough knowledge and experience in a topic and
|
||||||
would like to be a long-term reviewer for related submissions, please contact
|
would 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
|
the current reviewers for that topic. They will give you information about the
|
||||||
reviewing process.
|
reviewing process.
|
||||||
The main reviewers for a topic can be hard to find as there is no list, but
|
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 git-blaming the code to see
|
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>
|
who committed to that topic can give some hints.</para>
|
||||||
|
|
||||||
<para>Container system, boot system and library changes are some examples of the
|
<para>Container system, boot system and library changes are some examples of the
|
||||||
pull requests fitting this category.</para>
|
pull requests fitting this category.</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section><title>Merging pull-requests</title>
|
<section><title>Merging pull-requests</title>
|
||||||
|
|
||||||
<para>It is possible for community members that have enough knowledge and
|
<para>It is possible for community members that have enough knowledge and
|
||||||
experience on a special topic to contribute by merging pull requests.</para>
|
experience on a special topic to contribute by merging pull requests.</para>
|
||||||
|
|
||||||
<para>TODO: add the procedure to request merging rights.</para>
|
<para>TODO: add the procedure to request merging rights.</para>
|
||||||
@ -380,13 +380,13 @@ The following paragraph about how to deal with unactive contributors is just a
|
|||||||
proposition and should be modified to what the community agrees to be the right
|
proposition and should be modified to what the community agrees to be the right
|
||||||
policy.
|
policy.
|
||||||
|
|
||||||
<para>Please note that contributors with commit rights unactive for more than
|
<para>Please note that contributors with commit rights unactive for more than
|
||||||
three months will have their commit rights revoked.</para>
|
three months will have their commit rights revoked.</para>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<para>In a case a contributor leaves definitively the Nix community, he should
|
<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
|
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
|
modules he maintains so the maintainership can be taken over by other
|
||||||
contributors.</para>
|
contributors.</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
20
doc/shell.md
Normal file
20
doc/shell.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
title: pkgs.mkShell
|
||||||
|
author: zimbatm
|
||||||
|
date: 2017-10-30
|
||||||
|
---
|
||||||
|
|
||||||
|
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 ];
|
||||||
|
}
|
||||||
|
```
|
500
doc/stdenv.xml
500
doc/stdenv.xml
@ -179,6 +179,269 @@ genericBuild
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section xml:id="ssec-stdenv-dependencies"><title>Specifying dependencies</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
As described in the Nix manual, almost any <filename>*.drv</filename> store path in a derivation's attribute set will induce a dependency on that derivation.
|
||||||
|
<varname>mkDerivation</varname>, however, takes a few attributes intended to, between them, include all the dependencies of a package.
|
||||||
|
This is done both for structure and consistency, but also so that certain other setup can take place.
|
||||||
|
For example, certain dependencies need their bin directories added to the <envar>PATH</envar>.
|
||||||
|
That is built-in, but other setup is done via a pluggable mechanism that works in conjunction with these dependency attributes.
|
||||||
|
See <xref linkend="ssec-setup-hooks"/> for details.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Dependencies can be broken down along three axes: their host and target platforms relative to the new derivation's, and whether they are propagated.
|
||||||
|
The platform distinctions are motivated by cross compilation; see <xref linkend="chap-cross"/> for exactly what each platform means.
|
||||||
|
<footnote><para>
|
||||||
|
The build platform is ignored because it is a mere implementation detail of the package satisfying the dependency:
|
||||||
|
As a general programming principle, dependencies are always <emphasis>specified</emphasis> as interfaces, not concrete implementation.
|
||||||
|
</para></footnote>
|
||||||
|
But even if one is not cross compiling, the platforms imply whether or not the dependency is needed at run-time or build-time, a concept that makes perfect sense outside of cross compilation.
|
||||||
|
For now, the run-time/build-time distinction is just a hint for mental clarity, but in the future it perhaps could be enforced.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The extension of <envar>PATH</envar> with dependencies, alluded to above, proceeds according to the relative platforms alone.
|
||||||
|
The process is carried out only for dependencies whose host platform matches the new derivation's build platform–i.e. which run on the platform where the new derivation will be built.
|
||||||
|
<footnote><para>
|
||||||
|
Currently, that means for native builds all dependencies are put on the <envar>PATH</envar>.
|
||||||
|
But in the future that may not be the case for sake of matching cross:
|
||||||
|
the platforms would be assumed to be unique for native and cross builds alike, so only the <varname>depsBuild*</varname> and <varname>nativeBuildDependencies</varname> dependencies would affect the <envar>PATH</envar>.
|
||||||
|
</para></footnote>
|
||||||
|
For each dependency <replaceable>dep</replaceable> of those dependencies, <filename><replaceable>dep</replaceable>/bin</filename>, if present, is added to the <envar>PATH</envar> environment variable.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The dependency is propagated when it forces some of its other-transitive (non-immediate) downstream dependencies to also take it on as an immediate dependency.
|
||||||
|
Nix itself already takes a package's transitive dependencies into account, but this propagation ensures nixpkgs-specific infrastructure like setup hooks (mentioned above) also are run as if the propagated dependency.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
It is important to note dependencies are not necessary propagated as the same sort of dependency that they were before, but rather as the corresponding sort so that the platform rules still line up.
|
||||||
|
The exact rules for dependency propagation can be given by assigning each sort of dependency two integers based one how it's host and target platforms are offset from the depending derivation's platforms.
|
||||||
|
Those offsets are given are given below in the descriptions of each dependency list attribute.
|
||||||
|
Algorithmically, we traverse propagated inputs, accumulating every propagated dep's propagated deps and adjusting them to account for the "shift in perspective" described by the current dep's platform offsets.
|
||||||
|
This results in sort a transitive closure of the dependency relation, with the offsets being approximately summed when two dependency links are combined.
|
||||||
|
We also prune transitive deps whose combined offsets go out-of-bounds, which can be viewed as a filter over that transitive closure removing dependencies that are blatantly absurd.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
We can define the process precisely with <link xlink:href="https://en.wikipedia.org/wiki/Natural_deduction">Natural Deduction</link> using the inference rules.
|
||||||
|
This probably seems a bit obtuse, but so is the bash code that actually implements it!
|
||||||
|
<footnote><para>
|
||||||
|
The <function>findInputs</function> function, currently residing in <filename>pkgs/stdenv/generic/setup.sh</filename>, implements the propagation logic.
|
||||||
|
</para></footnote>
|
||||||
|
They're confusing in very different ways so...hopefully if something doesn't make sense in one presentation, it does in the other!
|
||||||
|
<programlisting>
|
||||||
|
let mapOffset(h, t, i) = i + (if i <= 0 then h else t - 1)
|
||||||
|
|
||||||
|
propagated-dep(h0, t0, A, B)
|
||||||
|
propagated-dep(h1, t1, B, C)
|
||||||
|
h0 + h1 in {-1, 0, 1}
|
||||||
|
h0 + t1 in {-1, 0, 1}
|
||||||
|
-------------------------------------- Transitive property
|
||||||
|
propagated-dep(mapOffset(h0, t0, h1),
|
||||||
|
mapOffset(h0, t0, t1),
|
||||||
|
A, C)</programlisting>
|
||||||
|
<programlisting>
|
||||||
|
let mapOffset(h, t, i) = i + (if i <= 0 then h else t - 1)
|
||||||
|
|
||||||
|
dep(h0, _, A, B)
|
||||||
|
propagated-dep(h1, t1, B, C)
|
||||||
|
h0 + h1 in {-1, 0, 1}
|
||||||
|
h0 + t1 in {-1, 0, -1}
|
||||||
|
-------------------------------------- Take immediate deps' propagated deps
|
||||||
|
propagated-dep(mapOffset(h0, t0, h1),
|
||||||
|
mapOffset(h0, t0, t1),
|
||||||
|
A, C)</programlisting>
|
||||||
|
<programlisting>
|
||||||
|
propagated-dep(h, t, A, B)
|
||||||
|
-------------------------------------- Propagated deps count as deps
|
||||||
|
dep(h, t, A, B)</programlisting>
|
||||||
|
Some explanation of this monstrosity is in order.
|
||||||
|
In the common case, the target offset of a dependency is the successor to the target offset: <literal>t = h + 1</literal>.
|
||||||
|
That means that:
|
||||||
|
<programlisting>
|
||||||
|
let f(h, t, i) = i + (if i <= 0 then h else t - 1)
|
||||||
|
let f(h, h + 1, i) = i + (if i <= 0 then h else (h + 1) - 1)
|
||||||
|
let f(h, h + 1, i) = i + (if i <= 0 then h else h)
|
||||||
|
let f(h, h + 1, i) = i + h
|
||||||
|
</programlisting>
|
||||||
|
This is where the "sum-like" comes from above:
|
||||||
|
We can just sum all the host offset to get the host offset of the transitive dependency.
|
||||||
|
The target offset is the transitive dep is simply the host offset + 1, just as it was with the dependencies composed to make this transitive one;
|
||||||
|
it can be ignored as it doesn't add any new information.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Because of the bounds checks, the uncommon cases are <literal>h = t</literal> and <literal>h + 2 = t</literal>.
|
||||||
|
In the former case, the motivation for <function>mapOffset</function> is that since its host and target platforms are the same, no transitive dep of it should be able to "discover" an offset greater than its reduced target offsets.
|
||||||
|
<function>mapOffset</function> effectively "squashes" all its transitive dependencies' offsets so that none will ever be greater than the target offset of the original <literal>h = t</literal> package.
|
||||||
|
In the other case, <literal>h + 1</literal> is skipped over between the host and target offsets.
|
||||||
|
Instead of squashing the offsets, we need to "rip" them apart so no transitive dependencies' offset is that one.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Overall, the unifying theme here is that propagation shouldn't be introducing transitive dependencies involving platforms the needing package is unaware of.
|
||||||
|
The offset bounds checking and definition of <function>mapOffset</function> together ensure that this is the case.
|
||||||
|
Discovering a new offset is discovering a new platform, and since those platforms weren't in the derivation "spec" of the needing package, they cannot be relevant.
|
||||||
|
From a capability perspective, we can imagine that the host and target platforms of a package are the capabilities a package requires, and the depending package must provide the capability to the dependency.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<title>Variables specifying dependencies</title>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>depsBuildBuild</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A list of dependencies whose host and target platforms are the new derivation's build platform.
|
||||||
|
This means a <literal>-1</literal> host and <literal>-1</literal> target offset from the new derivation's platforms.
|
||||||
|
They are programs/libraries used at build time that furthermore produce programs/libraries also used at build time.
|
||||||
|
If the dependency doesn't care about the target platform (i.e. isn't a compiler or similar tool), put it in <varname>nativeBuildInputs</varname>instead.
|
||||||
|
The most common use for this <literal>buildPackages.stdenv.cc</literal>, the default C compiler for this role.
|
||||||
|
That example crops up more than one might think in old commonly used C libraries.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Since these packages are able to be run at build time, that are always added to the <envar>PATH</envar>, as described above.
|
||||||
|
But since these packages are only guaranteed to be able to run then, they shouldn't persist as run-time dependencies.
|
||||||
|
This isn't currently enforced, but could be in the future.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>nativeBuildInputs</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A list of dependencies whose host platform is the new derivation's build platform, and target platform is the new derivation's host platform.
|
||||||
|
This means a <literal>-1</literal> host offset and <literal>0</literal> target offset from the new derivation's platforms.
|
||||||
|
They are programs/libraries used at build time that, if they are a compiler or similar tool, produce code to run at run time—i.e. tools used to build the new derivation.
|
||||||
|
If the dependency doesn't care about the target platform (i.e. isn't a compiler or similar tool), put it here, rather than in <varname>depsBuildBuild</varname> or <varname>depsBuildTarget</varname>.
|
||||||
|
This would be called <varname>depsBuildHost</varname> but for historical continuity.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Since these packages are able to be run at build time, that are added to the <envar>PATH</envar>, as described above.
|
||||||
|
But since these packages only are guaranteed to be able to run then, they shouldn't persist as run-time dependencies.
|
||||||
|
This isn't currently enforced, but could be in the future.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>depsBuildTarget</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A list of dependencies whose host platform is the new derivation's build platform, and target platform is the new derivation's target platform.
|
||||||
|
This means a <literal>-1</literal> host offset and <literal>1</literal> target offset from the new derivation's platforms.
|
||||||
|
They are programs used at build time that produce code to run at run with code produced by the depending package.
|
||||||
|
Most commonly, these would tools used to build the runtime or standard library the currently-being-built compiler will inject into any code it compiles.
|
||||||
|
In many cases, the currently-being built compiler is itself employed for that task, but when that compiler won't run (i.e. its build and host platform differ) this is not possible.
|
||||||
|
Other times, the compiler relies on some other tool, like binutils, that is always built separately so the dependency is unconditional.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This is a somewhat confusing dependency to wrap ones head around, and for good reason.
|
||||||
|
As the only one where the platform offsets are not adjacent integers, it requires thinking of a bootstrapping stage <emphasis>two</emphasis> away from the current one.
|
||||||
|
It and it's use-case go hand in hand and are both considered poor form:
|
||||||
|
try not to need this sort dependency, and try not avoid building standard libraries / runtimes in the same derivation as the compiler produces code using them.
|
||||||
|
Instead strive to build those like a normal library, using the newly-built compiler just as a normal library would.
|
||||||
|
In short, do not use this attribute unless you are packaging a compiler and are sure it is needed.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Since these packages are able to be run at build time, that are added to the <envar>PATH</envar>, as described above.
|
||||||
|
But since these packages only are guaranteed to be able to run then, they shouldn't persist as run-time dependencies.
|
||||||
|
This isn't currently enforced, but could be in the future.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>depsHostHost</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
A list of dependencies whose host and target platforms match the new derivation's host platform.
|
||||||
|
This means a both <literal>0</literal> host offset and <literal>0</literal> target offset from the new derivation's host platform.
|
||||||
|
These are packages used at run-time to generate code also used at run-time.
|
||||||
|
In practice, that would usually be tools used by compilers for metaprogramming/macro systems, or libraries used by the macros/metaprogramming code itself.
|
||||||
|
It's always preferable to use a <varname>depsBuildBuild</varname> dependency in the derivation being built than a <varname>depsHostHost</varname> on the tool doing the building for this purpose.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>buildInputs</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A list of dependencies whose host platform and target platform match the new derivation's.
|
||||||
|
This means a <literal>0</literal> host offset and <literal>1</literal> target offset from the new derivation's host platform.
|
||||||
|
This would be called <varname>depsHostTarget</varname> but for historical continuity.
|
||||||
|
If the dependency doesn't care about the target platform (i.e. isn't a compiler or similar tool), put it here, rather than in <varname>depsBuildBuild</varname>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
These often are programs/libraries used by the new derivation at <emphasis>run</emphasis>-time, but that isn't always the case.
|
||||||
|
For example, the machine code in a statically linked library is only used at run time, but the derivation containing the library is only needed at build time.
|
||||||
|
Even in the dynamic case, the library may also be needed at build time to appease the linker.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>depsTargetTarget</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
A list of dependencies whose host platform matches the new derivation's target platform.
|
||||||
|
This means a <literal>1</literal> offset from the new derivation's platforms.
|
||||||
|
These are packages that run on the target platform, e.g. the standard library or run-time deps of standard library that a compiler insists on knowing about.
|
||||||
|
It's poor form in almost all cases for a package to depend on another from a future stage [future stage corresponding to positive offset].
|
||||||
|
Do not use this attribute unless you are packaging a compiler and are sure it is needed.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>depsBuildBuildPropagated</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
The propagated equivalent of <varname>depsBuildBuild</varname>.
|
||||||
|
This perhaps never ought to be used, but it is included for consistency [see below for the others].
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>propagatedNativeBuildInputs</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
The propagated equivalent of <varname>nativeBuildInputs</varname>.
|
||||||
|
This would be called <varname>depsBuildHostPropagated</varname> but for historical continuity.
|
||||||
|
For example, if package <varname>Y</varname> has <literal>propagatedNativeBuildInputs = [X]</literal>, and package <varname>Z</varname> has <literal>buildInputs = [Y]</literal>, then package <varname>Z</varname> will be built as if it included package <varname>X</varname> in its <varname>nativeBuildInputs</varname>.
|
||||||
|
If instead, package <varname>Z</varname> has <literal>nativeBuildInputs = [Y]</literal>, then <varname>Z</varname> will be built as if it included <varname>X</varname> in the <varname>depsBuildBuild</varname> of package <varname>Z</varname>, because of the sum of the two <literal>-1</literal> host offsets.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>depsBuildTargetPropagated</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
The propagated equivalent of <varname>depsBuildTarget</varname>.
|
||||||
|
This is prefixed for the same reason of alerting potential users.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>depsHostHostPropagated</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
The propagated equivalent of <varname>depsHostHost</varname>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>propagatedBuildInputs</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
The propagated equivalent of <varname>buildInputs</varname>.
|
||||||
|
This would be called <varname>depsHostTargetPropagated</varname> but for historical continuity.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>depsTargetTarget</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
The propagated equivalent of <varname>depsTargetTarget</varname>.
|
||||||
|
This is prefixed for the same reason of alerting potential users.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section xml:id="ssec-stdenv-attributes"><title>Attributes</title>
|
<section xml:id="ssec-stdenv-attributes"><title>Attributes</title>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
@ -198,63 +461,22 @@ genericBuild
|
|||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<title>Variables specifying dependencies</title>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>nativeBuildInputs</varname></term>
|
|
||||||
<listitem><para>
|
|
||||||
A list of dependencies used by the new derivation at <emphasis>build</emphasis>-time.
|
|
||||||
I.e. these dependencies should not make it into the package's runtime-closure, though this is currently not checked.
|
|
||||||
For each dependency <replaceable>dir</replaceable>, the directory <filename><replaceable>dir</replaceable>/bin</filename>, if it exists, is added to the <envar>PATH</envar> environment variable.
|
|
||||||
Other environment variables are also set up via a pluggable mechanism.
|
|
||||||
For instance, if <varname>buildInputs</varname> contains Perl, then the <filename>lib/site_perl</filename> subdirectory of each input is added to the <envar>PERL5LIB</envar> environment variable.
|
|
||||||
See <xref linkend="ssec-setup-hooks"/> for details.
|
|
||||||
</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>buildInputs</varname></term>
|
|
||||||
<listitem><para>
|
|
||||||
A list of dependencies used by the new derivation at <emphasis>run</emphasis>-time.
|
|
||||||
Currently, the build-time environment is modified in the exact same way as with <varname>nativeBuildInputs</varname>.
|
|
||||||
This is problematic in that when cross-compiling, foreign executables can clobber native ones on the <envar>PATH</envar>.
|
|
||||||
Even more confusing is static-linking.
|
|
||||||
A statically-linked library should be listed here because ultimately that generated machine code will be used at run-time, even though a derivation containing the object files or static archives will only be used at build-time.
|
|
||||||
A less confusing solution to this would be nice.
|
|
||||||
</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>propagatedNativeBuildInputs</varname></term>
|
|
||||||
<listitem><para>
|
|
||||||
Like <varname>nativeBuildInputs</varname>, but these dependencies are <emphasis>propagated</emphasis>:
|
|
||||||
that is, the dependencies listed here are added to the <varname>nativeBuildInputs</varname> of any package that uses <emphasis>this</emphasis> package as a dependency.
|
|
||||||
So if package Y has <literal>propagatedNativeBuildInputs = [X]</literal>, and package Z has <literal>nativeBuildInputs = [Y]</literal>,
|
|
||||||
then package X will appear in Z’s build environment automatically.
|
|
||||||
</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>propagatedBuildInputs</varname></term>
|
|
||||||
<listitem><para>
|
|
||||||
Like <varname>buildInputs</varname>, but propagated just like <varname>propagatedNativeBuildInputs</varname>.
|
|
||||||
This inherits <varname>buildInputs</varname>'s flaws of clobbering native executables when cross-compiling and being confusing for static linking.
|
|
||||||
</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables affecting build properties</title>
|
<title>Variables affecting build properties</title>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>enableParallelBuilding</varname></term>
|
<term><varname>enableParallelBuilding</varname></term>
|
||||||
<listitem><para>If set, <literal>stdenv</literal> will pass specific
|
<listitem>
|
||||||
flags to <literal>make</literal> and other build tools to enable
|
<para>If set to <literal>true</literal>, <literal>stdenv</literal> will
|
||||||
parallel building with up to <literal>build-cores</literal>
|
pass specific flags to <literal>make</literal> and other build tools to
|
||||||
workers.</para></listitem>
|
enable parallel building with up to <literal>build-cores</literal>
|
||||||
|
workers.</para>
|
||||||
|
|
||||||
|
<para>Unless set to <literal>false</literal>, some build systems with good
|
||||||
|
support for parallel building including <literal>cmake</literal>,
|
||||||
|
<literal>meson</literal>, and <literal>qmake</literal> will set it to
|
||||||
|
<literal>true</literal>.</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -649,7 +871,7 @@ script) if it exists.</para>
|
|||||||
By default, when cross compiling, the configure script has <option>--build=...</option> and <option>--host=...</option> passed.
|
By default, when cross compiling, the configure script has <option>--build=...</option> and <option>--host=...</option> passed.
|
||||||
Packages can instead pass <literal>[ "build" "host" "target" ]</literal> or a subset to control exactly which platform flags are passed.
|
Packages can instead pass <literal>[ "build" "host" "target" ]</literal> or a subset to control exactly which platform flags are passed.
|
||||||
Compilers and other tools should use this to also pass the target platform, for example.
|
Compilers and other tools should use this to also pass the target platform, for example.
|
||||||
Note eventually these will be passed when in native builds too, to improve determinism: build-time guessing, as is done today, is a risk of impurity.
|
<footnote><para>Eventually these will be passed when in native builds too, to improve determinism: build-time guessing, as is done today, is a risk of impurity.</para></footnote>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@ -773,13 +995,14 @@ but only if the <varname>doCheck</varname> variable is enabled.</para>
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>doCheck</varname></term>
|
<term><varname>doCheck</varname></term>
|
||||||
<listitem><para>If set to a non-empty string, the check phase is
|
<listitem><para>
|
||||||
executed, otherwise it is skipped (default). Thus you should set
|
Controls whether the check phase is executed.
|
||||||
|
By default it is skipped, but if <varname>doCheck</varname> is set to true, the check phase is usually executed.
|
||||||
<programlisting>
|
Thus you should set <programlisting>doCheck = true;</programlisting> in the derivation to enable checks.
|
||||||
doCheck = true;</programlisting>
|
The exception is cross compilation.
|
||||||
|
Cross compiled builds never run tests, no matter how <varname>doCheck</varname> is set,
|
||||||
in the derivation to enable checks.</para></listitem>
|
as the newly-built program won't run on the platform used to build it.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -916,6 +1139,20 @@ following:
|
|||||||
<listitem><para>If set, libraries and executables are not
|
<listitem><para>If set, libraries and executables are not
|
||||||
stripped. By default, they are.</para></listitem>
|
stripped. By default, they are.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>dontStripHost</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
Like <varname>dontStripHost</varname>, but only affects the <command>strip</command> command targetting the package's host platform.
|
||||||
|
Useful when supporting cross compilation, but otherwise feel free to ignore.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>dontStripTarget</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
Like <varname>dontStripHost</varname>, but only affects the <command>strip</command> command targetting the packages' target platform.
|
||||||
|
Useful when supporting cross compilation, but otherwise feel free to ignore.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>dontMoveSbin</varname></term>
|
<term><varname>dontMoveSbin</varname></term>
|
||||||
@ -1044,12 +1281,14 @@ installcheck</command>.</para>
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>doInstallCheck</varname></term>
|
<term><varname>doInstallCheck</varname></term>
|
||||||
<listitem><para>If set to a non-empty string, the installCheck phase is
|
<listitem><para>
|
||||||
executed, otherwise it is skipped (default). Thus you should set
|
Controls whether the installCheck phase is executed.
|
||||||
|
By default it is skipped, but if <varname>doInstallCheck</varname> is set to true, the installCheck phase is usually executed.
|
||||||
<programlisting>doInstallCheck = true;</programlisting>
|
Thus you should set <programlisting>doInstallCheck = true;</programlisting> in the derivation to enable install checks.
|
||||||
|
The exception is cross compilation.
|
||||||
in the derivation to enable install checks.</para></listitem>
|
Cross compiled builds never run tests, no matter how <varname>doInstallCheck</varname> is set,
|
||||||
|
as the newly-built program won't run on the platform used to build it.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1346,46 +1585,127 @@ someVar=$(stripHash $name)
|
|||||||
|
|
||||||
<section xml:id="ssec-setup-hooks"><title>Package setup hooks</title>
|
<section xml:id="ssec-setup-hooks"><title>Package setup hooks</title>
|
||||||
|
|
||||||
<para>The following packages provide a setup hook:
|
<para>
|
||||||
|
Nix itself considers a build-time dependency merely something that should previously be built and accessible at build time—packages themselves are on their own to perform any additional setup.
|
||||||
|
In most cases, that is fine, and the downstream derivation can deal with it's own dependencies.
|
||||||
|
But for a few common tasks, that would result in almost every package doing the same sort of setup work---depending not on the package itself, but entirely on which dependencies were used.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
In order to alleviate this burden, the <firstterm>setup hook></firstterm>mechanism was written, where any package can include a shell script that [by convention rather than enforcement by Nix], any downstream reverse-dependency will source as part of its build process.
|
||||||
|
That allows the downstream dependency to merely specify its dependencies, and lets those dependencies effectively initialize themselves.
|
||||||
|
No boilerplate mirroring the list of dependencies is needed.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The Setup hook mechanism is a bit of a sledgehammer though: a powerful feature with a broad and indiscriminate area of effect.
|
||||||
|
The combination of its power and implicit use may be expedient, but isn't without costs.
|
||||||
|
Nix itself is unchanged, but the spirit of adding dependencies being effect-free is violated even if the letter isn't.
|
||||||
|
For example, if a derivation path is mentioned more than once, Nix itself doesn't care and simply makes sure the dependency derivation is already built just the same—depending is just needing something to exist, and needing is idempotent.
|
||||||
|
However, a dependency specified twice will have its setup hook run twice, and that could easily change the build environment (though a well-written setup hook will therefore strive to be idempotent so this is in fact not observable).
|
||||||
|
More broadly, setup hooks are anti-modular in that multiple dependencies, whether the same or different, should not interfere and yet their setup hooks may well do so.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The most typical use of the setup hook is actually to add other hooks which are then run (i.e. after all the setup hooks) on each dependency.
|
||||||
|
For example, the C compiler wrapper's setup hook feeds itself flags for each dependency that contains relevant libaries and headers.
|
||||||
|
This is done by defining a bash function, and appending its name to one of
|
||||||
|
<envar>envBuildBuildHooks</envar>`,
|
||||||
|
<envar>envBuildHostHooks</envar>`,
|
||||||
|
<envar>envBuildTargetHooks</envar>`,
|
||||||
|
<envar>envHostHostHooks</envar>`,
|
||||||
|
<envar>envHostTargetHooks</envar>`, or
|
||||||
|
<envar>envTargetTargetHooks</envar>`.
|
||||||
|
These 6 bash variables correspond to the 6 sorts of dependencies by platform (there's 12 total but we ignore the propagated/non-propagated axis).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Packages adding a hook should not hard code a specific hook, but rather choose a variable <emphasis>relative</emphasis> to how they are included.
|
||||||
|
Returning to the C compiler wrapper example, if it itself is an <literal>n</literal> dependency, then it only wants to accumulate flags from <literal>n + 1</literal> dependencies, as only those ones match the compiler's target platform.
|
||||||
|
The <envar>hostOffset</envar> variable is defined with the current dependency's host offset <envar>targetOffset</envar> with its target offset, before it's setup hook is sourced.
|
||||||
|
Additionally, since most environment hooks don't care about the target platform,
|
||||||
|
That means the setup hook can append to the right bash array by doing something like
|
||||||
|
<programlisting language="bash">
|
||||||
|
addEnvHooks "$hostOffset" myBashFunction
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The <emphasis>existence</emphasis> of setups hooks has long been documented and packages inside Nixpkgs are free to use these mechanism.
|
||||||
|
Other packages, however, should not rely on these mechanisms not changing between Nixpkgs versions.
|
||||||
|
Because of the existing issues with this system, there's little benefit from mandating it be stable for any period of time.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Here are some packages that provide a setup hook.
|
||||||
|
Since the mechanism is modular, this probably isn't an exhaustive list.
|
||||||
|
Then again, since the mechanism is only to be used as a last resort, it might be.
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>CC Wrapper</term>
|
<term>Bintools Wrapper</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
CC Wrapper wraps a C toolchain for a bunch of miscellaneous purposes.
|
Bintools Wrapper wraps the binary utilities for a bunch of miscellaneous purposes.
|
||||||
Specifically, a C compiler (GCC or Clang), Binutils (or the CCTools + binutils mashup when targetting Darwin), and a C standard library (glibc or Darwin's libSystem) are all fed in, and dependency finding, hardening (see below), and purity checks for each are handled by CC Wrapper.
|
These are GNU Binutils when targetting Linux, and a mix of cctools and GNU binutils for Darwin.
|
||||||
Packages typically depend on only CC Wrapper, instead of those 3 inputs directly.
|
[The "Bintools" name is supposed to be a compromise between "Binutils" and "cctools" not denoting any specific implementation.]
|
||||||
|
Specifically, the underlying bintools package, and a C standard library (glibc or Darwin's libSystem, just for the dynamic loader) are all fed in, and dependency finding, hardening (see below), and purity checks for each are handled by Bintools Wrapper.
|
||||||
|
Packages typically depend on CC Wrapper, which in turn (at run time) depends on Bintools Wrapper.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Dependency finding is undoubtedly the main task of CC wrapper.
|
Bintools Wrapper was only just recently split off from CC Wrapper, so the division of labor is still being worked out.
|
||||||
|
For example, it shouldn't care about about the C standard library, but just take a derivation with the dynamic loader (which happens to be the glibc on linux).
|
||||||
|
Dependency finding however is a task both wrappers will continue to need to share, and probably the most important to understand.
|
||||||
It is currently accomplished by collecting directories of host-platform dependencies (i.e. <varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>) in environment variables.
|
It is currently accomplished by collecting directories of host-platform dependencies (i.e. <varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>) in environment variables.
|
||||||
CC wrapper's setup hook causes any <filename>include</filename> subdirectory of such a dependency to be added to <envar>NIX_CFLAGS_COMPILE</envar>, and any <filename>lib</filename> and <filename>lib64</filename> subdirectories to <envar>NIX_LDFLAGS</envar>.
|
Bintools Wrapper's setup hook causes any <filename>lib</filename> and <filename>lib64</filename> subdirectories to be added to <envar>NIX_LDFLAGS</envar>.
|
||||||
The setup hook itself contains some lengthy comments describing the exact convoluted mechanism by which this is accomplished.
|
Since CC Wrapper and Bintools Wrapper use the same strategy, most of the Bintools Wrapper code is sparsely commented and refers to CC Wrapper.
|
||||||
|
But CC Wrapper's code, by contrast, has quite lengthy comments.
|
||||||
|
Bintools Wrapper merely cites those, rather than repeating them, to avoid falling out of sync.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
A final task of the setup hook is defining a number of standard environment variables to tell build systems which executables full-fill which purpose.
|
A final task of the setup hook is defining a number of standard environment variables to tell build systems which executables full-fill which purpose.
|
||||||
They are defined to just be the base name of the tools, under the assumption that CC Wrapper's binaries will be on the path.
|
They are defined to just be the base name of the tools, under the assumption that Bintools Wrapper's binaries will be on the path.
|
||||||
Firstly, this helps poorly-written packages, e.g. ones that look for just <command>gcc</command> when <envar>CC</envar> isn't defined yet <command>clang</command> is to be used.
|
Firstly, this helps poorly-written packages, e.g. ones that look for just <command>gcc</command> when <envar>CC</envar> isn't defined yet <command>clang</command> is to be used.
|
||||||
Secondly, this helps packages not get confused when cross-compiling, in which case multiple CC wrappers may be simultaneous in use (targeting different platforms).
|
Secondly, this helps packages not get confused when cross-compiling, in which case multiple Bintools Wrappers may simultaneously be in use.
|
||||||
<envar>BUILD_</envar>- and <envar>TARGET_</envar>-prefixed versions of the normal environment variable are defined for the additional CC Wrappers, properly disambiguating them.
|
<footnote><para>
|
||||||
|
Each wrapper targets a single platform, so if binaries for multiple platforms are needed, the underlying binaries must be wrapped multiple times.
|
||||||
|
As this is a property of the wrapper itself, the multiple wrappings are needed whether or not the same underlying binaries can target multiple platforms.
|
||||||
|
</para></footnote>
|
||||||
|
<envar>BUILD_</envar>- and <envar>TARGET_</envar>-prefixed versions of the normal environment variable are defined for the additional Bintools Wrappers, properly disambiguating them.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
A problem with this final task is that CC Wrapper is honest and defines <envar>LD</envar> as <command>ld</command>.
|
A problem with this final task is that Bintools Wrapper is honest and defines <envar>LD</envar> as <command>ld</command>.
|
||||||
Most packages, however, firstly use the C compiler for linking, secondly use <envar>LD</envar> anyways, defining it as the C compiler, and thirdly, only so define <envar>LD</envar> when it is undefined as a fallback.
|
Most packages, however, firstly use the C compiler for linking, secondly use <envar>LD</envar> anyways, defining it as the C compiler, and thirdly, only so define <envar>LD</envar> when it is undefined as a fallback.
|
||||||
This triple-threat means CC Wrapper will break those packages, as LD is already defined as the actually linker which the package won't override yet doesn't want to use.
|
This triple-threat means Bintools Wrapper will break those packages, as LD is already defined as the actual linker which the package won't override yet doesn't want to use.
|
||||||
The workaround is to define, just for the problematic package, <envar>LD</envar> as the C compiler.
|
The workaround is to define, just for the problematic package, <envar>LD</envar> as the C compiler.
|
||||||
A good way to do this would be <command>preConfigure = "LD=$CC"</command>.
|
A good way to do this would be <command>preConfigure = "LD=$CC"</command>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>CC Wrapper</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
CC Wrapper wraps a C toolchain for a bunch of miscellaneous purposes.
|
||||||
|
Specifically, a C compiler (GCC or Clang), wrapped binary tools, and a C standard library (glibc or Darwin's libSystem, just for the dynamic loader) are all fed in, and dependency finding, hardening (see below), and purity checks for each are handled by CC Wrapper.
|
||||||
|
Packages typically depend on CC Wrapper, which in turn (at run time) depends on Bintools Wrapper.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Dependency finding is undoubtedly the main task of CC Wrapper.
|
||||||
|
This works just like Bintools Wrapper, except that any <filename>include</filename> subdirectory of any relevant dependency is added to <envar>NIX_CFLAGS_COMPILE</envar>.
|
||||||
|
The setup hook itself contains some lengthy comments describing the exact convoluted mechanism by which this is accomplished.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
CC Wrapper also like Bintools Wrapper defines standard environment variables with the names of the tools it wraps, for the same reasons described above.
|
||||||
|
Importantly, while it includes a <command>cc</command> symlink to the c compiler for portability, the <envar>CC</envar> will be defined using the compiler's "real name" (i.e. <command>gcc</command> or <command>clang</command>).
|
||||||
|
This helps lousy build systems that inspect on the name of the compiler rather than run it.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>Perl</term>
|
<term>Perl</term>
|
||||||
<listitem><para>Adds the <filename>lib/site_perl</filename> subdirectory
|
<listitem>
|
||||||
of each build input to the <envar>PERL5LIB</envar>
|
<para>
|
||||||
environment variable.</para></listitem>
|
Adds the <filename>lib/site_perl</filename> subdirectory of each build input to the <envar>PERL5LIB</envar> environment variable.
|
||||||
|
For instance, if <varname>buildInputs</varname> contains Perl, then the <filename>lib/site_perl</filename> subdirectory of each input is added to the <envar>PERL5LIB</envar> environment variable.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1482,6 +1802,20 @@ someVar=$(stripHash $name)
|
|||||||
disabled or patched to work with PaX.</para></listitem>
|
disabled or patched to work with PaX.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>autoPatchelfHook</term>
|
||||||
|
<listitem><para>This is a special setup hook which helps in packaging
|
||||||
|
proprietary software in that it automatically tries to find missing shared
|
||||||
|
library dependencies of ELF files. All packages within the
|
||||||
|
<envar>runtimeDependencies</envar> environment variable are unconditionally
|
||||||
|
added to executables, which is useful for programs that use
|
||||||
|
<citerefentry>
|
||||||
|
<refentrytitle>dlopen</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</citerefentry>
|
||||||
|
to load libraries at runtime.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{ lib }:
|
{ lib }:
|
||||||
let
|
let
|
||||||
|
|
||||||
inherit (builtins) attrNames isFunction;
|
inherit (builtins) attrNames;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ rec {
|
|||||||
overrideDerivation = drv: f:
|
overrideDerivation = drv: f:
|
||||||
let
|
let
|
||||||
newDrv = derivation (drv.drvAttrs // (f drv));
|
newDrv = derivation (drv.drvAttrs // (f drv));
|
||||||
in addPassthru newDrv (
|
in lib.flip (extendDerivation true) newDrv (
|
||||||
{ meta = drv.meta or {};
|
{ meta = drv.meta or {};
|
||||||
passthru = if drv ? passthru then drv.passthru else {};
|
passthru = if drv ? passthru then drv.passthru else {};
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ rec {
|
|||||||
makeOverridable = f: origArgs:
|
makeOverridable = f: origArgs:
|
||||||
let
|
let
|
||||||
ff = f origArgs;
|
ff = f origArgs;
|
||||||
overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs);
|
overrideWith = newArgs: origArgs // (if lib.isFunction newArgs then newArgs origArgs else newArgs);
|
||||||
in
|
in
|
||||||
if builtins.isAttrs ff then (ff // {
|
if builtins.isAttrs ff then (ff // {
|
||||||
override = newArgs: makeOverridable f (overrideWith newArgs);
|
override = newArgs: makeOverridable f (overrideWith newArgs);
|
||||||
@ -81,7 +81,7 @@ rec {
|
|||||||
${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
|
${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
|
||||||
makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
|
makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
|
||||||
})
|
})
|
||||||
else if builtins.isFunction ff then {
|
else if lib.isFunction ff then {
|
||||||
override = newArgs: makeOverridable f (overrideWith newArgs);
|
override = newArgs: makeOverridable f (overrideWith newArgs);
|
||||||
__functor = self: ff;
|
__functor = self: ff;
|
||||||
overrideDerivation = throw "overrideDerivation not yet supported for functors";
|
overrideDerivation = throw "overrideDerivation not yet supported for functors";
|
||||||
@ -112,8 +112,8 @@ rec {
|
|||||||
*/
|
*/
|
||||||
callPackageWith = autoArgs: fn: args:
|
callPackageWith = autoArgs: fn: args:
|
||||||
let
|
let
|
||||||
f = if builtins.isFunction fn then fn else import fn;
|
f = if lib.isFunction fn then fn else import fn;
|
||||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
|
||||||
in makeOverridable f (auto // args);
|
in makeOverridable f (auto // args);
|
||||||
|
|
||||||
|
|
||||||
@ -122,8 +122,8 @@ rec {
|
|||||||
individual attributes. */
|
individual attributes. */
|
||||||
callPackagesWith = autoArgs: fn: args:
|
callPackagesWith = autoArgs: fn: args:
|
||||||
let
|
let
|
||||||
f = if builtins.isFunction fn then fn else import fn;
|
f = if lib.isFunction fn then fn else import fn;
|
||||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
|
||||||
origArgs = auto // args;
|
origArgs = auto // args;
|
||||||
pkgs = f origArgs;
|
pkgs = f origArgs;
|
||||||
mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
|
mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
|
||||||
@ -131,8 +131,8 @@ rec {
|
|||||||
|
|
||||||
|
|
||||||
/* Add attributes to each output of a derivation without changing
|
/* Add attributes to each output of a derivation without changing
|
||||||
the derivation itself. */
|
the derivation itself and check a given condition when evaluating. */
|
||||||
addPassthru = drv: passthru:
|
extendDerivation = condition: passthru: drv:
|
||||||
let
|
let
|
||||||
outputs = drv.outputs or [ "out" ];
|
outputs = drv.outputs or [ "out" ];
|
||||||
|
|
||||||
@ -142,13 +142,18 @@ rec {
|
|||||||
outputToAttrListElement = outputName:
|
outputToAttrListElement = outputName:
|
||||||
{ name = outputName;
|
{ name = outputName;
|
||||||
value = commonAttrs // {
|
value = commonAttrs // {
|
||||||
inherit (drv.${outputName}) outPath drvPath type outputName;
|
inherit (drv.${outputName}) type outputName;
|
||||||
|
drvPath = assert condition; drv.${outputName}.drvPath;
|
||||||
|
outPath = assert condition; drv.${outputName}.outPath;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputsList = map outputToAttrListElement outputs;
|
outputsList = map outputToAttrListElement outputs;
|
||||||
in commonAttrs // { outputUnspecified = true; };
|
in commonAttrs // {
|
||||||
|
outputUnspecified = true;
|
||||||
|
drvPath = assert condition; drv.drvPath;
|
||||||
|
outPath = assert condition; drv.outPath;
|
||||||
|
};
|
||||||
|
|
||||||
/* Strip a derivation of all non-essential attributes, returning
|
/* Strip a derivation of all non-essential attributes, returning
|
||||||
only those needed by hydra-eval-jobs. Also strictly evaluate the
|
only those needed by hydra-eval-jobs. Also strictly evaluate the
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt
|
inherit (builtins) trace attrNamesToStr isAttrs isList isInt
|
||||||
isString isBool head substring attrNames;
|
isString isBool head substring attrNames;
|
||||||
|
|
||||||
inherit (lib) all id mapAttrsFlatten elem;
|
inherit (lib) all id mapAttrsFlatten elem isFunction;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
|
@ -21,10 +21,10 @@ let
|
|||||||
|
|
||||||
# packaging
|
# packaging
|
||||||
customisation = callLibs ./customisation.nix;
|
customisation = callLibs ./customisation.nix;
|
||||||
maintainers = callLibs ./maintainers.nix;
|
maintainers = import ../maintainers/maintainer-list.nix;
|
||||||
meta = callLibs ./meta.nix;
|
meta = callLibs ./meta.nix;
|
||||||
sources = callLibs ./sources.nix;
|
sources = callLibs ./sources.nix;
|
||||||
|
versions = callLibs ./versions.nix;
|
||||||
|
|
||||||
# module system
|
# module system
|
||||||
modules = callLibs ./modules.nix;
|
modules = callLibs ./modules.nix;
|
||||||
@ -41,23 +41,23 @@ let
|
|||||||
generators = callLibs ./generators.nix;
|
generators = callLibs ./generators.nix;
|
||||||
misc = callLibs ./deprecated.nix;
|
misc = callLibs ./deprecated.nix;
|
||||||
# domain-specific
|
# domain-specific
|
||||||
sandbox = callLibs ./sandbox.nix;
|
|
||||||
fetchers = callLibs ./fetchers.nix;
|
fetchers = callLibs ./fetchers.nix;
|
||||||
|
|
||||||
# Eval-time filesystem handling
|
# Eval-time filesystem handling
|
||||||
filesystem = callLibs ./filesystem.nix;
|
filesystem = callLibs ./filesystem.nix;
|
||||||
|
|
||||||
# back-compat aliases
|
# back-compat aliases
|
||||||
platforms = systems.doubles;
|
platforms = systems.forMeta;
|
||||||
|
|
||||||
inherit (builtins) add addErrorContext attrNames
|
inherit (builtins) add addErrorContext attrNames
|
||||||
concatLists deepSeq elem elemAt filter genericClosure genList
|
concatLists deepSeq elem elemAt filter genericClosure genList
|
||||||
getAttr hasAttr head isAttrs isBool isFunction isInt isList
|
getAttr hasAttr head isAttrs isBool isInt isList
|
||||||
isString length lessThan listToAttrs pathExists readFile
|
isString length lessThan listToAttrs pathExists readFile
|
||||||
replaceStrings seq stringLength sub substring tail;
|
replaceStrings seq stringLength sub substring tail;
|
||||||
inherit (trivial) id const concat or and boolToString mergeAttrs
|
inherit (trivial) id const concat or and boolToString mergeAttrs
|
||||||
flip mapNullable inNixShell min max importJSON warn info
|
flip mapNullable inNixShell min max importJSON warn info
|
||||||
nixpkgsVersion mod;
|
nixpkgsVersion mod compare splitByAndCompare
|
||||||
|
functionArgs setFunctionArgs isFunction;
|
||||||
|
|
||||||
inherit (fixedPoints) fix fix' extends composeExtensions
|
inherit (fixedPoints) fix fix' extends composeExtensions
|
||||||
makeExtensible makeExtensibleWithCustomName;
|
makeExtensible makeExtensibleWithCustomName;
|
||||||
@ -72,8 +72,8 @@ let
|
|||||||
inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
|
inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
|
||||||
concatMap flatten remove findSingle findFirst any all count
|
concatMap flatten remove findSingle findFirst any all count
|
||||||
optional optionals toList range partition zipListsWith zipLists
|
optional optionals toList range partition zipListsWith zipLists
|
||||||
reverseList listDfs toposort sort take drop sublist last init
|
reverseList listDfs toposort sort compareLists take drop sublist
|
||||||
crossLists unique intersectLists subtractLists
|
last init crossLists unique intersectLists subtractLists
|
||||||
mutuallyExclusive;
|
mutuallyExclusive;
|
||||||
inherit (strings) concatStrings concatMapStrings concatImapStrings
|
inherit (strings) concatStrings concatMapStrings concatImapStrings
|
||||||
intersperse concatStringsSep concatMapStringsSep
|
intersperse concatStringsSep concatMapStringsSep
|
||||||
@ -88,13 +88,14 @@ let
|
|||||||
inherit (stringsWithDeps) textClosureList textClosureMap
|
inherit (stringsWithDeps) textClosureList textClosureMap
|
||||||
noDepEntry fullDepEntry packEntry stringAfter;
|
noDepEntry fullDepEntry packEntry stringAfter;
|
||||||
inherit (customisation) overrideDerivation makeOverridable
|
inherit (customisation) overrideDerivation makeOverridable
|
||||||
callPackageWith callPackagesWith addPassthru hydraJob makeScope;
|
callPackageWith callPackagesWith extendDerivation
|
||||||
|
hydraJob makeScope;
|
||||||
inherit (meta) addMetaAttrs dontDistribute setName updateName
|
inherit (meta) addMetaAttrs dontDistribute setName updateName
|
||||||
appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
|
appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
|
||||||
hiPrioSet;
|
hiPrioSet;
|
||||||
inherit (sources) pathType pathIsDirectory cleanSourceFilter
|
inherit (sources) pathType pathIsDirectory cleanSourceFilter
|
||||||
cleanSource sourceByRegex sourceFilesBySuffices
|
cleanSource sourceByRegex sourceFilesBySuffices
|
||||||
commitIdFromGitRepo;
|
commitIdFromGitRepo cleanSourceWith pathHasContext canCleanSource;
|
||||||
inherit (modules) evalModules closeModules unifyModuleSyntax
|
inherit (modules) evalModules closeModules unifyModuleSyntax
|
||||||
applyIfFunction unpackSubmodule packSubmodule mergeModules
|
applyIfFunction unpackSubmodule packSubmodule mergeModules
|
||||||
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
|
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ lib }:
|
{ lib }:
|
||||||
let
|
let
|
||||||
inherit (builtins) isFunction head tail isList isAttrs isInt attrNames;
|
inherit (builtins) head tail isList isAttrs isInt attrNames;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ rec {
|
|||||||
f: # the function applied to the arguments
|
f: # the function applied to the arguments
|
||||||
initial: # you pass attrs, the functions below are passing a function taking the fix argument
|
initial: # you pass attrs, the functions below are passing a function taking the fix argument
|
||||||
let
|
let
|
||||||
takeFixed = if isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument
|
takeFixed = if lib.isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument
|
||||||
tidy = args:
|
tidy = args:
|
||||||
let # apply all functions given in "applyPreTidy" in sequence
|
let # apply all functions given in "applyPreTidy" in sequence
|
||||||
applyPreTidyFun = fold ( n: a: x: n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
|
applyPreTidyFun = fold ( n: a: x: n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
|
||||||
@ -63,7 +63,7 @@ rec {
|
|||||||
let args = takeFixed fixed;
|
let args = takeFixed fixed;
|
||||||
mergeFun = args.${n};
|
mergeFun = args.${n};
|
||||||
in if isAttrs x then (mergeFun args x)
|
in if isAttrs x then (mergeFun args x)
|
||||||
else assert isFunction x;
|
else assert lib.isFunction x;
|
||||||
mergeFun args (x ( args // { inherit fixed; }));
|
mergeFun args (x ( args // { inherit fixed; }));
|
||||||
in overridableDelayableArgs f newArgs;
|
in overridableDelayableArgs f newArgs;
|
||||||
in
|
in
|
||||||
@ -374,7 +374,7 @@ rec {
|
|||||||
if isAttrs x then
|
if isAttrs x then
|
||||||
if x ? outPath then "derivation"
|
if x ? outPath then "derivation"
|
||||||
else "attrs"
|
else "attrs"
|
||||||
else if isFunction x then "function"
|
else if lib.isFunction x then "function"
|
||||||
else if isList x then "list"
|
else if isList x then "list"
|
||||||
else if x == true then "bool"
|
else if x == true then "bool"
|
||||||
else if x == false then "bool"
|
else if x == false then "bool"
|
||||||
|
@ -14,6 +14,8 @@ let
|
|||||||
libAttr = lib.attrsets;
|
libAttr = lib.attrsets;
|
||||||
|
|
||||||
flipMapAttrs = flip libAttr.mapAttrs;
|
flipMapAttrs = flip libAttr.mapAttrs;
|
||||||
|
|
||||||
|
inherit (lib) isFunction;
|
||||||
in
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
@ -22,11 +24,15 @@ rec {
|
|||||||
* character sep. If sep appears in k, it is escaped.
|
* character sep. If sep appears in k, it is escaped.
|
||||||
* Helper for synaxes with different separators.
|
* Helper for synaxes with different separators.
|
||||||
*
|
*
|
||||||
* mkKeyValueDefault ":" "f:oo" "bar"
|
* mkValueString specifies how values should be formatted.
|
||||||
|
*
|
||||||
|
* mkKeyValueDefault {} ":" "f:oo" "bar"
|
||||||
* > "f\:oo:bar"
|
* > "f\:oo:bar"
|
||||||
*/
|
*/
|
||||||
mkKeyValueDefault = sep: k: v:
|
mkKeyValueDefault = {
|
||||||
"${libStr.escape [sep] k}${sep}${toString v}";
|
mkValueString ? toString
|
||||||
|
}: sep: k: v:
|
||||||
|
"${libStr.escape [sep] k}${sep}${mkValueString v}";
|
||||||
|
|
||||||
|
|
||||||
/* Generate a key-value-style config file from an attrset.
|
/* Generate a key-value-style config file from an attrset.
|
||||||
@ -34,7 +40,7 @@ rec {
|
|||||||
* mkKeyValue is the same as in toINI.
|
* mkKeyValue is the same as in toINI.
|
||||||
*/
|
*/
|
||||||
toKeyValue = {
|
toKeyValue = {
|
||||||
mkKeyValue ? mkKeyValueDefault "="
|
mkKeyValue ? mkKeyValueDefault {} "="
|
||||||
}: attrs:
|
}: attrs:
|
||||||
let mkLine = k: v: mkKeyValue k v + "\n";
|
let mkLine = k: v: mkKeyValue k v + "\n";
|
||||||
in libStr.concatStrings (libAttr.mapAttrsToList mkLine attrs);
|
in libStr.concatStrings (libAttr.mapAttrsToList mkLine attrs);
|
||||||
@ -64,7 +70,7 @@ rec {
|
|||||||
# apply transformations (e.g. escapes) to section names
|
# apply transformations (e.g. escapes) to section names
|
||||||
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
|
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
|
||||||
# format a setting line from key and value
|
# format a setting line from key and value
|
||||||
mkKeyValue ? mkKeyValueDefault "="
|
mkKeyValue ? mkKeyValueDefault {} "="
|
||||||
}: attrsOfAttrs:
|
}: attrsOfAttrs:
|
||||||
let
|
let
|
||||||
# map function to string for each key val
|
# map function to string for each key val
|
||||||
@ -106,7 +112,7 @@ rec {
|
|||||||
else if isString v then "\"" + v + "\""
|
else if isString v then "\"" + v + "\""
|
||||||
else if null == v then "null"
|
else if null == v then "null"
|
||||||
else if isFunction v then
|
else if isFunction v then
|
||||||
let fna = functionArgs v;
|
let fna = lib.functionArgs v;
|
||||||
showFnas = concatStringsSep "," (libAttr.mapAttrsToList
|
showFnas = concatStringsSep "," (libAttr.mapAttrsToList
|
||||||
(name: hasDefVal: if hasDefVal then "(${name})" else name)
|
(name: hasDefVal: if hasDefVal then "(${name})" else name)
|
||||||
fna);
|
fna);
|
||||||
@ -126,6 +132,6 @@ rec {
|
|||||||
(name: value:
|
(name: value:
|
||||||
"${toPretty args name} = ${toPretty args value};") v)
|
"${toPretty args name} = ${toPretty args value};") v)
|
||||||
+ " }"
|
+ " }"
|
||||||
else "toPretty: should never happen (v = ${v})";
|
else abort "toPretty: should never happen (v = ${v})";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
let
|
let
|
||||||
|
|
||||||
spdx = lic: lic // {
|
spdx = lic: lic // {
|
||||||
url = "http://spdx.org/licenses/${lic.spdxId}";
|
url = "http://spdx.org/licenses/${lic.spdxId}.html";
|
||||||
};
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
@ -15,7 +15,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
|
|
||||||
afl21 = spdx {
|
afl21 = spdx {
|
||||||
spdxId = "AFL-2.1";
|
spdxId = "AFL-2.1";
|
||||||
fullName = "Academic Free License";
|
fullName = "Academic Free License v2.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
afl3 = spdx {
|
||||||
|
spdxId = "AFL-3.0";
|
||||||
|
fullName = "Academic Free License v3.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
agpl3 = spdx {
|
agpl3 = spdx {
|
||||||
@ -74,6 +79,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = ''Beerware License'';
|
fullName = ''Beerware License'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bsd0 = spdx {
|
||||||
|
spdxId = "0BSD";
|
||||||
|
fullName = "BSD Zero Clause License";
|
||||||
|
};
|
||||||
|
|
||||||
bsd2 = spdx {
|
bsd2 = spdx {
|
||||||
spdxId = "BSD-2-Clause";
|
spdxId = "BSD-2-Clause";
|
||||||
fullName = ''BSD 2-clause "Simplified" License'';
|
fullName = ''BSD 2-clause "Simplified" License'';
|
||||||
@ -89,6 +99,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = ''BSD 4-clause "Original" or "Old" License'';
|
fullName = ''BSD 4-clause "Original" or "Old" License'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
clArtistic = spdx {
|
||||||
|
spdxId = "ClArtistic";
|
||||||
|
fullName = "Clarified Artistic License";
|
||||||
|
};
|
||||||
|
|
||||||
cc0 = spdx {
|
cc0 = spdx {
|
||||||
spdxId = "CC0-1.0";
|
spdxId = "CC0-1.0";
|
||||||
fullName = "Creative Commons Zero v1.0 Universal";
|
fullName = "Creative Commons Zero v1.0 Universal";
|
||||||
@ -164,6 +179,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "CeCILL-C Free Software License Agreement";
|
fullName = "CeCILL-C Free Software License Agreement";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cpal10 = spdx {
|
||||||
|
spdxId = "CPAL-1.0";
|
||||||
|
fullName = "Common Public Attribution License 1.0";
|
||||||
|
};
|
||||||
|
|
||||||
cpl10 = spdx {
|
cpl10 = spdx {
|
||||||
spdxId = "CPL-1.0";
|
spdxId = "CPL-1.0";
|
||||||
fullName = "Common Public License 1.0";
|
fullName = "Common Public License 1.0";
|
||||||
@ -195,6 +215,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "Eclipse Public License 1.0";
|
fullName = "Eclipse Public License 1.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
epl20 = spdx {
|
||||||
|
spdxId = "EPL-2.0";
|
||||||
|
fullName = "Eclipse Public License 2.0";
|
||||||
|
};
|
||||||
|
|
||||||
epson = {
|
epson = {
|
||||||
fullName = "Seiko Epson Corporation Software License Agreement for Linux";
|
fullName = "Seiko Epson Corporation Software License Agreement for Linux";
|
||||||
url = https://download.ebz.epson.net/dsc/du/02/eula/global/LINUX_EN.html;
|
url = https://download.ebz.epson.net/dsc/du/02/eula/global/LINUX_EN.html;
|
||||||
@ -304,6 +329,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
free = false;
|
free = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inria-icesl = {
|
||||||
|
fullName = "INRIA Non-Commercial License Agreement for IceSL";
|
||||||
|
url = "http://shapeforge.loria.fr/icesl/EULA_IceSL_binary.pdf";
|
||||||
|
free = false;
|
||||||
|
};
|
||||||
|
|
||||||
ipa = spdx {
|
ipa = spdx {
|
||||||
spdxId = "IPA";
|
spdxId = "IPA";
|
||||||
fullName = "IPA Font License";
|
fullName = "IPA Font License";
|
||||||
@ -426,6 +457,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "Notion modified LGPL";
|
fullName = "Notion modified LGPL";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nposl3 = spdx {
|
||||||
|
spdxId = "NPOSL-3.0";
|
||||||
|
fullName = "Non-Profit Open Software License 3.0";
|
||||||
|
};
|
||||||
|
|
||||||
ofl = spdx {
|
ofl = spdx {
|
||||||
spdxId = "OFL-1.1";
|
spdxId = "OFL-1.1";
|
||||||
fullName = "SIL Open Font License 1.1";
|
fullName = "SIL Open Font License 1.1";
|
||||||
@ -441,6 +477,16 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "OpenSSL License";
|
fullName = "OpenSSL License";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
osl21 = spdx {
|
||||||
|
spdxId = "OSL-2.1";
|
||||||
|
fullName = "Open Software License 2.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
osl3 = spdx {
|
||||||
|
spdxId = "OSL-3.0";
|
||||||
|
fullName = "Open Software License 3.0";
|
||||||
|
};
|
||||||
|
|
||||||
php301 = spdx {
|
php301 = spdx {
|
||||||
spdxId = "PHP-3.01";
|
spdxId = "PHP-3.01";
|
||||||
fullName = "PHP License v3.01";
|
fullName = "PHP License v3.01";
|
||||||
@ -451,6 +497,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "PostgreSQL License";
|
fullName = "PostgreSQL License";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
postman = {
|
||||||
|
fullName = "Postman EULA";
|
||||||
|
url = https://www.getpostman.com/licenses/postman_base_app;
|
||||||
|
free = false;
|
||||||
|
};
|
||||||
|
|
||||||
psfl = spdx {
|
psfl = spdx {
|
||||||
spdxId = "Python-2.0";
|
spdxId = "Python-2.0";
|
||||||
fullName = "Python Software Foundation License version 2";
|
fullName = "Python Software Foundation License version 2";
|
||||||
@ -538,6 +590,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "Vovida Software License v1.0";
|
fullName = "Vovida Software License v1.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watcom = spdx {
|
||||||
|
spdxId = "Watcom-1.0";
|
||||||
|
fullName = "Sybase Open Watcom Public License 1.0";
|
||||||
|
};
|
||||||
|
|
||||||
w3c = spdx {
|
w3c = spdx {
|
||||||
spdxId = "W3C";
|
spdxId = "W3C";
|
||||||
fullName = "W3C Software Notice and License";
|
fullName = "W3C Software Notice and License";
|
||||||
@ -572,5 +629,4 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
spdxId = "ZPL-2.1";
|
spdxId = "ZPL-2.1";
|
||||||
fullName = "Zope Public License 2.1";
|
fullName = "Zope Public License 2.1";
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -385,6 +385,30 @@ rec {
|
|||||||
if len < 2 then list
|
if len < 2 then list
|
||||||
else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right));
|
else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right));
|
||||||
|
|
||||||
|
/* Compare two lists element-by-element.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
compareLists compare [] []
|
||||||
|
=> 0
|
||||||
|
compareLists compare [] [ "a" ]
|
||||||
|
=> -1
|
||||||
|
compareLists compare [ "a" ] []
|
||||||
|
=> 1
|
||||||
|
compareLists compare [ "a" "b" ] [ "a" "c" ]
|
||||||
|
=> 1
|
||||||
|
*/
|
||||||
|
compareLists = cmp: a: b:
|
||||||
|
if a == []
|
||||||
|
then if b == []
|
||||||
|
then 0
|
||||||
|
else -1
|
||||||
|
else if b == []
|
||||||
|
then 1
|
||||||
|
else let rel = cmp (head a) (head b); in
|
||||||
|
if rel == 0
|
||||||
|
then compareLists cmp (tail a) (tail b)
|
||||||
|
else rel;
|
||||||
|
|
||||||
/* Return the first (at most) N elements of a list.
|
/* Return the first (at most) N elements of a list.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -440,8 +464,12 @@ rec {
|
|||||||
init = list: assert list != []; take (length list - 1) list;
|
init = list: assert list != []; take (length list - 1) list;
|
||||||
|
|
||||||
|
|
||||||
/* FIXME(zimbatm) Not used anywhere
|
/* 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]]
|
||||||
|
=> [ "13" "14" "23" "24" ]
|
||||||
|
*/
|
||||||
crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f];
|
crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f];
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,723 +0,0 @@
|
|||||||
{ ...}:
|
|
||||||
/* List of NixOS maintainers. The format is:
|
|
||||||
|
|
||||||
handle = "Real Name <address@example.org>";
|
|
||||||
|
|
||||||
where <handle> is preferred to be your GitHub username (so it's easy
|
|
||||||
to ping a package @<handle>), and <Real Name> is your real name, not
|
|
||||||
a pseudonym. Please keep the list alphabetically sorted. */
|
|
||||||
{
|
|
||||||
a1russell = "Adam Russell <adamlr6+pub@gmail.com>";
|
|
||||||
aaronschif = "Aaron Schif <aaronschif@gmail.com>";
|
|
||||||
abaldeau = "Andreas Baldeau <andreas@baldeau.net>";
|
|
||||||
abbradar = "Nikolay Amiantov <ab@fmap.me>";
|
|
||||||
abigailbuccaneer = "Abigail Bunyan <abigailbuccaneer@gmail.com>";
|
|
||||||
aboseley = "Adam Boseley <adam.boseley@gmail.com>";
|
|
||||||
abuibrahim = "Ruslan Babayev <ruslan@babayev.com>";
|
|
||||||
acowley = "Anthony Cowley <acowley@gmail.com>";
|
|
||||||
adelbertc = "Adelbert Chang <adelbertc@gmail.com>";
|
|
||||||
adev = "Adrien Devresse <adev@adev.name>";
|
|
||||||
adisbladis = "Adam Hose <adis@blad.is>";
|
|
||||||
Adjective-Object = "Maxwell Huang-Hobbs <mhuan13@gmail.com>";
|
|
||||||
adnelson = "Allen Nelson <ithinkican@gmail.com>";
|
|
||||||
adolfogc = "Adolfo E. García Castro <adolfo.garcia.cr@gmail.com>";
|
|
||||||
aespinosa = "Allan Espinosa <allan.espinosa@outlook.com>";
|
|
||||||
aflatter = "Alexander Flatter <flatter@fastmail.fm>";
|
|
||||||
afldcr = "James Alexander Feldman-Crough <alex@fldcr.com>";
|
|
||||||
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
|
|
||||||
afranchuk = "Alex Franchuk <alex.franchuk@gmail.com>";
|
|
||||||
aherrmann = "Andreas Herrmann <andreash87@gmx.ch>";
|
|
||||||
ahmedtd = "Taahir Ahmed <ahmed.taahir@gmail.com>";
|
|
||||||
ak = "Alexander Kjeldaas <ak@formalprivacy.com>";
|
|
||||||
akaWolf = "Artjom Vejsel <akawolf0@gmail.com>";
|
|
||||||
akc = "Anders Claesson <akc@akc.is>";
|
|
||||||
alexvorobiev = "Alex Vorobiev <alexander.vorobiev@gmail.com";
|
|
||||||
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
|
|
||||||
alibabzo = "Alistair Bill <alistair.bill@gmail.com>";
|
|
||||||
all = "Nix Committers <nix-commits@lists.science.uu.nl>";
|
|
||||||
alunduil = "Alex Brandt <alunduil@alunduil.com>";
|
|
||||||
ambrop72 = "Ambroz Bizjak <ambrop7@gmail.com>";
|
|
||||||
amiddelk = "Arie Middelkoop <amiddelk@gmail.com>";
|
|
||||||
amiloradovsky = "Andrew Miloradovsky <miloradovsky@gmail.com>";
|
|
||||||
amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>";
|
|
||||||
AndersonTorres = "Anderson Torres <torres.anderson.85@gmail.com>";
|
|
||||||
anderspapitto = "Anders Papitto <anderspapitto@gmail.com>";
|
|
||||||
andir = "Andreas Rammhold <andreas@rammhold.de>";
|
|
||||||
andres = "Andres Loeh <ksnixos@andres-loeh.de>";
|
|
||||||
andrestylianos = "Andre S. Ramos <andre.stylianos@gmail.com>";
|
|
||||||
andrewrk = "Andrew Kelley <superjoe30@gmail.com>";
|
|
||||||
andsild = "Anders Sildnes <andsild@gmail.com>";
|
|
||||||
aneeshusa = "Aneesh Agrawal <aneeshusa@gmail.com>";
|
|
||||||
ankhers = "Justin Wood <justin.k.wood@gmail.com>";
|
|
||||||
antono = "Antono Vasiljev <self@antono.info>";
|
|
||||||
antonxy = "Anton Schirg <anton.schirg@posteo.de>";
|
|
||||||
apeschar = "Albert Peschar <albert@peschar.net>";
|
|
||||||
apeyroux = "Alexandre Peyroux <alex@px.io>";
|
|
||||||
ardumont = "Antoine R. Dumont <eniotna.t@gmail.com>";
|
|
||||||
aristid = "Aristid Breitkreuz <aristidb@gmail.com>";
|
|
||||||
arobyn = "Alexei Robyn <shados@shados.net>";
|
|
||||||
artuuge = "Artur E. Ruuge <artuuge@gmail.com>";
|
|
||||||
ashalkhakov = "Artyom Shalkhakov <artyom.shalkhakov@gmail.com>";
|
|
||||||
aske = "Kirill Boltaev <aske@fmap.me>";
|
|
||||||
asppsa = "Alastair Pharo <asppsa@gmail.com>";
|
|
||||||
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
|
|
||||||
asymmetric = "Lorenzo Manacorda <lorenzo@mailbox.org>";
|
|
||||||
aszlig = "aszlig <aszlig@nix.build>";
|
|
||||||
auntie = "Jonathan Glines <auntieNeo@gmail.com>";
|
|
||||||
avnik = "Alexander V. Nikolaev <avn@avnik.info>";
|
|
||||||
aycanirican = "Aycan iRiCAN <iricanaycan@gmail.com>";
|
|
||||||
bachp = "Pascal Bach <pascal.bach@nextrem.ch>";
|
|
||||||
backuitist = "Bruno Bieth";
|
|
||||||
badi = "Badi' Abdul-Wahid <abdulwahidc@gmail.com>";
|
|
||||||
balajisivaraman = "Balaji Sivaraman <sivaraman.balaji@gmail.com>";
|
|
||||||
barrucadu = "Michael Walker <mike@barrucadu.co.uk>";
|
|
||||||
basvandijk = "Bas van Dijk <v.dijk.bas@gmail.com>";
|
|
||||||
Baughn = "Svein Ove Aas <sveina@gmail.com>";
|
|
||||||
bcarrell = "Brandon Carrell <brandoncarrell@gmail.com>";
|
|
||||||
bcdarwin = "Ben Darwin <bcdarwin@gmail.com>";
|
|
||||||
bdimcheff = "Brandon Dimcheff <brandon@dimcheff.com>";
|
|
||||||
bendlas = "Herwig Hochleitner <herwig@bendlas.net>";
|
|
||||||
benley = "Benjamin Staffin <benley@gmail.com>";
|
|
||||||
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
|
|
||||||
benwbooth = "Ben Booth <benwbooth@gmail.com>";
|
|
||||||
berdario = "Dario Bertini <berdario@gmail.com>";
|
|
||||||
bergey = "Daniel Bergey <bergey@teallabs.org>";
|
|
||||||
bhipple = "Benjamin Hipple <bhipple@protonmail.com>";
|
|
||||||
binarin = "Alexey Lebedeff <binarin@binarin.ru>";
|
|
||||||
bjg = "Brian Gough <bjg@gnu.org>";
|
|
||||||
bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>";
|
|
||||||
bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>";
|
|
||||||
bobakker = "Bo Bakker <bobakk3r@gmail.com>";
|
|
||||||
bobvanderlinden = "Bob van der Linden <bobvanderlinden@gmail.com>";
|
|
||||||
bodil = "Bodil Stokke <nix@bodil.org>";
|
|
||||||
boothead = "Ben Ford <ben@perurbis.com>";
|
|
||||||
bosu = "Boris Sukholitko <boriss@gmail.com>";
|
|
||||||
bradediger = "Brad Ediger <brad@bradediger.com>";
|
|
||||||
bramd = "Bram Duvigneau <bram@bramd.nl>";
|
|
||||||
bstrik = "Berno Strik <dutchman55@gmx.com>";
|
|
||||||
bzizou = "Bruno Bzeznik <Bruno@bzizou.net>";
|
|
||||||
c0bw3b = "Renaud <c0bw3b@gmail.com>";
|
|
||||||
c0dehero = "CodeHero <codehero@nerdpol.ch>";
|
|
||||||
calbrecht = "Christian Albrecht <christian.albrecht@mayflower.de>";
|
|
||||||
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
|
|
||||||
calvertvl = "Victor Calvert <calvertvl@gmail.com>";
|
|
||||||
campadrenalin = "Philip Horger <campadrenalin@gmail.com>";
|
|
||||||
canndrew = "Andrew Cann <shum@canndrew.org>";
|
|
||||||
carlsverre = "Carl Sverre <accounts@carlsverre.com>";
|
|
||||||
casey = "Casey Rodarmor <casey@rodarmor.net>";
|
|
||||||
catern = "Spencer Baugh <sbaugh@catern.com>";
|
|
||||||
caugner = "Claas Augner <nixos@caugner.de>";
|
|
||||||
cdepillabout = "Dennis Gosnell <cdep.illabout@gmail.com>";
|
|
||||||
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
|
|
||||||
changlinli = "Changlin Li <mail@changlinli.com>";
|
|
||||||
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
|
||||||
chattered = "Phil Scott <me@philscotted.com>";
|
|
||||||
ChengCat = "Yucheng Zhang <yu@cheng.cat>";
|
|
||||||
choochootrain = "Hurshal Patel <hurshal@imap.cc>";
|
|
||||||
chpatrick = "Patrick Chilton <chpatrick@gmail.com>";
|
|
||||||
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
|
||||||
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
|
||||||
chrisrosset = "Christopher Rosset <chris@rosset.org.uk>";
|
|
||||||
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
|
|
||||||
ciil = "Simon Lackerbauer <simon@lackerbauer.com>";
|
|
||||||
ckampka = "Christian Kampka <christian@kampka.net>";
|
|
||||||
ckauhaus = "Christian Kauhaus <christian@kauhaus.de>";
|
|
||||||
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
|
||||||
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
|
||||||
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
|
||||||
cmfwyp = "cmfwyp <cmfwyp@riseup.net>";
|
|
||||||
cobbal = "Andrew Cobb <andrew.cobb@gmail.com>";
|
|
||||||
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
|
|
||||||
codsl = "codsl <codsl@riseup.net>";
|
|
||||||
codyopel = "Cody Opel <codyopel@gmail.com>";
|
|
||||||
colemickens = "Cole Mickens <cole.mickens@gmail.com>";
|
|
||||||
colescott = "Cole Scott <colescottsf@gmail.com>";
|
|
||||||
copumpkin = "Dan Peebles <pumpkingod@gmail.com>";
|
|
||||||
corngood = "David McFarland <corngood@gmail.com>";
|
|
||||||
coroa = "Jonas Hörsch <jonas@chaoflow.net>";
|
|
||||||
couchemar = "Andrey Pavlov <couchemar@yandex.ru>";
|
|
||||||
cpages = "Carles Pagès <page@ruiec.cat>";
|
|
||||||
cransom = "Casey Ransom <cransom@hubns.net>";
|
|
||||||
cryptix = "Henry Bubert <cryptix@riseup.net>";
|
|
||||||
CrystalGamma = "Jona Stubbe <nixos@crystalgamma.de>";
|
|
||||||
cstrahan = "Charles Strahan <charles@cstrahan.com>";
|
|
||||||
csingley = "Christopher Singley <csingley@gmail.com>";
|
|
||||||
cwoac = "Oliver Matthews <oliver@codersoffortune.net>";
|
|
||||||
DamienCassou = "Damien Cassou <damien@cassou.me>";
|
|
||||||
danbst = "Danylo Hlynskyi <abcz2.uprola@gmail.com>";
|
|
||||||
dancek = "Hannu Hartikainen <hannu.hartikainen@gmail.com>";
|
|
||||||
danharaj = "Dan Haraj <dan@obsidian.systems>";
|
|
||||||
danielfullmer = "Daniel Fullmer <danielrf12@gmail.com>";
|
|
||||||
dasuxullebt = "Christoph-Simon Senjak <christoph.senjak@googlemail.com>";
|
|
||||||
david50407 = "David Kuo <me@davy.tw>";
|
|
||||||
davidak = "David Kleuker <post@davidak.de>";
|
|
||||||
davidrusu = "David Rusu <davidrusu.me@gmail.com>";
|
|
||||||
davorb = "Davor Babic <davor@davor.se>";
|
|
||||||
dbohdan = "Danyil Bohdan <danyil.bohdan@gmail.com>";
|
|
||||||
dbrock = "Daniel Brockman <daniel@brockman.se>";
|
|
||||||
deepfire = "Kosyrev Serge <_deepfire@feelingofgreen.ru>";
|
|
||||||
demin-dmitriy = "Dmitriy Demin <demindf@gmail.com>";
|
|
||||||
derchris = "Christian Gerbrandt <derchris@me.com>";
|
|
||||||
DerGuteMoritz = "Moritz Heidkamp <moritz@twoticketsplease.de>";
|
|
||||||
dermetfan = "Robin Stumm <serverkorken@gmail.com>";
|
|
||||||
DerTim1 = "Tim Digel <tim.digel@active-group.de>";
|
|
||||||
desiderius = "Didier J. Devroye <didier@devroye.name>";
|
|
||||||
devhell = "devhell <\"^\"@regexmail.net>";
|
|
||||||
dezgeg = "Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>";
|
|
||||||
dfordivam = "Divam <dfordivam+nixpkgs@gmail.com>";
|
|
||||||
dfoxfranke = "Daniel Fox Franke <dfoxfranke@gmail.com>";
|
|
||||||
dgonyeo = "Derek Gonyeo <derek@gonyeo.com>";
|
|
||||||
dipinhora = "Dipin Hora <dipinhora+github@gmail.com>";
|
|
||||||
disassembler = "Samuel Leathers <disasm@gmail.com>";
|
|
||||||
dizfer = "David Izquierdo <david@izquierdofernandez.com>";
|
|
||||||
dmalikov = "Dmitry Malikov <malikov.d.y@gmail.com>";
|
|
||||||
DmitryTsygankov = "Dmitry Tsygankov <dmitry.tsygankov@gmail.com>";
|
|
||||||
dmjio = "David Johnson <djohnson.m@gmail.com>";
|
|
||||||
dochang = "Desmond O. Chang <dochang@gmail.com>";
|
|
||||||
domenkozar = "Domen Kozar <domen@dev.si>";
|
|
||||||
dotlambda = "Robert Schütz <rschuetz17@gmail.com>";
|
|
||||||
doublec = "Chris Double <chris.double@double.co.nz>";
|
|
||||||
dpaetzel = "David Pätzel <david.a.paetzel@gmail.com>";
|
|
||||||
dpflug = "David Pflug <david@pflug.email>";
|
|
||||||
drets = "Dmytro Rets <dmitryrets@gmail.com>";
|
|
||||||
drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
|
|
||||||
dsferruzza = "David Sferruzza <david.sferruzza@gmail.com>";
|
|
||||||
dtzWill = "Will Dietz <nix@wdtz.org>";
|
|
||||||
dupgit = "Olivier Delhomme <olivier.delhomme@free.fr>";
|
|
||||||
dywedir = "Vladyslav M. <dywedir@protonmail.ch>";
|
|
||||||
e-user = "Alexander Kahl <nixos@sodosopa.io>";
|
|
||||||
earldouglas = "James Earl Douglas <james@earldouglas.com>";
|
|
||||||
ebzzry = "Rommel Martinez <ebzzry@ebzzry.io>";
|
|
||||||
edanaher = "Evan Danaher <nixos@edanaher.net>";
|
|
||||||
edef = "edef <edef@edef.eu>";
|
|
||||||
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
|
||||||
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
|
|
||||||
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
|
|
||||||
eelco = "Eelco Dolstra <eelco.dolstra@logicblox.com>";
|
|
||||||
ehegnes = "Eric Hegnes <eric.hegnes@gmail.com>";
|
|
||||||
ehmry = "Emery Hemingway <emery@vfemail.net>";
|
|
||||||
eikek = "Eike Kettner <eike.kettner@posteo.de>";
|
|
||||||
ekleog = "Leo Gaspard <leo@gaspard.io>";
|
|
||||||
elasticdog = "Aaron Bull Schaefer <aaron@elasticdog.com>";
|
|
||||||
eleanor = "Dejan Lukan <dejan@proteansec.com>";
|
|
||||||
elijahcaine = "Elijah Caine <elijahcainemv@gmail.com>";
|
|
||||||
elitak = "Eric Litak <elitak@gmail.com>";
|
|
||||||
ellis = "Ellis Whitehead <nixos@ellisw.net>";
|
|
||||||
eperuffo = "Emanuele Peruffo <info@emanueleperuffo.com>";
|
|
||||||
epitrochoid = "Mabry Cervin <mpcervin@uncg.edu>";
|
|
||||||
eqyiel = "Ruben Maher <r@rkm.id.au>";
|
|
||||||
ericbmerritt = "Eric Merritt <eric@afiniate.com>";
|
|
||||||
ericsagnes = "Eric Sagnes <eric.sagnes@gmail.com>";
|
|
||||||
erictapen = "Justin Humm <justin.humm@posteo.de>";
|
|
||||||
erikryb = "Erik Rybakken <erik.rybakken@math.ntnu.no>";
|
|
||||||
ertes = "Ertugrul Söylemez <esz@posteo.de>";
|
|
||||||
ethercrow = "Dmitry Ivanov <ethercrow@gmail.com>";
|
|
||||||
etu = "Elis Hirwing <elis@hirwing.se>";
|
|
||||||
exi = "Reno Reckling <nixos@reckling.org>";
|
|
||||||
exlevan = "Alexey Levan <exlevan@gmail.com>";
|
|
||||||
expipiplus1 = "Joe Hermaszewski <nix@monoid.al>";
|
|
||||||
fadenb = "Tristan Helmich <tristan.helmich+nixos@gmail.com>";
|
|
||||||
falsifian = "James Cook <james.cook@utoronto.ca>";
|
|
||||||
fare = "Francois-Rene Rideau <fahree@gmail.com>";
|
|
||||||
fgaz = "Francesco Gazzetta <francygazz@gmail.com>";
|
|
||||||
FireyFly = "Jonas Höglund <nix@firefly.nu>";
|
|
||||||
flokli = "Florian Klink <flokli@flokli.de>";
|
|
||||||
florianjacob = "Florian Jacob <projects+nixos@florianjacob.de>";
|
|
||||||
flosse = "Markus Kohlhase <mail@markus-kohlhase.de>";
|
|
||||||
fluffynukeit = "Daniel Austin <dan@fluffynukeit.com>";
|
|
||||||
fmthoma = "Franz Thoma <f.m.thoma@googlemail.com>";
|
|
||||||
forkk = "Andrew Okin <forkk@forkk.net>";
|
|
||||||
fornever = "Friedrich von Never <friedrich@fornever.me>";
|
|
||||||
fpletz = "Franz Pletz <fpletz@fnordicwalking.de>";
|
|
||||||
fps = "Florian Paul Schmidt <mista.tapas@gmx.net>";
|
|
||||||
fridh = "Frederik Rietdijk <fridh@fridh.nl>";
|
|
||||||
frlan = "Frank Lanitz <frank@frank.uvena.de>";
|
|
||||||
fro_ozen = "fro_ozen <fro_ozen@gmx.de>";
|
|
||||||
ftrvxmtrx = "Siarhei Zirukin <ftrvxmtrx@gmail.com>";
|
|
||||||
funfunctor = "Edward O'Callaghan <eocallaghan@alterapraxis.com>";
|
|
||||||
fuuzetsu = "Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>";
|
|
||||||
fuzzy-id = "Thomas Bach <hacking+nixos@babibo.de>";
|
|
||||||
fxfactorial = "Edgar Aroutiounian <edgar.factorial@gmail.com>";
|
|
||||||
gabesoft = "Gabriel Adomnicai <gabesoft@gmail.com>";
|
|
||||||
gal_bolle = "Florent Becker <florent.becker@ens-lyon.org>";
|
|
||||||
garbas = "Rok Garbas <rok@garbas.si>";
|
|
||||||
garrison = "Jim Garrison <jim@garrison.cc>";
|
|
||||||
gavin = "Gavin Rogers <gavin@praxeology.co.uk>";
|
|
||||||
gebner = "Gabriel Ebner <gebner@gebner.org>";
|
|
||||||
geistesk = "Alvar Penning <post@0x21.biz>";
|
|
||||||
georgewhewell = "George Whewell <georgerw@gmail.com>";
|
|
||||||
gilligan = "Tobias Pflug <tobias.pflug@gmail.com>";
|
|
||||||
giogadi = "Luis G. Torres <lgtorres42@gmail.com>";
|
|
||||||
gleber = "Gleb Peregud <gleber.p@gmail.com>";
|
|
||||||
glenns = "Glenn Searby <glenn.searby@gmail.com>";
|
|
||||||
globin = "Robin Gloster <mail@glob.in>";
|
|
||||||
gnidorah = "Alex Ivanov <yourbestfriend@opmbx.org>";
|
|
||||||
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
|
|
||||||
Gonzih = "Max Gonzih <gonzih@gmail.com>";
|
|
||||||
goodrone = "Andrew Trachenko <goodrone@gmail.com>";
|
|
||||||
gpyh = "Yacine Hmito <yacine.hmito@gmail.com>";
|
|
||||||
grahamc = "Graham Christensen <graham@grahamc.com>";
|
|
||||||
grburst = "Julius Elias <grburst@openmailbox.org>";
|
|
||||||
gridaphobe = "Eric Seidel <eric@seidel.io>";
|
|
||||||
guibert = "David Guibert <david.guibert@gmail.com>";
|
|
||||||
guibou = "Guillaume Bouchard <guillaum.bouchard@gmail.com>";
|
|
||||||
guillaumekoenig = "Guillaume Koenig <guillaume.edward.koenig@gmail.com>";
|
|
||||||
guyonvarch = "Joris Guyonvarch <joris@guyonvarch.me>";
|
|
||||||
hakuch = "Jesse Haber-Kucharsky <hakuch@gmail.com>";
|
|
||||||
hamhut1066 = "Hamish Hutchings <github@hamhut1066.com>";
|
|
||||||
havvy = "Ryan Scheel <ryan.havvy@gmail.com>";
|
|
||||||
hbunke = "Hendrik Bunke <bunke.hendrik@gmail.com>";
|
|
||||||
hce = "Hans-Christian Esperer <hc@hcesperer.org>";
|
|
||||||
hectorj = "Hector Jusforgues <hector.jusforgues+nixos@gmail.com>";
|
|
||||||
hedning = "Tor Hedin Brønner <torhedinbronner@gmail.com>";
|
|
||||||
heel = "Sergii Paryzhskyi <parizhskiy@gmail.com>";
|
|
||||||
henrytill = "Henry Till <henrytill@gmail.com>";
|
|
||||||
hhm = "hhm <heehooman+nixpkgs@gmail.com>";
|
|
||||||
hinton = "Tom Hinton <t@larkery.com>";
|
|
||||||
hodapp = "Chris Hodapp <hodapp87@gmail.com>";
|
|
||||||
hrdinka = "Christoph Hrdinka <c.nix@hrdinka.at>";
|
|
||||||
htr = "Hugo Tavares Reis <hugo@linux.com>";
|
|
||||||
iand675 = "Ian Duncan <ian@iankduncan.com>";
|
|
||||||
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
|
|
||||||
iblech = "Ingo Blechschmidt <iblech@speicherleck.de>";
|
|
||||||
igsha = "Igor Sharonov <igor.sharonov@gmail.com>";
|
|
||||||
ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>";
|
|
||||||
infinisil = "Silvan Mosberger <infinisil@icloud.com>";
|
|
||||||
ironpinguin = "Michele Catalano <michele@catalano.de>";
|
|
||||||
ivan-tkatchev = "Ivan Tkatchev <tkatchev@gmail.com>";
|
|
||||||
ixmatus = "Parnell Springmeyer <parnell@digitalmentat.com>";
|
|
||||||
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
|
|
||||||
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
|
|
||||||
jammerful = "jammerful <jammerful@gmail.com>";
|
|
||||||
jansol = "Jan Solanti <jan.solanti@paivola.fi>";
|
|
||||||
javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
|
|
||||||
jb55 = "William Casarin <jb55@jb55.com>";
|
|
||||||
jbedo = "Justin Bedő <cu@cua0.org>";
|
|
||||||
jcumming = "Jack Cummings <jack@mudshark.org>";
|
|
||||||
jdagilliland = "Jason Gilliland <jdagilliland@gmail.com>";
|
|
||||||
jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>";
|
|
||||||
jensbin = "Jens Binkert <jensbin@protonmail.com>";
|
|
||||||
jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>";
|
|
||||||
jfb = "James Felix Black <james@yamtime.com>";
|
|
||||||
jfrankenau = "Johannes Frankenau <johannes@frankenau.net>";
|
|
||||||
jgeerds = "Jascha Geerds <jascha@jgeerds.name>";
|
|
||||||
jgertm = "Tim Jaeger <jger.tm@gmail.com>";
|
|
||||||
jgillich = "Jakob Gillich <jakob@gillich.me>";
|
|
||||||
jhhuh = "Ji-Haeng Huh <jhhuh.note@gmail.com>";
|
|
||||||
jirkamarsik = "Jirka Marsik <jiri.marsik89@gmail.com>";
|
|
||||||
jlesquembre = "José Luis Lafuente <jl@lafuente.me>";
|
|
||||||
jluttine = "Jaakko Luttinen <jaakko.luttinen@iki.fi>";
|
|
||||||
joachifm = "Joachim Fasting <joachifm@fastmail.fm>";
|
|
||||||
joamaki = "Jussi Maki <joamaki@gmail.com>";
|
|
||||||
joelmo = "Joel Moberg <joel.moberg@gmail.com>";
|
|
||||||
joelteon = "Joel Taylor <me@joelt.io>";
|
|
||||||
johbo = "Johannes Bornhold <johannes@bornhold.name>";
|
|
||||||
johnmh = "John M. Harris, Jr. <johnmh@openblox.org>";
|
|
||||||
johnramsden = "John Ramsden <johnramsden@riseup.net>";
|
|
||||||
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
|
|
||||||
jonafato = "Jon Banafato <jon@jonafato.com>";
|
|
||||||
joncojonathan = "Jonathan Haddock <joncojonathan@gmail.com>";
|
|
||||||
jpierre03 = "Jean-Pierre PRUNARET <nix@prunetwork.fr>";
|
|
||||||
jpotier = "Martin Potier <jpo.contributes.to.nixos@marvid.fr>";
|
|
||||||
jraygauthier = "Raymond Gauthier <jraygauthier@gmail.com>";
|
|
||||||
jtojnar = "Jan Tojnar <jtojnar@gmail.com>";
|
|
||||||
juliendehos = "Julien Dehos <dehos@lisic.univ-littoral.fr>";
|
|
||||||
jwiegley = "John Wiegley <johnw@newartisans.com>";
|
|
||||||
jwilberding = "Jordan Wilberding <jwilberding@afiniate.com>";
|
|
||||||
jyp = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
|
|
||||||
jzellner = "Jeff Zellner <jeffz@eml.cc>";
|
|
||||||
kaiha = "Kai Harries <kai.harries@gmail.com>";
|
|
||||||
kamilchm = "Kamil Chmielewski <kamil.chm@gmail.com>";
|
|
||||||
kampfschlaefer = "Arnold Krille <arnold@arnoldarts.de>";
|
|
||||||
karolchmist = "karolchmist <info+nix@chmist.com>";
|
|
||||||
kentjames = "James Kent <jameschristopherkent@gmail.com";
|
|
||||||
kevincox = "Kevin Cox <kevincox@kevincox.ca>";
|
|
||||||
khumba = "Bryan Gardiner <bog@khumba.net>";
|
|
||||||
KibaFox = "Kiba Fox <kiba.fox@foxypossibilities.com>";
|
|
||||||
kierdavis = "Kier Davis <kierdavis@gmail.com>";
|
|
||||||
kiloreux = "Kiloreux Emperex <kiloreux@gmail.com>";
|
|
||||||
kini = "Keshav Kini <keshav.kini@gmail.com>";
|
|
||||||
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
|
|
||||||
knedlsepp = "Josef Kemetmüller <josef.kemetmueller@gmail.com>";
|
|
||||||
konimex = "Muhammad Herdiansyah <herdiansyah@netc.eu>";
|
|
||||||
koral = "Koral <koral@mailoo.org>";
|
|
||||||
kovirobi = "Kovacsics Robert <kovirobi@gmail.com>";
|
|
||||||
kquick = "Kevin Quick <quick@sparq.org>";
|
|
||||||
kragniz = "Louis Taylor <louis@kragniz.eu>";
|
|
||||||
kristoff3r = "Kristoffer Søholm <k.soeholm@gmail.com>";
|
|
||||||
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
|
|
||||||
kuznero = "Roman Kuznetsov <roman@kuznero.com>";
|
|
||||||
lassulus = "Lassulus <lassulus@gmail.com>";
|
|
||||||
layus = "Guillaume Maudoux <layus.on@gmail.com>";
|
|
||||||
ldesgoui = "Lucas Desgouilles <ldesgoui@gmail.com>";
|
|
||||||
league = "Christopher League <league@contrapunctus.net>";
|
|
||||||
lebastr = "Alexander Lebedev <lebastr@gmail.com>";
|
|
||||||
leemachin = "Lee Machin <me@mrl.ee>";
|
|
||||||
leenaars = "Michiel Leenaars <ml.software@leenaa.rs>";
|
|
||||||
leonardoce = "Leonardo Cecchi <leonardo.cecchi@gmail.com>";
|
|
||||||
lethalman = "Luca Bruno <lucabru@src.gnome.org>";
|
|
||||||
lewo = "Antoine Eiche <lewo@abesis.fr>";
|
|
||||||
lheckemann = "Linus Heckemann <git@sphalerite.org>";
|
|
||||||
lhvwb = "Nathaniel Baxter <nathaniel.baxter@gmail.com>";
|
|
||||||
lihop = "Leroy Hopson <nixos@leroy.geek.nz>";
|
|
||||||
linquize = "Linquize <linquize@yahoo.com.hk>";
|
|
||||||
linus = "Linus Arver <linusarver@gmail.com>";
|
|
||||||
lluchs = "Lukas Werling <lukas.werling@gmail.com>";
|
|
||||||
lnl7 = "Daiderd Jordan <daiderd@gmail.com>";
|
|
||||||
lo1tuma = "Mathias Schreck <schreck.mathias@gmail.com>";
|
|
||||||
loskutov = "Ignat Loskutov <ignat.loskutov@gmail.com>";
|
|
||||||
lovek323 = "Jason O'Conal <jason@oconal.id.au>";
|
|
||||||
lowfatcomputing = "Andreas Wagner <andreas.wagner@lowfatcomputing.org>";
|
|
||||||
lsix = "Lancelot SIX <lsix@lancelotsix.com>";
|
|
||||||
ltavard = "Laure Tavard <laure.tavard@univ-grenoble-alpes.fr>";
|
|
||||||
lucas8 = "Luc Chabassier <luc.linux@mailoo.org>";
|
|
||||||
ludo = "Ludovic Courtès <ludo@gnu.org>";
|
|
||||||
lufia = "Kyohei Kadota <lufia@lufia.org>";
|
|
||||||
luispedro = "Luis Pedro Coelho <luis@luispedro.org>";
|
|
||||||
lukego = "Luke Gorrie <luke@snabb.co>";
|
|
||||||
lw = "Sergey Sofeychuk <lw@fmap.me>";
|
|
||||||
lyt = "Tim Liou <wheatdoge@gmail.com>";
|
|
||||||
m3tti = "Mathaeus Sander <mathaeus.peter.sander@gmail.com>";
|
|
||||||
ma27 = "Maximilian Bosch <maximilian@mbosch.me>";
|
|
||||||
madjar = "Georges Dubus <georges.dubus@compiletoi.net>";
|
|
||||||
magnetophon = "Bart Brouns <bart@magnetophon.nl>";
|
|
||||||
mahe = "Matthias Herrmann <matthias.mh.herrmann@gmail.com>";
|
|
||||||
makefu = "Felix Richter <makefu@syntax-fehler.de>";
|
|
||||||
malyn = "Michael Alyn Miller <malyn@strangeGizmo.com>";
|
|
||||||
manveru = "Michael Fellinger <m.fellinger@gmail.com>";
|
|
||||||
marcweber = "Marc Weber <marco-oweber@gmx.de>";
|
|
||||||
markus1189 = "Markus Hauck <markus1189@gmail.com>";
|
|
||||||
markWot = "Markus Wotringer <markus@wotringer.de>";
|
|
||||||
martijnvermaat = "Martijn Vermaat <martijn@vermaat.name>";
|
|
||||||
martingms = "Martin Gammelsæter <martin@mg.am>";
|
|
||||||
matejc = "Matej Cotman <cotman.matej@gmail.com>";
|
|
||||||
mathnerd314 = "Mathnerd314 <mathnerd314.gph+hs@gmail.com>";
|
|
||||||
matthewbauer = "Matthew Bauer <mjbauer95@gmail.com>";
|
|
||||||
matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>";
|
|
||||||
maurer = "Matthew Maurer <matthew.r.maurer+nix@gmail.com>";
|
|
||||||
mbakke = "Marius Bakke <mbakke@fastmail.com>";
|
|
||||||
mbbx6spp = "Susan Potter <me@susanpotter.net>";
|
|
||||||
mbe = "Brandon Edens <brandonedens@gmail.com>";
|
|
||||||
mboes = "Mathieu Boespflug <mboes@tweag.net>";
|
|
||||||
mbrgm = "Marius Bergmann <marius@yeai.de>";
|
|
||||||
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
|
||||||
mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>";
|
|
||||||
meditans = "Carlo Nucera <meditans@gmail.com>";
|
|
||||||
mehandes = "Matt Deming <niewskici@gmail.com>";
|
|
||||||
meisternu = "Matt Miemiec <meister@krutt.org>";
|
|
||||||
metabar = "Celine Mercier <softs@metabarcoding.org>";
|
|
||||||
mgdelacroix = "Miguel de la Cruz <mgdelacroix@gmail.com>";
|
|
||||||
mguentner = "Maximilian Güntner <code@klandest.in>";
|
|
||||||
mic92 = "Jörg Thalheim <joerg@thalheim.io>";
|
|
||||||
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
|
||||||
michalrus = "Michal Rus <m@michalrus.com>";
|
|
||||||
michelk = "Michel Kuhlmann <michel@kuhlmanns.info>";
|
|
||||||
midchildan = "midchildan <midchildan+nix@gmail.com>";
|
|
||||||
mikefaille = "Michaël Faille <michael@faille.io>";
|
|
||||||
miltador = "Vasiliy Solovey <miltador@yandex.ua>";
|
|
||||||
mimadrid = "Miguel Madrid <mimadrid@ucm.es>";
|
|
||||||
mirdhyn = "Merlin Gaillard <mirdhyn@gmail.com>";
|
|
||||||
mirrexagon = "Andrew Abbott <mirrexagon@mirrexagon.com>";
|
|
||||||
mjanczyk = "Marcin Janczyk <m@dragonvr.pl>";
|
|
||||||
mlieberman85 = "Michael Lieberman <mlieberman85@gmail.com>";
|
|
||||||
modulistic = "Pablo Costa <modulistic@gmail.com>";
|
|
||||||
mog = "Matthew O'Gorman <mog-lists@rldn.net>";
|
|
||||||
montag451 = "montag451 <montag451@laposte.net>";
|
|
||||||
moosingin3space = "Nathan Moos <moosingin3space@gmail.com>";
|
|
||||||
moretea = "Maarten Hoogendoorn <maarten@moretea.nl>";
|
|
||||||
mornfall = "Petr Ročkai <me@mornfall.net>";
|
|
||||||
MostAwesomeDude = "Corbin Simpson <cds@corbinsimpson.com>";
|
|
||||||
mounium = "Katona László <muoniurn@gmail.com>";
|
|
||||||
MP2E = "Cray Elliott <MP2E@archlinux.us>";
|
|
||||||
mpcsh = "Mark Cohen <m@mpc.sh>";
|
|
||||||
mpscholten = "Marc Scholten <marc@mpscholten.de>";
|
|
||||||
mpsyco = "Francis St-Amour <fr.st-amour@gmail.com>";
|
|
||||||
msackman = "Matthew Sackman <matthew@wellquite.org>";
|
|
||||||
mschristiansen = "Mikkel Christiansen <mikkel@rheosystems.com>";
|
|
||||||
msteen = "Matthijs Steen <emailmatthijs@gmail.com>";
|
|
||||||
mt-caret = "Masayuki Takeda <mtakeda.enigsol@gmail.com>";
|
|
||||||
mtreskin = "Max Treskin <zerthurd@gmail.com>";
|
|
||||||
mudri = "James Wood <lamudri@gmail.com>";
|
|
||||||
muflax = "Stefan Dorn <mail@muflax.com>";
|
|
||||||
myrl = "Myrl Hex <myrl.0xf@gmail.com>";
|
|
||||||
namore = "Roman Naumann <namor@hemio.de>";
|
|
||||||
nand0p = "Fernando Jose Pando <nando@hex7.com>";
|
|
||||||
Nate-Devv = "Nathan Moore <natedevv@gmail.com>";
|
|
||||||
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
|
|
||||||
nckx = "Tobias Geerinckx-Rice <github@tobias.gr>";
|
|
||||||
ndowens = "Nathan Owens <ndowens04@gmail.com>";
|
|
||||||
neeasade = "Nathan Isom <nathanisom27@gmail.com>";
|
|
||||||
nequissimus = "Tim Steinbach <tim@nequissimus.com>";
|
|
||||||
nfjinjing = "Jinjing Wang <nfjinjing@gmail.com>";
|
|
||||||
nh2 = "Niklas Hambüchen <mail@nh2.me>";
|
|
||||||
nhooyr = "Anmol Sethi <anmol@aubble.com>";
|
|
||||||
nickhu = "Nick Hu <me@nickhu.co.uk>";
|
|
||||||
nicknovitski = "Nick Novitski <nixpkgs@nicknovitski.com>";
|
|
||||||
nico202 = "Nicolò Balzarotti <anothersms@gmail.com>";
|
|
||||||
NikolaMandic = "Ratko Mladic <nikola@mandic.email>";
|
|
||||||
nixy = "Andrew R. M. <nixy@nixy.moe>";
|
|
||||||
nocoolnametom = "Tom Doggett <nocoolnametom@gmail.com>";
|
|
||||||
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
|
|
||||||
np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>";
|
|
||||||
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
|
|
||||||
nthorne = "Niklas Thörne <notrupertthorne@gmail.com>";
|
|
||||||
nyarly = "Judson Lester <nyarly@gmail.com>";
|
|
||||||
obadz = "obadz <obadz-nixos@obadz.com>";
|
|
||||||
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
|
||||||
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
|
|
||||||
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
|
|
||||||
oida = "oida <oida@posteo.de>";
|
|
||||||
okasu = "Okasu <oka.sux@gmail.com>";
|
|
||||||
olcai = "Erik Timan <dev@timan.info>";
|
|
||||||
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
|
||||||
olynch = "Owen Lynch <owen@olynch.me>";
|
|
||||||
orbekk = "KJ Ørbekk <kjetil.orbekk@gmail.com>";
|
|
||||||
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
|
||||||
orivej = "Orivej Desh <orivej@gmx.fr>";
|
|
||||||
osener = "Ozan Sener <ozan@ozansener.com>";
|
|
||||||
otwieracz = "Slawomir Gonet <slawek@otwiera.cz>";
|
|
||||||
oxij = "Jan Malakhovski <oxij@oxij.org>";
|
|
||||||
paholg = "Paho Lurie-Gregg <paho@paholg.com>";
|
|
||||||
pakhfn = "Fedor Pakhomov <pakhfn@gmail.com>";
|
|
||||||
palo = "Ingolf Wanger <palipalo9@googlemail.com>";
|
|
||||||
panaeon = "Vitalii Voloshyn <vitalii.voloshyn@gmail.com";
|
|
||||||
paperdigits = "Mica Semrick <mica@silentumbrella.com>";
|
|
||||||
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
|
||||||
patternspandemic = "Brad Christensen <patternspandemic@live.com>";
|
|
||||||
pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>";
|
|
||||||
pbogdan = "Piotr Bogdan <ppbogdan@gmail.com>";
|
|
||||||
periklis = "theopompos@gmail.com";
|
|
||||||
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
|
|
||||||
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
|
|
||||||
peterromfeldhk = "Peter Romfeld <peter.romfeld.hk@gmail.com>";
|
|
||||||
peti = "Peter Simons <simons@cryp.to>";
|
|
||||||
philandstuff = "Philip Potter <philip.g.potter@gmail.com>";
|
|
||||||
phile314 = "Philipp Hausmann <nix@314.ch>";
|
|
||||||
Phlogistique = "Noé Rubinstein <noe.rubinstein@gmail.com>";
|
|
||||||
phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>";
|
|
||||||
phunehehe = "Hoang Xuan Phu <phunehehe@gmail.com>";
|
|
||||||
pierrechevalier83 = "Pierre Chevalier <pierrechevalier83@gmail.com>";
|
|
||||||
pierrer = "Pierre Radermecker <pierrer@pi3r.be>";
|
|
||||||
pierron = "Nicolas B. Pierron <nixos@nbp.name>";
|
|
||||||
piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>";
|
|
||||||
pjbarnoy = "Perry Barnoy <pjbarnoy@gmail.com>";
|
|
||||||
pjones = "Peter Jones <pjones@devalot.com>";
|
|
||||||
pkmx = "Chih-Mao Chen <pkmx.tw@gmail.com>";
|
|
||||||
plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>";
|
|
||||||
plumps = "Maksim Bronsky <maks.bronsky@web.de";
|
|
||||||
pmahoney = "Patrick Mahoney <pat@polycrystal.org>";
|
|
||||||
pmiddend = "Philipp Middendorf <pmidden@secure.mailbox.org>";
|
|
||||||
polyrod = "Maurizio Di Pietro <dc1mdp@gmail.com>";
|
|
||||||
pradeepchhetri = "Pradeep Chhetri <pradeep.chhetri89@gmail.com>";
|
|
||||||
prikhi = "Pavan Rikhi <pavan.rikhi@gmail.com>";
|
|
||||||
primeos = "Michael Weiss <dev.primeos@gmail.com>";
|
|
||||||
profpatsch = "Profpatsch <mail@profpatsch.de>";
|
|
||||||
proglodyte = "Proglodyte <proglodyte23@gmail.com>";
|
|
||||||
pshendry = "Paul Hendry <paul@pshendry.com>";
|
|
||||||
psibi = "Sibi <sibi@psibi.in>";
|
|
||||||
pstn = "Philipp Steinpaß <philipp@xndr.de>";
|
|
||||||
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
|
|
||||||
puffnfresh = "Brian McKenna <brian@brianmckenna.org>";
|
|
||||||
pxc = "Patrick Callahan <patrick.callahan@latitudeengineering.com>";
|
|
||||||
qknight = "Joachim Schiele <js@lastlog.de>";
|
|
||||||
ragge = "Ragnar Dahlen <r.dahlen@gmail.com>";
|
|
||||||
ralith = "Benjamin Saunders <ben.e.saunders@gmail.com>";
|
|
||||||
ramkromberg = "Ram Kromberg <ramkromberg@mail.com>";
|
|
||||||
rardiol = "Ricardo Ardissone <ricardo.ardissone@gmail.com>";
|
|
||||||
rasendubi = "Alexey Shmalko <rasen.dubi@gmail.com>";
|
|
||||||
raskin = "Michael Raskin <7c6f434c@mail.ru>";
|
|
||||||
ravloony = "Tom Macdonald <ravloony@gmail.com>";
|
|
||||||
rbasso = "Rafael Basso <rbasso@sharpgeeks.net>";
|
|
||||||
redbaron = "Maxim Ivanov <ivanov.maxim@gmail.com>";
|
|
||||||
redvers = "Redvers Davies <red@infect.me>";
|
|
||||||
refnil = "Martin Lavoie <broemartino@gmail.com>";
|
|
||||||
regnat = "Théophane Hufschmitt <regnat@regnat.ovh>";
|
|
||||||
relrod = "Ricky Elrod <ricky@elrod.me>";
|
|
||||||
renzo = "Renzo Carbonara <renzocarbonara@gmail.com>";
|
|
||||||
retrry = "Tadas Barzdžius <retrry@gmail.com>";
|
|
||||||
rht = "rht <rhtbot@protonmail.com>";
|
|
||||||
richardipsum = "Richard Ipsum <richardipsum@fastmail.co.uk>";
|
|
||||||
rick68 = "Wei-Ming Yang <rick68@gmail.com>";
|
|
||||||
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
|
||||||
ris = "Robert Scott <code@humanleg.org.uk>";
|
|
||||||
rlupton20 = "Richard Lupton <richard.lupton@gmail.com>";
|
|
||||||
rnhmjoj = "Michele Guerini Rocco <micheleguerinirocco@me.com>";
|
|
||||||
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
|
|
||||||
robberer = "Longrin Wischnewski <robberer@freakmail.de>";
|
|
||||||
robbinch = "Robbin C. <robbinch33@gmail.com>";
|
|
||||||
roberth = "Robert Hensing <nixpkgs@roberthensing.nl>";
|
|
||||||
robertodr = "Roberto Di Remigio <roberto.diremigio@gmail.com>";
|
|
||||||
robgssp = "Rob Glossop <robgssp@gmail.com>";
|
|
||||||
roblabla = "Robin Lambertz <robinlambertz+dev@gmail.com>";
|
|
||||||
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
|
|
||||||
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
|
|
||||||
rongcuid = "Rongcui Dong <rongcuid@outlook.com>";
|
|
||||||
rszibele = "Richard Szibele <richard@szibele.com>";
|
|
||||||
rtreffer = "Rene Treffer <treffer+nixos@measite.de>";
|
|
||||||
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
|
|
||||||
rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>";
|
|
||||||
rvlander = "Gaëtan André <rvlander@gaetanandre.eu>";
|
|
||||||
rvolosatovs = "Roman Volosatovs <rvolosatovs@riseup.net";
|
|
||||||
ryanartecona = "Ryan Artecona <ryanartecona@gmail.com>";
|
|
||||||
ryansydnor = "Ryan Sydnor <ryan.t.sydnor@gmail.com>";
|
|
||||||
ryantm = "Ryan Mulligan <ryan@ryantm.com>";
|
|
||||||
rybern = "Ryan Bernstein <ryan.bernstein@columbia.edu>";
|
|
||||||
rycee = "Robert Helgesson <robert@rycee.net>";
|
|
||||||
ryneeverett = "Ryne Everett <ryneeverett@gmail.com>";
|
|
||||||
rzetterberg = "Richard Zetterberg <richard.zetterberg@gmail.com>";
|
|
||||||
s1lvester = "Markus Silvester <s1lvester@bockhacker.me>";
|
|
||||||
samdroid-apps = "Sam Parkinson <sam@sam.today>";
|
|
||||||
samuelrivas = "Samuel Rivas <samuelrivas@gmail.com>";
|
|
||||||
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
|
|
||||||
sargon = "Daniel Ehlers <danielehlers@mindeye.net>";
|
|
||||||
sauyon = "Sauyon Lee <s@uyon.co>";
|
|
||||||
schmitthenner = "Fabian Schmitthenner <development@schmitthenner.eu>";
|
|
||||||
schneefux = "schneefux <schneefux+nixos_pkg@schneefux.xyz>";
|
|
||||||
schristo = "Scott Christopher <schristopher@konputa.com>";
|
|
||||||
scolobb = "Sergiu Ivanov <sivanov@colimite.fr>";
|
|
||||||
sdll = "Sasha Illarionov <sasha.delly@gmail.com>";
|
|
||||||
SeanZicari = "Sean Zicari <sean.zicari@gmail.com>";
|
|
||||||
sepi = "Raffael Mancini <raffael@mancini.lu>";
|
|
||||||
seppeljordan = "Sebastian Jordan <sebastian.jordan.mail@googlemail.com>";
|
|
||||||
shanemikel = "Shane Pearlman <shanemikel1@gmail.com>";
|
|
||||||
shawndellysse = "Shawn Dellysse <sdellysse@gmail.com>";
|
|
||||||
sheenobu = "Sheena Artrip <sheena.artrip@gmail.com>";
|
|
||||||
sheganinans = "Aistis Raulinaitis <sheganinans@gmail.com>";
|
|
||||||
shell = "Shell Turner <cam.turn@gmail.com>";
|
|
||||||
shlevy = "Shea Levy <shea@shealevy.com>";
|
|
||||||
siddharthist = "Langston Barrett <langston.barrett@gmail.com>";
|
|
||||||
sifmelcara = "Ming Chuan <ming@culpring.com>";
|
|
||||||
sigma = "Yann Hodique <yann.hodique@gmail.com>";
|
|
||||||
simonvandel = "Simon Vandel Sillesen <simon.vandel@gmail.com>";
|
|
||||||
sivteck = "Sivaram Balakrishnan <sivaram1992@gmail.com>";
|
|
||||||
sjagoe = "Simon Jagoe <simon@simonjagoe.com>";
|
|
||||||
sjmackenzie = "Stewart Mackenzie <setori88@gmail.com>";
|
|
||||||
sjourdois = "Stéphane ‘kwisatz’ Jourdois <sjourdois@gmail.com>";
|
|
||||||
skeidel = "Sven Keidel <svenkeidel@gmail.com>";
|
|
||||||
skrzyp = "Jakub Skrzypnik <jot.skrzyp@gmail.com>";
|
|
||||||
sleexyz = "Sean Lee <freshdried@gmail.com>";
|
|
||||||
smironov = "Sergey Mironov <grrwlf@gmail.com>";
|
|
||||||
snyh = "Xia Bin <snyh@snyh.org>";
|
|
||||||
solson = "Scott Olson <scott@solson.me>";
|
|
||||||
sorpaas = "Wei Tang <hi@that.world>";
|
|
||||||
sorki = "Richard Marko <srk@48.io>";
|
|
||||||
spacefrogg = "Michael Raitza <spacefrogg-nixos@meterriblecrew.net>";
|
|
||||||
spencerjanssen = "Spencer Janssen <spencerjanssen@gmail.com>";
|
|
||||||
spinus = "Tomasz Czyż <tomasz.czyz@gmail.com>";
|
|
||||||
sprock = "Roger Mason <rmason@mun.ca>";
|
|
||||||
spwhitt = "Spencer Whitt <sw@swhitt.me>";
|
|
||||||
srhb = "Sarah Brofeldt <sbrofeldt@gmail.com>";
|
|
||||||
SShrike = "Severen Redwood <severen@shrike.me>";
|
|
||||||
stephenmw = "Stephen Weinberg <stephen@q5comm.com>";
|
|
||||||
sternenseemann = "Lukas Epple <post@lukasepple.de>";
|
|
||||||
stesie = "Stefan Siegl <stesie@brokenpipe.de>";
|
|
||||||
steveej = "Stefan Junker <mail@stefanjunker.de>";
|
|
||||||
stumoss = "Stuart Moss <samoss@gmail.com>";
|
|
||||||
SuprDewd = "Bjarki Ágúst Guðmundsson <suprdewd@gmail.com>";
|
|
||||||
swarren83 = "Shawn Warren <shawn.w.warren@gmail.com>";
|
|
||||||
swflint = "Samuel W. Flint <swflint@flintfam.org>";
|
|
||||||
swistak35 = "Rafał Łasocha <me@swistak35.com>";
|
|
||||||
symphorien = "Guillaume Girol <symphorien_nixpkgs@xlumurb.eu>";
|
|
||||||
szczyp = "Szczyp <qb@szczyp.com>";
|
|
||||||
sztupi = "Attila Sztupak <attila.sztupak@gmail.com>";
|
|
||||||
taeer = "Taeer Bar-Yam <taeer@necsi.edu>";
|
|
||||||
tailhook = "Paul Colomiets <paul@colomiets.name>";
|
|
||||||
taketwo = "Sergey Alexandrov <alexandrov88@gmail.com>";
|
|
||||||
takikawa = "Asumu Takikawa <asumu@igalia.com>";
|
|
||||||
taktoa = "Remy Goldschmidt <taktoa@gmail.com>";
|
|
||||||
taku0 = "Takuo Yonezawa <mxxouy6x3m_github@tatapa.org>";
|
|
||||||
tari = "Peter Marheine <peter@taricorp.net>";
|
|
||||||
tavyc = "Octavian Cerna <octavian.cerna@gmail.com>";
|
|
||||||
TealG = "Teal Gaure <~@Teal.Gr>";
|
|
||||||
teh = "Tom Hunger <tehunger@gmail.com>";
|
|
||||||
telotortium = "Robert Irelan <rirelan@gmail.com>";
|
|
||||||
teto = "Matthieu Coudron <mcoudron@hotmail.com>";
|
|
||||||
tex = "Milan Svoboda <milan.svoboda@centrum.cz>";
|
|
||||||
thall = "Niclas Thall <niclas.thall@gmail.com>";
|
|
||||||
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
|
|
||||||
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
|
|
||||||
theuni = "Christian Theune <ct@flyingcircus.io>";
|
|
||||||
ThomasMader = "Thomas Mader <thomas.mader@gmail.com>";
|
|
||||||
thoughtpolice = "Austin Seipp <aseipp@pobox.com>";
|
|
||||||
timbertson = "Tim Cuthbertson <tim@gfxmonk.net>";
|
|
||||||
timokau = "Timo Kaufmann <timokau@zoho.com>";
|
|
||||||
titanous = "Jonathan Rudenberg <jonathan@titanous.com>";
|
|
||||||
tnias = "Philipp Bartsch <phil@grmr.de>";
|
|
||||||
tohl = "Tomas Hlavaty <tom@logand.com>";
|
|
||||||
tokudan = "Daniel Frank <git@danielfrank.net>";
|
|
||||||
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
|
|
||||||
tomsmeets = "Tom Smeets <tom@tsmeets.nl>";
|
|
||||||
travisbhartwell = "Travis B. Hartwell <nafai@travishartwell.net>";
|
|
||||||
trevorj = "Trevor Joynson <nix@trevor.joynson.io>";
|
|
||||||
trino = "Hubert Mühlhans <muehlhans.hubert@ekodia.de>";
|
|
||||||
tstrobel = "Thomas Strobel <4ZKTUB6TEP74PYJOPWIR013S2AV29YUBW5F9ZH2F4D5UMJUJ6S@hash.domains>";
|
|
||||||
ttuegel = "Thomas Tuegel <ttuegel@mailbox.org>";
|
|
||||||
tv = "Tomislav Viljetić <tv@shackspace.de>";
|
|
||||||
tvestelind = "Tomas Vestelind <tomas.vestelind@fripost.org>";
|
|
||||||
tvorog = "Marsel Zaripov <marszaripov@gmail.com>";
|
|
||||||
tweber = "Thorsten Weber <tw+nixpkgs@360vier.de>";
|
|
||||||
twey = "James ‘Twey’ Kay <twey@twey.co.uk>";
|
|
||||||
uralbash = "Svintsov Dmitry <root@uralbash.ru>";
|
|
||||||
utdemir = "Utku Demir <me@utdemir.com>";
|
|
||||||
#urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>"; inactive since 2012
|
|
||||||
uwap = "uwap <me@uwap.name>";
|
|
||||||
vaibhavsagar = "Vaibhav Sagar <vaibhavsagar@gmail.com>";
|
|
||||||
valeriangalliat = "Valérian Galliat <val@codejam.info>";
|
|
||||||
vandenoever = "Jos van den Oever <jos@vandenoever.info>";
|
|
||||||
vanschelven = "Klaas van Schelven <klaas@vanschelven.com>";
|
|
||||||
vanzef = "Ivan Solyankin <vanzef@gmail.com>";
|
|
||||||
vbgl = "Vincent Laporte <Vincent.Laporte@gmail.com>";
|
|
||||||
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
|
|
||||||
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
|
|
||||||
vdemeester = "Vincent Demeester <vincent@sbr.pm>";
|
|
||||||
veprbl = "Dmitry Kalinkin <veprbl@gmail.com>";
|
|
||||||
vifino = "Adrian Pistol <vifino@tty.sh>";
|
|
||||||
vinymeuh = "VinyMeuh <vinymeuh@gmail.com>";
|
|
||||||
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
|
||||||
vizanto = "Danny Wilson <danny@prime.vc>";
|
|
||||||
vklquevs = "vklquevs <vklquevs@gmail.com>";
|
|
||||||
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
|
||||||
vmandela = "Venkateswara Rao Mandela <venkat.mandela@gmail.com>";
|
|
||||||
vmchale = "Vanessa McHale <tmchale@wisc.edu>";
|
|
||||||
volhovm = "Mikhail Volkhov <volhovm.cs@gmail.com>";
|
|
||||||
volth = "Jaroslavas Pocepko <jaroslavas@volth.com>";
|
|
||||||
vozz = "Oliver Hunt <oliver.huntuk@gmail.com>";
|
|
||||||
vrthra = "Rahul Gopinath <rahul@gopinath.org>";
|
|
||||||
vyp = "vyp <elisp.vim@gmail.com>";
|
|
||||||
wedens = "wedens <kirill.wedens@gmail.com>";
|
|
||||||
willibutz = "Willi Butz <willibutz@posteo.de>";
|
|
||||||
willtim = "Tim Philip Williams <tim.williams.public@gmail.com>";
|
|
||||||
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
|
|
||||||
wizeman = "Ricardo M. Correia <rcorreia@wizy.org>";
|
|
||||||
wjlroe = "William Roe <willroe@gmail.com>";
|
|
||||||
wkennington = "William A. Kennington III <william@wkennington.com>";
|
|
||||||
wmertens = "Wout Mertens <Wout.Mertens@gmail.com>";
|
|
||||||
woffs = "Frank Doepper <github@woffs.de>";
|
|
||||||
womfoo = "Kranium Gikos Mendoza <kranium@gikos.net>";
|
|
||||||
wscott = "Wayne Scott <wsc9tt@gmail.com>";
|
|
||||||
wyvie = "Elijah Rum <elijahrum@gmail.com>";
|
|
||||||
xnwdd = "Guillermo NWDD <nwdd+nixos@no.team>";
|
|
||||||
xvapx = "Marti Serra <marti.serra.coscollano@gmail.com>";
|
|
||||||
xwvvvvwx = "David Terry <davidterry@posteo.de>";
|
|
||||||
xzfc = "Albert Safin <xzfcpw@gmail.com>";
|
|
||||||
yarr = "Dmitry V. <savraz@gmail.com>";
|
|
||||||
yegortimoshenko = "Yegor Timoshenko <yegortimoshenko@gmail.com>";
|
|
||||||
ylwghst = "Burim Augustin Berisa <ylwghst@onionmail.info>";
|
|
||||||
yochai = "Yochai <yochai@titat.info>";
|
|
||||||
yorickvp = "Yorick van Pelt <yorickvanpelt@gmail.com>";
|
|
||||||
yuriaisaka = "Yuri Aisaka <yuri.aisaka+nix@gmail.com>";
|
|
||||||
yurrriq = "Eric Bailey <eric@ericb.me>";
|
|
||||||
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
|
||||||
zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
|
|
||||||
zalakain = "Unai Zalakain <contact@unaizalakain.info>";
|
|
||||||
zarelit = "David Costa <david@zarel.net>";
|
|
||||||
zauberpony = "Elmar Athmer <elmar@athmer.org>";
|
|
||||||
zef = "Zef Hemel <zef@zef.me>";
|
|
||||||
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
|
|
||||||
Zimmi48 = "Théo Zimmermann <theo.zimmermann@univ-paris-diderot.fr>";
|
|
||||||
zohl = "Al Zohali <zohl@fmap.me>";
|
|
||||||
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
|
|
||||||
zraexy = "David Mell <zraexy@gmail.com>";
|
|
||||||
zx2c4 = "Jason A. Donenfeld <Jason@zx2c4.com>";
|
|
||||||
zzamboni = "Diego Zamboni <diego@zzamboni.org>";
|
|
||||||
}
|
|
19
lib/meta.nix
19
lib/meta.nix
@ -67,4 +67,23 @@ rec {
|
|||||||
*/
|
*/
|
||||||
hiPrioSet = set: mapDerivationAttrset hiPrio set;
|
hiPrioSet = set: mapDerivationAttrset hiPrio set;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check to see if a platform is matched by the given `meta.platforms`
|
||||||
|
element.
|
||||||
|
|
||||||
|
A `meta.platform` pattern is either
|
||||||
|
|
||||||
|
1. (legacy) a system string.
|
||||||
|
|
||||||
|
2. (modern) a pattern for the platform `parsed` field.
|
||||||
|
|
||||||
|
We can inject these into a patten for the whole of a structured platform,
|
||||||
|
and then match that.
|
||||||
|
*/
|
||||||
|
platformMatch = platform: elem: let
|
||||||
|
pattern =
|
||||||
|
if builtins.isString elem
|
||||||
|
then { system = elem; }
|
||||||
|
else { parsed = elem; };
|
||||||
|
in lib.matchAttrs pattern platform;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ rec {
|
|||||||
# a module will resolve strictly the attributes used as argument but
|
# a module will resolve strictly the attributes used as argument but
|
||||||
# not their values. The values are forwarding the result of the
|
# not their values. The values are forwarding the result of the
|
||||||
# evaluation of the option.
|
# evaluation of the option.
|
||||||
requiredArgs = builtins.attrNames (builtins.functionArgs f);
|
requiredArgs = builtins.attrNames (lib.functionArgs f);
|
||||||
context = name: ''while evaluating the module argument `${name}' in "${key}":'';
|
context = name: ''while evaluating the module argument `${name}' in "${key}":'';
|
||||||
extraArgs = builtins.listToAttrs (map (name: {
|
extraArgs = builtins.listToAttrs (map (name: {
|
||||||
inherit name;
|
inherit name;
|
||||||
|
@ -14,6 +14,7 @@ rec {
|
|||||||
, defaultText ? null # Textual representation of the default, for in the manual.
|
, defaultText ? null # Textual representation of the default, for in the manual.
|
||||||
, example ? null # Example value used in the manual.
|
, example ? null # Example value used in the manual.
|
||||||
, description ? null # String describing the option.
|
, 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.
|
, type ? null # Option type, providing type-checking and value merging.
|
||||||
, apply ? null # Function that converts the option value to something else.
|
, apply ? null # Function that converts the option value to something else.
|
||||||
, internal ? null # Whether the option is for NixOS developers only.
|
, internal ? null # Whether the option is for NixOS developers only.
|
||||||
@ -76,7 +77,6 @@ rec {
|
|||||||
getValues = map (x: x.value);
|
getValues = map (x: x.value);
|
||||||
getFiles = map (x: x.file);
|
getFiles = map (x: x.file);
|
||||||
|
|
||||||
|
|
||||||
# Generate documentation template from the list of option declaration like
|
# Generate documentation template from the list of option declaration like
|
||||||
# the set generated with filterOptionSets.
|
# the set generated with filterOptionSets.
|
||||||
optionAttrSetToDocList = optionAttrSetToDocList' [];
|
optionAttrSetToDocList = optionAttrSetToDocList' [];
|
||||||
@ -85,6 +85,7 @@ rec {
|
|||||||
concatMap (opt:
|
concatMap (opt:
|
||||||
let
|
let
|
||||||
docOption = rec {
|
docOption = rec {
|
||||||
|
loc = opt.loc;
|
||||||
name = showOption opt.loc;
|
name = showOption opt.loc;
|
||||||
description = opt.description or (throw "Option `${name}' has no description.");
|
description = opt.description or (throw "Option `${name}' has no description.");
|
||||||
declarations = filter (x: x != unknownModule) opt.declarations;
|
declarations = filter (x: x != unknownModule) opt.declarations;
|
||||||
@ -93,9 +94,10 @@ rec {
|
|||||||
readOnly = opt.readOnly or false;
|
readOnly = opt.readOnly or false;
|
||||||
type = opt.type.description or null;
|
type = opt.type.description or null;
|
||||||
}
|
}
|
||||||
// (if opt ? example then { example = scrubOptionValue opt.example; } else {})
|
// optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; }
|
||||||
// (if opt ? default then { default = scrubOptionValue opt.default; } else {})
|
// optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }
|
||||||
// (if opt ? defaultText then { default = opt.defaultText; } else {});
|
// optionalAttrs (opt ? defaultText) { default = opt.defaultText; }
|
||||||
|
// optionalAttrs (opt ? relatedPackages && opt.relatedPackages != null) { inherit (opt) relatedPackages; };
|
||||||
|
|
||||||
subOptions =
|
subOptions =
|
||||||
let ss = opt.type.getSubOptions opt.loc;
|
let ss = opt.type.getSubOptions opt.loc;
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
{ lib }:
|
|
||||||
with lib.strings;
|
|
||||||
|
|
||||||
/* Helpers for creating lisp S-exprs for the Apple sandbox
|
|
||||||
|
|
||||||
lib.sandbox.allowFileRead [ "/usr/bin/file" ];
|
|
||||||
# => "(allow file-read* (literal \"/usr/bin/file\"))";
|
|
||||||
|
|
||||||
lib.sandbox.allowFileRead {
|
|
||||||
literal = [ "/usr/bin/file" ];
|
|
||||||
subpath = [ "/usr/lib/system" ];
|
|
||||||
}
|
|
||||||
# => "(allow file-read* (literal \"/usr/bin/file\") (subpath \"/usr/lib/system\"))"
|
|
||||||
*/
|
|
||||||
|
|
||||||
let
|
|
||||||
|
|
||||||
sexp = tokens: "(" + builtins.concatStringsSep " " tokens + ")";
|
|
||||||
generateFileList = files:
|
|
||||||
if builtins.isList files
|
|
||||||
then concatMapStringsSep " " (x: sexp [ "literal" ''"${x}"'' ]) files
|
|
||||||
else if builtins.isString files
|
|
||||||
then generateFileList [ files ]
|
|
||||||
else concatStringsSep " " (
|
|
||||||
(map (x: sexp [ "literal" ''"${x}"'' ]) (files.literal or [])) ++
|
|
||||||
(map (x: sexp [ "subpath" ''"${x}"'' ]) (files.subpath or []))
|
|
||||||
);
|
|
||||||
applyToFiles = f: act: files: f "${act} ${generateFileList files}";
|
|
||||||
genActions = actionName: let
|
|
||||||
action = feature: sexp [ actionName feature ];
|
|
||||||
self = {
|
|
||||||
"${actionName}" = action;
|
|
||||||
"${actionName}File" = applyToFiles action "file*";
|
|
||||||
"${actionName}FileRead" = applyToFiles action "file-read*";
|
|
||||||
"${actionName}FileReadMetadata" = applyToFiles action "file-read-metadata";
|
|
||||||
"${actionName}DirectoryList" = self."${actionName}FileReadMetadata";
|
|
||||||
"${actionName}FileWrite" = applyToFiles action "file-write*";
|
|
||||||
"${actionName}FileWriteMetadata" = applyToFiles action "file-write-metadata";
|
|
||||||
};
|
|
||||||
in self;
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
genActions "allow" // genActions "deny" // {
|
|
||||||
importProfile = derivation: ''
|
|
||||||
(import "${derivation}")
|
|
||||||
'';
|
|
||||||
}
|
|
@ -26,14 +26,35 @@ rec {
|
|||||||
(type == "symlink" && lib.hasPrefix "result" baseName)
|
(type == "symlink" && lib.hasPrefix "result" baseName)
|
||||||
);
|
);
|
||||||
|
|
||||||
cleanSource = builtins.filterSource cleanSourceFilter;
|
cleanSource = src: cleanSourceWith { filter = cleanSourceFilter; inherit src; };
|
||||||
|
|
||||||
|
# Like `builtins.filterSource`, except it will compose with itself,
|
||||||
|
# allowing you to chain multiple calls together without any
|
||||||
|
# intermediate copies being put in the nix store.
|
||||||
|
#
|
||||||
|
# lib.cleanSourceWith f (lib.cleanSourceWith g ./.) # Succeeds!
|
||||||
|
# builtins.filterSource f (builtins.filterSource g ./.) # Fails!
|
||||||
|
cleanSourceWith = { filter, src }:
|
||||||
|
let
|
||||||
|
isFiltered = src ? _isLibCleanSourceWith;
|
||||||
|
origSrc = if isFiltered then src.origSrc else src;
|
||||||
|
filter' = if isFiltered then name: type: filter name type && src.filter name type else filter;
|
||||||
|
in {
|
||||||
|
inherit origSrc;
|
||||||
|
filter = filter';
|
||||||
|
outPath = builtins.filterSource filter' origSrc;
|
||||||
|
_isLibCleanSourceWith = true;
|
||||||
|
};
|
||||||
|
|
||||||
# Filter sources by a list of regular expressions.
|
# Filter sources by a list of regular expressions.
|
||||||
#
|
#
|
||||||
# E.g. `src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]`
|
# E.g. `src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]`
|
||||||
sourceByRegex = src: regexes: builtins.filterSource (path: type:
|
sourceByRegex = src: regexes: cleanSourceWith {
|
||||||
let relPath = lib.removePrefix (toString src + "/") (toString path);
|
filter = (path: type:
|
||||||
in lib.any (re: builtins.match re relPath != null) regexes) src;
|
let relPath = lib.removePrefix (toString src + "/") (toString path);
|
||||||
|
in lib.any (re: builtins.match re relPath != null) regexes);
|
||||||
|
inherit src;
|
||||||
|
};
|
||||||
|
|
||||||
# Get all files ending with the specified suffices from the given
|
# Get all files ending with the specified suffices from the given
|
||||||
# directory or its descendants. E.g. `sourceFilesBySuffices ./dir
|
# directory or its descendants. E.g. `sourceFilesBySuffices ./dir
|
||||||
@ -42,7 +63,7 @@ rec {
|
|||||||
let filter = name: type:
|
let filter = name: type:
|
||||||
let base = baseNameOf (toString name);
|
let base = baseNameOf (toString name);
|
||||||
in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
|
in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
|
||||||
in builtins.filterSource filter path;
|
in cleanSourceWith { inherit filter; src = path; };
|
||||||
|
|
||||||
|
|
||||||
# Get the commit id of a git repo
|
# Get the commit id of a git repo
|
||||||
@ -72,4 +93,8 @@ rec {
|
|||||||
else lib.head matchRef
|
else lib.head matchRef
|
||||||
else throw ("Not a .git directory: " + path);
|
else throw ("Not a .git directory: " + path);
|
||||||
in lib.flip readCommitFromFile "HEAD";
|
in lib.flip readCommitFromFile "HEAD";
|
||||||
|
|
||||||
|
pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir);
|
||||||
|
|
||||||
|
canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
|
||||||
}
|
}
|
||||||
|
@ -219,6 +219,14 @@ rec {
|
|||||||
*/
|
*/
|
||||||
escapeShellArgs = concatMapStringsSep " " escapeShellArg;
|
escapeShellArgs = concatMapStringsSep " " escapeShellArg;
|
||||||
|
|
||||||
|
/* Turn a string into a Nix expression representing that 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 (
|
replaceChars = builtins.replaceStrings or (
|
||||||
del: new: s:
|
del: new: s:
|
||||||
@ -429,6 +437,13 @@ rec {
|
|||||||
*/
|
*/
|
||||||
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
|
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
|
||||||
|
|
||||||
|
/* Check whether a value can be coerced to a string */
|
||||||
|
isCoercibleToString = x:
|
||||||
|
builtins.elem (builtins.typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
|
||||||
|
(builtins.isList x && lib.all isCoercibleToString x) ||
|
||||||
|
x ? outPath ||
|
||||||
|
x ? __toString;
|
||||||
|
|
||||||
/* Check whether a value is a store path.
|
/* Check whether a value is a store path.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -442,7 +457,7 @@ rec {
|
|||||||
=> false
|
=> false
|
||||||
*/
|
*/
|
||||||
isStorePath = x:
|
isStorePath = x:
|
||||||
builtins.isString x
|
isCoercibleToString x
|
||||||
&& builtins.substring 0 1 (toString x) == "/"
|
&& builtins.substring 0 1 (toString x) == "/"
|
||||||
&& dirOf (builtins.toPath x) == builtins.storeDir;
|
&& dirOf (builtins.toPath x) == builtins.storeDir;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
rec {
|
rec {
|
||||||
doubles = import ./doubles.nix { inherit lib; };
|
doubles = import ./doubles.nix { inherit lib; };
|
||||||
|
forMeta = import ./for-meta.nix { inherit lib; };
|
||||||
parse = import ./parse.nix { inherit lib; };
|
parse = import ./parse.nix { inherit lib; };
|
||||||
inspect = import ./inspect.nix { inherit lib; };
|
inspect = import ./inspect.nix { inherit lib; };
|
||||||
platforms = import ./platforms.nix { inherit lib; };
|
platforms = import ./platforms.nix { inherit lib; };
|
||||||
@ -23,12 +24,15 @@ rec {
|
|||||||
config = parse.tripleFromSystem final.parsed;
|
config = parse.tripleFromSystem final.parsed;
|
||||||
# Just a guess, based on `system`
|
# Just a guess, based on `system`
|
||||||
platform = platforms.selectBySystem final.system;
|
platform = platforms.selectBySystem final.system;
|
||||||
|
# Derived meta-data
|
||||||
libc =
|
libc =
|
||||||
/**/ if final.isDarwin then "libSystem"
|
/**/ if final.isDarwin then "libSystem"
|
||||||
else if final.isMinGW then "msvcrt"
|
else if final.isMinGW then "msvcrt"
|
||||||
else if final.isLinux then "glibc"
|
else if final.isMusl then "musl"
|
||||||
|
else if final.isAndroid then "bionic"
|
||||||
|
else if final.isLinux /* default */ then "glibc"
|
||||||
# TODO(@Ericson2314) think more about other operating systems
|
# TODO(@Ericson2314) think more about other operating systems
|
||||||
else "native/impure";
|
else "native/impure";
|
||||||
extensions = {
|
extensions = {
|
||||||
sharedLibrary =
|
sharedLibrary =
|
||||||
/**/ if final.isDarwin then ".dylib"
|
/**/ if final.isDarwin then ".dylib"
|
||||||
@ -38,7 +42,10 @@ rec {
|
|||||||
/**/ if final.isWindows then ".exe"
|
/**/ if final.isWindows then ".exe"
|
||||||
else "";
|
else "";
|
||||||
};
|
};
|
||||||
|
# Misc boolean options
|
||||||
|
useAndroidPrebuilt = false;
|
||||||
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
||||||
// args;
|
// args;
|
||||||
in final;
|
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
||||||
|
final;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
{ lib }:
|
{ lib }:
|
||||||
let
|
let
|
||||||
inherit (lib) lists;
|
inherit (lib) lists;
|
||||||
parse = import ./parse.nix { inherit lib; };
|
inherit (lib.systems) parse;
|
||||||
inherit (import ./inspect.nix { inherit lib; }) predicates;
|
inherit (lib.systems.inspect) predicates;
|
||||||
inherit (lib.attrsets) matchAttrs;
|
inherit (lib.attrsets) matchAttrs;
|
||||||
|
|
||||||
all = [
|
all = [
|
||||||
"aarch64-linux"
|
"aarch64-linux"
|
||||||
"armv5tel-linux" "armv6l-linux" "armv7l-linux"
|
"armv5tel-linux" "armv6l-linux" "armv7l-linux"
|
||||||
|
|
||||||
"mips64el-linux"
|
"mipsel-linux"
|
||||||
|
|
||||||
"i686-cygwin" "i686-freebsd" "i686-linux" "i686-netbsd" "i686-openbsd"
|
"i686-cygwin" "i686-freebsd" "i686-linux" "i686-netbsd" "i686-openbsd"
|
||||||
|
|
||||||
@ -24,19 +24,20 @@ let
|
|||||||
in rec {
|
in rec {
|
||||||
inherit all;
|
inherit all;
|
||||||
|
|
||||||
allBut = platforms: lists.filter (x: !(builtins.elem x platforms)) all;
|
|
||||||
none = [];
|
none = [];
|
||||||
|
|
||||||
arm = filterDoubles predicates.isArm;
|
arm = filterDoubles predicates.isArm;
|
||||||
|
aarch64 = filterDoubles predicates.isAarch64;
|
||||||
|
x86 = filterDoubles predicates.isx86;
|
||||||
i686 = filterDoubles predicates.isi686;
|
i686 = filterDoubles predicates.isi686;
|
||||||
mips = filterDoubles predicates.isMips;
|
|
||||||
x86_64 = filterDoubles predicates.isx86_64;
|
x86_64 = filterDoubles predicates.isx86_64;
|
||||||
|
mips = filterDoubles predicates.isMips;
|
||||||
|
|
||||||
cygwin = filterDoubles predicates.isCygwin;
|
cygwin = filterDoubles predicates.isCygwin;
|
||||||
darwin = filterDoubles predicates.isDarwin;
|
darwin = filterDoubles predicates.isDarwin;
|
||||||
freebsd = filterDoubles predicates.isFreeBSD;
|
freebsd = filterDoubles predicates.isFreeBSD;
|
||||||
# Should be better, but MinGW is unclear, and HURD is bit-rotted.
|
# Should be better, but MinGW is unclear, and HURD is bit-rotted.
|
||||||
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; });
|
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; });
|
||||||
illumos = filterDoubles predicates.isSunOS;
|
illumos = filterDoubles predicates.isSunOS;
|
||||||
linux = filterDoubles predicates.isLinux;
|
linux = filterDoubles predicates.isLinux;
|
||||||
netbsd = filterDoubles predicates.isNetBSD;
|
netbsd = filterDoubles predicates.isNetBSD;
|
||||||
|
@ -11,84 +11,78 @@ rec {
|
|||||||
|
|
||||||
sheevaplug = rec {
|
sheevaplug = rec {
|
||||||
config = "armv5tel-unknown-linux-gnueabi";
|
config = "armv5tel-unknown-linux-gnueabi";
|
||||||
bigEndian = false;
|
|
||||||
arch = "armv5tel";
|
arch = "armv5tel";
|
||||||
float = "soft";
|
float = "soft";
|
||||||
withTLS = true;
|
|
||||||
libc = "glibc";
|
|
||||||
platform = platforms.sheevaplug;
|
platform = platforms.sheevaplug;
|
||||||
openssl.system = "linux-generic32";
|
|
||||||
inherit (platform) gcc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
raspberryPi = rec {
|
raspberryPi = rec {
|
||||||
config = "armv6l-unknown-linux-gnueabihf";
|
config = "armv6l-unknown-linux-gnueabihf";
|
||||||
bigEndian = false;
|
|
||||||
arch = "armv6l";
|
arch = "armv6l";
|
||||||
float = "hard";
|
float = "hard";
|
||||||
fpu = "vfp";
|
fpu = "vfp";
|
||||||
withTLS = true;
|
|
||||||
libc = "glibc";
|
|
||||||
platform = platforms.raspberrypi;
|
platform = platforms.raspberrypi;
|
||||||
openssl.system = "linux-generic32";
|
|
||||||
inherit (platform) gcc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
armv7l-hf-multiplatform = rec {
|
armv7l-hf-multiplatform = rec {
|
||||||
config = "arm-unknown-linux-gnueabihf";
|
config = "arm-unknown-linux-gnueabihf";
|
||||||
bigEndian = false;
|
|
||||||
arch = "armv7-a";
|
arch = "armv7-a";
|
||||||
float = "hard";
|
float = "hard";
|
||||||
fpu = "vfpv3-d16";
|
fpu = "vfpv3-d16";
|
||||||
withTLS = true;
|
|
||||||
libc = "glibc";
|
|
||||||
platform = platforms.armv7l-hf-multiplatform;
|
platform = platforms.armv7l-hf-multiplatform;
|
||||||
openssl.system = "linux-generic32";
|
|
||||||
inherit (platform) gcc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
aarch64-multiplatform = rec {
|
aarch64-multiplatform = rec {
|
||||||
config = "aarch64-unknown-linux-gnu";
|
config = "aarch64-unknown-linux-gnu";
|
||||||
bigEndian = false;
|
|
||||||
arch = "aarch64";
|
arch = "aarch64";
|
||||||
withTLS = true;
|
|
||||||
libc = "glibc";
|
|
||||||
platform = platforms.aarch64-multiplatform;
|
platform = platforms.aarch64-multiplatform;
|
||||||
inherit (platform) gcc;
|
};
|
||||||
|
|
||||||
|
aarch64-android-prebuilt = rec {
|
||||||
|
config = "aarch64-unknown-linux-android";
|
||||||
|
arch = "aarch64";
|
||||||
|
platform = platforms.aarch64-multiplatform;
|
||||||
|
useAndroidPrebuilt = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
scaleway-c1 = armv7l-hf-multiplatform // rec {
|
scaleway-c1 = armv7l-hf-multiplatform // rec {
|
||||||
platform = platforms.scaleway-c1;
|
platform = platforms.scaleway-c1;
|
||||||
inherit (platform) gcc;
|
inherit (platform.gcc) fpu;
|
||||||
inherit (gcc) fpu;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pogoplug4 = rec {
|
pogoplug4 = rec {
|
||||||
arch = "armv5tel";
|
arch = "armv5tel";
|
||||||
config = "armv5tel-softfloat-linux-gnueabi";
|
config = "armv5tel-unknown-linux-gnueabi";
|
||||||
float = "soft";
|
float = "soft";
|
||||||
|
|
||||||
platform = platforms.pogoplug4;
|
platform = platforms.pogoplug4;
|
||||||
|
|
||||||
inherit (platform) gcc;
|
|
||||||
libc = "glibc";
|
|
||||||
|
|
||||||
withTLS = true;
|
|
||||||
openssl.system = "linux-generic32";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fuloongminipc = rec {
|
fuloongminipc = rec {
|
||||||
config = "mips64el-unknown-linux-gnu";
|
config = "mipsel-unknown-linux-gnu";
|
||||||
bigEndian = false;
|
|
||||||
arch = "mips";
|
arch = "mips";
|
||||||
float = "hard";
|
float = "hard";
|
||||||
withTLS = true;
|
|
||||||
libc = "glibc";
|
|
||||||
platform = platforms.fuloong2f_n32;
|
platform = platforms.fuloong2f_n32;
|
||||||
openssl.system = "linux-generic32";
|
|
||||||
inherit (platform) gcc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
muslpi = raspberryPi // {
|
||||||
|
config = "armv6l-unknown-linux-musleabihf";
|
||||||
|
};
|
||||||
|
|
||||||
|
aarch64-multiplatform-musl = aarch64-multiplatform // {
|
||||||
|
config = "aarch64-unknown-linux-musl";
|
||||||
|
};
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Darwin
|
# Darwin
|
||||||
#
|
#
|
||||||
|
30
lib/systems/for-meta.nix
Normal file
30
lib/systems/for-meta.nix
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{ lib }:
|
||||||
|
let
|
||||||
|
inherit (lib.systems) parse;
|
||||||
|
inherit (lib.systems.inspect) patterns;
|
||||||
|
|
||||||
|
in rec {
|
||||||
|
all = [ {} ]; # `{}` matches anything
|
||||||
|
none = [];
|
||||||
|
|
||||||
|
arm = [ patterns.isArm ];
|
||||||
|
aarch64 = [ patterns.isAarch64 ];
|
||||||
|
x86 = [ patterns.isx86 ];
|
||||||
|
i686 = [ patterns.isi686 ];
|
||||||
|
x86_64 = [ patterns.isx86_64 ];
|
||||||
|
mips = [ patterns.isMips ];
|
||||||
|
|
||||||
|
cygwin = [ patterns.isCygwin ];
|
||||||
|
darwin = [ patterns.isDarwin ];
|
||||||
|
freebsd = [ patterns.isFreeBSD ];
|
||||||
|
# Should be better, but MinGW is unclear, and HURD is bit-rotted.
|
||||||
|
gnu = [ { kernel = parse.kernels.linux; abi = parse.abis.gnu; } ];
|
||||||
|
illumos = [ patterns.isSunOS ];
|
||||||
|
linux = [ patterns.isLinux ];
|
||||||
|
netbsd = [ patterns.isNetBSD ];
|
||||||
|
openbsd = [ patterns.isOpenBSD ];
|
||||||
|
unix = patterns.isUnix; # Actually a list
|
||||||
|
windows = [ patterns.isWindows ];
|
||||||
|
|
||||||
|
inherit (lib.systems.doubles) mesaPlatforms;
|
||||||
|
}
|
@ -5,38 +5,51 @@ with lib.lists;
|
|||||||
|
|
||||||
rec {
|
rec {
|
||||||
patterns = rec {
|
patterns = rec {
|
||||||
"32bit" = { cpu = { bits = 32; }; };
|
isi686 = { cpu = cpuTypes.i686; };
|
||||||
"64bit" = { cpu = { bits = 64; }; };
|
isx86_64 = { cpu = cpuTypes.x86_64; };
|
||||||
i686 = { cpu = cpuTypes.i686; };
|
isPowerPC = { cpu = cpuTypes.powerpc; };
|
||||||
x86_64 = { cpu = cpuTypes.x86_64; };
|
isx86 = { cpu = { family = "x86"; }; };
|
||||||
PowerPC = { cpu = cpuTypes.powerpc; };
|
isArm = { cpu = { family = "arm"; }; };
|
||||||
x86 = { cpu = { family = "x86"; }; };
|
isAarch64 = { cpu = { family = "aarch64"; }; };
|
||||||
Arm = { cpu = { family = "arm"; }; };
|
isMips = { cpu = { family = "mips"; }; };
|
||||||
Aarch64 = { cpu = { family = "aarch64"; }; };
|
isRiscV = { cpu = { family = "riscv"; }; };
|
||||||
Mips = { cpu = { family = "mips"; }; };
|
isWasm = { cpu = { family = "wasm"; }; };
|
||||||
BigEndian = { cpu = { significantByte = significantBytes.bigEndian; }; };
|
|
||||||
LittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
|
|
||||||
|
|
||||||
BSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
|
is32bit = { cpu = { bits = 32; }; };
|
||||||
Unix = [ BSD Darwin Linux SunOS Hurd Cygwin ];
|
is64bit = { cpu = { bits = 64; }; };
|
||||||
|
isBigEndian = { cpu = { significantByte = significantBytes.bigEndian; }; };
|
||||||
|
isLittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
|
||||||
|
|
||||||
Darwin = { kernel = kernels.darwin; };
|
isBSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
|
||||||
Linux = { kernel = kernels.linux; };
|
isDarwin = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
|
||||||
SunOS = { kernel = kernels.solaris; };
|
isUnix = [ isBSD isDarwin isLinux isSunOS isHurd isCygwin ];
|
||||||
FreeBSD = { kernel = kernels.freebsd; };
|
|
||||||
Hurd = { kernel = kernels.hurd; };
|
isMacOS = { kernel = kernels.macos; };
|
||||||
NetBSD = { kernel = kernels.netbsd; };
|
isiOS = { kernel = kernels.ios; };
|
||||||
OpenBSD = { kernel = kernels.openbsd; };
|
isLinux = { kernel = kernels.linux; };
|
||||||
Windows = { kernel = kernels.windows; };
|
isSunOS = { kernel = kernels.solaris; };
|
||||||
Cygwin = { kernel = kernels.windows; abi = abis.cygnus; };
|
isFreeBSD = { kernel = kernels.freebsd; };
|
||||||
MinGW = { kernel = kernels.windows; abi = abis.gnu; };
|
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; };
|
||||||
|
|
||||||
|
isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
|
||||||
|
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
|
||||||
|
|
||||||
|
isKexecable = map (family: { kernel = kernels.linux; cpu.family = family; })
|
||||||
|
[ "x86" "arm" "aarch64" "mips" ];
|
||||||
|
isEfi = map (family: { cpu.family = family; })
|
||||||
|
[ "x86" "arm" "aarch64" ];
|
||||||
|
isSeccomputable = map (family: { kernel = kernels.linux; cpu.family = family; })
|
||||||
|
[ "x86" "arm" "aarch64" "mips" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
matchAnyAttrs = patterns:
|
matchAnyAttrs = patterns:
|
||||||
if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
|
if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
|
||||||
else matchAttrs patterns;
|
else matchAttrs patterns;
|
||||||
|
|
||||||
predicates = mapAttrs'
|
predicates = mapAttrs (_: matchAnyAttrs) patterns;
|
||||||
(name: value: nameValuePair ("is" + name) (matchAnyAttrs value))
|
|
||||||
patterns;
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,16 @@
|
|||||||
# http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html especially
|
# http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html especially
|
||||||
# Triple::normalize. Parsing should essentially act as a more conservative
|
# Triple::normalize. Parsing should essentially act as a more conservative
|
||||||
# version of that last function.
|
# version of that last function.
|
||||||
|
#
|
||||||
|
# Most of the types below come in "open" and "closed" pairs. The open ones
|
||||||
|
# specify what information we need to know about systems in general, and the
|
||||||
|
# closed ones are sub-types representing the whitelist of systems we support in
|
||||||
|
# practice.
|
||||||
|
#
|
||||||
|
# Code in the remainder of nixpkgs shouldn't rely on the closed ones in
|
||||||
|
# e.g. exhaustive cases. Its more a sanity check to make sure nobody defines
|
||||||
|
# systems that overlap with existing ones and won't notice something amiss.
|
||||||
|
#
|
||||||
{ lib }:
|
{ lib }:
|
||||||
with lib.lists;
|
with lib.lists;
|
||||||
with lib.types;
|
with lib.types;
|
||||||
@ -11,29 +21,52 @@ with lib.attrsets;
|
|||||||
with (import ./inspect.nix { inherit lib; }).predicates;
|
with (import ./inspect.nix { inherit lib; }).predicates;
|
||||||
|
|
||||||
let
|
let
|
||||||
setTypesAssert = type: pred:
|
inherit (lib.options) mergeOneOption;
|
||||||
|
|
||||||
|
setTypes = type:
|
||||||
mapAttrs (name: value:
|
mapAttrs (name: value:
|
||||||
assert pred value;
|
assert type.check value;
|
||||||
setType type ({ inherit name; } // value));
|
setType type.name ({ inherit name; } // value));
|
||||||
setTypes = type: setTypesAssert type (_: true);
|
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
isSignificantByte = isType "significant-byte";
|
################################################################################
|
||||||
significantBytes = setTypes "significant-byte" {
|
|
||||||
|
types.openSignifiantByte = mkOptionType {
|
||||||
|
name = "significant-byte";
|
||||||
|
description = "Endianness";
|
||||||
|
merge = mergeOneOption;
|
||||||
|
};
|
||||||
|
|
||||||
|
types.significantByte = enum (attrValues significantBytes);
|
||||||
|
|
||||||
|
significantBytes = setTypes types.openSignifiantByte {
|
||||||
bigEndian = {};
|
bigEndian = {};
|
||||||
littleEndian = {};
|
littleEndian = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
isCpuType = isType "cpu-type";
|
################################################################################
|
||||||
cpuTypes = with significantBytes; setTypesAssert "cpu-type"
|
|
||||||
(x: elem x.bits [8 16 32 64 128]
|
# Reasonable power of 2
|
||||||
&& (if 8 < x.bits
|
types.bitWidth = enum [ 8 16 32 64 128 ];
|
||||||
then isSignificantByte x.significantByte
|
|
||||||
else !(x ? significantByte)))
|
################################################################################
|
||||||
{
|
|
||||||
|
types.openCpuType = mkOptionType {
|
||||||
|
name = "cpu-type";
|
||||||
|
description = "instruction set architecture name and information";
|
||||||
|
merge = mergeOneOption;
|
||||||
|
check = x: types.bitWidth.check x.bits
|
||||||
|
&& (if 8 < x.bits
|
||||||
|
then types.significantByte.check x.significantByte
|
||||||
|
else !(x ? significantByte));
|
||||||
|
};
|
||||||
|
|
||||||
|
types.cpuType = enum (attrValues cpuTypes);
|
||||||
|
|
||||||
|
cpuTypes = with significantBytes; setTypes types.openCpuType {
|
||||||
arm = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
arm = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
||||||
armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
||||||
armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
||||||
@ -42,20 +75,45 @@ rec {
|
|||||||
aarch64 = { bits = 64; significantByte = littleEndian; family = "aarch64"; };
|
aarch64 = { bits = 64; significantByte = littleEndian; family = "aarch64"; };
|
||||||
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
||||||
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
|
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
|
||||||
mips64el = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
|
||||||
|
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||||
|
mips64 = { bits = 64; significantByte = bigEndian; family = "mips"; };
|
||||||
|
mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
|
||||||
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
|
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
|
||||||
|
riscv32 = { bits = 32; significantByte = littleEndian; family = "riscv"; };
|
||||||
|
riscv64 = { bits = 64; significantByte = littleEndian; family = "riscv"; };
|
||||||
|
wasm32 = { bits = 32; significantByte = littleEndian; family = "wasm"; };
|
||||||
|
wasm64 = { bits = 64; significantByte = littleEndian; family = "wasm"; };
|
||||||
};
|
};
|
||||||
|
|
||||||
isVendor = isType "vendor";
|
################################################################################
|
||||||
vendors = setTypes "vendor" {
|
|
||||||
|
types.openVendor = mkOptionType {
|
||||||
|
name = "vendor";
|
||||||
|
description = "vendor for the platform";
|
||||||
|
merge = mergeOneOption;
|
||||||
|
};
|
||||||
|
|
||||||
|
types.vendor = enum (attrValues vendors);
|
||||||
|
|
||||||
|
vendors = setTypes types.openVendor {
|
||||||
apple = {};
|
apple = {};
|
||||||
pc = {};
|
pc = {};
|
||||||
|
|
||||||
unknown = {};
|
unknown = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
isExecFormat = isType "exec-format";
|
################################################################################
|
||||||
execFormats = setTypes "exec-format" {
|
|
||||||
|
types.openExecFormat = mkOptionType {
|
||||||
|
name = "exec-format";
|
||||||
|
description = "executable container used by the kernel";
|
||||||
|
merge = mergeOneOption;
|
||||||
|
};
|
||||||
|
|
||||||
|
types.execFormat = enum (attrValues execFormats);
|
||||||
|
|
||||||
|
execFormats = setTypes types.openExecFormat {
|
||||||
aout = {}; # a.out
|
aout = {}; # a.out
|
||||||
elf = {};
|
elf = {};
|
||||||
macho = {};
|
macho = {};
|
||||||
@ -64,16 +122,38 @@ rec {
|
|||||||
unknown = {};
|
unknown = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
isKernelFamily = isType "kernel-family";
|
################################################################################
|
||||||
kernelFamilies = setTypes "kernel-family" {
|
|
||||||
bsd = {};
|
types.openKernelFamily = mkOptionType {
|
||||||
|
name = "exec-format";
|
||||||
|
description = "executable container used by the kernel";
|
||||||
|
merge = mergeOneOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
isKernel = x: isType "kernel" x;
|
types.kernelFamily = enum (attrValues kernelFamilies);
|
||||||
kernels = with execFormats; with kernelFamilies; setTypesAssert "kernel"
|
|
||||||
(x: isExecFormat x.execFormat && all isKernelFamily (attrValues x.families))
|
kernelFamilies = setTypes types.openKernelFamily {
|
||||||
{
|
bsd = {};
|
||||||
darwin = { execFormat = macho; families = { }; };
|
darwin = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
types.openKernel = mkOptionType {
|
||||||
|
name = "kernel";
|
||||||
|
description = "kernel name and information";
|
||||||
|
merge = mergeOneOption;
|
||||||
|
check = x: types.execFormat.check x.execFormat
|
||||||
|
&& all types.kernelFamily.check (attrValues x.families);
|
||||||
|
};
|
||||||
|
|
||||||
|
types.kernel = enum (attrValues kernels);
|
||||||
|
|
||||||
|
kernels = with execFormats; with kernelFamilies; setTypes types.openKernel {
|
||||||
|
# TODO(@Ericson2314): Don't want to mass-rebuild yet to keeping 'darwin' as
|
||||||
|
# the nnormalized name for macOS.
|
||||||
|
macos = { execFormat = macho; families = { inherit darwin; }; name = "darwin"; };
|
||||||
|
ios = { execFormat = macho; families = { inherit darwin; }; };
|
||||||
freebsd = { execFormat = elf; families = { inherit bsd; }; };
|
freebsd = { execFormat = elf; families = { inherit bsd; }; };
|
||||||
hurd = { execFormat = elf; families = { }; };
|
hurd = { execFormat = elf; families = { }; };
|
||||||
linux = { execFormat = elf; families = { }; };
|
linux = { execFormat = elf; families = { }; };
|
||||||
@ -83,14 +163,28 @@ rec {
|
|||||||
solaris = { execFormat = elf; families = { }; };
|
solaris = { execFormat = elf; families = { }; };
|
||||||
windows = { execFormat = pe; families = { }; };
|
windows = { execFormat = pe; families = { }; };
|
||||||
} // { # aliases
|
} // { # aliases
|
||||||
|
# 'darwin' is the kernel for all of them. We choose macOS by default.
|
||||||
|
darwin = kernels.macos;
|
||||||
# TODO(@Ericson2314): Handle these Darwin version suffixes more generally.
|
# TODO(@Ericson2314): Handle these Darwin version suffixes more generally.
|
||||||
darwin10 = kernels.darwin;
|
darwin10 = kernels.macos;
|
||||||
darwin14 = kernels.darwin;
|
darwin14 = kernels.macos;
|
||||||
|
watchos = kernels.ios;
|
||||||
|
tvos = kernels.ios;
|
||||||
win32 = kernels.windows;
|
win32 = kernels.windows;
|
||||||
};
|
};
|
||||||
|
|
||||||
isAbi = isType "abi";
|
################################################################################
|
||||||
abis = setTypes "abi" {
|
|
||||||
|
types.openAbi = mkOptionType {
|
||||||
|
name = "abi";
|
||||||
|
description = "binary interface for compiled code and syscalls";
|
||||||
|
merge = mergeOneOption;
|
||||||
|
};
|
||||||
|
|
||||||
|
types.abi = enum (attrValues abis);
|
||||||
|
|
||||||
|
abis = setTypes types.openAbi {
|
||||||
|
android = {};
|
||||||
cygnus = {};
|
cygnus = {};
|
||||||
gnu = {};
|
gnu = {};
|
||||||
msvc = {};
|
msvc = {};
|
||||||
@ -98,16 +192,31 @@ rec {
|
|||||||
androideabi = {};
|
androideabi = {};
|
||||||
gnueabi = {};
|
gnueabi = {};
|
||||||
gnueabihf = {};
|
gnueabihf = {};
|
||||||
|
musleabi = {};
|
||||||
|
musleabihf = {};
|
||||||
|
musl = {};
|
||||||
|
|
||||||
unknown = {};
|
unknown = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
types.system = mkOptionType {
|
||||||
|
name = "system";
|
||||||
|
description = "fully parsed representation of llvm- or nix-style platform tuple";
|
||||||
|
merge = mergeOneOption;
|
||||||
|
check = { cpu, vendor, kernel, abi }:
|
||||||
|
types.cpuType.check cpu
|
||||||
|
&& types.vendor.check vendor
|
||||||
|
&& types.kernel.check kernel
|
||||||
|
&& types.abi.check abi;
|
||||||
|
};
|
||||||
|
|
||||||
isSystem = isType "system";
|
isSystem = isType "system";
|
||||||
mkSystem = { cpu, vendor, kernel, abi }:
|
|
||||||
assert isCpuType cpu && isVendor vendor && isKernel kernel && isAbi abi;
|
mkSystem = components:
|
||||||
setType "system" {
|
assert types.system.check components;
|
||||||
inherit cpu vendor kernel abi;
|
setType "system" components;
|
||||||
};
|
|
||||||
|
|
||||||
mkSkeletonFromList = l: {
|
mkSkeletonFromList = l: {
|
||||||
"2" = # We only do 2-part hacks for things Nix already supports
|
"2" = # We only do 2-part hacks for things Nix already supports
|
||||||
@ -162,12 +271,14 @@ rec {
|
|||||||
mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
|
mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
|
||||||
|
|
||||||
doubleFromSystem = { cpu, vendor, kernel, abi, ... }:
|
doubleFromSystem = { cpu, vendor, kernel, abi, ... }:
|
||||||
if abi == abis.cygnus
|
/**/ if abi == abis.cygnus then "${cpu.name}-cygwin"
|
||||||
then "${cpu.name}-cygwin"
|
else if kernel.families ? darwin then "${cpu.name}-darwin"
|
||||||
else "${cpu.name}-${kernel.name}";
|
else "${cpu.name}-${kernel.name}";
|
||||||
|
|
||||||
tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let
|
tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let
|
||||||
optAbi = lib.optionalString (abi != abis.unknown) "-${abi.name}";
|
optAbi = lib.optionalString (abi != abis.unknown) "-${abi.name}";
|
||||||
in "${cpu.name}-${vendor.name}-${kernel.name}${optAbi}";
|
in "${cpu.name}-${vendor.name}-${kernel.name}${optAbi}";
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
rec {
|
rec {
|
||||||
pcBase = {
|
pcBase = {
|
||||||
name = "pc";
|
name = "pc";
|
||||||
kernelHeadersBaseConfig = "defconfig";
|
|
||||||
kernelBaseConfig = "defconfig";
|
kernelBaseConfig = "defconfig";
|
||||||
# Build whatever possible as a module, if not stated in the extra config.
|
# Build whatever possible as a module, if not stated in the extra config.
|
||||||
kernelAutoModules = true;
|
kernelAutoModules = true;
|
||||||
@ -30,7 +29,6 @@ rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
kernelMajor = "2.6";
|
kernelMajor = "2.6";
|
||||||
kernelHeadersBaseConfig = "multi_v5_defconfig";
|
|
||||||
kernelBaseConfig = "multi_v5_defconfig";
|
kernelBaseConfig = "multi_v5_defconfig";
|
||||||
kernelArch = "arm";
|
kernelArch = "arm";
|
||||||
kernelAutoModules = false;
|
kernelAutoModules = false;
|
||||||
@ -54,7 +52,6 @@ rec {
|
|||||||
sheevaplug = {
|
sheevaplug = {
|
||||||
name = "sheevaplug";
|
name = "sheevaplug";
|
||||||
kernelMajor = "2.6";
|
kernelMajor = "2.6";
|
||||||
kernelHeadersBaseConfig = "multi_v5_defconfig";
|
|
||||||
kernelBaseConfig = "multi_v5_defconfig";
|
kernelBaseConfig = "multi_v5_defconfig";
|
||||||
kernelArch = "arm";
|
kernelArch = "arm";
|
||||||
kernelAutoModules = false;
|
kernelAutoModules = false;
|
||||||
@ -168,7 +165,6 @@ rec {
|
|||||||
raspberrypi = {
|
raspberrypi = {
|
||||||
name = "raspberrypi";
|
name = "raspberrypi";
|
||||||
kernelMajor = "2.6";
|
kernelMajor = "2.6";
|
||||||
kernelHeadersBaseConfig = "bcm2835_defconfig";
|
|
||||||
kernelBaseConfig = "bcmrpi_defconfig";
|
kernelBaseConfig = "bcmrpi_defconfig";
|
||||||
kernelDTB = true;
|
kernelDTB = true;
|
||||||
kernelArch = "arm";
|
kernelArch = "arm";
|
||||||
@ -347,7 +343,6 @@ rec {
|
|||||||
utilite = {
|
utilite = {
|
||||||
name = "utilite";
|
name = "utilite";
|
||||||
kernelMajor = "2.6";
|
kernelMajor = "2.6";
|
||||||
kernelHeadersBaseConfig = "multi_v7_defconfig";
|
|
||||||
kernelBaseConfig = "multi_v7_defconfig";
|
kernelBaseConfig = "multi_v7_defconfig";
|
||||||
kernelArch = "arm";
|
kernelArch = "arm";
|
||||||
kernelAutoModules = false;
|
kernelAutoModules = false;
|
||||||
@ -379,13 +374,11 @@ rec {
|
|||||||
# patch.
|
# patch.
|
||||||
|
|
||||||
kernelBaseConfig = "guruplug_defconfig";
|
kernelBaseConfig = "guruplug_defconfig";
|
||||||
#kernelHeadersBaseConfig = "guruplug_defconfig";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fuloong2f_n32 = {
|
fuloong2f_n32 = {
|
||||||
name = "fuloong2f_n32";
|
name = "fuloong2f_n32";
|
||||||
kernelMajor = "2.6";
|
kernelMajor = "2.6";
|
||||||
kernelHeadersBaseConfig = "fuloong2e_defconfig";
|
|
||||||
kernelBaseConfig = "lemote2f_defconfig";
|
kernelBaseConfig = "lemote2f_defconfig";
|
||||||
kernelArch = "mips";
|
kernelArch = "mips";
|
||||||
kernelAutoModules = false;
|
kernelAutoModules = false;
|
||||||
@ -471,7 +464,6 @@ rec {
|
|||||||
armv7l-hf-multiplatform = {
|
armv7l-hf-multiplatform = {
|
||||||
name = "armv7l-hf-multiplatform";
|
name = "armv7l-hf-multiplatform";
|
||||||
kernelMajor = "2.6"; # Using "2.6" enables 2.6 kernel syscalls in glibc.
|
kernelMajor = "2.6"; # Using "2.6" enables 2.6 kernel syscalls in glibc.
|
||||||
kernelHeadersBaseConfig = "multi_v7_defconfig";
|
|
||||||
kernelBaseConfig = "multi_v7_defconfig";
|
kernelBaseConfig = "multi_v7_defconfig";
|
||||||
kernelArch = "arm";
|
kernelArch = "arm";
|
||||||
kernelDTB = true;
|
kernelDTB = true;
|
||||||
@ -479,6 +471,11 @@ rec {
|
|||||||
kernelPreferBuiltin = true;
|
kernelPreferBuiltin = true;
|
||||||
kernelTarget = "zImage";
|
kernelTarget = "zImage";
|
||||||
kernelExtraConfig = ''
|
kernelExtraConfig = ''
|
||||||
|
# Serial port for Raspberry Pi 3. Upstream forgot to add it to the ARMv7 defconfig.
|
||||||
|
SERIAL_8250_BCM2835AUX y
|
||||||
|
SERIAL_8250_EXTENDED y
|
||||||
|
SERIAL_8250_SHARE_IRQ y
|
||||||
|
|
||||||
# Fix broken sunxi-sid nvmem driver.
|
# Fix broken sunxi-sid nvmem driver.
|
||||||
TI_CPTS y
|
TI_CPTS y
|
||||||
|
|
||||||
@ -512,7 +509,6 @@ rec {
|
|||||||
aarch64-multiplatform = {
|
aarch64-multiplatform = {
|
||||||
name = "aarch64-multiplatform";
|
name = "aarch64-multiplatform";
|
||||||
kernelMajor = "2.6"; # Using "2.6" enables 2.6 kernel syscalls in glibc.
|
kernelMajor = "2.6"; # Using "2.6" enables 2.6 kernel syscalls in glibc.
|
||||||
kernelHeadersBaseConfig = "defconfig";
|
|
||||||
kernelBaseConfig = "defconfig";
|
kernelBaseConfig = "defconfig";
|
||||||
kernelArch = "arm64";
|
kernelArch = "arm64";
|
||||||
kernelDTB = true;
|
kernelDTB = true;
|
||||||
@ -545,6 +541,19 @@ rec {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
riscv-multiplatform = bits: {
|
||||||
|
name = "riscv-multiplatform";
|
||||||
|
kernelArch = "riscv";
|
||||||
|
bfdEmulation = "elf${bits}lriscv";
|
||||||
|
kernelTarget = "vmlinux";
|
||||||
|
kernelAutoModules = true;
|
||||||
|
kernelBaseConfig = "defconfig";
|
||||||
|
kernelExtraConfig = ''
|
||||||
|
FTRACE n
|
||||||
|
SERIAL_OF_PLATFORM y
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
selectBySystem = system: {
|
selectBySystem = system: {
|
||||||
"i686-linux" = pc32;
|
"i686-linux" = pc32;
|
||||||
"x86_64-linux" = pc64;
|
"x86_64-linux" = pc64;
|
||||||
@ -552,6 +561,6 @@ rec {
|
|||||||
"armv6l-linux" = raspberrypi;
|
"armv6l-linux" = raspberrypi;
|
||||||
"armv7l-linux" = armv7l-hf-multiplatform;
|
"armv7l-linux" = armv7l-hf-multiplatform;
|
||||||
"aarch64-linux" = aarch64-multiplatform;
|
"aarch64-linux" = aarch64-multiplatform;
|
||||||
"mips64el-linux" = fuloong2f_n32;
|
"mipsel-linux" = fuloong2f_n32;
|
||||||
}.${system} or pcBase;
|
}.${system} or pcBase;
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,7 @@ runTests {
|
|||||||
"${builtins.storeDir}/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11";
|
"${builtins.storeDir}/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11";
|
||||||
in {
|
in {
|
||||||
storePath = isStorePath goodPath;
|
storePath = isStorePath goodPath;
|
||||||
|
storePathDerivation = isStorePath (import ../.. {}).hello;
|
||||||
storePathAppendix = isStorePath
|
storePathAppendix = isStorePath
|
||||||
"${goodPath}/bin/python";
|
"${goodPath}/bin/python";
|
||||||
nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
|
nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
|
||||||
@ -106,6 +107,7 @@ runTests {
|
|||||||
};
|
};
|
||||||
expected = {
|
expected = {
|
||||||
storePath = true;
|
storePath = true;
|
||||||
|
storePathDerivation = true;
|
||||||
storePathAppendix = false;
|
storePathAppendix = false;
|
||||||
nonAbsolute = false;
|
nonAbsolute = false;
|
||||||
asPath = true;
|
asPath = true;
|
||||||
@ -201,7 +203,7 @@ runTests {
|
|||||||
# in alphabetical order
|
# in alphabetical order
|
||||||
|
|
||||||
testMkKeyValueDefault = {
|
testMkKeyValueDefault = {
|
||||||
expr = generators.mkKeyValueDefault ":" "f:oo" "bar";
|
expr = generators.mkKeyValueDefault {} ":" "f:oo" "bar";
|
||||||
expected = ''f\:oo:bar'';
|
expected = ''f\:oo:bar'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ pkgs.stdenv.mkDerivation {
|
|||||||
export NIX_DB_DIR=$TEST_ROOT/db
|
export NIX_DB_DIR=$TEST_ROOT/db
|
||||||
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
||||||
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
||||||
export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
|
|
||||||
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
||||||
export NIX_STORE_DIR=$TEST_ROOT/store
|
export NIX_STORE_DIR=$TEST_ROOT/store
|
||||||
export PAGER=cat
|
export PAGER=cat
|
||||||
@ -21,7 +20,7 @@ pkgs.stdenv.mkDerivation {
|
|||||||
nix-store --init
|
nix-store --init
|
||||||
|
|
||||||
cd ${pkgs.path}/lib/tests
|
cd ${pkgs.path}/lib/tests
|
||||||
./modules.sh
|
bash ./modules.sh
|
||||||
|
|
||||||
[[ "$(nix-instantiate --eval --strict misc.nix)" == "[ ]" ]]
|
[[ "$(nix-instantiate --eval --strict misc.nix)" == "[ ]" ]]
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ in with lib.systems.doubles; lib.runTests {
|
|||||||
|
|
||||||
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ]);
|
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ]);
|
||||||
i686 = assertTrue (mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" ]);
|
i686 = assertTrue (mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" ]);
|
||||||
mips = assertTrue (mseteq mips [ "mips64el-linux" ]);
|
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" ]);
|
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" ]);
|
||||||
|
|
||||||
cygwin = assertTrue (mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ]);
|
cygwin = assertTrue (mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ]);
|
||||||
@ -24,7 +24,7 @@ in with lib.systems.doubles; lib.runTests {
|
|||||||
freebsd = assertTrue (mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ]);
|
freebsd = assertTrue (mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ]);
|
||||||
gnu = assertTrue (mseteq gnu (linux /* ++ hurd ++ kfreebsd ++ ... */));
|
gnu = assertTrue (mseteq gnu (linux /* ++ hurd ++ kfreebsd ++ ... */));
|
||||||
illumos = assertTrue (mseteq illumos [ "x86_64-solaris" ]);
|
illumos = assertTrue (mseteq illumos [ "x86_64-solaris" ]);
|
||||||
linux = assertTrue (mseteq linux [ "i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mips64el-linux" ]);
|
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" ]);
|
netbsd = assertTrue (mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ]);
|
||||||
openbsd = assertTrue (mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ]);
|
openbsd = assertTrue (mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ]);
|
||||||
unix = assertTrue (mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
|
unix = assertTrue (mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
|
||||||
|
@ -52,7 +52,7 @@ rec {
|
|||||||
|
|
||||||
# Pull in some builtins not included elsewhere.
|
# Pull in some builtins not included elsewhere.
|
||||||
inherit (builtins)
|
inherit (builtins)
|
||||||
pathExists readFile isBool isFunction
|
pathExists readFile isBool
|
||||||
isInt add sub lessThan
|
isInt add sub lessThan
|
||||||
seq deepSeq genericClosure;
|
seq deepSeq genericClosure;
|
||||||
|
|
||||||
@ -81,6 +81,42 @@ rec {
|
|||||||
*/
|
*/
|
||||||
mod = base: int: base - (int * (builtins.div base int));
|
mod = base: int: base - (int * (builtins.div base int));
|
||||||
|
|
||||||
|
/* C-style comparisons
|
||||||
|
|
||||||
|
a < b, compare a b => -1
|
||||||
|
a == b, compare a b => 0
|
||||||
|
a > b, compare a b => 1
|
||||||
|
*/
|
||||||
|
compare = a: b:
|
||||||
|
if a < b
|
||||||
|
then -1
|
||||||
|
else if a > b
|
||||||
|
then 1
|
||||||
|
else 0;
|
||||||
|
|
||||||
|
/* Split type into two subtypes by predicate `p`, take all elements
|
||||||
|
of the first subtype to be less than all the elements of the
|
||||||
|
second subtype, compare elements of a single subtype with `yes`
|
||||||
|
and `no` respectively.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in
|
||||||
|
|
||||||
|
cmp "a" "z" => -1
|
||||||
|
cmp "fooa" "fooz" => -1
|
||||||
|
|
||||||
|
cmp "f" "a" => 1
|
||||||
|
cmp "fooa" "a" => -1
|
||||||
|
# while
|
||||||
|
compare "fooa" "a" => 1
|
||||||
|
|
||||||
|
*/
|
||||||
|
splitByAndCompare = p: yes: no: a: 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. */
|
||||||
importJSON = path:
|
importJSON = path:
|
||||||
builtins.fromJSON (builtins.readFile path);
|
builtins.fromJSON (builtins.readFile path);
|
||||||
@ -99,4 +135,29 @@ rec {
|
|||||||
*/
|
*/
|
||||||
warn = msg: builtins.trace "WARNING: ${msg}";
|
warn = msg: builtins.trace "WARNING: ${msg}";
|
||||||
info = msg: builtins.trace "INFO: ${msg}";
|
info = msg: builtins.trace "INFO: ${msg}";
|
||||||
|
|
||||||
|
# | Add metadata about expected function arguments to a function.
|
||||||
|
# The metadata should match the format given by
|
||||||
|
# builtins.functionArgs, i.e. a set from expected argument to a bool
|
||||||
|
# representing whether that argument has a default or not.
|
||||||
|
# setFunctionArgs : (a → b) → Map String Bool → (a → b)
|
||||||
|
#
|
||||||
|
# This function is necessary because you can't dynamically create a
|
||||||
|
# function of the { a, b ? foo, ... }: format, but some facilities
|
||||||
|
# like callPackage expect to be able to query expected arguments.
|
||||||
|
setFunctionArgs = f: args:
|
||||||
|
{ # TODO: Should we add call-time "type" checking like built in?
|
||||||
|
__functor = self: f;
|
||||||
|
__functionArgs = args;
|
||||||
|
};
|
||||||
|
|
||||||
|
# | Extract the expected function arguments from a function.
|
||||||
|
# This works both with nix-native { a, b ? foo, ... }: style
|
||||||
|
# functions and functions with args set with 'setFunctionArgs'. It
|
||||||
|
# has the same return type and semantics as builtins.functionArgs.
|
||||||
|
# setFunctionArgs : (a → b) → Map String Bool.
|
||||||
|
functionArgs = f: f.__functionArgs or (builtins.functionArgs f);
|
||||||
|
|
||||||
|
isFunction = f: builtins.isFunction f ||
|
||||||
|
(f ? __functor && isFunction (f.__functor f));
|
||||||
}
|
}
|
||||||
|
@ -174,6 +174,13 @@ rec {
|
|||||||
merge = mergeOneOption;
|
merge = mergeOneOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
strMatching = pattern: mkOptionType {
|
||||||
|
name = "strMatching ${escapeNixString pattern}";
|
||||||
|
description = "string matching the pattern ${pattern}";
|
||||||
|
check = x: str.check x && builtins.match pattern x != null;
|
||||||
|
inherit (str) merge;
|
||||||
|
};
|
||||||
|
|
||||||
# Merge multiple definitions by concatenating them (with the given
|
# Merge multiple definitions by concatenating them (with the given
|
||||||
# separator between the values).
|
# separator between the values).
|
||||||
separatedString = sep: mkOptionType rec {
|
separatedString = sep: mkOptionType rec {
|
||||||
@ -249,6 +256,10 @@ rec {
|
|||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nonEmptyListOf = elemType:
|
||||||
|
let list = addCheck (types.listOf elemType) (l: l != []);
|
||||||
|
in list // { description = "non-empty " + list.description; };
|
||||||
|
|
||||||
attrsOf = elemType: mkOptionType rec {
|
attrsOf = elemType: mkOptionType rec {
|
||||||
name = "attrsOf";
|
name = "attrsOf";
|
||||||
description = "attribute set of ${elemType.description}s";
|
description = "attribute set of ${elemType.description}s";
|
||||||
|
47
lib/versions.nix
Normal file
47
lib/versions.nix
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* Version string functions. */
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
splitVersion = builtins.splitVersion or (lib.splitString ".");
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
rec {
|
||||||
|
|
||||||
|
/* Get the major version string from a string.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
major "1.2.3"
|
||||||
|
=> "1"
|
||||||
|
*/
|
||||||
|
major = v: builtins.elemAt (splitVersion v) 0;
|
||||||
|
|
||||||
|
/* Get the minor version string from a string.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
minor "1.2.3"
|
||||||
|
=> "2"
|
||||||
|
*/
|
||||||
|
minor = v: builtins.elemAt (splitVersion v) 1;
|
||||||
|
|
||||||
|
/* Get the patch version string from a string.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
patch "1.2.3"
|
||||||
|
=> "3"
|
||||||
|
*/
|
||||||
|
patch = v: builtins.elemAt (splitVersion v) 2;
|
||||||
|
|
||||||
|
/* Get string of the first two parts (major and minor)
|
||||||
|
of a version string.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
majorMinor "1.2.3"
|
||||||
|
=> "1.2"
|
||||||
|
*/
|
||||||
|
majorMinor = v:
|
||||||
|
builtins.concatStringsSep "."
|
||||||
|
(lib.take 2 (splitVersion v));
|
||||||
|
|
||||||
|
}
|
4028
maintainers/maintainer-list.nix
Normal file
4028
maintainers/maintainer-list.nix
Normal file
File diff suppressed because it is too large
Load Diff
66
maintainers/scripts/check-maintainer-github-handles.sh
Executable file
66
maintainers/scripts/check-maintainer-github-handles.sh
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p jq parallel
|
||||||
|
|
||||||
|
# Example how to work with the `lib.maintainers` attrset.
|
||||||
|
# Can be used to check whether all user handles are still valid.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# nixpkgs='<nixpkgs>'
|
||||||
|
# if [ -n "$1" ]; then
|
||||||
|
|
||||||
|
function checkCommits {
|
||||||
|
local user="$1"
|
||||||
|
local tmp=$(mktemp)
|
||||||
|
curl --silent -w "%{http_code}" \
|
||||||
|
"https://github.com/NixOS/nixpkgs/commits?author=$user" \
|
||||||
|
> "$tmp"
|
||||||
|
# the last line of tmp contains the http status
|
||||||
|
local status=$(tail -n1 "$tmp")
|
||||||
|
local ret=
|
||||||
|
case $status in
|
||||||
|
200) if <"$tmp" grep -i "no commits found" > /dev/null; then
|
||||||
|
ret=1
|
||||||
|
else
|
||||||
|
ret=0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
# because of github’s hard request limits, this can take some time
|
||||||
|
429) sleep 2
|
||||||
|
printf "."
|
||||||
|
checkCommits "$user"
|
||||||
|
ret=$?
|
||||||
|
;;
|
||||||
|
*) printf "BAD STATUS: $(tail -n1 $tmp) for %s\n" "$user"; ret=1
|
||||||
|
ret=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
rm "$tmp"
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
export -f checkCommits
|
||||||
|
|
||||||
|
function checkUser {
|
||||||
|
local user="$1"
|
||||||
|
local status=
|
||||||
|
status="$(curl --silent --head "https://github.com/${user}" | grep Status)"
|
||||||
|
# checks whether a user handle can be found on github
|
||||||
|
if [[ "$status" =~ 404 ]]; then
|
||||||
|
printf "%s\t\t\t\t%s\n" "$status" "$user"
|
||||||
|
# checks whether the user handle has any nixpkgs commits
|
||||||
|
elif checkCommits "$user"; then
|
||||||
|
printf "OK!\t\t\t\t%s\n" "$user"
|
||||||
|
else
|
||||||
|
printf "No Commits!\t\t\t%s\n" "$user"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
export -f checkUser
|
||||||
|
|
||||||
|
# output the maintainers set as json
|
||||||
|
# and filter out the github username of each maintainer (if it exists)
|
||||||
|
# then check some at the same time
|
||||||
|
nix-instantiate -A lib.maintainers --eval --strict --json \
|
||||||
|
| jq -r '.[]|.github|select(.)' \
|
||||||
|
| parallel -j5 checkUser
|
||||||
|
|
||||||
|
# parallel -j100 checkUser ::: "eelco" "profpatsch" "Profpatsch" "a"
|
@ -1,5 +1,5 @@
|
|||||||
#! /usr/bin/env nix-shell
|
#! /usr/bin/env nix-shell
|
||||||
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.FileSlurp nixUnstable
|
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.FileSlurp nixUnstable nixUnstable.perl-bindings
|
||||||
|
|
||||||
# This command uploads tarballs to tarballs.nixos.org, the
|
# This command uploads tarballs to tarballs.nixos.org, the
|
||||||
# content-addressed cache used by fetchurl as a fallback for when
|
# content-addressed cache used by fetchurl as a fallback for when
|
||||||
@ -59,6 +59,7 @@ my $s3 = Net::Amazon::S3->new(
|
|||||||
{ aws_access_key_id => $aws_access_key_id,
|
{ aws_access_key_id => $aws_access_key_id,
|
||||||
aws_secret_access_key => $aws_secret_access_key,
|
aws_secret_access_key => $aws_secret_access_key,
|
||||||
retry => 1,
|
retry => 1,
|
||||||
|
host => "s3-eu-west-1.amazonaws.com",
|
||||||
});
|
});
|
||||||
|
|
||||||
my $bucket = $s3->bucket("nixpkgs-tarballs") or die;
|
my $bucket = $s3->bucket("nixpkgs-tarballs") or die;
|
||||||
|
@ -4,11 +4,13 @@
|
|||||||
# Usage $0 debian-patches.txt debian-patches.nix
|
# Usage $0 debian-patches.txt debian-patches.nix
|
||||||
# An example input and output files can be found in applications/graphics/xara/
|
# An example input and output files can be found in applications/graphics/xara/
|
||||||
|
|
||||||
DEB_URL=http://patch-tracker.debian.org/patch/series/dl
|
DEB_URL=https://sources.debian.org/data/main
|
||||||
declare -a deb_patches
|
declare -a deb_patches
|
||||||
mapfile -t deb_patches < $1
|
mapfile -t deb_patches < $1
|
||||||
|
|
||||||
prefix="${DEB_URL}/${deb_patches[0]}"
|
# First letter
|
||||||
|
deb_prefix="${deb_patches[0]:0:1}"
|
||||||
|
prefix="${DEB_URL}/${deb_prefix}/${deb_patches[0]}/debian/patches"
|
||||||
|
|
||||||
if [[ -n "$2" ]]; then
|
if [[ -n "$2" ]]; then
|
||||||
exec 1> $2
|
exec 1> $2
|
||||||
|
@ -21,7 +21,7 @@ find . -type f | while read src; do
|
|||||||
# Sanitize file name
|
# Sanitize file name
|
||||||
filename=$(basename "$src" | tr '@' '_')
|
filename=$(basename "$src" | tr '@' '_')
|
||||||
nameVersion="${filename%.tar.*}"
|
nameVersion="${filename%.tar.*}"
|
||||||
name=$(echo "$nameVersion" | sed -e 's,-[[:digit:]].*,,' | sed -e 's,-opensource-src$,,')
|
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:]]*-\)\+,,')
|
version=$(echo "$nameVersion" | sed -e 's,^\([[:alpha:]][[:alnum:]]*-\)\+,,')
|
||||||
echo "$name,$version,$src,$filename" >>$csv
|
echo "$name,$version,$src,$filename" >>$csv
|
||||||
done
|
done
|
||||||
|
@ -1,192 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
GNOME_FTP=ftp.gnome.org/pub/GNOME/sources
|
|
||||||
|
|
||||||
# projects that don't follow the GNOME major versioning, or that we don't want to
|
|
||||||
# programmatically update
|
|
||||||
NO_GNOME_MAJOR="ghex gtkhtml gdm gucharmap"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo "Usage: $0 <show project>|<update project>|<update-all> [major.minor]" >&2
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$#" -lt 1 ]; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
GNOME_TOP=pkgs/desktops/gnome-3
|
|
||||||
|
|
||||||
action=$1
|
|
||||||
|
|
||||||
# curl -l ftp://... doesn't work from my office in HSE, and I don't want to have
|
|
||||||
# any conversations with sysadmin. Somehow lftp works.
|
|
||||||
if [ "$FTP_CLIENT" = "lftp" ]; then
|
|
||||||
ls_ftp() {
|
|
||||||
lftp -c "open $1; cls"
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ls_ftp() {
|
|
||||||
curl -s -l "$1"/
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
find_project() {
|
|
||||||
exec find "$GNOME_TOP" -mindepth 2 -maxdepth 2 -type d "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
show_project() {
|
|
||||||
local project=$1
|
|
||||||
local majorVersion=$2
|
|
||||||
local version=
|
|
||||||
|
|
||||||
if [ -z "$majorVersion" ]; then
|
|
||||||
echo "Looking for available versions..." >&2
|
|
||||||
local available_baseversions=$(ls_ftp ftp://${GNOME_FTP}/${project} | grep '[0-9]\.[0-9]' | sort -t. -k1,1n -k 2,2n)
|
|
||||||
if [ "$?" -ne 0 ]; then
|
|
||||||
echo "Project $project not found" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "The following versions are available:\n ${available_baseversions[@]}" >&2
|
|
||||||
echo -en "Choose one of them: " >&2
|
|
||||||
read majorVersion
|
|
||||||
fi
|
|
||||||
|
|
||||||
if echo "$majorVersion" | grep -q "[0-9]\+\.[0-9]\+\.[0-9]\+"; then
|
|
||||||
# not a major version
|
|
||||||
version=$majorVersion
|
|
||||||
majorVersion=$(echo "$majorVersion" | cut -d '.' -f 1,2)
|
|
||||||
fi
|
|
||||||
|
|
||||||
local FTPDIR=${GNOME_FTP}/${project}/${majorVersion}
|
|
||||||
|
|
||||||
#version=`curl -l ${FTPDIR}/ 2>/dev/null | grep LATEST-IS | sed -e s/LATEST-IS-//`
|
|
||||||
# gnome's LATEST-IS is broken. Do not trust it.
|
|
||||||
|
|
||||||
if [ -z "$version" ]; then
|
|
||||||
local files=$(ls_ftp "${FTPDIR}")
|
|
||||||
declare -A versions
|
|
||||||
|
|
||||||
for f in $files; do
|
|
||||||
case $f in
|
|
||||||
(LATEST-IS-*|*.news|*.changes|*.sha256sum|*.diff*):
|
|
||||||
;;
|
|
||||||
($project-*.*.9*.tar.*):
|
|
||||||
tmp=${f#$project-}
|
|
||||||
tmp=${tmp%.tar*}
|
|
||||||
echo "Ignored unstable version ${tmp}" >&2
|
|
||||||
;;
|
|
||||||
($project-*.tar.*):
|
|
||||||
tmp=${f#$project-}
|
|
||||||
tmp=${tmp%.tar*}
|
|
||||||
versions[${tmp}]=1
|
|
||||||
;;
|
|
||||||
(*):
|
|
||||||
echo "UNKNOWN FILE $f" >&2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
echo "Found versions ${!versions[@]}" >&2
|
|
||||||
version=$(echo ${!versions[@]} | sed -e 's/ /\n/g' | sort -t. -k1,1n -k 2,2n -k 3,3n | tail -n1)
|
|
||||||
if [ -z "$version" ]; then
|
|
||||||
echo "No version available for major $majorVersion" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Latest version is: ${version}" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local name=${project}-${version}
|
|
||||||
echo "Fetching .sha256 file" >&2
|
|
||||||
local sha256out=$(curl -s -f http://"${FTPDIR}"/"${name}".sha256sum)
|
|
||||||
|
|
||||||
if [ "$?" -ne "0" ]; then
|
|
||||||
echo "Version not found" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
extensions=( "xz" "bz2" "gz" )
|
|
||||||
echo "Choosing archive extension (known are ${extensions[@]})..." >&2
|
|
||||||
for ext in ${extensions[@]}; do
|
|
||||||
if echo -e "$sha256out" | grep -q "\\.tar\\.${ext}$"; then
|
|
||||||
ext_pref=$ext
|
|
||||||
sha256=$(echo -e "$sha256out" | grep "\\.tar\\.${ext}$" | cut -f1 -d\ )
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo "Chosen ${ext_pref}, hash is ${sha256}" >&2
|
|
||||||
|
|
||||||
echo "# Autogenerated by maintainers/scripts/gnome.sh update
|
|
||||||
|
|
||||||
fetchurl: {
|
|
||||||
name = \"${project}-${version}\";
|
|
||||||
|
|
||||||
src = fetchurl {
|
|
||||||
url = mirror://gnome/sources/${project}/${majorVersion}/${project}-${version}.tar.${ext_pref};
|
|
||||||
sha256 = \"${sha256}\";
|
|
||||||
};
|
|
||||||
}"
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
update_project() {
|
|
||||||
local project=$1
|
|
||||||
local majorVersion=$2
|
|
||||||
|
|
||||||
# find project in nixpkgs tree
|
|
||||||
projectPath=$(find_project -name "$project" -print)
|
|
||||||
if [ -z "$projectPath" ]; then
|
|
||||||
echo "Project $project not found under $GNOME_TOP"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
src=$(show_project "$project" "$majorVersion")
|
|
||||||
|
|
||||||
if [ "$?" -eq "0" ]; then
|
|
||||||
echo "Updating $projectPath/src.nix" >&2
|
|
||||||
echo -e "$src" > "$projectPath"/src.nix
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$action" = "update-all" ]; then
|
|
||||||
majorVersion=$2
|
|
||||||
if [ -z "$majorVersion" ]; then
|
|
||||||
echo "No major version specified" >&2
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
# find projects
|
|
||||||
projects=$(find_project -exec basename '{}' \;)
|
|
||||||
for project in $projects; do
|
|
||||||
if echo "$NO_GNOME_MAJOR"|grep -q $project; then
|
|
||||||
echo "Skipping $project"
|
|
||||||
else
|
|
||||||
echo "= Updating $project to $majorVersion" >&2
|
|
||||||
update_project "$project" "$majorVersion"
|
|
||||||
echo >&2
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
else
|
|
||||||
project=$2
|
|
||||||
majorVersion=$3
|
|
||||||
|
|
||||||
if [ -z "$project" ]; then
|
|
||||||
echo "No project specified, exiting" >&2
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$action" = show ]; then
|
|
||||||
show_project "$project" "$majorVersion"
|
|
||||||
elif [ "$action" = update ]; then
|
|
||||||
update_project "$project" "$majorVersion"
|
|
||||||
else
|
|
||||||
echo "Unknown action $action" >&2
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
fi
|
|
@ -13,7 +13,7 @@ from pyquery import PyQuery as pq
|
|||||||
|
|
||||||
|
|
||||||
maintainers_json = subprocess.check_output([
|
maintainers_json = subprocess.check_output([
|
||||||
'nix-instantiate', '-E', 'import ./lib/maintainers.nix {}', '--eval', '--json'
|
'nix-instantiate', '-E', 'import ./maintainers/maintainer-list.nix {}', '--eval', '--json'
|
||||||
])
|
])
|
||||||
maintainers = json.loads(maintainers_json)
|
maintainers = json.loads(maintainers_json)
|
||||||
MAINTAINERS = {v: k for k, v in maintainers.iteritems()}
|
MAINTAINERS = {v: k for k, v in maintainers.iteritems()}
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
# --print: avoid dependency on environment
|
||||||
|
optPrint=
|
||||||
|
if [ "$1" == "--print" ]; then
|
||||||
|
optPrint=true
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$#" != 1 ] && [ "$#" != 2 ]; then
|
if [ "$#" != 1 ] && [ "$#" != 2 ]; then
|
||||||
cat <<-EOF
|
cat <<-EOF
|
||||||
Usage: $0 commit-spec [commit-spec]
|
Usage: $0 [--print] commit-spec [commit-spec]
|
||||||
You need to be in a git-controlled nixpkgs tree.
|
You need to be in a git-controlled nixpkgs tree.
|
||||||
The current state of the tree will be used if the second commit is missing.
|
The current state of the tree will be used if the second commit is missing.
|
||||||
EOF
|
EOF
|
||||||
@ -113,3 +120,8 @@ newPkgs "${tree[1]}" "${tree[2]}" '--argstr system "x86_64-linux"' > "$newlist"
|
|||||||
sed -n 's/\([^. ]*\.\)*\([^. ]*\) .*$/\2/p' < "$newlist" \
|
sed -n 's/\([^. ]*\.\)*\([^. ]*\) .*$/\2/p' < "$newlist" \
|
||||||
| sort | uniq -c
|
| sort | uniq -c
|
||||||
|
|
||||||
|
if [ -n "$optPrint" ]; then
|
||||||
|
echo
|
||||||
|
cat "$newlist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#! /usr/bin/env nix-shell
|
#! /usr/bin/env nix-shell
|
||||||
#! nix-shell -i python3 -p 'python3.withPackages(ps: with ps; [ requests toolz ])'
|
#! nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ packaging requests toolz ])" -p git
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Update a Python package expression by passing in the `.nix` file, or the directory containing it.
|
Update a Python package expression by passing in the `.nix` file, or the directory containing it.
|
||||||
@ -18,7 +18,12 @@ import os
|
|||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
import toolz
|
import toolz
|
||||||
from concurrent.futures import ThreadPoolExecutor as pool
|
from concurrent.futures import ThreadPoolExecutor as Pool
|
||||||
|
from packaging.version import Version as _Version
|
||||||
|
from packaging.version import InvalidVersion
|
||||||
|
from packaging.specifiers import SpecifierSet
|
||||||
|
import collections
|
||||||
|
import subprocess
|
||||||
|
|
||||||
INDEX = "https://pypi.io/pypi"
|
INDEX = "https://pypi.io/pypi"
|
||||||
"""url of PyPI"""
|
"""url of PyPI"""
|
||||||
@ -26,10 +31,30 @@ INDEX = "https://pypi.io/pypi"
|
|||||||
EXTENSIONS = ['tar.gz', 'tar.bz2', 'tar', 'zip', '.whl']
|
EXTENSIONS = ['tar.gz', 'tar.bz2', 'tar', 'zip', '.whl']
|
||||||
"""Permitted file extensions. These are evaluated from left to right and the first occurance is returned."""
|
"""Permitted file extensions. These are evaluated from left to right and the first occurance is returned."""
|
||||||
|
|
||||||
|
PRERELEASES = False
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
class Version(_Version, collections.abc.Sequence):
|
||||||
|
|
||||||
|
def __init__(self, version):
|
||||||
|
super().__init__(version)
|
||||||
|
# We cannot use `str(Version(0.04.21))` because that becomes `0.4.21`
|
||||||
|
# https://github.com/avian2/unidecode/issues/13#issuecomment-354538882
|
||||||
|
self.raw_version = version
|
||||||
|
|
||||||
|
def __getitem__(self, i):
|
||||||
|
return self._version.release[i]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._version.release)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
yield from self._version.release
|
||||||
|
|
||||||
|
|
||||||
def _get_values(attribute, text):
|
def _get_values(attribute, text):
|
||||||
"""Match attribute in text and return all matches.
|
"""Match attribute in text and return all matches.
|
||||||
|
|
||||||
@ -82,13 +107,59 @@ def _fetch_page(url):
|
|||||||
else:
|
else:
|
||||||
raise ValueError("request for {} failed".format(url))
|
raise ValueError("request for {} failed".format(url))
|
||||||
|
|
||||||
def _get_latest_version_pypi(package, extension):
|
|
||||||
|
SEMVER = {
|
||||||
|
'major' : 0,
|
||||||
|
'minor' : 1,
|
||||||
|
'patch' : 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _determine_latest_version(current_version, target, versions):
|
||||||
|
"""Determine latest version, given `target`.
|
||||||
|
"""
|
||||||
|
current_version = Version(current_version)
|
||||||
|
|
||||||
|
def _parse_versions(versions):
|
||||||
|
for v in versions:
|
||||||
|
try:
|
||||||
|
yield Version(v)
|
||||||
|
except InvalidVersion:
|
||||||
|
pass
|
||||||
|
|
||||||
|
versions = _parse_versions(versions)
|
||||||
|
|
||||||
|
index = SEMVER[target]
|
||||||
|
|
||||||
|
ceiling = list(current_version[0:index])
|
||||||
|
if len(ceiling) == 0:
|
||||||
|
ceiling = None
|
||||||
|
else:
|
||||||
|
ceiling[-1]+=1
|
||||||
|
ceiling = Version(".".join(map(str, ceiling)))
|
||||||
|
|
||||||
|
# We do not want prereleases
|
||||||
|
versions = SpecifierSet(prereleases=PRERELEASES).filter(versions)
|
||||||
|
|
||||||
|
if ceiling is not None:
|
||||||
|
versions = SpecifierSet(f"<{ceiling}").filter(versions)
|
||||||
|
|
||||||
|
return (max(sorted(versions))).raw_version
|
||||||
|
|
||||||
|
|
||||||
|
def _get_latest_version_pypi(package, extension, current_version, target):
|
||||||
"""Get latest version and hash from PyPI."""
|
"""Get latest version and hash from PyPI."""
|
||||||
url = "{}/{}/json".format(INDEX, package)
|
url = "{}/{}/json".format(INDEX, package)
|
||||||
json = _fetch_page(url)
|
json = _fetch_page(url)
|
||||||
|
|
||||||
version = json['info']['version']
|
versions = json['releases'].keys()
|
||||||
for release in json['releases'][version]:
|
version = _determine_latest_version(current_version, target, versions)
|
||||||
|
|
||||||
|
try:
|
||||||
|
releases = json['releases'][version]
|
||||||
|
except KeyError as e:
|
||||||
|
raise KeyError('Could not find version {} for {}'.format(version, package)) from e
|
||||||
|
for release in releases:
|
||||||
if release['filename'].endswith(extension):
|
if release['filename'].endswith(extension):
|
||||||
# TODO: In case of wheel we need to do further checks!
|
# TODO: In case of wheel we need to do further checks!
|
||||||
sha256 = release['digests']['sha256']
|
sha256 = release['digests']['sha256']
|
||||||
@ -98,7 +169,7 @@ def _get_latest_version_pypi(package, extension):
|
|||||||
return version, sha256
|
return version, sha256
|
||||||
|
|
||||||
|
|
||||||
def _get_latest_version_github(package, extension):
|
def _get_latest_version_github(package, extension, current_version, target):
|
||||||
raise ValueError("updating from GitHub is not yet supported.")
|
raise ValueError("updating from GitHub is not yet supported.")
|
||||||
|
|
||||||
|
|
||||||
@ -141,9 +212,9 @@ def _determine_extension(text, fetcher):
|
|||||||
"""
|
"""
|
||||||
if fetcher == 'fetchPypi':
|
if fetcher == 'fetchPypi':
|
||||||
try:
|
try:
|
||||||
format = _get_unique_value('format', text)
|
src_format = _get_unique_value('format', text)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
format = None # format was not given
|
src_format = None # format was not given
|
||||||
|
|
||||||
try:
|
try:
|
||||||
extension = _get_unique_value('extension', text)
|
extension = _get_unique_value('extension', text)
|
||||||
@ -151,9 +222,11 @@ def _determine_extension(text, fetcher):
|
|||||||
extension = None # extension was not given
|
extension = None # extension was not given
|
||||||
|
|
||||||
if extension is None:
|
if extension is None:
|
||||||
if format is None:
|
if src_format is None:
|
||||||
format = 'setuptools'
|
src_format = 'setuptools'
|
||||||
extension = FORMATS[format]
|
elif src_format == 'flit':
|
||||||
|
raise ValueError("Don't know how to update a Flit package.")
|
||||||
|
extension = FORMATS[src_format]
|
||||||
|
|
||||||
elif fetcher == 'fetchurl':
|
elif fetcher == 'fetchurl':
|
||||||
url = _get_unique_value('url', text)
|
url = _get_unique_value('url', text)
|
||||||
@ -167,9 +240,7 @@ def _determine_extension(text, fetcher):
|
|||||||
return extension
|
return extension
|
||||||
|
|
||||||
|
|
||||||
def _update_package(path):
|
def _update_package(path, target):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Read the expression
|
# Read the expression
|
||||||
with open(path, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
@ -186,11 +257,13 @@ def _update_package(path):
|
|||||||
|
|
||||||
extension = _determine_extension(text, fetcher)
|
extension = _determine_extension(text, fetcher)
|
||||||
|
|
||||||
new_version, new_sha256 = _get_latest_version_pypi(pname, extension)
|
new_version, new_sha256 = FETCHERS[fetcher](pname, extension, version, target)
|
||||||
|
|
||||||
if new_version == version:
|
if new_version == version:
|
||||||
logging.info("Path {}: no update available for {}.".format(path, pname))
|
logging.info("Path {}: no update available for {}.".format(path, pname))
|
||||||
return False
|
return False
|
||||||
|
elif new_version <= version:
|
||||||
|
raise ValueError("downgrade for {}.".format(pname))
|
||||||
if not new_sha256:
|
if not new_sha256:
|
||||||
raise ValueError("no file available for {}.".format(pname))
|
raise ValueError("no file available for {}.".format(pname))
|
||||||
|
|
||||||
@ -202,10 +275,19 @@ def _update_package(path):
|
|||||||
|
|
||||||
logging.info("Path {}: updated {} from {} to {}".format(path, pname, version, new_version))
|
logging.info("Path {}: updated {} from {} to {}".format(path, pname, version, new_version))
|
||||||
|
|
||||||
return True
|
result = {
|
||||||
|
'path' : path,
|
||||||
|
'target': target,
|
||||||
|
'pname': pname,
|
||||||
|
'old_version' : version,
|
||||||
|
'new_version' : new_version,
|
||||||
|
#'fetcher' : fetcher,
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def _update(path):
|
def _update(path, target):
|
||||||
|
|
||||||
# We need to read and modify a Nix expression.
|
# We need to read and modify a Nix expression.
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
@ -222,24 +304,58 @@ def _update(path):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _update_package(path)
|
return _update_package(path, target)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
logging.warning("Path {}: {}".format(path, e))
|
logging.warning("Path {}: {}".format(path, e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _commit(path, pname, old_version, new_version, **kwargs):
|
||||||
|
"""Commit result.
|
||||||
|
"""
|
||||||
|
|
||||||
|
msg = f'python: {pname}: {old_version} -> {new_version}'
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.check_call(['git', 'add', path])
|
||||||
|
subprocess.check_call(['git', 'commit', '-m', msg])
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
subprocess.check_call(['git', 'checkout', path])
|
||||||
|
raise subprocess.CalledProcessError(f'Could not commit {path}') from e
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('package', type=str, nargs='+')
|
parser.add_argument('package', type=str, nargs='+')
|
||||||
|
parser.add_argument('--target', type=str, choices=SEMVER.keys(), default='major')
|
||||||
|
parser.add_argument('--commit', action='store_true', help='Create a commit for each package update')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
target = args.target
|
||||||
|
|
||||||
packages = map(os.path.abspath, args.package)
|
packages = list(map(os.path.abspath, args.package))
|
||||||
|
|
||||||
|
logging.info("Updating packages...")
|
||||||
|
|
||||||
|
# Use threads to update packages concurrently
|
||||||
|
with Pool() as p:
|
||||||
|
results = list(p.map(lambda pkg: _update(pkg, target), packages))
|
||||||
|
|
||||||
|
logging.info("Finished updating packages.")
|
||||||
|
|
||||||
|
# Commits are created sequentially.
|
||||||
|
if args.commit:
|
||||||
|
logging.info("Committing updates...")
|
||||||
|
list(map(lambda x: _commit(**x), filter(bool, results)))
|
||||||
|
logging.info("Finished committing updates")
|
||||||
|
|
||||||
|
count = sum(map(bool, results))
|
||||||
|
logging.info("{} package(s) updated".format(count))
|
||||||
|
|
||||||
with pool() as p:
|
|
||||||
count = list(p.map(_update, packages))
|
|
||||||
|
|
||||||
logging.info("{} package(s) updated".format(sum(count)))
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -1,37 +1,51 @@
|
|||||||
{ package ? null
|
{ package ? null
|
||||||
, maintainer ? null
|
, maintainer ? null
|
||||||
|
, path ? null
|
||||||
}:
|
}:
|
||||||
|
|
||||||
# TODO: add assert statements
|
# TODO: add assert statements
|
||||||
|
|
||||||
let
|
let
|
||||||
|
/* Remove duplicate elements from the list based on some extracted value. O(n^2) complexity.
|
||||||
|
*/
|
||||||
|
nubOn = f: list:
|
||||||
|
if list == [] then
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
let
|
||||||
|
x = pkgs.lib.head list;
|
||||||
|
xs = pkgs.lib.filter (p: f x != f p) (pkgs.lib.drop 1 list);
|
||||||
|
in
|
||||||
|
[x] ++ nubOn f xs;
|
||||||
|
|
||||||
pkgs = import ./../../default.nix { };
|
pkgs = import ./../../default.nix { };
|
||||||
|
|
||||||
packagesWith = cond: return: set:
|
packagesWith = cond: return: set:
|
||||||
pkgs.lib.flatten
|
nubOn (pkg: pkg.updateScript)
|
||||||
(pkgs.lib.mapAttrsToList
|
(pkgs.lib.flatten
|
||||||
(name: pkg:
|
(pkgs.lib.mapAttrsToList
|
||||||
let
|
(name: pkg:
|
||||||
result = builtins.tryEval (
|
let
|
||||||
if pkgs.lib.isDerivation pkg && cond name pkg
|
result = builtins.tryEval (
|
||||||
then [(return name pkg)]
|
if pkgs.lib.isDerivation pkg && cond name pkg
|
||||||
else if pkg.recurseForDerivations or false || pkg.recurseForRelease or false
|
then [(return name pkg)]
|
||||||
then packagesWith cond return pkg
|
else if pkg.recurseForDerivations or false || pkg.recurseForRelease or false
|
||||||
|
then packagesWith cond return pkg
|
||||||
|
else []
|
||||||
|
);
|
||||||
|
in
|
||||||
|
if result.success then result.value
|
||||||
else []
|
else []
|
||||||
);
|
)
|
||||||
in
|
set
|
||||||
if result.success then result.value
|
|
||||||
else []
|
|
||||||
)
|
)
|
||||||
set
|
|
||||||
);
|
);
|
||||||
|
|
||||||
packagesWithUpdateScriptAndMaintainer = maintainer':
|
packagesWithUpdateScriptAndMaintainer = maintainer':
|
||||||
let
|
let
|
||||||
maintainer =
|
maintainer =
|
||||||
if ! builtins.hasAttr maintainer' pkgs.lib.maintainers then
|
if ! builtins.hasAttr maintainer' pkgs.lib.maintainers then
|
||||||
builtins.throw "Maintainer with name `${maintainer'} does not exist in `lib/maintainers.nix`."
|
builtins.throw "Maintainer with name `${maintainer'} does not exist in `maintainers/maintainer-list.nix`."
|
||||||
else
|
else
|
||||||
builtins.getAttr maintainer' pkgs.lib.maintainers;
|
builtins.getAttr maintainer' pkgs.lib.maintainers;
|
||||||
in
|
in
|
||||||
@ -47,6 +61,14 @@ let
|
|||||||
(name: pkg: pkg)
|
(name: pkg: pkg)
|
||||||
pkgs;
|
pkgs;
|
||||||
|
|
||||||
|
packagesWithUpdateScript = path:
|
||||||
|
let
|
||||||
|
attrSet = pkgs.lib.attrByPath (pkgs.lib.splitString "." path) null pkgs;
|
||||||
|
in
|
||||||
|
packagesWith (name: pkg: builtins.hasAttr "updateScript" pkg)
|
||||||
|
(name: pkg: pkg)
|
||||||
|
attrSet;
|
||||||
|
|
||||||
packageByName = name:
|
packageByName = name:
|
||||||
let
|
let
|
||||||
package = pkgs.lib.attrByPath (pkgs.lib.splitString "." name) null pkgs;
|
package = pkgs.lib.attrByPath (pkgs.lib.splitString "." name) null pkgs;
|
||||||
@ -54,7 +76,7 @@ let
|
|||||||
if package == null then
|
if package == null then
|
||||||
builtins.throw "Package with an attribute name `${name}` does not exists."
|
builtins.throw "Package with an attribute name `${name}` does not exists."
|
||||||
else if ! builtins.hasAttr "updateScript" package then
|
else if ! builtins.hasAttr "updateScript" package then
|
||||||
builtins.throw "Package with an attribute name `${name}` does have an `passthru.updateScript` defined."
|
builtins.throw "Package with an attribute name `${name}` does not have a `passthru.updateScript` attribute defined."
|
||||||
else
|
else
|
||||||
package;
|
package;
|
||||||
|
|
||||||
@ -63,6 +85,8 @@ let
|
|||||||
[ (packageByName package) ]
|
[ (packageByName package) ]
|
||||||
else if maintainer != null then
|
else if maintainer != null then
|
||||||
packagesWithUpdateScriptAndMaintainer maintainer
|
packagesWithUpdateScriptAndMaintainer maintainer
|
||||||
|
else if path != null then
|
||||||
|
packagesWithUpdateScript path
|
||||||
else
|
else
|
||||||
builtins.throw "No arguments provided.\n\n${helpText}";
|
builtins.throw "No arguments provided.\n\n${helpText}";
|
||||||
|
|
||||||
@ -76,7 +100,11 @@ let
|
|||||||
|
|
||||||
% nix-shell maintainers/scripts/update.nix --argstr package garbas
|
% nix-shell maintainers/scripts/update.nix --argstr package garbas
|
||||||
|
|
||||||
to run update script for specific package.
|
to run update script for specific package, or
|
||||||
|
|
||||||
|
% nix-shell maintainers/scripts/update.nix --argstr path gnome3
|
||||||
|
|
||||||
|
to run update script for all package under an attribute path.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
runUpdateScript = package: ''
|
runUpdateScript = package: ''
|
||||||
|
@ -10,7 +10,7 @@ git_data="$(echo "$raw_git_log" | grep 'Author:' |
|
|||||||
|
|
||||||
# Name - nick - email correspondence from log and from maintainer list
|
# Name - nick - email correspondence from log and from maintainer list
|
||||||
# Also there are a few manual entries
|
# Also there are a few manual entries
|
||||||
maintainers="$(cat "$(dirname "$0")/../../lib/maintainers.nix" |
|
maintainers="$(cat "$(dirname "$0")/../maintainer-list.nix" |
|
||||||
grep '=' | sed -re 's/\\"/''/g;
|
grep '=' | sed -re 's/\\"/''/g;
|
||||||
s/[ ]*([^ =]*)[ ]*=[ ]*" *(.*[^ ]) *[<](.*)[>] *".*/\1\t\2\t\3/')"
|
s/[ ]*([^ =]*)[ ]*=[ ]*" *(.*[^ ]) *[<](.*)[>] *".*/\1\t\2\t\3/')"
|
||||||
git_lines="$( ( echo "$git_data";
|
git_lines="$( ( echo "$git_data";
|
||||||
|
@ -9,8 +9,6 @@ let
|
|||||||
modules = [ configuration ];
|
modules = [ configuration ];
|
||||||
};
|
};
|
||||||
|
|
||||||
inherit (eval) pkgs;
|
|
||||||
|
|
||||||
# This is for `nixos-rebuild build-vm'.
|
# This is for `nixos-rebuild build-vm'.
|
||||||
vmConfig = (import ./lib/eval-config.nix {
|
vmConfig = (import ./lib/eval-config.nix {
|
||||||
inherit system;
|
inherit system;
|
||||||
@ -30,7 +28,7 @@ let
|
|||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
inherit (eval) config options;
|
inherit (eval) pkgs config options;
|
||||||
|
|
||||||
system = eval.config.system.build.toplevel;
|
system = eval.config.system.build.toplevel;
|
||||||
|
|
||||||
|
@ -23,10 +23,23 @@ networking.firewall.allowedTCPPorts = [ 80 443 ];
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon
|
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon
|
||||||
is enabled (<option>services.openssh.enable = true</option>). UDP
|
is enabled (<option>services.openssh.enable = true</option>). UDP
|
||||||
ports can be opened through
|
ports can be opened through
|
||||||
<option>networking.firewall.allowedUDPPorts</option>. Also of
|
<option>networking.firewall.allowedUDPPorts</option>.</para>
|
||||||
interest is
|
|
||||||
|
<para>To open ranges of TCP ports:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
networking.firewall.allowedTCPPortRanges = [
|
||||||
|
{ from = 4000; to = 4007; }
|
||||||
|
{ from = 8000; to = 8010; }
|
||||||
|
];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Similarly, UDP port ranges can be opened through
|
||||||
|
<option>networking.firewall.allowedUDPPortRanges</option>.</para>
|
||||||
|
|
||||||
|
<para>Also of interest is
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
networking.firewall.allowPing = true;
|
networking.firewall.allowPing = true;
|
||||||
|
@ -12,7 +12,7 @@ interfaces. However, you can configure an interface manually as
|
|||||||
follows:
|
follows:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
networking.interfaces.eth0.ip4 = [ { address = "192.168.1.2"; prefixLength = 24; } ];
|
networking.interfaces.eth0.ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
Typically you’ll also want to set a default gateway and set of name
|
Typically you’ll also want to set a default gateway and set of name
|
||||||
|
@ -26,7 +26,7 @@ boot.kernel.sysctl."net.ipv6.conf.eth0.disable_ipv6" = true;
|
|||||||
DHCPv6. You can configure an interface manually:
|
DHCPv6. You can configure an interface manually:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
networking.interfaces.eth0.ip6 = [ { address = "fe00:aa:bb:cc::2"; prefixLength = 64; } ];
|
networking.interfaces.eth0.ipv6.addresses = [ { address = "fe00:aa:bb:cc::2"; prefixLength = 64; } ];
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ management. In the declarative style, users are specified in
|
|||||||
states that a user account named <literal>alice</literal> shall exist:
|
states that a user account named <literal>alice</literal> shall exist:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
users.extraUsers.alice =
|
users.users.alice =
|
||||||
{ isNormalUser = true;
|
{ isNormalUser = true;
|
||||||
home = "/home/alice";
|
home = "/home/alice";
|
||||||
description = "Alice Foobar";
|
description = "Alice Foobar";
|
||||||
@ -34,7 +34,7 @@ to set a password, which is retained across invocations of
|
|||||||
|
|
||||||
<para>If you set users.mutableUsers to false, then the contents of /etc/passwd
|
<para>If you set users.mutableUsers to false, then the contents of /etc/passwd
|
||||||
and /etc/group will be congruent to your NixOS configuration. For instance,
|
and /etc/group will be congruent to your NixOS configuration. For instance,
|
||||||
if you remove a user from users.extraUsers and run nixos-rebuild, the user
|
if you remove a user from users.users and run nixos-rebuild, the user
|
||||||
account will cease to exist. Also, imperative commands for managing users
|
account will cease to exist. Also, imperative commands for managing users
|
||||||
and groups, such as useradd, are no longer available. Passwords may still be
|
and groups, such as useradd, are no longer available. Passwords may still be
|
||||||
assigned by setting the user's <literal>hashedPassword</literal> option. A
|
assigned by setting the user's <literal>hashedPassword</literal> option. A
|
||||||
@ -54,7 +54,7 @@ to the user specification.</para>
|
|||||||
group named <literal>students</literal> shall exist:
|
group named <literal>students</literal> shall exist:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
users.extraGroups.students.gid = 1000;
|
users.groups.students.gid = 1000;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
As with users, the group ID (gid) is optional and will be assigned
|
As with users, the group ID (gid) is optional and will be assigned
|
||||||
@ -68,8 +68,8 @@ account named <literal>alice</literal>:
|
|||||||
<screen>
|
<screen>
|
||||||
# useradd -m alice</screen>
|
# useradd -m alice</screen>
|
||||||
|
|
||||||
To make all nix tools available to this new user use `su - USER` which
|
To make all nix tools available to this new user use `su - USER` which
|
||||||
opens a login shell (==shell that loads the profile) for given user.
|
opens a login shell (==shell that loads the profile) for given user.
|
||||||
This will create the ~/.nix-defexpr symlink. So run:
|
This will create the ~/.nix-defexpr symlink. So run:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
|
@ -115,13 +115,14 @@ hardware.opengl.driSupport32Bit = true;
|
|||||||
<para>Support for Synaptics touchpads (found in many laptops such as
|
<para>Support for Synaptics touchpads (found in many laptops such as
|
||||||
the Dell Latitude series) can be enabled as follows:
|
the Dell Latitude series) can be enabled as follows:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
services.xserver.synaptics.enable = true;
|
services.xserver.libinput.enable = true;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
The driver has many options (see <xref linkend="ch-options"/>). For
|
The driver has many options (see <xref linkend="ch-options"/>). For
|
||||||
instance, the following enables two-finger scrolling:
|
instance, the following disables tap-to-click behavior:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
services.xserver.synaptics.twoFingerScroll = true;
|
services.xserver.libinput.tapping = false;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
Note: the use of <literal>services.xserver.synaptics</literal> is deprecated since NixOS 17.09.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</simplesect>
|
</simplesect>
|
||||||
@ -129,7 +130,7 @@ services.xserver.synaptics.twoFingerScroll = true;
|
|||||||
<simplesect><title>GTK/Qt themes</title>
|
<simplesect><title>GTK/Qt themes</title>
|
||||||
|
|
||||||
<para>GTK themes can be installed either to user profile or system-wide (via
|
<para>GTK themes can be installed either to user profile or system-wide (via
|
||||||
<literal>system.environmentPackages</literal>). To make Qt 5 applications look similar
|
<literal>environment.systemPackages</literal>). To make Qt 5 applications look similar
|
||||||
to GTK2 ones, you can install <literal>qt5.qtbase.gtk</literal> package into your
|
to GTK2 ones, you can install <literal>qt5.qtbase.gtk</literal> package into your
|
||||||
system environment. It should work for all Qt 5 library versions.
|
system environment. It should work for all Qt 5 library versions.
|
||||||
</para>
|
</para>
|
||||||
|
@ -35,18 +35,7 @@ services.compton = {
|
|||||||
To install them manually (system wide), put them into your
|
To install them manually (system wide), put them into your
|
||||||
<literal>environment.systemPackages</literal>.
|
<literal>environment.systemPackages</literal>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
NixOS’s default <emphasis>display manager</emphasis> is SLiM.
|
|
||||||
(DM is the program that provides a graphical login prompt
|
|
||||||
and manages the X server.)
|
|
||||||
You can, for example, select KDE’s
|
|
||||||
<command>sddm</command> instead:
|
|
||||||
<programlisting>
|
|
||||||
services.xserver.displayManager.sddm.enable = true;
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<simplesect>
|
<simplesect>
|
||||||
<title>Thunar Volume Support</title>
|
<title>Thunar Volume Support</title>
|
||||||
|
|
||||||
|
@ -6,22 +6,52 @@ let
|
|||||||
lib = pkgs.lib;
|
lib = pkgs.lib;
|
||||||
|
|
||||||
# Remove invisible and internal options.
|
# Remove invisible and internal options.
|
||||||
optionsList = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
|
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
|
||||||
|
|
||||||
# Replace functions by the string <function>
|
# Replace functions by the string <function>
|
||||||
substFunction = x:
|
substFunction = x:
|
||||||
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
||||||
else if builtins.isList x then map substFunction x
|
else if builtins.isList x then map substFunction x
|
||||||
else if builtins.isFunction x then "<function>"
|
else if lib.isFunction x then "<function>"
|
||||||
else x;
|
else x;
|
||||||
|
|
||||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
# Generate DocBook documentation for a list of packages. This is
|
||||||
optionsList' = lib.flip map optionsList (opt: opt // {
|
# what `relatedPackages` option of `mkOption` from
|
||||||
|
# ../../../lib/options.nix influences.
|
||||||
|
#
|
||||||
|
# Each element of `relatedPackages` can be either
|
||||||
|
# - a string: that will be interpreted as an attribute name from `pkgs`,
|
||||||
|
# - a list: that will be interpreted as an attribute path from `pkgs`,
|
||||||
|
# - an attrset: that can specify `name`, `path`, `package`, `comment`
|
||||||
|
# (either of `name`, `path` is required, the rest are optional).
|
||||||
|
genRelatedPackages = packages:
|
||||||
|
let
|
||||||
|
unpack = p: if lib.isString p then { name = p; }
|
||||||
|
else if lib.isList p then { path = p; }
|
||||||
|
else p;
|
||||||
|
describe = args:
|
||||||
|
let
|
||||||
|
name = args.name or (lib.concatStringsSep "." args.path);
|
||||||
|
path = args.path or [ args.name ];
|
||||||
|
package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}'") pkgs);
|
||||||
|
in "<listitem>"
|
||||||
|
+ "<para><literal>pkgs.${name} (${package.meta.name})</literal>"
|
||||||
|
+ lib.optionalString (!package.meta.available) " <emphasis>[UNAVAILABLE]</emphasis>"
|
||||||
|
+ ": ${package.meta.description or "???"}.</para>"
|
||||||
|
+ lib.optionalString (args ? comment) "\n<para>${args.comment}</para>"
|
||||||
|
# Lots of `longDescription's break DocBook, so we just wrap them into <programlisting>
|
||||||
|
+ lib.optionalString (package.meta ? longDescription) "\n<programlisting>${package.meta.longDescription}</programlisting>"
|
||||||
|
+ "</listitem>";
|
||||||
|
in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
|
||||||
|
|
||||||
|
optionsListDesc = lib.flip map optionsListVisible (opt: opt // {
|
||||||
|
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||||
declarations = map stripAnyPrefixes opt.declarations;
|
declarations = map stripAnyPrefixes opt.declarations;
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
||||||
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
||||||
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; });
|
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
|
||||||
|
// lib.optionalAttrs (opt ? relatedPackages) { relatedPackages = genRelatedPackages opt.relatedPackages; });
|
||||||
|
|
||||||
# We need to strip references to /nix/store/* from options,
|
# We need to strip references to /nix/store/* from options,
|
||||||
# including any `extraSources` if some modules came from elsewhere,
|
# including any `extraSources` if some modules came from elsewhere,
|
||||||
@ -32,8 +62,21 @@ let
|
|||||||
prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
|
prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
|
||||||
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
|
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
|
||||||
|
|
||||||
|
# Custom "less" that pushes up all the things ending in ".enable*"
|
||||||
|
# and ".package*"
|
||||||
|
optionLess = a: b:
|
||||||
|
let
|
||||||
|
ise = lib.hasPrefix "enable";
|
||||||
|
isp = lib.hasPrefix "package";
|
||||||
|
cmp = lib.splitByAndCompare ise lib.compare
|
||||||
|
(lib.splitByAndCompare isp lib.compare lib.compare);
|
||||||
|
in lib.compareLists cmp a.loc b.loc < 0;
|
||||||
|
|
||||||
|
# Customly sort option list for the man page.
|
||||||
|
optionsList = lib.sort optionLess optionsListDesc;
|
||||||
|
|
||||||
# Convert the list of options into an XML file.
|
# Convert the list of options into an XML file.
|
||||||
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList');
|
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
|
||||||
|
|
||||||
optionsDocBook = runCommand "options-db.xml" {} ''
|
optionsDocBook = runCommand "options-db.xml" {} ''
|
||||||
optionsXML=${optionsXML}
|
optionsXML=${optionsXML}
|
||||||
@ -44,7 +87,7 @@ let
|
|||||||
echo "for hints about the offending path)."
|
echo "for hints about the offending path)."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
${libxslt.bin}/bin/xsltproc \
|
${buildPackages.libxslt.bin}/bin/xsltproc \
|
||||||
--stringparam revision '${revision}' \
|
--stringparam revision '${revision}' \
|
||||||
-o $out ${./options-to-docbook.xsl} $optionsXML
|
-o $out ${./options-to-docbook.xsl} $optionsXML
|
||||||
'';
|
'';
|
||||||
@ -96,7 +139,7 @@ let
|
|||||||
|
|
||||||
manual-combined = runCommand "nixos-manual-combined"
|
manual-combined = runCommand "nixos-manual-combined"
|
||||||
{ inherit sources;
|
{ inherit sources;
|
||||||
buildInputs = [ libxml2 libxslt ];
|
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||||
meta.description = "The NixOS manual as plain docbook XML";
|
meta.description = "The NixOS manual as plain docbook XML";
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
@ -106,13 +149,43 @@ let
|
|||||||
xmllint --xinclude --noxincludenode \
|
xmllint --xinclude --noxincludenode \
|
||||||
--output ./man-pages-combined.xml ./man-pages.xml
|
--output ./man-pages-combined.xml ./man-pages.xml
|
||||||
|
|
||||||
xmllint --debug --noout --nonet \
|
# outputs the context of an xmllint error output
|
||||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
# LEN lines around the failing line are printed
|
||||||
manual-combined.xml
|
function context {
|
||||||
xmllint --debug --noout --nonet \
|
# length of context
|
||||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
local LEN=6
|
||||||
man-pages-combined.xml
|
# lines to print before error line
|
||||||
|
local BEFORE=4
|
||||||
|
|
||||||
|
# xmllint output lines are:
|
||||||
|
# file.xml:1234: there was an error on line 1234
|
||||||
|
while IFS=':' read -r file line rest; do
|
||||||
|
echo
|
||||||
|
if [[ -n "$rest" ]]; then
|
||||||
|
echo "$file:$line:$rest"
|
||||||
|
local FROM=$(($line>$BEFORE ? $line - $BEFORE : 1))
|
||||||
|
# number lines & filter context
|
||||||
|
nl --body-numbering=a "$file" | sed -n "$FROM,+$LEN p"
|
||||||
|
else
|
||||||
|
if [[ -n "$line" ]]; then
|
||||||
|
echo "$file:$line"
|
||||||
|
else
|
||||||
|
echo "$file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function lintrng {
|
||||||
|
xmllint --debug --noout --nonet \
|
||||||
|
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||||
|
"$1" \
|
||||||
|
2>&1 | context 1>&2
|
||||||
|
# ^ redirect assumes xmllint doesn’t print to stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
lintrng manual-combined.xml
|
||||||
|
lintrng man-pages-combined.xml
|
||||||
|
|
||||||
mkdir $out
|
mkdir $out
|
||||||
cp manual-combined.xml $out/
|
cp manual-combined.xml $out/
|
||||||
@ -121,7 +194,7 @@ let
|
|||||||
|
|
||||||
olinkDB = runCommand "manual-olinkdb"
|
olinkDB = runCommand "manual-olinkdb"
|
||||||
{ inherit sources;
|
{ inherit sources;
|
||||||
buildInputs = [ libxml2 libxslt ];
|
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
xsltproc \
|
xsltproc \
|
||||||
@ -161,7 +234,7 @@ in rec {
|
|||||||
mkdir -p $dst
|
mkdir -p $dst
|
||||||
|
|
||||||
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
|
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
|
||||||
(builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList'))))
|
(builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList))))
|
||||||
} $dst/options.json
|
} $dst/options.json
|
||||||
|
|
||||||
mkdir -p $out/nix-support
|
mkdir -p $out/nix-support
|
||||||
@ -171,7 +244,7 @@ in rec {
|
|||||||
# Generate the NixOS manual.
|
# Generate the NixOS manual.
|
||||||
manual = runCommand "nixos-manual"
|
manual = runCommand "nixos-manual"
|
||||||
{ inherit sources;
|
{ inherit sources;
|
||||||
buildInputs = [ libxml2 libxslt ];
|
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||||
meta.description = "The NixOS manual in HTML format";
|
meta.description = "The NixOS manual in HTML format";
|
||||||
allowedReferences = ["out"];
|
allowedReferences = ["out"];
|
||||||
}
|
}
|
||||||
@ -199,7 +272,7 @@ in rec {
|
|||||||
|
|
||||||
manualEpub = runCommand "nixos-manual-epub"
|
manualEpub = runCommand "nixos-manual-epub"
|
||||||
{ inherit sources;
|
{ inherit sources;
|
||||||
buildInputs = [ libxml2 libxslt zip ];
|
buildInputs = [ libxml2.bin libxslt.bin zip ];
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
# Generate the epub manual.
|
# Generate the epub manual.
|
||||||
@ -229,7 +302,7 @@ in rec {
|
|||||||
# Generate the NixOS manpages.
|
# Generate the NixOS manpages.
|
||||||
manpages = runCommand "nixos-manpages"
|
manpages = runCommand "nixos-manpages"
|
||||||
{ inherit sources;
|
{ inherit sources;
|
||||||
buildInputs = [ libxml2 libxslt ];
|
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||||
allowedReferences = ["out"];
|
allowedReferences = ["out"];
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
|
@ -22,6 +22,15 @@ options = {
|
|||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
|
The attribute names within the <replaceable>name</replaceable>
|
||||||
|
attribute path must be camel cased in general but should, as an
|
||||||
|
exception, match the
|
||||||
|
<link
|
||||||
|
xlink:href="https://nixos.org/nixpkgs/manual/#sec-package-naming">
|
||||||
|
package attribute name</link> when referencing a Nixpkgs package. For
|
||||||
|
example, the option <varname>services.nix-serve.bindAddress</varname>
|
||||||
|
references the <varname>nix-serve</varname> Nixpkgs package.
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The function <varname>mkOption</varname> accepts the following arguments.
|
<para>The function <varname>mkOption</varname> accepts the following arguments.
|
||||||
|
@ -110,6 +110,12 @@
|
|||||||
<listitem><para>A string. Multiple definitions are concatenated with a
|
<listitem><para>A string. Multiple definitions are concatenated with a
|
||||||
collon <literal>":"</literal>.</para></listitem>
|
collon <literal>":"</literal>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.strMatching</varname></term>
|
||||||
|
<listitem><para>A string matching a specific regular expression. Multiple
|
||||||
|
definitions cannot be merged. The regular expression is processed using
|
||||||
|
<literal>builtins.match</literal>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -276,8 +282,8 @@ options.mod = mkOption {
|
|||||||
option set (<xref linkend='ex-submodule-listof-definition' />).</para>
|
option set (<xref linkend='ex-submodule-listof-definition' />).</para>
|
||||||
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
|
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
|
||||||
nof submodules</title>
|
of submodules</title>
|
||||||
<screen>
|
<screen>
|
||||||
options.mod = mkOption {
|
options.mod = mkOption {
|
||||||
description = "submodule example";
|
description = "submodule example";
|
||||||
|
@ -11,15 +11,17 @@ tedious, so here is a quick way to see if the installer works
|
|||||||
properly:
|
properly:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build -A config.system.build.nixos-install
|
|
||||||
# mount -t tmpfs none /mnt
|
# mount -t tmpfs none /mnt
|
||||||
|
# nixos-generate-config --root /mnt
|
||||||
|
$ nix-build '<nixpkgs/nixos>' -A config.system.build.nixos-install
|
||||||
# ./result/bin/nixos-install</screen>
|
# ./result/bin/nixos-install</screen>
|
||||||
|
|
||||||
To start a login shell in the new NixOS installation in
|
To start a login shell in the new NixOS installation in
|
||||||
<filename>/mnt</filename>:
|
<filename>/mnt</filename>:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
# ./result/bin/nixos-install --chroot
|
$ nix-build '<nixpkgs/nixos>' -A config.system.build.nixos-enter
|
||||||
|
# ./result/bin/nixos-enter
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
@ -262,8 +262,47 @@ startAll;
|
|||||||
<literal>waitForWindow(qr/Terminal/)</literal>.</para></listitem>
|
<literal>waitForWindow(qr/Terminal/)</literal>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>copyFileFromHost</methodname></term>
|
||||||
|
<listitem><para>Copies a file from host to machine, e.g.,
|
||||||
|
<literal>copyFileFromHost("myfile", "/etc/my/important/file")</literal>.</para>
|
||||||
|
<para>The first argument is the file on the host. The file needs to be
|
||||||
|
accessible while building the nix derivation. The second argument is
|
||||||
|
the location of the file on the machine.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>systemctl</methodname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Runs <literal>systemctl</literal> commands with optional support for
|
||||||
|
<literal>systemctl --user</literal></para>
|
||||||
|
<para>
|
||||||
|
<programlisting>
|
||||||
|
$machine->systemctl("list-jobs --no-pager"); // runs `systemctl list-jobs --no-pager`
|
||||||
|
$machine->systemctl("list-jobs --no-pager", "any-user"); // spawns a shell for `any-user` and runs `systemctl --user list-jobs --no-pager`
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</section>
|
<para>
|
||||||
|
To test user units declared by <literal>systemd.user.services</literal> the optional <literal>$user</literal>
|
||||||
|
argument can be used:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
$machine->start;
|
||||||
|
$machine->waitForX;
|
||||||
|
$machine->waitForUnit("xautolock.service", "x-session-user");
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
This applies to <literal>systemctl</literal>, <literal>getUnitInfo</literal>,
|
||||||
|
<literal>waitForUnit</literal>, <literal>startJob</literal>
|
||||||
|
and <literal>stopJob</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
@ -70,9 +70,21 @@ $ ./result/bin/run-*-vm
|
|||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
The VM does not have any data from your host system, so your existing
|
The VM does not have any data from your host system, so your existing
|
||||||
user accounts and home directories will not be available. You can
|
user accounts and home directories will not be available unless you
|
||||||
forward ports on the host to the guest. For instance, the following
|
have set <literal>mutableUsers = false</literal>. Another way is to
|
||||||
will forward host port 2222 to guest port 22 (SSH):
|
temporarily add the following to your configuration:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
users.extraUsers.your-user.initialPassword = "test"
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<emphasis>Important:</emphasis> delete the $hostname.qcow2 file if you
|
||||||
|
have started the virtual machine at least once without the right
|
||||||
|
users, otherwise the changes will not get picked up.
|
||||||
|
|
||||||
|
You can forward ports on the host to the guest. For
|
||||||
|
instance, the following will forward host port 2222 to guest port 22
|
||||||
|
(SSH):
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ QEMU_NET_OPTS="hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
|
$ QEMU_NET_OPTS="hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
|
||||||
|
309
nixos/doc/manual/installation/installing-from-other-distro.xml
Normal file
309
nixos/doc/manual/installation/installing-from-other-distro.xml
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
<!-- vim: set expandtab ts=2 softtabstop=2 shiftwidth=2 smarttab textwidth=80 wrapmargin=2 -->
|
||||||
|
<section
|
||||||
|
xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-installing-from-other-distro">
|
||||||
|
|
||||||
|
<title>Installing from another Linux distribution</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Because Nix (the package manager) & Nixpkgs (the Nix packages
|
||||||
|
collection) can both be installed on any (most?) Linux distributions,
|
||||||
|
they can be used to install NixOS in various creative ways. You can,
|
||||||
|
for instance:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>Install NixOS on another partition, from your existing
|
||||||
|
Linux distribution (without the use of a USB or optical
|
||||||
|
device!)</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Install NixOS on the same partition (in place!), from
|
||||||
|
your existing non-NixOS Linux distribution using
|
||||||
|
<literal>NIXOS_LUSTRATE</literal>.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Install NixOS on your hard drive from the Live CD of
|
||||||
|
any Linux distribution.</para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
|
||||||
|
<para>The first steps to all these are the same:</para>
|
||||||
|
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Install the Nix package manager:</para>
|
||||||
|
|
||||||
|
<para>Short version:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ bash <(curl https://nixos.org/nix/install)
|
||||||
|
$ . $HOME/.nix-profile/etc/profile.d/nix.sh # …or open a fresh shell</screen>
|
||||||
|
|
||||||
|
<para>More details in the <link
|
||||||
|
xlink:href="https://nixos.org/nix/manual/#chap-quick-start">
|
||||||
|
Nix manual</link></para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Switch to the NixOS channel:</para>
|
||||||
|
|
||||||
|
<para>If you've just installed Nix on a non-NixOS distribution, you
|
||||||
|
will be on the <literal>nixpkgs</literal> channel by
|
||||||
|
default.</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nix-channel --list
|
||||||
|
nixpkgs https://nixos.org/channels/nixpkgs-unstable</screen>
|
||||||
|
|
||||||
|
<para>As that channel gets released without running the NixOS
|
||||||
|
tests, it will be safer to use the <literal>nixos-*</literal>
|
||||||
|
channels instead:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nix-channel --add https://nixos.org/channels/nixos-<replaceable>version</replaceable> nixpkgs</screen>
|
||||||
|
|
||||||
|
<para>You may want to throw in a <literal>nix-channel
|
||||||
|
--update</literal> for good measure.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Install the NixOS installation tools:</para>
|
||||||
|
|
||||||
|
<para>You'll need <literal>nixos-generate-config</literal> and
|
||||||
|
<literal>nixos-install</literal> and we'll throw in some man
|
||||||
|
pages and <literal>nixos-enter</literal> just in case you want
|
||||||
|
to chroot into your NixOS partition. They are installed by
|
||||||
|
default on NixOS, but you don't have NixOS yet..</para>
|
||||||
|
|
||||||
|
<screen>$ nix-env -iE "_: with import <nixpkgs/nixos> { configuration = {}; }; with config.system.build; [ nixos-generate-config nixos-install nixos-enter manual.manpages ]"</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<note><para>The following 5 steps are only for installing NixOS to
|
||||||
|
another partition. For installing NixOS in place using
|
||||||
|
<literal>NIXOS_LUSTRATE</literal>, skip ahead.</para></note>
|
||||||
|
|
||||||
|
<para>Prepare your target partition:</para>
|
||||||
|
|
||||||
|
<para>At this point it is time to prepare your target partition.
|
||||||
|
Please refer to the partitioning, file-system creation, and
|
||||||
|
mounting steps of <xref linkend="sec-installation" /></para>
|
||||||
|
|
||||||
|
<para>If you're about to install NixOS in place using
|
||||||
|
<literal>NIXOS_LUSTRATE</literal> there is nothing to do for
|
||||||
|
this step.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Generate your NixOS configuration:</para>
|
||||||
|
|
||||||
|
<screen>$ sudo `which nixos-generate-config` --root /mnt</screen>
|
||||||
|
|
||||||
|
<para>You'll probably want to edit the configuration files. Refer
|
||||||
|
to the <literal>nixos-generate-config</literal> step in <xref
|
||||||
|
linkend="sec-installation" /> for more information.</para>
|
||||||
|
|
||||||
|
<para>Consider setting up the NixOS bootloader to give you the
|
||||||
|
ability to boot on your existing Linux partition. For instance,
|
||||||
|
if you're using GRUB and your existing distribution is running
|
||||||
|
Ubuntu, you may want to add something like this to your
|
||||||
|
<literal>configuration.nix</literal>:</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
boot.loader.grub.extraEntries = ''
|
||||||
|
menuentry "Ubuntu" {
|
||||||
|
search --set=ubuntu --fs-uuid 3cc3e652-0c1f-4800-8451-033754f68e6e
|
||||||
|
configfile "($ubuntu)/boot/grub/grub.cfg"
|
||||||
|
}
|
||||||
|
'';</programlisting>
|
||||||
|
|
||||||
|
<para>(You can find the appropriate UUID for your partition in
|
||||||
|
<literal>/dev/disk/by-uuid</literal>)</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Create the <literal>nixbld</literal> group and user on your
|
||||||
|
original distribution:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ sudo groupadd -g 30000 nixbld
|
||||||
|
$ sudo useradd -u 30000 -g nixbld -G nixbld nixbld</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Download/build/install NixOS:</para>
|
||||||
|
|
||||||
|
<warning><para>Once you complete this step, you might no longer be
|
||||||
|
able to boot on existing systems without the help of a
|
||||||
|
rescue USB drive or similar.</para></warning>
|
||||||
|
|
||||||
|
<screen>$ sudo PATH="$PATH" NIX_PATH="$NIX_PATH" `which nixos-install` --root /mnt</screen>
|
||||||
|
|
||||||
|
<para>Again, please refer to the <literal>nixos-install</literal>
|
||||||
|
step in <xref linkend="sec-installation" /> for more
|
||||||
|
information.</para>
|
||||||
|
|
||||||
|
<para>That should be it for installation to another partition!</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Optionally, you may want to clean up your non-NixOS distribution:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ sudo userdel nixbld
|
||||||
|
$ sudo groupdel nixbld</screen>
|
||||||
|
|
||||||
|
<para>If you do not wish to keep the Nix package mananager
|
||||||
|
installed either, run something like <literal>sudo rm -rv
|
||||||
|
~/.nix-* /nix</literal> and remove the line that the Nix
|
||||||
|
installer added to your <literal>~/.profile</literal>.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<note><para>The following steps are only for installing NixOS in
|
||||||
|
place using
|
||||||
|
<literal>NIXOS_LUSTRATE</literal>:</para></note>
|
||||||
|
|
||||||
|
<para>Generate your NixOS configuration:</para>
|
||||||
|
|
||||||
|
<screen>$ sudo `which nixos-generate-config` --root /</screen>
|
||||||
|
|
||||||
|
<para>Note that this will place the generated configuration files
|
||||||
|
in <literal>/etc/nixos</literal>. You'll probably want to edit
|
||||||
|
the configuration files. Refer to the
|
||||||
|
<literal>nixos-generate-config</literal> step in <xref
|
||||||
|
linkend="sec-installation" /> for more information.</para>
|
||||||
|
|
||||||
|
<para>You'll likely want to set a root password for your first boot
|
||||||
|
using the configuration files because you won't have a chance
|
||||||
|
to enter a password until after you reboot. You can initalize
|
||||||
|
the root password to an empty one with this line: (and of course
|
||||||
|
don't forget to set one once you've rebooted or to lock the
|
||||||
|
account with <literal>sudo passwd -l root</literal> if you use
|
||||||
|
<literal>sudo</literal>)</para>
|
||||||
|
|
||||||
|
<programlisting>users.extraUsers.root.initialHashedPassword = "";</programlisting>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Build the NixOS closure and install it in the
|
||||||
|
<literal>system</literal> profile:</para>
|
||||||
|
|
||||||
|
<screen>$ nix-env -p /nix/var/nix/profiles/system -f '<nixpkgs/nixos>' -I nixos-config=/etc/nixos/configuration.nix -iA system</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Change ownership of the <literal>/nix</literal> tree to root
|
||||||
|
(since your Nix install was probably single user):</para>
|
||||||
|
|
||||||
|
<screen>$ sudo chown -R 0.0 /nix</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Set up the <literal>/etc/NIXOS</literal> and
|
||||||
|
<literal>/etc/NIXOS_LUSTRATE</literal> files:</para>
|
||||||
|
|
||||||
|
<para><literal>/etc/NIXOS</literal> officializes that this is now a
|
||||||
|
NixOS partition (the bootup scripts require its presence).</para>
|
||||||
|
|
||||||
|
<para><literal>/etc/NIXOS_LUSTRATE</literal> tells the NixOS bootup
|
||||||
|
scripts to move <emphasis>everything</emphasis> that's in the
|
||||||
|
root partition to <literal>/old-root</literal>. This will move
|
||||||
|
your existing distribution out of the way in the very early
|
||||||
|
stages of the NixOS bootup. There are exceptions (we do need to
|
||||||
|
keep NixOS there after all), so the NixOS lustrate process will
|
||||||
|
not touch:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>The <literal>/nix</literal>
|
||||||
|
directory</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The <literal>/boot</literal>
|
||||||
|
directory</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Any file or directory listed in
|
||||||
|
<literal>/etc/NIXOS_LUSTRATE</literal> (one per
|
||||||
|
line)</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
<note><para>Support for <literal>NIXOS_LUSTRATE</literal> was added
|
||||||
|
in NixOS 16.09. The act of "lustrating" refers to the
|
||||||
|
wiping of the existing distribution. Creating
|
||||||
|
<literal>/etc/NIXOS_LUSTRATE</literal> can also be used on
|
||||||
|
NixOS to remove all mutable files from your root partition
|
||||||
|
(anything that's not in <literal>/nix</literal> or
|
||||||
|
<literal>/boot</literal> gets "lustrated" on the next
|
||||||
|
boot.</para>
|
||||||
|
<para>lustrate /ˈlʌstreɪt/ verb.</para>
|
||||||
|
<para>purify by expiatory sacrifice, ceremonial washing, or
|
||||||
|
some other ritual action.</para></note>
|
||||||
|
|
||||||
|
<para>Let's create the files:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ sudo touch /etc/NIXOS
|
||||||
|
$ sudo touch /etc/NIXOS_LUSTRATE</screen>
|
||||||
|
|
||||||
|
<para>Let's also make sure the NixOS configuration files are kept
|
||||||
|
once we reboot on NixOS:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ echo etc/nixos | sudo tee -a /etc/NIXOS_LUSTRATE</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Finally, move the <literal>/boot</literal> directory of your
|
||||||
|
current distribution out of the way (the lustrate process will
|
||||||
|
take care of the rest once you reboot, but this one must be
|
||||||
|
moved out now because NixOS needs to install its own boot
|
||||||
|
files:</para>
|
||||||
|
|
||||||
|
<warning><para>Once you complete this step, your current
|
||||||
|
distribution will no longer be bootable! If you didn't get
|
||||||
|
all the NixOS configuration right, especially those
|
||||||
|
settings pertaining to boot loading and root partition,
|
||||||
|
NixOS may not be bootable either. Have a USB rescue device
|
||||||
|
ready in case this happens. </para></warning>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ sudo mv -v /boot /boot.bak &&
|
||||||
|
sudo /nix/var/nix/profiles/system/bin/switch-to-configuration boot</screen>
|
||||||
|
|
||||||
|
<para>Cross your fingers, reboot, hopefully you should get a NixOS
|
||||||
|
prompt!</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>If for some reason you want to revert to the old
|
||||||
|
distribution, you'll need to boot on a USB rescue disk and do
|
||||||
|
something along these lines:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# mkdir root
|
||||||
|
# mount /dev/sdaX root
|
||||||
|
# mkdir root/nixos-root
|
||||||
|
# mv -v root/* root/nixos-root/
|
||||||
|
# mv -v root/nixos-root/old-root/* root/
|
||||||
|
# mv -v root/boot.bak root/boot # We had renamed this by hand earlier
|
||||||
|
# umount root
|
||||||
|
# reboot</screen>
|
||||||
|
|
||||||
|
<para>This may work as is or you might also need to reinstall the
|
||||||
|
boot loader</para>
|
||||||
|
|
||||||
|
<para>And of course, if you're happy with NixOS and no longer need
|
||||||
|
the old distribution:</para>
|
||||||
|
|
||||||
|
<screen>sudo rm -rf /old-root</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>It's also worth noting that this whole process can be
|
||||||
|
automated. This is especially useful for Cloud VMs, where
|
||||||
|
provider do not provide NixOS. For instance, <link
|
||||||
|
xlink:href="https://github.com/elitak/nixos-infect">nixos-infect</link>
|
||||||
|
uses the lustrate process to convert Digital Ocean droplets to
|
||||||
|
NixOS from other distributions automatically.</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</section>
|
@ -1,48 +0,0 @@
|
|||||||
<section xmlns="http://docbook.org/ns/docbook"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
|
||||||
version="5.0"
|
|
||||||
xml:id="sec-uefi-installation">
|
|
||||||
|
|
||||||
<title>UEFI Installation</title>
|
|
||||||
|
|
||||||
<para>NixOS can also be installed on UEFI systems. The procedure
|
|
||||||
is by and large the same as a BIOS installation, with the following
|
|
||||||
changes:
|
|
||||||
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>You should boot the live CD in UEFI mode (consult your
|
|
||||||
specific hardware's documentation for instructions). You may find
|
|
||||||
the <link
|
|
||||||
xlink:href="http://www.rodsbooks.com/refind">rEFInd
|
|
||||||
boot manager</link> useful.</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>Instead of <command>fdisk</command>, you should use
|
|
||||||
<command>gdisk</command> to partition your disks. You will need to
|
|
||||||
have a separate partition for <filename>/boot</filename> with
|
|
||||||
partition code EF00, and it should be formatted as a
|
|
||||||
<literal>vfat</literal> filesystem.</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>Instead of <option>boot.loader.grub.device</option>,
|
|
||||||
you must set <option>boot.loader.systemd-boot.enable</option> to
|
|
||||||
<literal>true</literal>. <command>nixos-generate-config</command>
|
|
||||||
should do this automatically for new configurations when booted in
|
|
||||||
UEFI mode.</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>After having mounted your installation partition to
|
|
||||||
<code>/mnt</code>, you must mount the <code>boot</code> partition
|
|
||||||
to <code>/mnt/boot</code>.</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>You may want to look at the options starting with
|
|
||||||
<option>boot.loader.efi</option> and <option>boot.loader.systemd-boot</option>
|
|
||||||
as well.</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
|
@ -11,10 +11,24 @@ a USB stick. You can use the <command>dd</command> utility to write the image:
|
|||||||
<command>dd if=<replaceable>path-to-image</replaceable>
|
<command>dd if=<replaceable>path-to-image</replaceable>
|
||||||
of=<replaceable>/dev/sdb</replaceable></command>. Be careful about specifying the
|
of=<replaceable>/dev/sdb</replaceable></command>. Be careful about specifying the
|
||||||
correct drive; you can use the <command>lsblk</command> command to get a list of
|
correct drive; you can use the <command>lsblk</command> command to get a list of
|
||||||
block devices. If you're on macOS you can run <command>diskutil list</command>
|
block devices.</para>
|
||||||
to see the list of devices; the device you'll use for the USB must be ejected
|
|
||||||
before writing the image.</para>
|
|
||||||
|
|
||||||
|
<para>On macOS:
|
||||||
|
<programlisting>
|
||||||
|
$ diskutil list
|
||||||
|
[..]
|
||||||
|
/dev/diskN (external, physical):
|
||||||
|
#: TYPE NAME SIZE IDENTIFIER
|
||||||
|
[..]
|
||||||
|
$ diskutil unmountDisk diskN
|
||||||
|
Unmount of all volumes on diskN was successful
|
||||||
|
$ sudo dd bs=1m if=nix.iso of=/dev/rdiskN
|
||||||
|
</programlisting>
|
||||||
|
Using the 'raw' <command>rdiskN</command> device instead of <command>diskN</command>
|
||||||
|
completes in minutes instead of hours. After <command>dd</command> completes, a GUI
|
||||||
|
dialog "The disk you inserted was not readable by this computer" will pop up, which
|
||||||
|
can be ignored.</para>
|
||||||
|
|
||||||
<para>The <command>dd</command> utility will write the image verbatim to the drive,
|
<para>The <command>dd</command> utility will write the image verbatim to the drive,
|
||||||
making it the recommended option for both UEFI and non-UEFI installations. For
|
making it the recommended option for both UEFI and non-UEFI installations. For
|
||||||
non-UEFI installations, you can alternatively use
|
non-UEFI installations, you can alternatively use
|
||||||
|
@ -4,18 +4,18 @@
|
|||||||
version="5.0"
|
version="5.0"
|
||||||
xml:id="sec-instaling-virtualbox-guest">
|
xml:id="sec-instaling-virtualbox-guest">
|
||||||
|
|
||||||
<title>Installing in a Virtualbox guest</title>
|
<title>Installing in a VirtualBox guest</title>
|
||||||
<para>
|
<para>
|
||||||
Installing NixOS into a Virtualbox guest is convenient for users who want to
|
Installing NixOS into a VirtualBox guest is convenient for users who want to
|
||||||
try NixOS without installing it on bare metal. If you want to use a pre-made
|
try NixOS without installing it on bare metal. If you want to use a pre-made
|
||||||
Virtualbox appliance, it is available at <link
|
VirtualBox appliance, it is available at <link
|
||||||
xlink:href="https://nixos.org/nixos/download.html">the downloads page</link>.
|
xlink:href="https://nixos.org/nixos/download.html">the downloads page</link>.
|
||||||
If you want to set up a Virtualbox guest manually, follow these instructions:
|
If you want to set up a VirtualBox guest manually, follow these instructions:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
|
|
||||||
<listitem><para>Add a New Machine in Virtualbox with OS Type "Linux / Other
|
<listitem><para>Add a New Machine in VirtualBox with OS Type "Linux / Other
|
||||||
Linux"</para></listitem>
|
Linux"</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Base Memory Size: 768 MB or higher.</para></listitem>
|
<listitem><para>Base Memory Size: 768 MB or higher.</para></listitem>
|
||||||
|
@ -6,9 +6,18 @@
|
|||||||
|
|
||||||
<title>Installing NixOS</title>
|
<title>Installing NixOS</title>
|
||||||
|
|
||||||
|
<para>NixOS can be installed on BIOS or UEFI systems. The procedure
|
||||||
|
for a UEFI installation is by and large the same as a BIOS installation. The differences are mentioned in the steps that follow.</para>
|
||||||
|
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
|
|
||||||
<listitem><para>Boot from the CD.</para></listitem>
|
<listitem><para>Boot from the CD.</para>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry><term>UEFI systems</term>
|
||||||
|
<listitem><para>You should boot the live CD in UEFI mode
|
||||||
|
(consult your specific hardware's documentation for instructions).
|
||||||
|
You may find the <link xlink:href="http://www.rodsbooks.com/refind">rEFInd boot
|
||||||
|
manager</link> useful.</para></listitem></varlistentry></variablelist></listitem>
|
||||||
|
|
||||||
<listitem><para>The CD contains a basic NixOS installation. (It
|
<listitem><para>The CD contains a basic NixOS installation. (It
|
||||||
also contains Memtest86+, useful if you want to test new hardware).
|
also contains Memtest86+, useful if you want to test new hardware).
|
||||||
@ -36,7 +45,10 @@
|
|||||||
using <command>ifconfig</command>.</para>
|
using <command>ifconfig</command>.</para>
|
||||||
<para>To manually configure the network on the graphical installer,
|
<para>To manually configure the network on the graphical installer,
|
||||||
first disable network-manager with
|
first disable network-manager with
|
||||||
<command>systemctl stop network-manager</command>.</para></listitem>
|
<command>systemctl stop network-manager</command>.</para>
|
||||||
|
<para>To manually configure the wifi on the minimal installer, run
|
||||||
|
<command>wpa_supplicant -B -i interface -c <(wpa_passphrase 'SSID' 'key')</command>.</para></listitem>
|
||||||
|
|
||||||
|
|
||||||
<listitem><para>If you would like to continue the installation from a different
|
<listitem><para>If you would like to continue the installation from a different
|
||||||
machine you need to activate the SSH daemon via <literal>systemctl start sshd</literal>.
|
machine you need to activate the SSH daemon via <literal>systemctl start sshd</literal>.
|
||||||
@ -50,7 +62,31 @@
|
|||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
|
||||||
<listitem><para>For partitioning:
|
<listitem><para>For partitioning:
|
||||||
<command>fdisk</command>.</para></listitem>
|
<command>fdisk</command>.
|
||||||
|
<screen>
|
||||||
|
# fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
||||||
|
-- for UEFI systems only
|
||||||
|
> n # <lineannotation>(create a new partition for /boot)</lineannotation>
|
||||||
|
> 3 # <lineannotation>(make it a partition number 3)</lineannotation>
|
||||||
|
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||||
|
> +512M # <lineannotation>(the size of the UEFI boot partition)</lineannotation>
|
||||||
|
> t # <lineannotation>(change the partition type ...)</lineannotation>
|
||||||
|
> 3 # <lineannotation>(... of the boot partition ...)</lineannotation>
|
||||||
|
> 1 # <lineannotation>(... to 'UEFI System')</lineannotation>
|
||||||
|
-- for BIOS or UEFI systems
|
||||||
|
> n # <lineannotation>(create a new partition for /swap)</lineannotation>
|
||||||
|
> 2 # <lineannotation>(make it a partition number 2)</lineannotation>
|
||||||
|
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||||
|
> +8G # <lineannotation>(the size of the swap partition, set to whatever you like)</lineannotation>
|
||||||
|
> n # <lineannotation>(create a new partition for /)</lineannotation>
|
||||||
|
> 1 # <lineannotation>(make it a partition number 1)</lineannotation>
|
||||||
|
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||||
|
> # <lineannotation>(press enter to accept the default and use the rest of the remaining space)</lineannotation>
|
||||||
|
> a # <lineannotation>(make the partition bootable)</lineannotation>
|
||||||
|
> x # <lineannotation>(enter expert mode)</lineannotation>
|
||||||
|
> f # <lineannotation>(fix up the partition ordering)</lineannotation>
|
||||||
|
> r # <lineannotation>(exit expert mode)</lineannotation>
|
||||||
|
> w # <lineannotation>(write the partition table to disk and exit)</lineannotation></screen></para></listitem>
|
||||||
|
|
||||||
<listitem><para>For initialising Ext4 partitions:
|
<listitem><para>For initialising Ext4 partitions:
|
||||||
<command>mkfs.ext4</command>. It is recommended that you assign a
|
<command>mkfs.ext4</command>. It is recommended that you assign a
|
||||||
@ -67,7 +103,25 @@
|
|||||||
<listitem><para>For creating swap partitions:
|
<listitem><para>For creating swap partitions:
|
||||||
<command>mkswap</command>. Again it’s recommended to assign a
|
<command>mkswap</command>. Again it’s recommended to assign a
|
||||||
label to the swap partition: <option>-L
|
label to the swap partition: <option>-L
|
||||||
<replaceable>label</replaceable></option>.</para></listitem>
|
<replaceable>label</replaceable></option>. For example:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# mkswap -L swap /dev/sda2</screen>
|
||||||
|
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry><term>UEFI systems</term>
|
||||||
|
<listitem><para>For creating boot partitions:
|
||||||
|
<command>mkfs.fat</command>. Again it’s recommended to assign a
|
||||||
|
label to the boot partition: <option>-L
|
||||||
|
<replaceable>label</replaceable></option>. For example:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# mkfs.fat -F 32 -L boot /dev/sda3</screen>
|
||||||
|
|
||||||
|
</para></listitem></varlistentry></variablelist></listitem>
|
||||||
|
|
||||||
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
|
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
|
||||||
|
|
||||||
@ -95,11 +149,27 @@
|
|||||||
|
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry><term>UEFI systems</term>
|
||||||
|
<listitem><para>Mount the boot file system on <filename>/mnt/boot</filename>, e.g.
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# mount /dev/disk/by-label/boot /mnt/boot
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para></listitem></varlistentry></variablelist></listitem>
|
||||||
|
|
||||||
<listitem><para>If your machine has a limited amount of memory, you
|
<listitem><para>If your machine has a limited amount of memory, you
|
||||||
may want to activate swap devices now (<command>swapon
|
may want to activate swap devices now (<command>swapon
|
||||||
<replaceable>device</replaceable></command>). The installer (or
|
<replaceable>device</replaceable></command>). The installer (or
|
||||||
rather, the build actions that it may spawn) may need quite a bit of
|
rather, the build actions that it may spawn) may need quite a bit of
|
||||||
RAM, depending on your configuration.</para></listitem>
|
RAM, depending on your configuration.
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# swapon /dev/sda2</screen>
|
||||||
|
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
||||||
@ -135,10 +205,25 @@
|
|||||||
install Emacs by running <literal>nix-env -i
|
install Emacs by running <literal>nix-env -i
|
||||||
emacs</literal>.</para>
|
emacs</literal>.</para>
|
||||||
|
|
||||||
<para>You <emphasis>must</emphasis> set the option
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry><term>BIOS systems</term>
|
||||||
|
<listitem><para>You <emphasis>must</emphasis> set the option
|
||||||
<option>boot.loader.grub.device</option> to specify on which disk
|
<option>boot.loader.grub.device</option> to specify on which disk
|
||||||
the GRUB boot loader is to be installed. Without it, NixOS cannot
|
the GRUB boot loader is to be installed. Without it, NixOS cannot
|
||||||
boot.</para>
|
boot.</para></listitem></varlistentry>
|
||||||
|
|
||||||
|
<varlistentry><term>UEFI systems</term>
|
||||||
|
<listitem><para>You <emphasis>must</emphasis> set the option
|
||||||
|
<option>boot.loader.systemd-boot.enable</option> to <literal>true</literal>.
|
||||||
|
<command>nixos-generate-config</command> should do this automatically for new
|
||||||
|
configurations when booted in
|
||||||
|
UEFI mode.</para>
|
||||||
|
<para>You may want to look at the options starting with
|
||||||
|
<option>boot.loader.efi</option> and <option>boot.loader.systemd-boot</option>
|
||||||
|
as well.</para></listitem></varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
<para>If there are other operating systems running on the machine before
|
<para>If there are other operating systems running on the machine before
|
||||||
installing NixOS, the
|
installing NixOS, the
|
||||||
@ -190,11 +275,20 @@ Enter new UNIX password: ***
|
|||||||
Retype new UNIX password: ***
|
Retype new UNIX password: ***
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
To prevent the password prompt, set <code>users.mutableUsers = false;</code> in
|
||||||
|
<filename>configuration.nix</filename>, which allows unattended installation
|
||||||
|
necessary in automation.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem><para>If everything went well:
|
<listitem>
|
||||||
|
<para>If everything went well:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
# reboot</screen>
|
# reboot</screen>
|
||||||
@ -247,10 +341,34 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
|||||||
<example xml:id='ex-install-sequence'><title>Commands for Installing NixOS on <filename>/dev/sda</filename></title>
|
<example xml:id='ex-install-sequence'><title>Commands for Installing NixOS on <filename>/dev/sda</filename></title>
|
||||||
<screen>
|
<screen>
|
||||||
# fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
# fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
|
||||||
|
-- for UEFI systems only
|
||||||
|
> n # <lineannotation>(create a new partition for /boot)</lineannotation>
|
||||||
|
> 3 # <lineannotation>(make it a partition number 3)</lineannotation>
|
||||||
|
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||||
|
> +512M # <lineannotation>(the size of the UEFI boot partition)</lineannotation>
|
||||||
|
> t # <lineannotation>(change the partition type ...)</lineannotation>
|
||||||
|
> 3 # <lineannotation>(... of the boot partition ...)</lineannotation>
|
||||||
|
> 1 # <lineannotation>(... to 'UEFI System')</lineannotation>
|
||||||
|
-- for BIOS or UEFI systems
|
||||||
|
> n # <lineannotation>(create a new partition for /swap)</lineannotation>
|
||||||
|
> 2 # <lineannotation>(make it a partition number 2)</lineannotation>
|
||||||
|
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||||
|
> +8G # <lineannotation>(the size of the swap partition)</lineannotation>
|
||||||
|
> n # <lineannotation>(create a new partition for /)</lineannotation>
|
||||||
|
> 1 # <lineannotation>(make it a partition number 1)</lineannotation>
|
||||||
|
> # <lineannotation>(press enter to accept the default)</lineannotation>
|
||||||
|
> # <lineannotation>(press enter to accept the default and use the rest of the remaining space)</lineannotation>
|
||||||
|
> a # <lineannotation>(make the partition bootable)</lineannotation>
|
||||||
|
> x # <lineannotation>(enter expert mode)</lineannotation>
|
||||||
|
> f # <lineannotation>(fix up the partition ordering)</lineannotation>
|
||||||
|
> r # <lineannotation>(exit expert mode)</lineannotation>
|
||||||
|
> w # <lineannotation>(write the partition table to disk and exit)</lineannotation>
|
||||||
# mkfs.ext4 -L nixos /dev/sda1
|
# mkfs.ext4 -L nixos /dev/sda1
|
||||||
# mkswap -L swap /dev/sda2
|
# mkswap -L swap /dev/sda2
|
||||||
# swapon /dev/sda2
|
# swapon /dev/sda2
|
||||||
|
# mkfs.fat -F 32 -L boot /dev/sda3 # <lineannotation>(for UEFI systems only)</lineannotation>
|
||||||
# mount /dev/disk/by-label/nixos /mnt
|
# mount /dev/disk/by-label/nixos /mnt
|
||||||
|
# mount /dev/disk/by-label/boot /mnt/boot # <lineannotation>(for UEFI systems only)</lineannotation>
|
||||||
# nixos-generate-config --root /mnt
|
# nixos-generate-config --root /mnt
|
||||||
# nano /mnt/etc/nixos/configuration.nix
|
# nano /mnt/etc/nixos/configuration.nix
|
||||||
# nixos-install
|
# nixos-install
|
||||||
@ -267,7 +385,8 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
|||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.loader.grub.device = "/dev/sda";
|
boot.loader.grub.device = "/dev/sda"; # <lineannotation>(for BIOS systems only)</lineannotation>
|
||||||
|
boot.loader.systemd-boot.enable = true; # <lineannotation>(for UEFI systems only)</lineannotation>
|
||||||
|
|
||||||
# Note: setting fileSystems is generally not
|
# Note: setting fileSystems is generally not
|
||||||
# necessary, since nixos-generate-config figures them out
|
# necessary, since nixos-generate-config figures them out
|
||||||
@ -279,9 +398,9 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
|||||||
}</screen>
|
}</screen>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<xi:include href="installing-uefi.xml" />
|
|
||||||
<xi:include href="installing-usb.xml" />
|
<xi:include href="installing-usb.xml" />
|
||||||
<xi:include href="installing-pxe.xml" />
|
<xi:include href="installing-pxe.xml" />
|
||||||
<xi:include href="installing-virtualbox-guest.xml" />
|
<xi:include href="installing-virtualbox-guest.xml" />
|
||||||
|
<xi:include href="installing-from-other-distro.xml" />
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -12,11 +12,10 @@ download page</link>. There are a number of installation options. If
|
|||||||
you happen to have an optical drive and a spare CD, burning the
|
you happen to have an optical drive and a spare CD, burning the
|
||||||
image to CD and booting from that is probably the easiest option.
|
image to CD and booting from that is probably the easiest option.
|
||||||
Most people will need to prepare a USB stick to boot from.
|
Most people will need to prepare a USB stick to boot from.
|
||||||
Unetbootin is recommended and the process is described in brief below.
|
<xref linkend="sec-booting-from-usb"/> describes the preferred method
|
||||||
Note that systems which use UEFI require some additional manual steps.
|
to prepare a USB stick.
|
||||||
If you run into difficulty a number of alternative methods are presented
|
A number of alternative methods are presented in the <link
|
||||||
in the <link
|
xlink:href="https://nixos.wiki/wiki/NixOS_Installation_Guide#Making_the_installation_media">NixOS
|
||||||
xlink:href="https://nixos.org/wiki/Installing_NixOS_from_a_USB_stick">NixOS
|
|
||||||
Wiki</link>.</para>
|
Wiki</link>.</para>
|
||||||
|
|
||||||
<para>As an alternative to installing NixOS yourself, you can get a
|
<para>As an alternative to installing NixOS yourself, you can get a
|
||||||
|
119
nixos/doc/manual/man-nixos-enter.xml
Normal file
119
nixos/doc/manual/man-nixos-enter.xml
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle><command>nixos-enter</command></refentrytitle>
|
||||||
|
<manvolnum>8</manvolnum>
|
||||||
|
<refmiscinfo class="source">NixOS</refmiscinfo>
|
||||||
|
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname><command>nixos-enter</command></refname>
|
||||||
|
<refpurpose>run a command in a NixOS chroot environment</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>nixos-enter</command>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>--root</option></arg>
|
||||||
|
<replaceable>root</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>--system</option></arg>
|
||||||
|
<replaceable>system</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>-c</option></arg>
|
||||||
|
<replaceable>shell-command</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>--help</option></arg>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>--</option></arg>
|
||||||
|
<replaceable>arguments</replaceable>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
|
||||||
|
<refsection><title>Description</title>
|
||||||
|
|
||||||
|
<para>This command runs a command in a NixOS chroot environment, that
|
||||||
|
is, in a filesystem hierarchy previously prepared using
|
||||||
|
<command>nixos-install</command>.</para>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
<refsection><title>Options</title>
|
||||||
|
|
||||||
|
<para>This command accepts the following options:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--root</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The path to the NixOS system you want to enter. It defaults to <filename>/mnt</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--system</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The NixOS system configuration to use. It defaults to
|
||||||
|
<filename>/nix/var/nix/profiles/system</filename>. You can enter
|
||||||
|
a previous NixOS configuration by specifying a path such as
|
||||||
|
<filename>/nix/var/nix/profiles/system-106-link</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--command</option></term>
|
||||||
|
<term><option>-c</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The bash command to execute.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Interpret the remaining arguments as the program
|
||||||
|
name and arguments to be invoked. The program is not executed in a
|
||||||
|
shell.</para></listitem>
|
||||||
|
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
|
||||||
|
<refsection><title>Examples</title>
|
||||||
|
|
||||||
|
<para>Start an interactive shell in the NixOS installation in
|
||||||
|
<filename>/mnt</filename>:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# nixos-enter /mnt
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>Run a shell command:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# nixos-enter -c 'ls -l /; cat /proc/mounts'
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>Run a non-shell command:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# nixos-enter -- cat /proc/mounts
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
</refentry>
|
@ -26,8 +26,8 @@
|
|||||||
<replaceable>root</replaceable>
|
<replaceable>root</replaceable>
|
||||||
</arg>
|
</arg>
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'><option>--closure</option></arg>
|
<arg choice='plain'><option>--system</option></arg>
|
||||||
<replaceable>closure</replaceable>
|
<replaceable>path</replaceable>
|
||||||
</arg>
|
</arg>
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'><option>--no-channel-copy</option></arg>
|
<arg choice='plain'><option>--no-channel-copy</option></arg>
|
||||||
@ -118,7 +118,7 @@ it.</para>
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--closure</option></term>
|
<term><option>--system</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>If this option is provided, <command>nixos-install</command> will install the specified closure
|
<para>If this option is provided, <command>nixos-install</command> will install the specified closure
|
||||||
rather than attempt to build one from <filename>/mnt/etc/nixos/configuration.nix</filename>.</para>
|
rather than attempt to build one from <filename>/mnt/etc/nixos/configuration.nix</filename>.</para>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</author>
|
</author>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2007-2015</year>
|
<year>2007-2018</year>
|
||||||
<holder>Eelco Dolstra</holder>
|
<holder>Eelco Dolstra</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
@ -25,6 +25,7 @@
|
|||||||
<xi:include href="man-nixos-build-vms.xml" />
|
<xi:include href="man-nixos-build-vms.xml" />
|
||||||
<xi:include href="man-nixos-generate-config.xml" />
|
<xi:include href="man-nixos-generate-config.xml" />
|
||||||
<xi:include href="man-nixos-install.xml" />
|
<xi:include href="man-nixos-install.xml" />
|
||||||
|
<xi:include href="man-nixos-enter.xml" />
|
||||||
<xi:include href="man-nixos-option.xml" />
|
<xi:include href="man-nixos-option.xml" />
|
||||||
<xi:include href="man-nixos-rebuild.xml" />
|
<xi:include href="man-nixos-rebuild.xml" />
|
||||||
<xi:include href="man-nixos-version.xml" />
|
<xi:include href="man-nixos-version.xml" />
|
||||||
|
@ -70,6 +70,15 @@
|
|||||||
</para>
|
</para>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
|
|
||||||
|
<xsl:if test="attr[@name = 'relatedPackages']">
|
||||||
|
<para>
|
||||||
|
<emphasis>Related packages:</emphasis>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of disable-output-escaping="yes"
|
||||||
|
select="attr[@name = 'relatedPackages']/string/@value" />
|
||||||
|
</para>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
<xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
|
<xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
|
||||||
<para>
|
<para>
|
||||||
<emphasis>Declared by:</emphasis>
|
<emphasis>Declared by:</emphasis>
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<para>This section lists the release notes for each stable version of NixOS
|
<para>This section lists the release notes for each stable version of NixOS
|
||||||
and current unstable revision.</para>
|
and current unstable revision.</para>
|
||||||
|
|
||||||
|
<xi:include href="rl-1809.xml" />
|
||||||
<xi:include href="rl-1803.xml" />
|
<xi:include href="rl-1803.xml" />
|
||||||
<xi:include href="rl-1709.xml" />
|
<xi:include href="rl-1709.xml" />
|
||||||
<xi:include href="rl-1703.xml" />
|
<xi:include href="rl-1703.xml" />
|
||||||
|
@ -13,7 +13,7 @@ the following highlights:
|
|||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
|
||||||
<listitem><para>Installation on UEFI systems is now supported. See
|
<listitem><para>Installation on UEFI systems is now supported. See
|
||||||
<xref linkend="sec-uefi-installation"/> for
|
<xref linkend="sec-installation"/> for
|
||||||
details.</para></listitem>
|
details.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Systemd has been updated to version 212, which has
|
<listitem><para>Systemd has been updated to version 212, which has
|
||||||
|
@ -20,8 +20,53 @@ has the following highlights: </para>
|
|||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
|
Nix now defaults to 2.0; see its
|
||||||
|
<link xlink:href="https://nixos.org/nix/manual/#ssec-relnotes-2.0">release notes</link>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Linux kernel defaults to the 4.14 branch (it was 4.9).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
GCC defaults to 7.x (it was 6.x).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
MariaDB 10.2, updated from 10.1, is now the default MySQL implementation. While upgrading a few changes
|
||||||
|
have been made to the infrastructure involved:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>libmysql</literal> has been deprecated, please use <literal>mysql.connector-c</literal>
|
||||||
|
instead, a compatibility passthru has been added to the MySQL packages.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>mysql57</literal> package has a new <literal>static</literal> output containing
|
||||||
|
the static libraries including <literal>libmysqld.a</literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The GNOME version is now 3.26.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>PHP now defaults to PHP 7.2</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -54,6 +99,11 @@ has the following highlights: </para>
|
|||||||
following incompatible changes:</para>
|
following incompatible changes:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>sound.enable</literal> now defaults to false.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Dollar signs in options under <option>services.postfix</option> are
|
Dollar signs in options under <option>services.postfix</option> are
|
||||||
@ -72,6 +122,28 @@ following incompatible changes:</para>
|
|||||||
<option>services.pgmanage</option>.
|
<option>services.pgmanage</option>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Package attributes starting with a digit have been prefixed with an
|
||||||
|
underscore sign. This is to avoid quoting in the configuration and
|
||||||
|
other issues with command-line tools like <literal>nix-env</literal>.
|
||||||
|
The change affects the following packages:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para><literal>2048-in-terminal</literal> → <literal>_2048-in-terminal</literal></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><literal>90secondportraits</literal> → <literal>_90secondportraits</literal></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><literal>2bwm</literal> → <literal>_2bwm</literal></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><literal>389-ds-base</literal> → <literal>_389-ds-base</literal></para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<emphasis role="strong">
|
<emphasis role="strong">
|
||||||
@ -95,6 +167,198 @@ following incompatible changes:</para>
|
|||||||
<link xlink:href="https://search.nix.gsc.io/?q=stateVersion">here</link>.
|
<link xlink:href="https://search.nix.gsc.io/?q=stateVersion">here</link>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>openssh</literal> package
|
||||||
|
now includes Kerberos support by default;
|
||||||
|
the <literal>openssh_with_kerberos</literal> package
|
||||||
|
is now a deprecated alias.
|
||||||
|
If you do not want Kerberos support,
|
||||||
|
you can do <literal>openssh.override { withKerboros = false; }</literal>.
|
||||||
|
Note, this also applies to the <literal>openssh_hpn</literal> package.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>cc-wrapper</literal> has been split in two; there is now also a <literal>bintools-wrapper</literal>.
|
||||||
|
The most commonly used files in <filename>nix-support</filename> are now split between the two wrappers.
|
||||||
|
Some commonly used ones, like <filename>nix-support/dynamic-linker</filename>, are duplicated for backwards compatability, even though they rightly belong only in <literal>bintools-wrapper</literal>.
|
||||||
|
Other more obscure ones are just moved.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The propagation logic has been changed.
|
||||||
|
The new logic, along with new types of dependencies that go with, is thoroughly documented in the "Specifying dependencies" section of the "Standard Environment" chapter of the nixpkgs manual.
|
||||||
|
<!-- That's <xref linkend="ssec-stdenv-attributes"> were we to merge the manuals. -->
|
||||||
|
The old logic isn't but is easy to describe: dependencies were propagated as the same type of dependency no matter what.
|
||||||
|
In practice, that means that many <function>propagatedNativeBuildInputs</function> should instead be <function>propagatedBuildInputs</function>.
|
||||||
|
Thankfully, that was and is the least used type of dependency.
|
||||||
|
Also, it means that some <function>propagatedBuildInputs</function> should instead be <function>depsTargetTargetPropagated</function>.
|
||||||
|
Other types dependencies should be unaffected.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>lib.addPassthru drv passthru</literal> is removed. Use <literal>lib.extendDerivation true passthru drv</literal> instead.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>memcached</literal> service no longer accept dynamic socket
|
||||||
|
paths via <option>services.memcached.socket</option>. Unix sockets can be
|
||||||
|
still enabled by <option>services.memcached.enableUnixSocket</option> and
|
||||||
|
will be accessible at <literal>/run/memcached/memcached.sock</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <varname>hardware.amdHybridGraphics.disable</varname> option was removed for lack of a maintainer. If you still need this module, you may wish to include a copy of it from an older version of nixos in your imports.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The merging of config options for <varname>services.postfix.config</varname>
|
||||||
|
was buggy. Previously, if other options in the Postfix module like
|
||||||
|
<varname>services.postfix.useSrs</varname> were set and the user set config
|
||||||
|
options that were also set by such options, the resulting config wouldn't
|
||||||
|
include all options that were needed. They are now merged correctly. If
|
||||||
|
config options need to be overridden, <literal>lib.mkForce</literal> or
|
||||||
|
<literal>lib.mkOverride</literal> can be used.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The following changes apply if the <literal>stateVersion</literal> is changed to 18.03 or higher.
|
||||||
|
For <literal>stateVersion = "17.09"</literal> or lower the old behavior is preserved.
|
||||||
|
</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>matrix-synapse</literal> uses postgresql by default instead of sqlite.
|
||||||
|
Migration instructions can be found <link xlink:href="https://github.com/matrix-org/synapse/blob/master/docs/postgres.rst#porting-from-sqlite"> here </link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>jid</literal> package has been removed, due to maintenance
|
||||||
|
overhead of a go package having non-versioned dependencies.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
When using <option>services.xserver.libinput</option> (enabled by default in GNOME),
|
||||||
|
it now handles all input devices, not just touchpads. As a result, you might need to
|
||||||
|
re-evaluate any custom Xorg configuration. In particular,
|
||||||
|
<literal>Option "XkbRules" "base"</literal> may result in broken keyboard layout.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>attic</literal> package was removed. A maintained fork called
|
||||||
|
<link xlink:href="https://www.borgbackup.org/">Borg</link> should be used instead.
|
||||||
|
Migration instructions can be found
|
||||||
|
<link xlink:href="http://borgbackup.readthedocs.io/en/stable/usage/upgrade.html#attic-and-borg-0-xx-to-borg-1-x">here</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The Piwik analytics software was renamed to Matomo:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>The package <literal>pkgs.piwik</literal> was renamed to <literal>pkgs.matomo</literal>.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>The service <literal>services.piwik</literal> was renamed to <literal>services.matomo</literal>.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The data directory <filename>/var/lib/piwik</filename> was renamed to <filename>/var/lib/matomo</filename>.
|
||||||
|
All files will be moved automatically on first startup, but you might need to adjust your backup scripts.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The default <option>serverName</option> for the nginx configuration changed from
|
||||||
|
<literal>piwik.${config.networking.hostName}</literal> to
|
||||||
|
<literal>matomo.${config.networking.hostName}.${config.networking.domain}</literal>
|
||||||
|
if <option>config.networking.domain</option> is set,
|
||||||
|
<literal>matomo.${config.networking.hostName}</literal> if it is not set.
|
||||||
|
If you change your <option>serverName</option>, remember you'll need to update the
|
||||||
|
<literal>trustedHosts[]</literal> array in <filename>/var/lib/matomo/config/config.ini.php</filename>
|
||||||
|
as well.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>piwik</literal> user was renamed to <literal>matomo</literal>.
|
||||||
|
The service will adjust ownership automatically for files in the data directory.
|
||||||
|
If you use unix socket authentication, remember to give the new <literal>matomo</literal> user
|
||||||
|
access to the database and to change the <literal>username</literal> to <literal>matomo</literal>
|
||||||
|
in the <literal>[database]</literal> section of <filename>/var/lib/matomo/config/config.ini.php</filename>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
If you named your database `piwik`, you might want to rename it to `matomo` to keep things clean,
|
||||||
|
but this is neither enforced nor required.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>nodejs-4_x</literal> is end-of-life.
|
||||||
|
<literal>nodejs-4_x</literal>, <literal>nodejs-slim-4_x</literal> and <literal>nodePackages_4_x</literal> are removed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>pump.io</literal> NixOS module was removed.
|
||||||
|
It is now maintained as an
|
||||||
|
<link xlink:href="https://github.com/rvl/pump.io-nixos">external module</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The Prosody XMPP server has received a major update. The following modules were renamed:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>services.prosody.modules.httpserver</option> is now <option>services.prosody.modules.http_files</option>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>services.prosody.modules.console</option> is now <option>services.prosody.modules.admin_telnet</option>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Many new modules are now core modules, most notably <option>services.prosody.modules.carbons</option>
|
||||||
|
and <option>services.prosody.modules.mam</option>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The better-performing <literal>libevent</literal> backend is now enabled by default.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<literal>withCommunityModules</literal> now passes through the modules to <option>services.prosody.extraModules</option>.
|
||||||
|
Use <literal>withOnlyInstalledCommunityModules</literal> for modules that should not be enabled directly, e.g <literal>lib_ldap</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
All prometheus exporter modules are now defined as submodules.
|
||||||
|
The exporters are configured using <literal>services.prometheus.exporters</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -125,10 +389,115 @@ following incompatible changes:</para>
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The option <option>services.xserver.desktopManager.default</option> is now <literal>none</literal> by default.
|
In the module <option>networking.interfaces.<name></option> the
|
||||||
An assertion failure is thrown if WM's and DM's default are <literal>none</literal>.
|
following options have been removed:
|
||||||
To explicitly run a plain X session without and DM or WM, the newly introduced option <option>services.xserver.plainX</option>
|
<itemizedlist>
|
||||||
must be set to true.
|
<listitem>
|
||||||
|
<para><option>ipAddress</option></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><option>ipv6Address</option></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><option>prefixLength</option></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><option>ipv6PrefixLength</option></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><option>subnetMask</option></para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
To assign static addresses to an interface the options
|
||||||
|
<option>ipv4.addresses</option> and <option>ipv6.addresses</option>
|
||||||
|
should be used instead.
|
||||||
|
The options <option>ip4</option> and <option>ip6</option> have been
|
||||||
|
renamed to <option>ipv4.addresses</option> <option>ipv6.addresses</option>
|
||||||
|
respectively.
|
||||||
|
The new options <option>ipv4.routes</option> and <option>ipv6.routes</option>
|
||||||
|
have been added to set up static routing.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The option <option>services.xserver.desktopManager.default</option> is now
|
||||||
|
<literal>none</literal> by default. An assertion failure is thrown if WM's
|
||||||
|
and DM's default are <literal>none</literal>.
|
||||||
|
To explicitly run a plain X session without and DM or WM, the newly
|
||||||
|
introduced option <option>services.xserver.plainX</option> must be set to true.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The option <option>services.logstash.listenAddress</option> is now <literal>127.0.0.1</literal> by default.
|
||||||
|
Previously the default behaviour was to listen on all interfaces.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>services.btrfs.autoScrub</literal> has been added, to
|
||||||
|
periodically check btrfs filesystems for data corruption.
|
||||||
|
If there's a correct copy available, it will automatically repair
|
||||||
|
corrupted blocks.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>displayManager.lightdm.greeters.gtk.clock-format.</literal>
|
||||||
|
has been added, the clock format string (as expected by
|
||||||
|
strftime, e.g. <literal>%H:%M</literal>) to use with the lightdm
|
||||||
|
gtk greeter panel.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If set to null the default clock format is used.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>displayManager.lightdm.greeters.gtk.indicators</literal>
|
||||||
|
has been added, a list of allowed indicator modules to use with
|
||||||
|
the lightdm gtk greeter panel.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Built-in indicators include <literal>~a11y</literal>,
|
||||||
|
<literal>~language</literal>, <literal>~session</literal>,
|
||||||
|
<literal>~power</literal>, <literal>~clock</literal>,
|
||||||
|
<literal>~host</literal>, <literal>~spacer</literal>. Unity
|
||||||
|
indicators can be represented by short name
|
||||||
|
(e.g. <literal>sound</literal>, <literal>power</literal>),
|
||||||
|
service file name, or absolute path.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If set to <literal>null</literal> the default indicators are
|
||||||
|
used.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
In order to have the previous default configuration add
|
||||||
|
<programlisting>
|
||||||
|
services.xserver.displayManager.lightdm.greeters.gtk.indicators = [
|
||||||
|
"~host" "~spacer"
|
||||||
|
"~clock" "~spacer"
|
||||||
|
"~session"
|
||||||
|
"~language"
|
||||||
|
"~a11y"
|
||||||
|
"~power"
|
||||||
|
];
|
||||||
|
</programlisting>
|
||||||
|
to your <literal>configuration.nix</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The NixOS test driver supports user services declared by <literal>systemd.user.services</literal>.
|
||||||
|
The methods <literal>waitForUnit</literal>, <literal>getUnitInfo</literal>, <literal>startJob</literal>
|
||||||
|
and <literal>stopJob</literal> provide an optional <literal>$user</literal> argument for that purpose.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Enabling bash completion on NixOS, <literal>programs.bash.enableCompletion</literal>, will now also enable
|
||||||
|
completion for the Nix command line tools by installing the
|
||||||
|
<link xlink:href="https://github.com/hedning/nix-bash-completions">nix-bash-completions</link> package.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
82
nixos/doc/manual/release-notes/rl-1809.xml
Normal file
82
nixos/doc/manual/release-notes/rl-1809.xml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.09">
|
||||||
|
|
||||||
|
<title>Release 18.09 (“Jellyfish”, 2018/09/??)</title>
|
||||||
|
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.09-highlights">
|
||||||
|
|
||||||
|
<title>Highlights</title>
|
||||||
|
|
||||||
|
<para>In addition to numerous new and upgraded packages, this release
|
||||||
|
has the following highlights: </para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
TODO
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.09-new-services">
|
||||||
|
|
||||||
|
<title>New Services</title>
|
||||||
|
|
||||||
|
<para>The following new services were added since the last release:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para></para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.09-incompatibilities">
|
||||||
|
|
||||||
|
<title>Backward Incompatibilities</title>
|
||||||
|
|
||||||
|
<para>When upgrading from a previous release, please be aware of the
|
||||||
|
following incompatible changes:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.09-notable-changes">
|
||||||
|
|
||||||
|
<title>Other Notable Changes</title>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</section>
|
@ -3,7 +3,7 @@
|
|||||||
let pkgs = import ../.. { inherit system config; }; in
|
let pkgs = import ../.. { inherit system config; }; in
|
||||||
|
|
||||||
with pkgs.lib;
|
with pkgs.lib;
|
||||||
with import ../lib/qemu-flags.nix;
|
with import ../lib/qemu-flags.nix { inherit pkgs; };
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ rec {
|
|||||||
let
|
let
|
||||||
interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
|
interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
|
||||||
interfaces = flip map interfacesNumbered ({ fst, snd }:
|
interfaces = flip map interfacesNumbered ({ fst, snd }:
|
||||||
nameValuePair "eth${toString snd}" { ip4 =
|
nameValuePair "eth${toString snd}" { ipv4.addresses =
|
||||||
[ { address = "192.168.${toString fst}.${toString m.snd}";
|
[ { address = "192.168.${toString fst}.${toString m.snd}";
|
||||||
prefixLength = 24;
|
prefixLength = 24;
|
||||||
} ];
|
} ];
|
||||||
@ -64,7 +64,7 @@ rec {
|
|||||||
networking.interfaces = listToAttrs interfaces;
|
networking.interfaces = listToAttrs interfaces;
|
||||||
|
|
||||||
networking.primaryIPAddress =
|
networking.primaryIPAddress =
|
||||||
optionalString (interfaces != []) (head (head interfaces).value.ip4).address;
|
optionalString (interfaces != []) (head (head interfaces).value.ipv4.addresses).address;
|
||||||
|
|
||||||
# Put the IP addresses of all VMs in this machine's
|
# Put the IP addresses of all VMs in this machine's
|
||||||
# /etc/hosts file. If a machine has multiple
|
# /etc/hosts file. If a machine has multiple
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
# grafted in the file system at path `target'.
|
# grafted in the file system at path `target'.
|
||||||
, contents ? []
|
, contents ? []
|
||||||
|
|
||||||
, # Whether the disk should be partitioned (with a single partition
|
, # Type of partition table to use; either "legacy", "efi", or "none".
|
||||||
# containing the root filesystem) or contain the root filesystem
|
# For "efi" images, the GPT partition table is used and a mandatory ESP
|
||||||
# directly.
|
# partition of reasonable size is created in addition to the root partition.
|
||||||
partitioned ? true
|
# If `installBootLoader` is true, GRUB will be installed in EFI mode.
|
||||||
|
# For "legacy", the msdos partition table is used and a single large root
|
||||||
|
# partition is created. If `installBootLoader` is true, GRUB will be
|
||||||
|
# installed in legacy mode.
|
||||||
|
# For "none", no partition table is created. Enabling `installBootLoader`
|
||||||
|
# most likely fails as GRUB will probably refuse to install.
|
||||||
|
partitionTableType ? "legacy"
|
||||||
|
|
||||||
# Whether to invoke switch-to-configuration boot during image creation
|
# Whether to invoke switch-to-configuration boot during image creation
|
||||||
, installBootLoader ? true
|
, installBootLoader ? true
|
||||||
@ -37,11 +43,15 @@
|
|||||||
format ? "raw"
|
format ? "raw"
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
assert partitionTableType == "legacy" || partitionTableType == "efi" || partitionTableType == "none";
|
||||||
|
# We use -E offset=X below, which is only supported by e2fsprogs
|
||||||
|
assert partitionTableType != "none" -> fsType == "ext4";
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let format' = format; in let
|
let format' = format; in let
|
||||||
|
|
||||||
format = if (format' == "qcow2-compressed") then "qcow2" else format';
|
format = if format' == "qcow2-compressed" then "qcow2" else format';
|
||||||
|
|
||||||
compress = optionalString (format' == "qcow2-compressed") "-c";
|
compress = optionalString (format' == "qcow2-compressed") "-c";
|
||||||
|
|
||||||
@ -51,9 +61,31 @@ let format' = format; in let
|
|||||||
raw = "img";
|
raw = "img";
|
||||||
}.${format};
|
}.${format};
|
||||||
|
|
||||||
|
rootPartition = { # switch-case
|
||||||
|
legacy = "1";
|
||||||
|
efi = "2";
|
||||||
|
}.${partitionTableType};
|
||||||
|
|
||||||
|
partitionDiskScript = { # switch-case
|
||||||
|
legacy = ''
|
||||||
|
parted --script $diskImage -- \
|
||||||
|
mklabel msdos \
|
||||||
|
mkpart primary ext4 1MiB -1
|
||||||
|
'';
|
||||||
|
efi = ''
|
||||||
|
parted --script $diskImage -- \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart ESP fat32 8MiB 256MiB \
|
||||||
|
set 1 boot on \
|
||||||
|
mkpart primary ext4 256MiB -1
|
||||||
|
'';
|
||||||
|
none = "";
|
||||||
|
}.${partitionTableType};
|
||||||
|
|
||||||
nixpkgs = cleanSource pkgs.path;
|
nixpkgs = cleanSource pkgs.path;
|
||||||
|
|
||||||
channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}" {} ''
|
# FIXME: merge with channel.nix / make-channel.nix.
|
||||||
|
channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}" {} ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp -prd ${nixpkgs} $out/nixos
|
cp -prd ${nixpkgs} $out/nixos
|
||||||
chmod -R u+w $out/nixos
|
chmod -R u+w $out/nixos
|
||||||
@ -61,16 +93,19 @@ let format' = format; in let
|
|||||||
ln -s . $out/nixos/nixpkgs
|
ln -s . $out/nixos/nixpkgs
|
||||||
fi
|
fi
|
||||||
rm -rf $out/nixos/.git
|
rm -rf $out/nixos/.git
|
||||||
echo -n ${config.system.nixosVersionSuffix} > $out/nixos/.version-suffix
|
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
|
||||||
'';
|
'';
|
||||||
|
|
||||||
metaClosure = pkgs.writeText "meta" ''
|
binPath = with pkgs; makeBinPath (
|
||||||
${config.system.build.toplevel}
|
[ rsync
|
||||||
${config.nix.package.out}
|
utillinux
|
||||||
${channelSources}
|
parted
|
||||||
'';
|
e2fsprogs
|
||||||
|
lkl
|
||||||
prepareImageInputs = with pkgs; [ rsync utillinux parted e2fsprogs lkl fakeroot config.system.build.nixos-prepare-root ] ++ stdenv.initialPath;
|
config.system.build.nixos-install
|
||||||
|
config.system.build.nixos-enter
|
||||||
|
nix
|
||||||
|
] ++ stdenv.initialPath);
|
||||||
|
|
||||||
# I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate
|
# I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate
|
||||||
# image building logic. The comment right below this now appears in 4 different places in nixpkgs :)
|
# image building logic. The comment right below this now appears in 4 different places in nixpkgs :)
|
||||||
@ -78,21 +113,34 @@ let format' = format; in let
|
|||||||
sources = map (x: x.source) contents;
|
sources = map (x: x.source) contents;
|
||||||
targets = map (x: x.target) contents;
|
targets = map (x: x.target) contents;
|
||||||
|
|
||||||
|
closureInfo = pkgs.closureInfo { rootPaths = [ config.system.build.toplevel channelSources ]; };
|
||||||
|
|
||||||
prepareImage = ''
|
prepareImage = ''
|
||||||
export PATH=${makeSearchPathOutput "bin" "bin" prepareImageInputs}
|
export PATH=${binPath}
|
||||||
|
|
||||||
|
# Yes, mkfs.ext4 takes different units in different contexts. Fun.
|
||||||
|
sectorsToKilobytes() {
|
||||||
|
echo $(( ( "$1" * 512 ) / 1024 ))
|
||||||
|
}
|
||||||
|
|
||||||
|
sectorsToBytes() {
|
||||||
|
echo $(( "$1" * 512 ))
|
||||||
|
}
|
||||||
|
|
||||||
mkdir $out
|
mkdir $out
|
||||||
diskImage=nixos.raw
|
diskImage=nixos.raw
|
||||||
truncate -s ${toString diskSize}M $diskImage
|
truncate -s ${toString diskSize}M $diskImage
|
||||||
|
|
||||||
${if partitioned then ''
|
${partitionDiskScript}
|
||||||
parted --script $diskImage -- mklabel msdos mkpart primary ext4 1M -1s
|
|
||||||
offset=$((2048*512))
|
|
||||||
'' else ''
|
|
||||||
offset=0
|
|
||||||
''}
|
|
||||||
|
|
||||||
mkfs.${fsType} -F -L nixos -E offset=$offset $diskImage
|
${if partitionTableType != "none" then ''
|
||||||
|
# Get start & length of the root partition in sectors to $START and $SECTORS.
|
||||||
|
eval $(partx $diskImage -o START,SECTORS --nr ${rootPartition} --pairs)
|
||||||
|
|
||||||
|
mkfs.${fsType} -F -L nixos $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
|
||||||
|
'' else ''
|
||||||
|
mkfs.${fsType} -F -L nixos $diskImage
|
||||||
|
''}
|
||||||
|
|
||||||
root="$PWD/root"
|
root="$PWD/root"
|
||||||
mkdir -p $root
|
mkdir -p $root
|
||||||
@ -126,17 +174,23 @@ let format' = format; in let
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# TODO: Nix really likes to chown things it creates to its current user...
|
export HOME=$TMPDIR
|
||||||
fakeroot nixos-prepare-root $root ${channelSources} ${config.system.build.toplevel} closure
|
|
||||||
|
# Provide a Nix database so that nixos-install can copy closures.
|
||||||
|
export NIX_STATE_DIR=$TMPDIR/state
|
||||||
|
nix-store --load-db < ${closureInfo}/registration
|
||||||
|
|
||||||
|
echo "running nixos-install..."
|
||||||
|
nixos-install --root $root --no-bootloader --no-root-passwd \
|
||||||
|
--system ${config.system.build.toplevel} --channel ${channelSources} --substituters ""
|
||||||
|
|
||||||
echo "copying staging root to image..."
|
echo "copying staging root to image..."
|
||||||
cptofs ${optionalString partitioned "-P 1"} -t ${fsType} -i $diskImage $root/* /
|
cptofs -p ${optionalString (partitionTableType != "none") "-P ${rootPartition}"} -t ${fsType} -i $diskImage $root/* /
|
||||||
'';
|
'';
|
||||||
in pkgs.vmTools.runInLinuxVM (
|
in pkgs.vmTools.runInLinuxVM (
|
||||||
pkgs.runCommand name
|
pkgs.runCommand name
|
||||||
{ preVM = prepareImage;
|
{ preVM = prepareImage;
|
||||||
buildInputs = with pkgs; [ utillinux e2fsprogs ];
|
buildInputs = with pkgs; [ utillinux e2fsprogs dosfstools ];
|
||||||
exportReferencesGraph = [ "closure" metaClosure ];
|
|
||||||
postVM = ''
|
postVM = ''
|
||||||
${if format == "raw" then ''
|
${if format == "raw" then ''
|
||||||
mv $diskImage $out/${filename}
|
mv $diskImage $out/${filename}
|
||||||
@ -149,13 +203,9 @@ in pkgs.vmTools.runInLinuxVM (
|
|||||||
memSize = 1024;
|
memSize = 1024;
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
${if partitioned then ''
|
export PATH=${binPath}:$PATH
|
||||||
. /sys/class/block/vda1/uevent
|
|
||||||
mknod /dev/vda1 b $MAJOR $MINOR
|
rootDisk=${if partitionTableType != "none" then "/dev/vda${rootPartition}" else "/dev/vda"}
|
||||||
rootDisk=/dev/vda1
|
|
||||||
'' else ''
|
|
||||||
rootDisk=/dev/vda
|
|
||||||
''}
|
|
||||||
|
|
||||||
# Some tools assume these exist
|
# Some tools assume these exist
|
||||||
ln -s vda /dev/xvda
|
ln -s vda /dev/xvda
|
||||||
@ -165,21 +215,22 @@ in pkgs.vmTools.runInLinuxVM (
|
|||||||
mkdir $mountPoint
|
mkdir $mountPoint
|
||||||
mount $rootDisk $mountPoint
|
mount $rootDisk $mountPoint
|
||||||
|
|
||||||
|
# Create the ESP and mount it. Unlike e2fsprogs, mkfs.vfat doesn't support an
|
||||||
|
# '-E offset=X' option, so we can't do this outside the VM.
|
||||||
|
${optionalString (partitionTableType == "efi") ''
|
||||||
|
mkdir -p /mnt/boot
|
||||||
|
mkfs.vfat -n ESP /dev/vda1
|
||||||
|
mount /dev/vda1 /mnt/boot
|
||||||
|
''}
|
||||||
|
|
||||||
# Install a configuration.nix
|
# Install a configuration.nix
|
||||||
mkdir -p /mnt/etc/nixos
|
mkdir -p /mnt/etc/nixos
|
||||||
${optionalString (configFile != null) ''
|
${optionalString (configFile != null) ''
|
||||||
cp ${configFile} /mnt/etc/nixos/configuration.nix
|
cp ${configFile} /mnt/etc/nixos/configuration.nix
|
||||||
''}
|
''}
|
||||||
|
|
||||||
mount --rbind /dev $mountPoint/dev
|
|
||||||
mount --rbind /proc $mountPoint/proc
|
|
||||||
mount --rbind /sys $mountPoint/sys
|
|
||||||
|
|
||||||
# Set up core system link, GRUB, etc.
|
# Set up core system link, GRUB, etc.
|
||||||
NIXOS_INSTALL_BOOTLOADER=1 chroot $mountPoint /nix/var/nix/profiles/system/bin/switch-to-configuration boot
|
NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root $mountPoint -- /nix/var/nix/profiles/system/bin/switch-to-configuration boot
|
||||||
|
|
||||||
# TODO: figure out if I should activate, but for now I won't
|
|
||||||
# chroot $mountPoint /nix/var/nix/profiles/system/activate
|
|
||||||
|
|
||||||
# The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images
|
# The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images
|
||||||
rm -f $mountPoint/etc/machine-id
|
rm -f $mountPoint/etc/machine-id
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
pkgs.stdenv.mkDerivation {
|
pkgs.stdenv.mkDerivation {
|
||||||
name = "ext4-fs.img";
|
name = "ext4-fs.img";
|
||||||
|
|
||||||
buildInputs = with pkgs; [e2fsprogs libfaketime perl];
|
nativeBuildInputs = with pkgs; [e2fsprogs libfaketime perl];
|
||||||
|
|
||||||
# For obtaining the closure of `storePaths'.
|
# For obtaining the closure of `storePaths'.
|
||||||
exportReferencesGraph =
|
exportReferencesGraph =
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ stdenv, perl, pathsFromGraph, xorriso, syslinux
|
{ stdenv, perl, closureInfo, xorriso, syslinux
|
||||||
|
|
||||||
, # The file name of the resulting ISO image.
|
, # The file name of the resulting ISO image.
|
||||||
isoName ? "cd.iso"
|
isoName ? "cd.iso"
|
||||||
@ -48,9 +48,9 @@ assert usbBootable -> isohybridMbrImage != "";
|
|||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = isoName;
|
name = isoName;
|
||||||
builder = ./make-iso9660-image.sh;
|
builder = ./make-iso9660-image.sh;
|
||||||
buildInputs = [perl xorriso syslinux];
|
buildInputs = [ xorriso syslinux ];
|
||||||
|
|
||||||
inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable isohybridMbrImage usbBootable;
|
inherit isoName bootable bootImage compressImage volumeID efiBootImage efiBootable isohybridMbrImage usbBootable;
|
||||||
|
|
||||||
# !!! should use XML.
|
# !!! should use XML.
|
||||||
sources = map (x: x.source) contents;
|
sources = map (x: x.source) contents;
|
||||||
@ -61,6 +61,5 @@ stdenv.mkDerivation {
|
|||||||
symlinks = map (x: x.symlink) storeContents;
|
symlinks = map (x: x.symlink) storeContents;
|
||||||
|
|
||||||
# For obtaining the closure of `storeContents'.
|
# For obtaining the closure of `storeContents'.
|
||||||
exportReferencesGraph =
|
closureInfo = closureInfo { rootPaths = map (x: x.object) storeContents; };
|
||||||
map (x: [("closure-" + baseNameOf x.object) x.object]) storeContents;
|
|
||||||
}
|
}
|
||||||
|
@ -72,16 +72,15 @@ done
|
|||||||
|
|
||||||
|
|
||||||
# Add the closures of the top-level store objects.
|
# Add the closures of the top-level store objects.
|
||||||
storePaths=$(perl $pathsFromGraph closure-*)
|
for i in $(< $closureInfo/store-paths); do
|
||||||
for i in $storePaths; do
|
|
||||||
addPath "${i:1}" "$i"
|
addPath "${i:1}" "$i"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
# Also include a manifest of the closures in a format suitable for
|
# Also include a manifest of the closures in a format suitable for
|
||||||
# nix-store --load-db.
|
# nix-store --load-db.
|
||||||
if [ -n "$object" ]; then
|
if [[ ${#objects[*]} != 0 ]]; then
|
||||||
printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration
|
cp $closureInfo/registration nix-path-registration
|
||||||
addPath "nix-path-registration" "nix-path-registration"
|
addPath "nix-path-registration" "nix-path-registration"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ stdenv, squashfsTools, perl, pathsFromGraph
|
{ stdenv, squashfsTools, closureInfo
|
||||||
|
|
||||||
, # The root directory of the squashfs filesystem is filled with the
|
, # The root directory of the squashfs filesystem is filled with the
|
||||||
# closures of the Nix store paths listed here.
|
# closures of the Nix store paths listed here.
|
||||||
@ -8,23 +8,18 @@
|
|||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = "squashfs.img";
|
name = "squashfs.img";
|
||||||
|
|
||||||
buildInputs = [perl squashfsTools];
|
nativeBuildInputs = [ squashfsTools ];
|
||||||
|
|
||||||
# For obtaining the closure of `storeContents'.
|
|
||||||
exportReferencesGraph =
|
|
||||||
map (x: [("closure-" + baseNameOf x) x]) storeContents;
|
|
||||||
|
|
||||||
buildCommand =
|
buildCommand =
|
||||||
''
|
''
|
||||||
# Add the closures of the top-level store objects.
|
closureInfo=${closureInfo { rootPaths = storeContents; }}
|
||||||
storePaths=$(perl ${pathsFromGraph} closure-*)
|
|
||||||
|
|
||||||
# Also include a manifest of the closures in a format suitable
|
# Also include a manifest of the closures in a format suitable
|
||||||
# for nix-store --load-db.
|
# for nix-store --load-db.
|
||||||
printRegistration=1 perl ${pathsFromGraph} closure-* > nix-path-registration
|
cp $closureInfo/registration nix-path-registration
|
||||||
|
|
||||||
# Generate the squashfs image.
|
# Generate the squashfs image.
|
||||||
mksquashfs nix-path-registration $storePaths $out \
|
mksquashfs nix-path-registration $(cat $closureInfo/store-paths) $out \
|
||||||
-keep-as-directory -all-root -b 1048576 -comp xz -Xdict-size 100%
|
-keep-as-directory -all-root -b 1048576 -comp xz -Xdict-size 100%
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# QEMU flags shared between various Nix expressions.
|
# QEMU flags shared between various Nix expressions.
|
||||||
|
{ pkgs }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -7,4 +8,14 @@
|
|||||||
"-net vde,vlan=${toString nic},sock=$QEMU_VDE_SOCKET_${toString net}"
|
"-net vde,vlan=${toString nic},sock=$QEMU_VDE_SOCKET_${toString net}"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
qemuSerialDevice = if pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64 then "ttyS0"
|
||||||
|
else if pkgs.stdenv.isArm || pkgs.stdenv.isAarch64 then "ttyAMA0"
|
||||||
|
else throw "Unknown QEMU serial device for system '${pkgs.stdenv.system}'";
|
||||||
|
|
||||||
|
qemuBinary = qemuPkg: {
|
||||||
|
"i686-linux" = "${qemuPkg}/bin/qemu-kvm";
|
||||||
|
"x86_64-linux" = "${qemuPkg}/bin/qemu-kvm -cpu kvm64";
|
||||||
|
"armv7l-linux" = "${qemuPkg}/bin/qemu-system-arm -enable-kvm -machine virt -cpu host";
|
||||||
|
"aarch64-linux" = "${qemuPkg}/bin/qemu-system-aarch64 -enable-kvm -machine virt,gic-version=host -cpu host";
|
||||||
|
}.${pkgs.stdenv.system} or (throw "Unknown QEMU binary for '${pkgs.stdenv.system}'");
|
||||||
}
|
}
|
||||||
|
@ -146,6 +146,7 @@ sub start {
|
|||||||
($self->{allowReboot} ? "" : "-no-reboot ") .
|
($self->{allowReboot} ? "" : "-no-reboot ") .
|
||||||
"-monitor unix:./monitor -chardev socket,id=shell,path=./shell " .
|
"-monitor unix:./monitor -chardev socket,id=shell,path=./shell " .
|
||||||
"-device virtio-serial -device virtconsole,chardev=shell " .
|
"-device virtio-serial -device virtconsole,chardev=shell " .
|
||||||
|
"-device virtio-rng-pci " .
|
||||||
($showGraphics ? "-serial stdio" : "-nographic") . " " . ($ENV{QEMU_OPTS} || "");
|
($showGraphics ? "-serial stdio" : "-nographic") . " " . ($ENV{QEMU_OPTS} || "");
|
||||||
chdir $self->{stateDir} or die;
|
chdir $self->{stateDir} or die;
|
||||||
exec $self->{startCommand};
|
exec $self->{startCommand};
|
||||||
@ -361,8 +362,8 @@ sub mustFail {
|
|||||||
|
|
||||||
|
|
||||||
sub getUnitInfo {
|
sub getUnitInfo {
|
||||||
my ($self, $unit) = @_;
|
my ($self, $unit, $user) = @_;
|
||||||
my ($status, $lines) = $self->execute("systemctl --no-pager show '$unit'");
|
my ($status, $lines) = $self->systemctl("--no-pager show \"$unit\"", $user);
|
||||||
return undef if $status != 0;
|
return undef if $status != 0;
|
||||||
my $info = {};
|
my $info = {};
|
||||||
foreach my $line (split '\n', $lines) {
|
foreach my $line (split '\n', $lines) {
|
||||||
@ -372,6 +373,16 @@ sub getUnitInfo {
|
|||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub systemctl {
|
||||||
|
my ($self, $q, $user) = @_;
|
||||||
|
if ($user) {
|
||||||
|
$q =~ s/'/\\'/g;
|
||||||
|
return $self->execute("su -l $user -c \$'XDG_RUNTIME_DIR=/run/user/`id -u` systemctl --user $q'");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self->execute("systemctl $q");
|
||||||
|
}
|
||||||
|
|
||||||
# Fail if the given systemd unit is not in the "active" state.
|
# Fail if the given systemd unit is not in the "active" state.
|
||||||
sub requireActiveUnit {
|
sub requireActiveUnit {
|
||||||
my ($self, $unit) = @_;
|
my ($self, $unit) = @_;
|
||||||
@ -386,16 +397,16 @@ sub requireActiveUnit {
|
|||||||
|
|
||||||
# Wait for a systemd unit to reach the "active" state.
|
# Wait for a systemd unit to reach the "active" state.
|
||||||
sub waitForUnit {
|
sub waitForUnit {
|
||||||
my ($self, $unit) = @_;
|
my ($self, $unit, $user) = @_;
|
||||||
$self->nest("waiting for unit ‘$unit’", sub {
|
$self->nest("waiting for unit ‘$unit’", sub {
|
||||||
retry sub {
|
retry sub {
|
||||||
my $info = $self->getUnitInfo($unit);
|
my $info = $self->getUnitInfo($unit, $user);
|
||||||
my $state = $info->{ActiveState};
|
my $state = $info->{ActiveState};
|
||||||
die "unit ‘$unit’ reached state ‘$state’\n" if $state eq "failed";
|
die "unit ‘$unit’ reached state ‘$state’\n" if $state eq "failed";
|
||||||
if ($state eq "inactive") {
|
if ($state eq "inactive") {
|
||||||
# If there are no pending jobs, then assume this unit
|
# If there are no pending jobs, then assume this unit
|
||||||
# will never reach active state.
|
# will never reach active state.
|
||||||
my ($status, $jobs) = $self->execute("systemctl list-jobs --full 2>&1");
|
my ($status, $jobs) = $self->systemctl("list-jobs --full 2>&1", $user);
|
||||||
if ($jobs =~ /No jobs/) { # FIXME: fragile
|
if ($jobs =~ /No jobs/) { # FIXME: fragile
|
||||||
# Handle the case where the unit may have started
|
# Handle the case where the unit may have started
|
||||||
# between the previous getUnitInfo() and
|
# between the previous getUnitInfo() and
|
||||||
@ -429,14 +440,14 @@ sub waitForFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub startJob {
|
sub startJob {
|
||||||
my ($self, $jobName) = @_;
|
my ($self, $jobName, $user) = @_;
|
||||||
$self->execute("systemctl start $jobName");
|
$self->systemctl("start $jobName", $user);
|
||||||
# FIXME: check result
|
# FIXME: check result
|
||||||
}
|
}
|
||||||
|
|
||||||
sub stopJob {
|
sub stopJob {
|
||||||
my ($self, $jobName) = @_;
|
my ($self, $jobName, $user) = @_;
|
||||||
$self->execute("systemctl stop $jobName");
|
$self->systemctl("stop $jobName", $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,11 @@
|
|||||||
with import ./build-vms.nix { inherit system minimal config; };
|
with import ./build-vms.nix { inherit system minimal config; };
|
||||||
with pkgs;
|
with pkgs;
|
||||||
|
|
||||||
rec {
|
let
|
||||||
|
jquery-ui = callPackage ./testing/jquery-ui.nix { };
|
||||||
|
jquery = callPackage ./testing/jquery.nix { };
|
||||||
|
|
||||||
|
in rec {
|
||||||
|
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
|
|
||||||
@ -29,7 +33,7 @@ rec {
|
|||||||
cp ${./test-driver/Logger.pm} $libDir/Logger.pm
|
cp ${./test-driver/Logger.pm} $libDir/Logger.pm
|
||||||
|
|
||||||
wrapProgram $out/bin/nixos-test-driver \
|
wrapProgram $out/bin/nixos-test-driver \
|
||||||
--prefix PATH : "${lib.makeBinPath [ qemu vde2 netpbm coreutils ]}" \
|
--prefix PATH : "${lib.makeBinPath [ qemu_test vde2 netpbm coreutils ]}" \
|
||||||
--prefix PERL5LIB : "${with perlPackages; lib.makePerlPath [ TermReadLineGnu XMLWriter IOTty FileSlurp ]}:$out/lib/perl5/site_perl"
|
--prefix PERL5LIB : "${with perlPackages; lib.makePerlPath [ TermReadLineGnu XMLWriter IOTty FileSlurp ]}:$out/lib/perl5/site_perl"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -78,14 +82,26 @@ rec {
|
|||||||
} @ t:
|
} @ t:
|
||||||
|
|
||||||
let
|
let
|
||||||
testDriverName = "nixos-test-driver-${name}";
|
# A standard store path to the vm monitor is built like this:
|
||||||
|
# /tmp/nix-build-vm-test-run-$name.drv-0/vm-state-machine/monitor
|
||||||
|
# The max filename length of a unix domain socket is 108 bytes.
|
||||||
|
# This means $name can at most be 50 bytes long.
|
||||||
|
maxTestNameLen = 50;
|
||||||
|
testNameLen = builtins.stringLength name;
|
||||||
|
|
||||||
|
testDriverName = with builtins;
|
||||||
|
if testNameLen > maxTestNameLen then
|
||||||
|
abort ("The name of the test '${name}' must not be longer than ${toString maxTestNameLen} " +
|
||||||
|
"it's currently ${toString testNameLen} characters long.")
|
||||||
|
else
|
||||||
|
"nixos-test-driver-${name}";
|
||||||
|
|
||||||
nodes = buildVirtualNetwork (
|
nodes = buildVirtualNetwork (
|
||||||
t.nodes or (if t ? machine then { machine = t.machine; } else { }));
|
t.nodes or (if t ? machine then { machine = t.machine; } else { }));
|
||||||
|
|
||||||
testScript' =
|
testScript' =
|
||||||
# Call the test script with the computed nodes.
|
# Call the test script with the computed nodes.
|
||||||
if builtins.isFunction testScript
|
if lib.isFunction testScript
|
||||||
then testScript { inherit nodes; }
|
then testScript { inherit nodes; }
|
||||||
else testScript;
|
else testScript;
|
||||||
|
|
||||||
@ -113,8 +129,7 @@ rec {
|
|||||||
--add-flags "''${vms[*]}" \
|
--add-flags "''${vms[*]}" \
|
||||||
${lib.optionalString enableOCR
|
${lib.optionalString enableOCR
|
||||||
"--prefix PATH : '${ocrProg}/bin:${imagemagick}/bin'"} \
|
"--prefix PATH : '${ocrProg}/bin:${imagemagick}/bin'"} \
|
||||||
--run "testScript=\"\$(cat $out/test-script)\"" \
|
--run "export testScript=\"\$(cat $out/test-script)\"" \
|
||||||
--set testScript '$testScript' \
|
|
||||||
--set VLANS '${toString vlans}'
|
--set VLANS '${toString vlans}'
|
||||||
ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms
|
ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms
|
||||||
wrapProgram $out/bin/nixos-run-vms \
|
wrapProgram $out/bin/nixos-run-vms \
|
||||||
@ -132,8 +147,8 @@ rec {
|
|||||||
test = passMeta (runTests driver);
|
test = passMeta (runTests driver);
|
||||||
report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; });
|
report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; });
|
||||||
|
|
||||||
in (if makeCoverageReport then report else test) // {
|
in (if makeCoverageReport then report else test) // {
|
||||||
inherit nodes driver test;
|
inherit nodes driver test;
|
||||||
};
|
};
|
||||||
|
|
||||||
runInMachine =
|
runInMachine =
|
||||||
|
@ -46,7 +46,7 @@ in {
|
|||||||
inherit lib config;
|
inherit lib config;
|
||||||
inherit (cfg) contents format name;
|
inherit (cfg) contents format name;
|
||||||
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
|
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
|
||||||
partitioned = config.ec2.hvm;
|
partitionTableType = if config.ec2.hvm then "legacy" else "none";
|
||||||
diskSize = cfg.sizeMB;
|
diskSize = cfg.sizeMB;
|
||||||
configFile = pkgs.writeText "configuration.nix"
|
configFile = pkgs.writeText "configuration.nix"
|
||||||
''
|
''
|
||||||
|
@ -18,7 +18,7 @@ rm -f ec2-amis.nix
|
|||||||
|
|
||||||
types="hvm"
|
types="hvm"
|
||||||
stores="ebs"
|
stores="ebs"
|
||||||
regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
|
regions="eu-west-1 eu-west-2 eu-west-3 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
|
||||||
|
|
||||||
for type in $types; do
|
for type in $types; do
|
||||||
link=$stateDir/$type
|
link=$stateDir/$type
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user