Compare commits

..

1 Commits

Author SHA1 Message Date
Eelco Dolstra
2b6c83f1f5 * Mark release as stable.
svn path=/nixpkgs/branches/0.6-release/; revision=1767
2004-11-14 12:36:14 +00:00
7739 changed files with 9511 additions and 406449 deletions

10
.gitignore vendored
View File

@@ -1,10 +0,0 @@
*~
,*
.*.swp
.*.swo
result
doc/NEWS.html
doc/NEWS.txt
doc/manual.html
doc/manual.pdf
.version-suffix

View File

@@ -1,5 +0,0 @@
language: python
python: "3.4"
before_install: ./maintainers/scripts/travis-nox-review-pr.sh nix
install: ./maintainers/scripts/travis-nox-review-pr.sh nox
script: ./maintainers/scripts/travis-nox-review-pr.sh build

View File

@@ -1 +0,0 @@
14.04

31
COPYING
View File

@@ -1,31 +0,0 @@
Copyright (c) 2003-2006 Eelco Dolstra
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
======================================================================
Note: the license above does not apply to the packages built by the
Nix Packages collection, merely to the package descriptions (i.e., Nix
expressions, build scripts, etc.). Also, the license does not apply
to some of the binaries used for bootstrapping Nixpkgs (e.g.,
pkgs/stdenv/linux/tools/bash). It also might not apply to patches
included in Nixpkgs, which may be derivative works of the packages to
which they apply. The aforementioned artifacts are all covered by the
licenses of the respective packages.

View File

@@ -1,10 +0,0 @@
Nixpkgs is a collection of packages for [Nix](http://nixos.org/nix/) package
manager. Nixpkgs also includes [NixOS](http://nixos.org/nixos/) linux distribution source code.
* [NixOS installation instructions](http://nixos.org/nixos/manual/#installing-nixos)
* [Manual (How to write packages for Nix)](http://nixos.org/nixpkgs/manual/)
* [Manual (NixOS)](http://nixos.org/nixos/manual/)
* [Continuous build](http://hydra.nixos.org/jobset/nixos/trunk-combined)
* [Tests](http://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
* [Mailing list](http://lists.science.uu.nl/mailman/listinfo/nix-dev)
* [IRC - #nixos on freenode.net](irc://irc.freenode.net/#nixos)

View File

@@ -1,7 +0,0 @@
if ! builtins ? nixVersion || builtins.compareVersions "1.6" builtins.nixVersion == 1 then
abort "This version of Nixpkgs requires Nix >= 1.6, please upgrade!"
else
import ./pkgs/top-level/all-packages.nix

View File

@@ -1,41 +0,0 @@
# You may need to override this.
docbookxsl = $(HOME)/.nix-profile/xml/xsl/docbook
dblatex = dblatex
XMLLINT = xmllint --catalogs
XSLTPROC = xsltproc --catalogs \
--param section.autolabel 1 \
--param section.label.includes.component.label 1 \
--param html.stylesheet \'style.css\' \
--param xref.with.number.and.title 1 \
--param toc.section.depth 3 \
--param admon.style \'\' \
--param callout.graphics.extension \'.gif\'
NEWS_OPTS = \
--stringparam generate.toc "article nop" \
--stringparam section.autolabel.max.depth 0 \
--stringparam header.rule 0
all: NEWS.html NEWS.txt manual.html manual.pdf
NEWS.html: release-notes.xml
$(XSLTPROC) --nonet --xinclude --output $@ $(NEWS_OPTS) \
$(docbookxsl)/xhtml/docbook.xsl release-notes.xml
NEWS.txt: release-notes.xml
$(XSLTPROC) --nonet --xinclude quote-literals.xsl release-notes.xml | \
$(XSLTPROC) --nonet --output $@.tmp.html $(NEWS_OPTS) \
$(docbookxsl)/xhtml/docbook.xsl -
LANG=en_US w3m -dump $@.tmp.html > $@
rm $@.tmp.html
manual.html: *.xml
$(XSLTPROC) --nonet --xinclude --output manual.html \
$(docbookxsl)/xhtml/docbook.xsl manual.xml
manual.pdf: *.xml
$(dblatex) \
-P doc.collab.show=0 \
-P latex.output.revhistory=0 \
manual.xml

View File

@@ -1,603 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-conventions">
<title>Coding conventions</title>
<section><title>Syntax</title>
<itemizedlist>
<listitem><para>Use 2 spaces of indentation per indentation level in
Nix expressions, 4 spaces in shell scripts.</para></listitem>
<listitem><para>Do not use tab characters, i.e. configure your
editor to use soft tabs. For instance, use <literal>(setq-default
indent-tabs-mode nil)</literal> in Emacs. Everybody has different
tab settings so its asking for trouble.</para></listitem>
<listitem><para>Use <literal>lowerCamelCase</literal> for variable
names, not <literal>UpperCamelCase</literal>. TODO: naming of
attributes in
<filename>all-packages.nix</filename>?</para></listitem>
<listitem><para>Function calls with attribute set arguments are
written as
<programlisting>
foo {
arg = ...;
}
</programlisting>
not
<programlisting>
foo
{
arg = ...;
}
</programlisting>
Also fine is
<programlisting>
foo { arg = ...; }
</programlisting>
if it's a short call.</para></listitem>
<listitem><para>In attribute sets or lists that span multiple lines,
the attribute names or list elements should be aligned:
<programlisting>
# A long list.
list =
[ elem1
elem2
elem3
];
# A long attribute set.
attrs =
{ attr1 = short_expr;
attr2 =
if true then big_expr else big_expr;
};
# Alternatively:
attrs = {
attr1 = short_expr;
attr2 =
if true then big_expr else big_expr;
};
</programlisting>
</para></listitem>
<listitem><para>Short lists or attribute sets can be written on one
line:
<programlisting>
# A short list.
list = [ elem1 elem2 elem3 ];
# A short set.
attrs = { x = 1280; y = 1024; };
</programlisting>
</para></listitem>
<listitem><para>Breaking in the middle of a function argument can
give hard-to-read code, like
<programlisting>
someFunction { x = 1280;
y = 1024; } otherArg
yetAnotherArg
</programlisting>
(especially if the argument is very large, spanning multiple
lines).</para>
<para>Better:
<programlisting>
someFunction
{ x = 1280; y = 1024; }
otherArg
yetAnotherArg
</programlisting>
or
<programlisting>
let res = { x = 1280; y = 1024; };
in someFunction res otherArg yetAnotherArg
</programlisting>
</para></listitem>
<listitem><para>The bodies of functions, asserts, and withs are not
indented to prevent a lot of superfluous indentation levels, i.e.
<programlisting>
{ arg1, arg2 }:
assert system == "i686-linux";
stdenv.mkDerivation { ...
</programlisting>
not
<programlisting>
{ arg1, arg2 }:
assert system == "i686-linux";
stdenv.mkDerivation { ...
</programlisting>
</para></listitem>
<listitem><para>Function formal arguments are written as:
<programlisting>
{ arg1, arg2, arg3 }:
</programlisting>
but if they don't fit on one line they're written as:
<programlisting>
{ arg1, arg2, arg3
, arg4, ...
, # Some comment...
argN
}:
</programlisting>
</para></listitem>
<listitem><para>Functions should list their expected arguments as
precisely as possible. That is, write
<programlisting>
{ stdenv, fetchurl, perl }: <replaceable>...</replaceable>
</programlisting>
instead of
<programlisting>
args: with args; <replaceable>...</replaceable>
</programlisting>
or
<programlisting>
{ stdenv, fetchurl, perl, ... }: <replaceable>...</replaceable>
</programlisting>
</para>
<para>For functions that are truly generic in the number of
arguments (such as wrappers around <varname>mkDerivation</varname>)
that have some required arguments, you should write them using an
<literal>@</literal>-pattern:
<programlisting>
{ stdenv, doCoverageAnalysis ? false, ... } @ args:
stdenv.mkDerivation (args // {
<replaceable>...</replaceable> if doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
})
</programlisting>
instead of
<programlisting>
args:
args.stdenv.mkDerivation (args // {
<replaceable>...</replaceable> if args ? doCoverageAnalysis &amp;&amp; args.doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable>
})
</programlisting>
</para></listitem>
</itemizedlist>
</section>
<section><title>Package naming</title>
<para>In Nixpkgs, there are generally three different names associated with a package:
<itemizedlist>
<listitem><para>The <varname>name</varname> attribute of the
derivation (excluding the version part). This is what most users
see, in particular when using
<command>nix-env</command>.</para></listitem>
<listitem><para>The variable name used for the instantiated package
in <filename>all-packages.nix</filename>, and when passing it as a
dependency to other functions. This is what Nix 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
expression.</para></listitem>
</itemizedlist>
Most of the time, these are the same. For instance, the package
<literal>e2fsprogs</literal> has a <varname>name</varname> attribute
<literal>"e2fsprogs-<replaceable>version</replaceable>"</literal>, is
bound to the variable name <varname>e2fsprogs</varname> in
<filename>all-packages.nix</filename>, and the Nix expression is in
<filename>pkgs/os-specific/linux/e2fsprogs/default.nix</filename>.
</para>
<para>There are a few naming guidelines:
<itemizedlist>
<listitem><para>Generally, try to stick to the upstream package
name.</para></listitem>
<listitem><para>Dont use uppercase letters in the
<literal>name</literal> attribute — e.g.,
<literal>"mplayer-1.0rc2"</literal> instead of
<literal>"MPlayer-1.0rc2"</literal>.</para></listitem>
<listitem><para>The version part of the <literal>name</literal>
attribute <emphasis>must</emphasis> start with a digit (following a
dash) — e.g., <literal>"hello-0.3-pre-r3910"</literal> instead of
<literal>"hello-svn-r3910"</literal>, as the latter would be seen as
a package named <literal>hello-svn</literal> by
<command>nix-env</command>.</para></listitem>
<listitem><para>Dashes in the package name should be preserved
in new variable names, rather than converted to underscores
(which was convention up to around 2013 and most names
still have underscores instead of dashes) — e.g.,
<varname>http-parser</varname> instead of
<varname>http_parser</varname>.</para></listitem>
<listitem><para>If there are multiple versions of a package, this
should be reflected in the variable names in
<filename>all-packages.nix</filename>,
e.g. <varname>json-c-0-9</varname> and <varname>json-c-0-11</varname>.
If there is an obvious “default” version, make an attribute like
<literal>json-c = json-c-0-9;</literal>.
See also <xref linkend="sec-versioning" /></para></listitem>
</itemizedlist>
</para>
</section>
<section xml:id="sec-organisation"><title>File naming and organisation</title>
<para>Names of files and directories should be in lowercase, with
dashes between words — not in camel case. For instance, it should be
<filename>all-packages.nix</filename>, not
<filename>allPackages.nix</filename> or
<filename>AllPackages.nix</filename>.</para>
<section><title>Hierarchy</title>
<para>Each package should be stored in its own directory somewhere in
the <filename>pkgs/</filename> tree, i.e. in
<filename>pkgs/<replaceable>category</replaceable>/<replaceable>subcategory</replaceable>/<replaceable>...</replaceable>/<replaceable>pkgname</replaceable></filename>.
Below are some rules for picking the right category for a package.
Many packages fall under several categories; what matters is the
<emphasis>primary</emphasis> purpose of a package. For example, the
<literal>libxml2</literal> package builds both a library and some
tools; but its a library foremost, so it goes under
<filename>pkgs/development/libraries</filename>.</para>
<para>When in doubt, consider refactoring the
<filename>pkgs/</filename> tree, e.g. creating new categories or
splitting up an existing category.</para>
<variablelist>
<varlistentry>
<term>If its used to support <emphasis>software development</emphasis>:</term>
<listitem>
<variablelist>
<varlistentry>
<term>If its a <emphasis>library</emphasis> used by other packages:</term>
<listitem>
<para><filename>development/libraries</filename> (e.g. <filename>libxml2</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>compiler</emphasis>:</term>
<listitem>
<para><filename>development/compilers</filename> (e.g. <filename>gcc</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its an <emphasis>interpreter</emphasis>:</term>
<listitem>
<para><filename>development/interpreters</filename> (e.g. <filename>guile</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a (set of) development <emphasis>tool(s)</emphasis>:</term>
<listitem>
<variablelist>
<varlistentry>
<term>If its a <emphasis>parser generator</emphasis> (including lexers):</term>
<listitem>
<para><filename>development/tools/parsing</filename> (e.g. <filename>bison</filename>, <filename>flex</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>build manager</emphasis>:</term>
<listitem>
<para><filename>development/tools/build-managers</filename> (e.g. <filename>gnumake</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Else:</term>
<listitem>
<para><filename>development/tools/misc</filename> (e.g. <filename>binutils</filename>)</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>Else:</term>
<listitem>
<para><filename>development/misc</filename></para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a (set of) <emphasis>tool(s)</emphasis>:</term>
<listitem>
<para>(A tool is a relatively small program, especially one intented
to be used non-interactively.)</para>
<variablelist>
<varlistentry>
<term>If its for <emphasis>networking</emphasis>:</term>
<listitem>
<para><filename>tools/networking</filename> (e.g. <filename>wget</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its for <emphasis>text processing</emphasis>:</term>
<listitem>
<para><filename>tools/text</filename> (e.g. <filename>diffutils</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>system utility</emphasis>, i.e.,
something related or essential to the operation of a
system:</term>
<listitem>
<para><filename>tools/system</filename> (e.g. <filename>cron</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its an <emphasis>archiver</emphasis> (which may
include a compression function):</term>
<listitem>
<para><filename>tools/archivers</filename> (e.g. <filename>zip</filename>, <filename>tar</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>compression</emphasis> program:</term>
<listitem>
<para><filename>tools/compression</filename> (e.g. <filename>gzip</filename>, <filename>bzip2</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>security</emphasis>-related program:</term>
<listitem>
<para><filename>tools/security</filename> (e.g. <filename>nmap</filename>, <filename>gnupg</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Else:</term>
<listitem>
<para><filename>tools/misc</filename></para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>shell</emphasis>:</term>
<listitem>
<para><filename>shells</filename> (e.g. <filename>bash</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>server</emphasis>:</term>
<listitem>
<variablelist>
<varlistentry>
<term>If its a web server:</term>
<listitem>
<para><filename>servers/http</filename> (e.g. <filename>apache-httpd</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its an implementation of the X Windowing System:</term>
<listitem>
<para><filename>servers/x11</filename> (e.g. <filename>xorg</filename> — this includes the client libraries and programs)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Else:</term>
<listitem>
<para><filename>servers/misc</filename></para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>desktop environment</emphasis>
(including <emphasis>window managers</emphasis>):</term>
<listitem>
<para><filename>desktops</filename> (e.g. <filename>kde</filename>, <filename>gnome</filename>, <filename>enlightenment</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its an <emphasis>application</emphasis>:</term>
<listitem>
<para>A (typically large) program with a distinct user
interface, primarily used interactively.</para>
<variablelist>
<varlistentry>
<term>If its a <emphasis>version management system</emphasis>:</term>
<listitem>
<para><filename>applications/version-management</filename> (e.g. <filename>subversion</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its for <emphasis>video playback / editing</emphasis>:</term>
<listitem>
<para><filename>applications/video</filename> (e.g. <filename>vlc</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its for <emphasis>graphics viewing / editing</emphasis>:</term>
<listitem>
<para><filename>applications/graphics</filename> (e.g. <filename>gimp</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its for <emphasis>networking</emphasis>:</term>
<listitem>
<variablelist>
<varlistentry>
<term>If its a <emphasis>mailreader</emphasis>:</term>
<listitem>
<para><filename>applications/networking/mailreaders</filename> (e.g. <filename>thunderbird</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>newsreader</emphasis>:</term>
<listitem>
<para><filename>applications/networking/newsreaders</filename> (e.g. <filename>pan</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>web browser</emphasis>:</term>
<listitem>
<para><filename>applications/networking/browsers</filename> (e.g. <filename>firefox</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Else:</term>
<listitem>
<para><filename>applications/networking/misc</filename></para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>Else:</term>
<listitem>
<para><filename>applications/misc</filename></para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>If its <emphasis>data</emphasis> (i.e., does not have a
straight-forward executable semantics):</term>
<listitem>
<variablelist>
<varlistentry>
<term>If its a <emphasis>font</emphasis>:</term>
<listitem>
<para><filename>data/fonts</filename></para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its related to <emphasis>SGML/XML processing</emphasis>:</term>
<listitem>
<variablelist>
<varlistentry>
<term>If its an <emphasis>XML DTD</emphasis>:</term>
<listitem>
<para><filename>data/sgml+xml/schemas/xml-dtd</filename> (e.g. <filename>docbook</filename>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>If its an <emphasis>XSLT stylesheet</emphasis>:</term>
<listitem>
<para>(Okay, these are executable...)</para>
<para><filename>data/sgml+xml/stylesheets/xslt</filename> (e.g. <filename>docbook-xsl</filename>)</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>If its a <emphasis>game</emphasis>:</term>
<listitem>
<para><filename>games</filename></para>
</listitem>
</varlistentry>
<varlistentry>
<term>Else:</term>
<listitem>
<para><filename>misc</filename></para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="sec-versioning"><title>Versioning</title>
<para>Because every version of a package in Nixpkgs creates a
potential maintenance burden, old versions of a package should not be
kept unless there is a good reason to do so. For instance, Nixpkgs
contains several versions of GCC because other packages dont build
with the latest version of GCC. Other examples are having both the
latest stable and latest pre-release version of a package, or to keep
several major releases of an application that differ significantly in
functionality.</para>
<para>If there is only one version of a package, its Nix expression
should be named <filename>e2fsprogs/default.nix</filename>. If there
are multiple versions, this should be reflected in the filename,
e.g. <filename>e2fsprogs/1.41.8.nix</filename> and
<filename>e2fsprogs/1.41.9.nix</filename>. The version in the
filename should leave out unnecessary detail. For instance, if we
keep the latest Firefox 2.0.x and 3.5.x versions in Nixpkgs, they
should be named <filename>firefox/2.0.nix</filename> and
<filename>firefox/3.5.nix</filename>, respectively (which, at a given
point, might contain versions <literal>2.0.0.20</literal> and
<literal>3.5.4</literal>). If a version requires many auxiliary
files, you can use a subdirectory for each version,
e.g. <filename>firefox/2.0/default.nix</filename> and
<filename>firefox/3.5/default.nix</filename>.</para>
<para>All versions of a package <emphasis>must</emphasis> be included
in <filename>all-packages.nix</filename> to make sure that they
evaluate correctly.</para>
</section>
</section>
</chapter>

View File

@@ -1,21 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-contributing">
<title>Contributing</title>
<para>If you make modifications to the manual, it's important to build the manual before contributing:</para>
<orderedlist>
<listitem><para><command>$ git clone git://github.com/NixOS/nixpkgs.git</command></para></listitem>
<listitem><para><command>$ cd nixpkgs/pkgs/top-level</command></para></listitem>
<listitem><para><command>$ nix-build -A tarball release.nix</command></para></listitem>
<listitem><para>Inside the built derivation you shall see <literal>manual/index.html</literal> file.</para></listitem>
</orderedlist>
</chapter>

View File

@@ -1,21 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-introduction">
<title>Introduction</title>
<para>This manual tells you how to write packages for the Nix Packages
collection (Nixpkgs). Thus its for packagers and developers who want
to add packages to Nixpkgs. End users are kindly referred to the
<link xlink:href="http://hydra.nixos.org/job/nix/trunk/tarball/latest/download-by-type/doc/manual">Nix
manual</link>.</para>
<para>This manual does not describe the syntax and semantics of the
Nix expression language, which are given in the Nix manual in the
<link
xlink:href="http://hydra.nixos.org/job/nix/trunk/tarball/latest/download-by-type/doc/manual/#chap-writing-nix-expressions">chapter
on writing Nix expressions</link>. It only describes the facilities
provided by Nixpkgs to make writing packages easier, such as the
standard build environment (<literal>stdenv</literal>).</para>
</chapter>

View File

@@ -1,333 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-language-support">
<title>Support for specific programming languages</title>
<para>The <link linkend="chap-stdenv">standard build
environment</link> makes it easy to build typical Autotools-based
packages with very little code. Any other kind of package can be
accomodated by overriding the appropriate phases of
<literal>stdenv</literal>. However, there are specialised functions
in Nixpkgs to easily build packages for other programming languages,
such as Perl or Haskell. These are described in this chapter.</para>
<section xml:id="ssec-language-perl"><title>Perl</title>
<para>Nixpkgs provides a function <varname>buildPerlPackage</varname>,
a generic package builder function for any Perl package that has a
standard <varname>Makefile.PL</varname>. Its implemented in <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/perl-modules/generic"><filename>pkgs/development/perl-modules/generic</filename></link>.</para>
<para>Perl packages from CPAN are defined in <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/perl-packages.nix"><filename>pkgs/top-level/perl-packages.nix</filename></link>,
rather than <filename>pkgs/all-packages.nix</filename>. Most Perl
packages are so straight-forward to build that they are defined here
directly, rather than having a separate function for each package
called from <filename>perl-packages.nix</filename>. However, more
complicated packages should be put in a separate file, typically in
<filename>pkgs/development/perl-modules</filename>. Here is an
example of the former:
<programlisting>
ClassC3 = buildPerlPackage rec {
name = "Class-C3-0.21";
src = fetchurl {
url = "mirror://cpan/authors/id/F/FL/FLORA/${name}.tar.gz";
sha256 = "1bl8z095y4js66pwxnm7s853pi9czala4sqc743fdlnk27kq94gz";
};
};
</programlisting>
Note the use of <literal>mirror://cpan/</literal>, and the
<literal>${name}</literal> in the URL definition to ensure that the
name attribute is consistent with the source that were actually
downloading. Perl packages are made available in
<filename>all-packages.nix</filename> through the variable
<varname>perlPackages</varname>. For instance, if you have a package
that needs <varname>ClassC3</varname>, you would typically write
<programlisting>
foo = import ../path/to/foo.nix {
inherit stdenv fetchurl ...;
inherit (perlPackages) ClassC3;
};
</programlisting>
in <filename>all-packages.nix</filename>. You can test building a
Perl package as follows:
<screen>
$ nix-build -A perlPackages.ClassC3
</screen>
<varname>buildPerlPackage</varname> adds <literal>perl-</literal> to
the start of the name attribute, so the package above is actually
called <literal>perl-Class-C3-0.21</literal>. So to install it, you
can say:
<screen>
$ nix-env -i perl-Class-C3
</screen>
(Of course you can also install using the attribute name:
<literal>nix-env -i -A perlPackages.ClassC3</literal>.)</para>
<para>So what does <varname>buildPerlPackage</varname> do? It does
the following:
<orderedlist>
<listitem><para>In the configure phase, it calls <literal>perl
Makefile.PL</literal> to generate a Makefile. You can set the
variable <varname>makeMakerFlags</varname> to pass flags to
<filename>Makefile.PL</filename></para></listitem>
<listitem><para>It adds the contents of the <envar>PERL5LIB</envar>
environment variable to <literal>#! .../bin/perl</literal> line of
Perl scripts as <literal>-I<replaceable>dir</replaceable></literal>
flags. This ensures that a script can find its
dependencies.</para></listitem>
<listitem><para>In the fixup phase, it writes the propagated build
inputs (<varname>propagatedBuildInputs</varname>) to the file
<filename>$out/nix-support/propagated-user-env-packages</filename>.
<command>nix-env</command> recursively installs all packages listed
in this file when you install a package that has it. This ensures
that a Perl package can find its dependencies.</para></listitem>
</orderedlist>
</para>
<para><varname>buildPerlPackage</varname> is built on top of
<varname>stdenv</varname>, so everything can be customised in the
usual way. For instance, the <literal>BerkeleyDB</literal> module has
a <varname>preConfigure</varname> hook to generate a configuration
file used by <filename>Makefile.PL</filename>:
<programlisting>
{buildPerlPackage, fetchurl, db}:
buildPerlPackage rec {
name = "BerkeleyDB-0.36";
src = fetchurl {
url = "mirror://cpan/authors/id/P/PM/PMQS/${name}.tar.gz";
sha256 = "07xf50riarb60l1h6m2dqmql8q5dij619712fsgw7ach04d8g3z1";
};
preConfigure = ''
echo "LIB = ${db}/lib" > config.in
echo "INCLUDE = ${db}/include" >> config.in
'';
}
</programlisting>
</para>
<para>Dependencies on other Perl packages can be specified in the
<varname>buildInputs</varname> and
<varname>propagatedBuildInputs</varname> attributes. If something is
exclusively a build-time dependency, use
<varname>buildInputs</varname>; if its (also) a runtime dependency,
use <varname>propagatedBuildInputs</varname>. For instance, this
builds a Perl module that has runtime dependencies on a bunch of other
modules:
<programlisting>
ClassC3Componentised = buildPerlPackage rec {
name = "Class-C3-Componentised-1.0004";
src = fetchurl {
url = "mirror://cpan/authors/id/A/AS/ASH/${name}.tar.gz";
sha256 = "0xql73jkcdbq4q9m0b0rnca6nrlvf5hyzy8is0crdk65bynvs8q1";
};
propagatedBuildInputs = [
ClassC3 ClassInspector TestException MROCompat
];
};
</programlisting>
</para>
<section><title>Generation from CPAN</title>
<para>Nix expressions for Perl packages can be generated (almost)
automatically from CPAN. This is done by the program
<command>nix-generate-from-cpan</command>, which can be installed
as follows:</para>
<screen>
$ nix-env -i nix-generate-from-cpan
</screen>
<para>This program takes a Perl module name, looks it up on CPAN,
fetches and unpacks the corresponding package, and prints a Nix
expression on standard output. For example:
<screen>
$ nix-generate-from-cpan XML::Simple
XMLSimple = buildPerlPackage {
name = "XML-Simple-2.20";
src = fetchurl {
url = mirror://cpan/authors/id/G/GR/GRANTM/XML-Simple-2.20.tar.gz;
sha256 = "5cff13d0802792da1eb45895ce1be461903d98ec97c9c953bc8406af7294434a";
};
propagatedBuildInputs = [ XMLNamespaceSupport XMLSAX XMLSAXExpat ];
meta = {
description = "Easily read/write XML (esp config files)";
license = "perl";
};
};
</screen>
The output can be pasted into
<filename>pkgs/top-level/perl-packages.nix</filename> or wherever else
you need it.</para>
</section>
</section>
<section><title>Python</title>
<para>
Python packages that
use <link xlink:href="http://pypi.python.org/pypi/setuptools/"><literal>setuptools</literal></link>,
which many Python packages do nowadays, can be built very simply using
the <varname>buildPythonPackage</varname> function. This function is
implemented
in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/generic/default.nix"><filename>pkgs/development/python-modules/generic/default.nix</filename></link>
and works similarly to <varname>buildPerlPackage</varname>. (See
<xref linkend="ssec-language-perl"/> for details.)
</para>
<para>
Python packages that use <varname>buildPythonPackage</varname> are
defined
in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/python-packages.nix"><filename>pkgs/top-level/python-packages.nix</filename></link>.
Most of them are simple. For example:
<programlisting>
twisted = buildPythonPackage {
name = "twisted-8.1.0";
src = fetchurl {
url = http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2;
sha256 = "0q25zbr4xzknaghha72mq57kh53qw1bf8csgp63pm9sfi72qhirl";
};
propagatedBuildInputs = [ pkgs.ZopeInterface ];
meta = {
homepage = http://twistedmatrix.com/;
description = "Twisted, an event-driven networking engine written in Python";
license = "MIT";
};
};
</programlisting>
</para>
</section>
<section xml:id="ssec-language-java"><title>Java</title>
<para>Ant-based Java packages are typically built from source as follows:
<programlisting>
stdenv.mkDerivation {
name = "...";
src = fetchurl { ... };
buildInputs = [ jdk ant ];
buildPhase = "ant";
}
</programlisting>
Note that <varname>jdk</varname> is an alias for the OpenJDK.</para>
<para>JAR files that are intended to be used by other packages should
be installed in <filename>$out/share/java</filename>. The OpenJDK has
a stdenv setup hook that adds any JARs in the
<filename>share/java</filename> directories of the build inputs to the
<envar>CLASSPATH</envar> environment variable. For instance, if the
package <literal>libfoo</literal> installs a JAR named
<filename>foo.jar</filename> in its <filename>share/java</filename>
directory, and another package declares the attribute
<programlisting>
buildInputs = [ jdk libfoo ];
</programlisting>
then <envar>CLASSPATH</envar> will be set to
<filename>/nix/store/...-libfoo/share/java/foo.jar</filename>.</para>
<para>Private JARs
should be installed in a location like
<filename>$out/share/<replaceable>package-name</replaceable></filename>.</para>
<para>If your Java package provides a program, you need to generate a
wrapper script to run it using the OpenJRE. You can use
<literal>makeWrapper</literal> for this:
<programlisting>
buildInputs = [ makeWrapper ];
installPhase =
''
mkdir -p $out/bin
makeWrapper ${jre}/bin/java $out/bin/foo \
--add-flags "-cp $out/share/java/foo.jar org.foo.Main"
'';
</programlisting>
Note the use of <literal>jre</literal>, which is the part of the
OpenJDK package that contains the Java Runtime Environment. By using
<literal>${jre}/bin/java</literal> instead of
<literal>${jdk}/bin/java</literal>, you prevent your package from
depending on the JDK at runtime.</para>
<para>It is possible to use a different Java compiler than
<command>javac</command> from the OpenJDK. For instance, to use the
Eclipse Java Compiler:
<programlisting>
buildInputs = [ jre ant ecj ];
</programlisting>
(Note that here you dont need the full JDK as an input, but just the
JRE.) The ECJ has a stdenv setup hook that sets some environment
variables to cause Ant to use ECJ, but this doesnt work with all Ant
files. Similarly, you can use the GNU Java Compiler:
<programlisting>
buildInputs = [ gcj ant ];
</programlisting>
Here, Ant will automatically use <command>gij</command> (the GNU Java
Runtime) instead of the OpenJRE.</para>
</section>
<!--
<section><title>Haskell</title>
<para>TODO</para>
</section>
<section><title>TeX / LaTeX</title>
<para>* Special support for building TeX documents</para>
</section>
-->
</chapter>

View File

@@ -1,38 +0,0 @@
<book xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude">
<info>
<title>Nixpkgs Manual</title>
<subtitle>Draft (Version <xi:include href="../.version"
parse="text" />)</subtitle>
<author>
<personname>
<firstname>Eelco</firstname>
<surname>Dolstra</surname>
</personname>
<affiliation>
<orgname>LogicBlox</orgname>
</affiliation>
</author>
<copyright>
<year>2008-2012</year>
<holder>Eelco Dolstra</holder>
</copyright>
</info>
<xi:include href="introduction.xml" />
<xi:include href="quick-start.xml" />
<xi:include href="stdenv.xml" />
<xi:include href="meta.xml" />
<xi:include href="language-support.xml" />
<xi:include href="package-notes.xml" />
<xi:include href="coding-conventions.xml" />
<xi:include href="contributing.xml" />
</book>

View File

@@ -1,264 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-meta">
<title>Meta-attributes</title>
<para>Nix packages can declare <emphasis>meta-attributes</emphasis>
that contain information about a package such as a description, its
homepage, its license, and so on. For instance, the GNU Hello package
has a <varname>meta</varname> declaration like this:
<programlisting>
meta = {
description = "A program that produces a familiar, friendly greeting";
longDescription = ''
GNU Hello is a program that prints "Hello, world!" when you run it.
It is fully customizable.
'';
homepage = http://www.gnu.org/software/hello/manual/;
license = stdenv.lib.licenses.gpl3Plus;
maintainers = [ stdenv.lib.maintainers.eelco ];
platforms = stdenv.lib.platforms.all;
};
</programlisting>
</para>
<para>Meta-attributes are not passed to the builder of the package.
Thus, a change to a meta-attribute doesnt trigger a recompilation of
the package. The value of a meta-attribute must a string.</para>
<para>The meta-attributes of a package can be queried from the
command-line using <command>nix-env</command>:
<screen>
$ nix-env -qa hello --meta --json
{
"hello": {
"meta": {
"description": "A program that produces a familiar, friendly greeting",
"homepage": "http://www.gnu.org/software/hello/manual/",
"license": {
"fullName": "GNU General Public License version 3 or later",
"shortName": "GPLv3+",
"url": "http://www.fsf.org/licensing/licenses/gpl.html"
},
"longDescription": "GNU Hello is a program that prints \"Hello, world!\" when you run it.\nIt is fully customizable.\n",
"maintainers": [
"Ludovic Court\u00e8s &lt;ludo@gnu.org>"
],
"platforms": [
"i686-linux",
"x86_64-linux",
"armv5tel-linux",
"armv7l-linux",
"mips64el-linux",
"x86_64-darwin",
"i686-cygwin",
"i686-freebsd",
"x86_64-freebsd",
"i686-openbsd",
"x86_64-openbsd"
],
"position": "/home/user/dev/nixpkgs/pkgs/applications/misc/hello/ex-2/default.nix:14"
},
"name": "hello-2.9",
"system": "x86_64-linux"
}
}
</screen>
<command>nix-env</command> knows about the
<varname>description</varname> field specifically:
<screen>
$ nix-env -qa hello --description
hello-2.3 A program that produces a familiar, friendly greeting
</screen>
</para>
<section><title>Standard meta-attributes</title>
<para>The following meta-attributes have a standard
interpretation:</para>
<variablelist>
<varlistentry>
<term><varname>description</varname></term>
<listitem><para>A short (one-line) description of the package.
This is shown by <command>nix-env -q --description</command> and
also on the Nixpkgs release pages.</para>
<para>Dont include a period at the end. Dont include newline
characters. Capitalise the first character. For brevity, dont
repeat the name of package — just describe what it does.</para>
<para>Wrong: <literal>"libpng is a library that allows you to decode PNG images."</literal></para>
<para>Right: <literal>"A library for decoding PNG images"</literal></para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>longDescription</varname></term>
<listitem><para>An arbitrarily long description of the
package.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>homepage</varname></term>
<listitem><para>The packages homepage. Example:
<literal>http://www.gnu.org/software/hello/manual/</literal></para></listitem>
</varlistentry>
<varlistentry>
<term><varname>license</varname></term>
<listitem><para>The license for the package. One from attribute set defined in
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix">
<filename>nixpkgs/lib/licenses.nix</filename></link>.
Example:
<literal>stdenv.lib.licenses.gpl3</literal>.</para></listitem>
See details in <xref linkend='sec-meta-license'/>,
</varlistentry>
<varlistentry>
<term><varname>maintainers</varname></term>
<listitem><para>A list of names and e-mail addresses of the
maintainers of this Nix expression. If
you would like to be a maintainer of a package, you may want to add
yourself to <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/maintainers.nix"><filename>nixpkgs/lib/maintainers.nix</filename></link>
and write something like <literal>[ stdenv.lib.maintainers.alice
stdenv.lib.maintainers.bob ]</literal>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>priority</varname></term>
<listitem><para>The <emphasis>priority</emphasis> of the package,
used by <command>nix-env</command> to resolve file name conflicts
between packages. See the Nix manual page for
<command>nix-env</command> for details. Example:
<literal>"10"</literal> (a low-priority
package).</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>platforms</varname></term>
<listitem><para>The list of Nix platform types on which the
package is supported. Hydra builds packages according to the
platform specified. If no platform is specified, the package does
not have prebuilt binaries. An example is:
<programlisting>
meta.platforms = stdenv.lib.platforms.linux;
</programlisting>
Attribute Set <varname>stdenv.lib.platforms</varname> in
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/platforms.nix">
<filename>nixpkgs/lib/platforms.nix</filename></link> defines various common
lists of platforms types.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>hydraPlatforms</varname></term>
<listitem><para>The list of Nix platform types for which the Hydra
instance at <literal>hydra.nixos.org</literal> will build the
package. (Hydra is the Nix-based continuous build system.) It
defaults to the value of <varname>meta.platforms</varname>. Thus,
the only reason to set <varname>meta.hydraPlatforms</varname> is
if you want <literal>hydra.nixos.org</literal> to build the
package on a subset of <varname>meta.platforms</varname>, or not
at all, e.g.
<programlisting>
meta.platforms = stdenv.lib.platforms.linux;
meta.hydraPlatforms = [];
</programlisting>
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>broken</varname></term>
<listitem><para>If set to <literal>true</literal>, the package is
marked as “broken”, meaning that it wont show up in
<literal>nix-env -qa</literal>, and cannot be built or installed.
Such packages should be removed from Nixpkgs eventually unless
they are fixed.</para></listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="sec-meta-license"><title>Licenses</title>
<para>The <varname>meta.license</varname> attribute should preferrably contain
a value from <varname>stdenv.lib.licenses</varname> defined in
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix">
<filename>nixpkgs/lib/licenses.nix</filename></link>,
or in-place license description of the same format if the license is
unlikely to be useful in another expression.
A few generic options are available, although it's typically better
to indicate the specific license:
<variablelist>
<varlistentry>
<term><varname>free</varname></term>
<listitem><para>Catch-all for free software licenses not listed
above.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>unfree-redistributable</varname></term>
<listitem><para>Unfree package that can be redistributed in binary
form. That is, its legal to redistribute the
<emphasis>output</emphasis> of the derivation. This means that
the package can be included in the Nixpkgs
channel.</para>
<para>Sometimes proprietary software can only be redistributed
unmodified. Make sure the builder doesnt actually modify the
original binaries; otherwise were breaking the license. For
instance, the NVIDIA X11 drivers can be redistributed unmodified,
but our builder applies <command>patchelf</command> to make them
work. Thus, its license is <varname>unfree</varname> and it
cannot be included in the Nixpkgs channel.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>unfree</varname></term>
<listitem><para>Unfree package that cannot be redistributed. You
can build it yourself, but you cannot redistribute the output of
the derivation. Thus it cannot be included in the Nixpkgs
channel.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>unfree-redistributable-firmware</varname></term>
<listitem><para>This package supplies unfree, redistributable
firmware. This is a separate value from
<varname>unfree-redistributable</varname> because not everybody
cares whether firmware is free.</para></listitem>
</varlistentry>
</variablelist>
</para>
</section>
</chapter>

View File

@@ -1,331 +0,0 @@
Setting up a cross compiler with Nix
"Cross compilation" means compiling a program on one machine for another
type of machine. A typical use of cross compilation is to compile programs
for embedded devices. These devices often don't have the computing power
and memory to compile programs natively.
For a fully working cross compiler the following are needed:
* cross binutils: assembler, archiver, linker, etcetera that understand
the format of the target system
* cross compiler: a compiler that can generate binary code and object files
for the target platform
* cross C library: a library to link object files with to create fully
functional programs
Cross compilers are difficult to set up. A lot of people report that they
cannot succeed in building a cross toolchain successfully. The answers
usually consist of "download this pre-built toolchain", which is equally
unhelpful.
A toolchain is set up in five steps:
1. build binutils to that can run on the host platform, but generate code
for the target platform
2. build Linux kernel headers for the target platform
3. build a minimal C only version of GCC, that can run on the host platform
and generate code for the target platform
4. build a C library for the target platform. This includes the dynamic
linker, C library, etc.
5. build a full GCC
****
NB:
Keep in mind that many programs are not very well suited for cross
compilation. Either they are not intended to run on other platforms,
because the code is highly platform specific, or the configuration process
is not written with cross compilation in mind.
Nix will not solve these problems for you!
***
This document describes to set up a cross compiler to generate code for
arm-linux with uClibc and runs on i686-linux. The "stdenv" used is the
default from the standard Nix packages collection.
Step 1: build binutils for arm-linux in the stdenv for i686-linux
---
{stdenv, fetchurl, noSysDirs}:
stdenv.mkDerivation {
name = "binutils-2.16.1-arm";
builder = ./builder.sh;
src = fetchurl {
url = http://ftp.nluug.nl/gnu/binutils/binutils-2.16.1.tar.bz2;
md5 = "6a9d529efb285071dad10e1f3d2b2967";
};
inherit noSysDirs;
configureFlags = "--target=arm-linux";
}
---
This will compile binutils that will run on i686-linux, but knows the
format used by arm-linux.
Step 2: build kernel headers for the target architecture
default.nix for kernel-headers-arm:
---
{stdenv, fetchurl}:
assert stdenv.system == "i686-linux";
stdenv.mkDerivation {
name = "linux-headers-2.6.13.4-arm";
builder = ./builder.sh;
src = fetchurl {
url = http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.13.4.tar.bz2;
md5 = "94768d7eef90a9d8174639b2a7d3f58d";
};
}
---
builder.sh for kernel-headers-arm:
---
source $stdenv/setup
buildPhase() {
make include/linux/version.h
}
buildPhase=buildPhase
installPhase() {
mkdir $out
mkdir $out/include
#cd $out/include
#ln -s asm-arm asm
make include/asm ARCH=arm
cp -prvd include/linux include/asm include/asm-arm include/asm-generic $out/include
echo -n > $out/include/linux/autoconf.h
}
installPhase=installPhase
genericBuild
---
Step 3: build a minimal GCC
Extra/different parameters include the target platform and the kernel
headers argument (this needs a major cleanup, as well as the name, it
needs to be different!). Profiled compilers are disabled. The tarball
used here is just gcc-core. For some reason it doesn't install nicely
if the whole tarball is used (or is this some braino on my side? -- AH).
Only C is used, because for other languages (such as C++) extra libraries
need to be compiled, for which libraries compiled for the target system
are needed.
There is a bit of evilness going on. The cross compiled utilities need
to be either copied to or be linked from the output tree of the compiler.
(Is this really true? Back this up with arguments! -- AH)
Symbolic links are not something we want inside the Nix store.
---
{ stdenv, fetchurl, noSysDirs
, langC ? true, langCC ? true, langF77 ? false
, profiledCompiler ? false
, binutilsArm
, kernelHeadersArm
}:
assert langC;
stdenv.mkDerivation {
name = "gcc-4.0.2-arm";
builder = ./builder.sh;
src = fetchurl {
url = ftp://ftp.nluug.nl/pub/gnu/gcc/gcc-4.0.2/gcc-core-4.0.2.tar.bz2;
md5 = "f7781398ada62ba255486673e6274b26";
#url = ftp://ftp.nluug.nl/pub/gnu/gcc/gcc-4.0.2/gcc-4.0.2.tar.bz2;
#md5 = "a659b8388cac9db2b13e056e574ceeb0";
};
# !!! apply only if noSysDirs is set
patches = [./no-sys-dirs.patch ./gcc-inhibit.patch];
inherit noSysDirs langC langCC langF77 profiledCompiler;
buildInputs = [binutilsArm];
inherit kernelHeadersArm binutilsArm;
platform = "arm-linux";
}
---
The builder.sh for a cross-compiler. Note that the binutils are prefixed
with the architecture name, so arm-linux-ld instead of ld, etc. This is
necessary because when we cross-compile a lot of programs look for these
tools with these specific names. The standard gcc-wrapper does not take this
into account yet.
---
source $stdenv/setup
export NIX_FIXINC_DUMMY=$NIX_BUILD_TOP/dummy
mkdir $NIX_FIXINC_DUMMY
if test "$noSysDirs" = "1"; then
if test "$noSysDirs" = "1"; then
# Figure out what extra flags to pass to the gcc compilers
# being generated to make sure that they use our glibc.
if test -e $NIX_GCC/nix-support/orig-glibc; then
glibc=$(cat $NIX_GCC/nix-support/orig-glibc)
# Ugh. Copied from gcc-wrapper/builder.sh. We can't just
# source in $NIX_GCC/nix-support/add-flags, since that
# would cause *this* GCC to be linked against the
# *previous* GCC. Need some more modularity there.
extraCFlags="-B$glibc/lib -isystem $glibc/include"
extraLDFlags="-B$glibc/lib -L$glibc/lib -Wl,-s \
-Wl,-dynamic-linker,$glibc/lib/ld-linux.so.2"
# Oh, what a hack. I should be shot for this.
# In stage 1, we should link against the previous GCC, but
# not afterwards. Otherwise we retain a dependency.
# However, ld-wrapper, which adds the linker flags for the
# previous GCC, is also used in stage 2/3. We can prevent
# it from adding them by NIX_GLIBC_FLAGS_SET, but then
# gcc-wrapper will also not add them, thereby causing
# stage 1 to fail. So we use a trick to only set the
# flags in gcc-wrapper.
hook=$(pwd)/ld-wrapper-hook
echo "NIX_GLIBC_FLAGS_SET=1" > $hook
export NIX_LD_WRAPPER_START_HOOK=$hook
fi
export NIX_EXTRA_CFLAGS=$extraCFlags
export NIX_EXTRA_LDFLAGS=$extraLDFlags
export CFLAGS=$extraCFlags
export CXXFLAGS=$extraCFlags
export LDFLAGS=$extraLDFlags
fi
else
patches=""
fi
preConfigure=preConfigure
preConfigure() {
# Determine the frontends to build.
langs="c"
if test -n "$langCC"; then
langs="$langs,c++"
fi
if test -n "$langF77"; then
langs="$langs,f77"
fi
# Cross compiler evilness
mkdir -p $out
mkdir -p $out/arm-linux
mkdir -p $out/arm-linux/bin
ln -s $binutilsArm/arm-linux/bin/as $out/arm-linux/bin/as
ln -s $binutilsArm/arm-linux/bin/ld $out/arm-linux/bin/ld
ln -s $binutilsArm/arm-linux/bin/ar $out/arm-linux/bin/ar
ln -s $binutilsArm/arm-linux/bin/ranlib $out/arm-linux/bin/ranlib
# Perform the build in a different directory.
mkdir ../build
cd ../build
configureScript=../$sourceRoot/configure
configureFlags="--enable-languages=$langs --target=$platform --disable-threads --disable-libmudflap --disable-shared --with-headers=$kernelHeadersArm/include --disable-multilib"
}
postInstall=postInstall
postInstall() {
# Remove precompiled headers for now. They are very big and
# probably not very useful yet.
find $out/include -name "*.gch" -exec rm -rf {} \; -prune
# Remove `fixincl' to prevent a retained dependency on the
# previous gcc.
rm -rf $out/libexec/gcc/*/*/install-tools
}
#if test -z "$profiledCompiler"; then
#makeFlags="bootstrap"
#else
#makeFlags="profiledbootstrap"
#fi
genericBuild
---
Step 4: build a C library for the target platform.
The previous steps are enough to compile a C library. In our case we take
uClibc. It's intended to be a small sized replacement for glibc. It is widely
used in embedded environments.
...
Step 5: Build a compiler to link with the newly built C library.
...
If we restrict the compiler to just C programs it is relatively easy,
since we only need to wrap the GCC we built in the previous step with all
the right tools and the right C library. Successfully compiled programs with
this compiler and verified to be working on a HP Jornada 820 running Linux
are "patch", "make" and "wget".
If we want to build C++ programs it gets a lot more difficult. GCC has a
three step compilation process. In the first step a simple compiler, called
xgcc, that can compile only C programs is built. With that compiler it
compiles itself two more times: one time to build a full compiler, and another
time to build a full compiler once again with the freshly built compiler from
step 2. In the second and third step support for C++ is compiled, if this
is configured.
One of the libraries that has to be built for C++ support step is libstdc++.
This library uses xgcc, even when cross compiling, since libstdc++ has to be
compiled for arm-linux.
One of the compiler flags that GCC uses for this compiler is called X_CFLAGS.
This is used by the Nix build process to set the dynamic linker, glibc
in the case of i686-linux using the default Nix packages collection.
Obiously, since we need to compile libstc++ for arm-linux with uClibc linking
will not be done correctly: you can't link object files built for arm-linux
with a glibc built for i686-linux.
Setting X_CFLAGS to use the uClibc libraries and dynamic linker will fail
too. Earlier on in the build process these flags are used to compile important
files like libgcc.a by the host system gcc, which does need to be linked
to glibc. To make this work correctly you will need to carefully juggle
with compilation flags. This is still work in progress for Nix.
---
After successfully completing the whole toolchain you can start building
packages with the newly built tools. To make everything build correctly
you will need a stdenv for your target platform. Setting up this platform
will take some effort. Right now there is a very experimental setup for
arm-linux, which needs to be cleaned up before it is production ready.
Please note that many packages are not well suited for cross-compilation.
Even though the package itself might be very well portable often the
buildscripts are not. One thing that we have seen that causes frequent
build failures is the use of the LD variable. This is often set to 'ld'
and not $(CROSS)-ld.

View File

@@ -1,14 +0,0 @@
Semi-automatic source information updating using "update-upstream-data.sh" script and "src-{,info-}for-*.nix"
1. Recognizing when a pre-existing package uses this mechanism.
Packages using this automatical update mechanism have src-info-for-default.nix and src-for-default.nix next to default.nix. src-info-for-default.nix describes getting the freshest source from upstream web site; src-for-default.nix is a generated file with the current data about used source. Both files define a simple attrSet.
src-info-for-default.nix (for a file grabbed via http) contains at least downloadPage attribute - it is the page we need to look at to find out the latest version. It also contains baseName that is used for automatical generation of package name containing version. It can contain extra data for trickier cases.
src-for-default.nix will contain advertisedUrl (raw URL chosen on the site; its change prompts regeneration of source data), url for fetchurl, hash, version retrieved from the download URL and suggested package name.
2. Updating a package
nixpkgs/pkgs/build-support/upstream-updater directory contains some scripts. The worker script is called update-upstream-data.sh. This script requires main expression name (e.g. default.nix). It can optionally accpet a second parameter, URL which will be used instead of getting one by parsing the downloadPage (version extraction, mirror URL creation etc. will still be run). After running the script, check src-for-default.nix (or replace default.nix with expression name, if there are seceral expressions in the directory) for new version information.

View File

@@ -1,223 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-package-notes">
<title>Package Notes</title>
<para>This chapter contains information about how to use and maintain
the Nix expressions for a number of specific packages, such as the
Linux kernel or X.org.</para>
<!--============================================================-->
<section xml:id="sec-linux-kernel">
<title>Linux kernel</title>
<para>The Nix expressions to build the Linux kernel are in <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel"><filename>pkgs/os-specific/linux/kernel</filename></link>.</para>
<para>The function that builds the kernel has an argument
<varname>kernelPatches</varname> which should be a list of
<literal>{name, patch, extraConfig}</literal> attribute sets, where
<varname>name</varname> is the name of the patch (which is included in
the kernels <varname>meta.description</varname> attribute),
<varname>patch</varname> is the patch itself (possibly compressed),
and <varname>extraConfig</varname> (optional) is a string specifying
extra options to be concatenated to the kernel configuration file
(<filename>.config</filename>).</para>
<para>The kernel derivation exports an attribute
<varname>features</varname> specifying whether optional functionality
is or isnt enabled. This is used in NixOS to implement
kernel-specific behaviour. For instance, if the kernel has the
<varname>iwlwifi</varname> feature (i.e. has built-in support for
Intel wireless chipsets), then NixOS doesnt have to build the
external <varname>iwlwifi</varname> package:
<programlisting>
modulesTree = [kernel]
++ pkgs.lib.optional (!kernel.features ? iwlwifi) kernelPackages.iwlwifi
++ ...;
</programlisting>
</para>
<para>How to add a new (major) version of the Linux kernel to Nixpkgs:
<orderedlist>
<listitem>
<para>Copy the old Nix expression
(e.g. <filename>linux-2.6.21.nix</filename>) to the new one
(e.g. <filename>linux-2.6.22.nix</filename>) and update it.</para>
</listitem>
<listitem>
<para>Add the new kernel to <filename>all-packages.nix</filename>
(e.g., create an attribute
<varname>kernel_2_6_22</varname>).</para>
</listitem>
<listitem>
<para>Now were going to update the kernel configuration. First
unpack the kernel. Then for each supported platform
(<literal>i686</literal>, <literal>x86_64</literal>,
<literal>uml</literal>) do the following:
<orderedlist>
<listitem>
<para>Make an copy from the old
config (e.g. <filename>config-2.6.21-i686-smp</filename>) to
the new one
(e.g. <filename>config-2.6.22-i686-smp</filename>).</para>
</listitem>
<listitem>
<para>Copy the config file for this platform
(e.g. <filename>config-2.6.22-i686-smp</filename>) to
<filename>.config</filename> in the kernel source tree.
</para>
</listitem>
<listitem>
<para>Run <literal>make oldconfig
ARCH=<replaceable>{i386,x86_64,um}</replaceable></literal>
and answer all questions. (For the uml configuration, also
add <literal>SHELL=bash</literal>.) Make sure to keep the
configuration consistent between platforms (i.e. dont
enable some feature on <literal>i686</literal> and disable
it on <literal>x86_64</literal>).
</para>
</listitem>
<listitem>
<para>If needed you can also run <literal>make
menuconfig</literal>:
<screen>
$ nix-env -i ncurses
$ export NIX_CFLAGS_LINK=-lncurses
$ make menuconfig ARCH=<replaceable>arch</replaceable></screen>
</para>
</listitem>
<listitem>
<para>Copy <filename>.config</filename> over the new config
file (e.g. <filename>config-2.6.22-i686-smp</filename>).</para>
</listitem>
</orderedlist>
</para>
</listitem>
<listitem>
<para>Test building the kernel: <literal>nix-build -A
kernel_2_6_22</literal>. If it compiles, ship it! For extra
credit, try booting NixOS with it.</para>
</listitem>
<listitem>
<para>It may be that the new kernel requires updating the external
kernel modules and kernel-dependent packages listed in the
<varname>kernelPackagesFor</varname> function in
<filename>all-packages.nix</filename> (such as the NVIDIA drivers,
AUFS, etc.). If the updated packages arent backwards compatible
with older kernels, you may need to keep the older versions
around.</para>
</listitem>
</orderedlist>
</para>
</section>
<!--============================================================-->
<section>
<title>X.org</title>
<para>The Nix expressions for the X.org packages reside in
<filename>pkgs/servers/x11/xorg/default.nix</filename>. This file is
automatically generated from lists of tarballs in an X.org release.
As such it should not be modified directly; rather, you should modify
the lists, the generator script or the file
<filename>pkgs/servers/x11/xorg/overrides.nix</filename>, in which you
can override or add to the derivations produced by the
generator.</para>
<para>The generator is invoked as follows:
<screen>
$ cd pkgs/servers/x11/xorg
$ cat tarballs-7.5.list extra.list old.list \
| perl ./generate-expr-from-tarballs.pl
</screen>
For each of the tarballs in the <filename>.list</filename> files, the
script downloads it, unpacks it, and searches its
<filename>configure.ac</filename> and <filename>*.pc.in</filename>
files for dependencies. This information is used to generate
<filename>default.nix</filename>. The generator caches downloaded
tarballs between runs. Pay close attention to the <literal>NOT FOUND:
<replaceable>name</replaceable></literal> messages at the end of the
run, since they may indicate missing dependencies. (Some might be
optional dependencies, however.)</para>
<para>A file like <filename>tarballs-7.5.list</filename> contains all
tarballs in a X.org release. It can be generated like this:
<screen>
$ export i="mirror://xorg/X11R7.4/src/everything/"
$ cat $(PRINT_PATH=1 nix-prefetch-url $i | tail -n 1) \
| perl -e 'while (&lt;>) { if (/(href|HREF)="([^"]*.bz2)"/) { print "$ENV{'i'}$2\n"; }; }' \
| sort > tarballs-7.4.list
</screen>
<filename>extra.list</filename> contains libraries that arent part of
X.org proper, but are closely related to it, such as
<literal>libxcb</literal>. <filename>old.list</filename> contains
some packages that were removed from X.org, but are still needed by
some people or by other packages (such as
<varname>imake</varname>).</para>
<para>If the expression for a package requires derivation attributes
that the generator cannot figure out automatically (say,
<varname>patches</varname> or a <varname>postInstall</varname> hook),
you should modify
<filename>pkgs/servers/x11/xorg/overrides.nix</filename>.</para>
</section>
<!--============================================================-->
<!--
<section>
<title>Gnome</title>
<para>* Expression is auto-generated</para>
<para>* How to update</para>
</section>
-->
<!--============================================================-->
<!--
<section>
<title>GCC</title>
<para>…</para>
</section>
-->
</chapter>

View File

@@ -1,234 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-quick-start">
<title>Quick Start to Adding a Package</title>
<para>To add a package to Nixpkgs:
<orderedlist>
<listitem>
<para>Checkout the Nixpkgs source tree:
<screen>
$ git clone git://github.com/NixOS/nixpkgs.git
$ cd nixpkgs</screen>
</para>
</listitem>
<listitem>
<para>Find a good place in the Nixpkgs tree to add the Nix
expression for your package. For instance, a library package
typically goes into
<filename>pkgs/development/libraries/<replaceable>pkgname</replaceable></filename>,
while a web browser goes into
<filename>pkgs/applications/networking/browsers/<replaceable>pkgname</replaceable></filename>.
See <xref linkend="sec-organisation" /> for some hints on the tree
organisation. Create a directory for your package, e.g.
<screen>
$ mkdir pkgs/development/libraries/libfoo</screen>
</para>
</listitem>
<listitem>
<para>In the package directory, create a Nix expression — a piece
of code that describes how to build the package. In this case, it
should be a <emphasis>function</emphasis> that is called with the
package dependencies as arguments, and returns a build of the
package in the Nix store. The expression should usually be called
<filename>default.nix</filename>.
<screen>
$ emacs pkgs/development/libraries/libfoo/default.nix
$ git add pkgs/development/libraries/libfoo/default.nix</screen>
</para>
<para>You can have a look at the existing Nix expressions under
<filename>pkgs/</filename> to see how its done. Here are some
good ones:
<itemizedlist>
<listitem>
<para>GNU cpio: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/archivers/cpio/default.nix"><filename>pkgs/tools/archivers/cpio/default.nix</filename></link>.
The simplest possible package. The generic builder in
<varname>stdenv</varname> does everything for you. It has
no dependencies beyond <varname>stdenv</varname>.</para>
</listitem>
<listitem>
<para>GNU Hello: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/hello/ex-2/default.nix"><filename>pkgs/applications/misc/hello/ex-2/default.nix</filename></link>.
Also trivial, but it specifies some <varname>meta</varname>
attributes which is good practice.</para>
</listitem>
<listitem>
<para>GNU Multiple Precision arithmetic library (GMP): <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/gmp/5.1.x.nix"><filename>pkgs/development/libraries/gmp/5.1.x.nix</filename></link>.
Also done by the generic builder, but has a dependency on
<varname>m4</varname>.</para>
</listitem>
<listitem>
<para>Pan, a GTK-based newsreader: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/newsreaders/pan/default.nix"><filename>pkgs/applications/networking/newsreaders/pan/default.nix</filename></link>.
Has an optional dependency on <varname>gtkspell</varname>,
which is only built if <varname>spellCheck</varname> is
<literal>true</literal>.</para>
</listitem>
<listitem>
<para>Apache HTTPD: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/http/apache-httpd/2.4.nix"><filename>pkgs/servers/http/apache-httpd/2.4.nix</filename></link>.
A bunch of optional features, variable substitutions in the
configure flags, a post-install hook, and miscellaneous
hackery.</para>
</listitem>
<listitem>
<para>BitTorrent (wxPython-based): <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/networking/p2p/bittorrent/default.nix"><filename>pkgs/tools/networking/p2p/bittorrent/default.nix</filename></link>.
Uses an external <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/networking/p2p/bittorrent/builder.sh">build
script</link>, which can be useful if you have lots of code
that you dont want cluttering up the Nix expression. But
external builders are mostly obsolete.
</para>
</listitem>
<listitem>
<para>Thunderbird: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/mailreaders/thunderbird/default.nix"><filename>pkgs/applications/networking/mailreaders/thunderbird/default.nix</filename></link>.
Lots of dependencies.</para>
</listitem>
<listitem>
<para>JDiskReport, a Java utility: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/misc/jdiskreport/default.nix"><filename>pkgs/tools/misc/jdiskreport/default.nix</filename></link>
(and the <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/misc/jdiskreport/builder.sh">builder</link>).
Nixpkgs doesnt have a decent <varname>stdenv</varname> for
Java yet so this is pretty ad-hoc.</para>
</listitem>
<listitem>
<para>XML::Simple, a Perl module: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/perl-packages.nix"><filename>pkgs/top-level/perl-packages.nix</filename></link>
(search for the <varname>XMLSimple</varname> attribute).
Most Perl modules are so simple to build that they are
defined directly in <filename>perl-packages.nix</filename>;
no need to make a separate file for them.</para>
</listitem>
<listitem>
<para>Adobe Reader: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/adobe-reader/default.nix"><filename>pkgs/applications/misc/adobe-reader/default.nix</filename></link>.
Shows how binary-only packages can be supported. In
particular the <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/adobe-reader/builder.sh">builder</link>
uses <command>patchelf</command> to set the RUNPATH and ELF
interpreter of the executables so that the right libraries
are found at runtime.</para>
</listitem>
</itemizedlist>
</para>
<para>Some notes:
<itemizedlist>
<listitem>
<para>All <varname linkend="chap-meta">meta</varname>
attributes are optional, but its still a good idea to
provide at least the <varname>description</varname>,
<varname>homepage</varname> and <varname
linkend="sec-meta-license">license</varname>.</para>
</listitem>
<listitem>
<para>You can use <command>nix-prefetch-url</command> (or similar nix-prefetch-git, etc)
<replaceable>url</replaceable> to get the SHA-256 hash of
source distributions. There are similar commands as <command>nix-prefetch-git</command> and
<command>nix-prefetch-hg</command> available in <literal>nix-prefetch-scripts</literal> package.</para>
</listitem>
<listitem>
<para>A list of schemes for <literal>mirror://</literal>
URLs can be found in <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/fetchurl/mirrors.nix"><filename>pkgs/build-support/fetchurl/mirrors.nix</filename></link>.</para>
</listitem>
</itemizedlist>
</para>
<para>The exact syntax and semantics of the Nix expression
language, including the built-in function, are described in the
Nix manual in the <link
xlink:href="http://hydra.nixos.org/job/nix/trunk/tarball/latest/download-by-type/doc/manual/#chap-writing-nix-expressions">chapter
on writing Nix expressions</link>.</para>
</listitem>
<listitem>
<para>Add a call to the function defined in the previous step to
<link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/all-packages.nix"><filename>pkgs/top-level/all-packages.nix</filename></link>
with some descriptive name for the variable,
e.g. <varname>libfoo</varname>.
<screen>
$ emacs pkgs/top-level/all-packages.nix</screen>
</para>
<para>The attributes in that file are sorted by category (like
“Development / Libraries”) that more-or-less correspond to the
directory structure of Nixpkgs, and then by attribute name.</para>
</listitem>
<listitem>
<para>To test whether the package builds, run the following command
from the root of the nixpkgs source tree:
<screen>
$ nix-build -A libfoo</screen>
where <varname>libfoo</varname> should be the variable name
defined in the previous step. You may want to add the flag
<option>-K</option> to keep the temporary build directory in case
something fails. If the build succeeds, a symlink
<filename>./result</filename> to the package in the Nix store is
created.</para>
</listitem>
<listitem>
<para>If you want to install the package into your profile
(optional), do
<screen>
$ nix-env -f . -iA libfoo</screen>
</para>
</listitem>
<listitem>
<para>Optionally commit the new package and open a pull request, or send a patch to
<literal>nix-dev@cs.uu.nl</literal>.</para>
</listitem>
</orderedlist>
</para>
</chapter>

View File

@@ -1,44 +0,0 @@
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="xml"/>
<xsl:template match="function|command|literal|varname|filename|option|quote">`<xsl:apply-templates/>'</xsl:template>
<xsl:template match="token"><xsl:text> </xsl:text><xsl:apply-templates /><xsl:text>
</xsl:text></xsl:template>
<xsl:template match="screen|programlisting">
<screen><xsl:apply-templates select="str:split(., '&#xA;')" /></screen>
</xsl:template>
<xsl:template match="section[following::section]">
<section>
<xsl:apply-templates />
<screen><xsl:text>
</xsl:text></screen>
</section>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="namespace::*" />
<xsl:for-each select="@*">
<xsl:attribute name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="translate(., '‘’“”—', concat(&quot;`'&quot;, '&quot;&quot;-'))" />
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,733 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<article xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Nixpkgs Release Notes</title>
<section><title>Release 0.14 (June 4, 2012)</title>
<para>In preparation for the switch from Subversion to Git, this
release is mainly the prevent the Nixpkgs version number from going
backwards. (This would happen because prerelease version numbers
produced for the Git repository are lower than those for the
Subversion repository.)</para>
<para>Since the last release, there have been thousands of changes and
new packages by numerous contributors. For details, see the commit
logs.</para>
</section>
<section><title>Release 0.13 (February 5, 2010)</title>
<para>As always, there are many changes. Some of the most important
updates are:
<itemizedlist>
<listitem><para>Glibc 2.9.</para></listitem>
<listitem><para>GCC 4.3.3.</para></listitem>
<listitem><para>Linux 2.6.32.</para></listitem>
<listitem><para>X.org 7.5.</para></listitem>
<listitem><para>KDE 4.3.4.</para></listitem>
</itemizedlist>
</para>
</section>
<section><title>Release 0.12 (April 24, 2009)</title>
<para>There are way too many additions to Nixpkgs since the last
release to list here: for example, the number of packages on Linux has
increased from 1002 to 2159. However, some specific improvements are
worth listing:
<itemizedlist>
<listitem><para>Nixpkgs now has a manual. In particular, it
describes the standard build environment in
detail.</para></listitem>
<listitem><para>Major new packages:
<itemizedlist>
<listitem><para>KDE 4.</para></listitem>
<listitem><para>TeXLive.</para></listitem>
<listitem><para>VirtualBox.</para></listitem>
</itemizedlist>
… and many others.
</para></listitem>
<listitem><para>Important updates:
<itemizedlist>
<listitem><para>Glibc 2.7.</para></listitem>
<listitem><para>GCC 4.2.4.</para></listitem>
<listitem><para>Linux 2.6.25 — 2.6.28.</para></listitem>
<listitem><para>Firefox 3.</para></listitem>
<listitem><para>X.org 7.3.</para></listitem>
</itemizedlist>
</para></listitem>
<listitem><para>Support for building derivations in a virtual
machine, including RPM and Debian builds in automatically generated
VM images. See
<filename>pkgs/build-support/vm/default.nix</filename> for
details.</para></listitem>
<listitem><para>Improved support for building Haskell
packages.</para></listitem>
</itemizedlist>
</para>
<para>The following people contributed to this release:
Andres Löh,
Arie Middelkoop,
Armijn Hemel,
Eelco Dolstra,
Lluís Batlle,
Ludovic Courtès,
Marc Weber,
Mart Kolthof,
Martin Bravenboer,
Michael Raskin,
Nicolas Pierron,
Peter Simons,
Pjotr Prins,
Rob Vermaas,
Sander van der Burg,
Tobias Hammerschmidt,
Valentin David,
Wouter den Breejen and
Yury G. Kudryashov.
In addition, several people contributed patches on the
<literal>nix-dev</literal> mailing list.</para>
</section>
<section><title>Release 0.11 (September 11, 2007)</title>
<para>This release has the following improvements:
<itemizedlist>
<listitem><para>The standard build environment
(<literal>stdenv</literal>) is now pure on the
<literal>x86_64-linux</literal> and <literal>powerpc-linux</literal>
platforms, just as on <literal>i686-linux</literal>. (Purity means
that building and using the standard environment has no dependencies
outside of the Nix store. For instance, it doesnt require an
external C compiler such as <filename>/usr/bin/gcc</filename>.)
Also, the statically linked binaries used in the bootstrap process
are now automatically reproducible, making it easy to update the
bootstrap tools and to add support for other Linux platforms. See
<filename>pkgs/stdenv/linux/make-bootstrap-tools.nix</filename> for
details.</para></listitem>
<listitem><para>Hook variables in the generic builder are now
executed using the <function>eval</function> shell command. This
has a major advantage: you can write hooks directly in Nix
expressions. For instance, rather than writing a builder like this:
<programlisting>
source $stdenv/setup
postInstall=postInstall
postInstall() {
ln -sf gzip $out/bin/gunzip
ln -sf gzip $out/bin/zcat
}
genericBuild</programlisting>
(the <literal>gzip</literal> builder), you can just add this
attribute to the derivation:
<programlisting>
postInstall = "ln -sf gzip $out/bin/gunzip; ln -sf gzip $out/bin/zcat";</programlisting>
and so a separate build script becomes unnecessary. This should
allow us to get rid of most builders in Nixpkgs.</para></listitem>
<listitem><para>It is now possible to have the generic builder pass
arguments to <command>configure</command> and
<command>make</command> that contain whitespace. Previously, for
example, you could say in a builder,
<programlisting>
configureFlags="CFLAGS=-O0"</programlisting>
but not
<programlisting>
configureFlags="CFLAGS=-O0 -g"</programlisting>
since the <literal>-g</literal> would be interpreted as a separate
argument to <command>configure</command>. Now you can say
<programlisting>
configureFlagsArray=("CFLAGS=-O0 -g")</programlisting>
or similarly
<programlisting>
configureFlagsArray=("CFLAGS=-O0 -g" "LDFLAGS=-L/foo -L/bar")</programlisting>
which does the right thing. Idem for <literal>makeFlags</literal>,
<literal>installFlags</literal>, <literal>checkFlags</literal> and
<literal>distFlags</literal>.</para>
<para>Unfortunately you can't pass arrays to Bash through the
environment, so you can't put the array above in a Nix expression,
e.g.,
<programlisting>
configureFlagsArray = ["CFLAGS=-O0 -g"];</programlisting>
since it would just be flattened to a since string. However, you
<emphasis>can</emphasis> use the inline hooks described above:
<programlisting>
preConfigure = "configureFlagsArray=(\"CFLAGS=-O0 -g\")";</programlisting>
</para></listitem>
<listitem><para>The function <function>fetchurl</function> now has
support for two different kinds of mirroring of files. First, it
has support for <emphasis>content-addressable mirrors</emphasis>.
For example, given the <function>fetchurl</function> call
<programlisting>
fetchurl {
url = http://releases.mozilla.org/<replaceable>...</replaceable>/firefox-2.0.0.6-source.tar.bz2;
sha1 = "eb72f55e4a8bf08e8c6ef227c0ade3d068ba1082";
}</programlisting>
<function>fetchurl</function> will first try to download this file
from <link
xlink:href="http://tarballs.nixos.org/sha1/eb72f55e4a8bf08e8c6ef227c0ade3d068ba1082"/>.
If that file doesnt exist, it will try the original URL. In
general, the “content-addressed” location is
<replaceable>mirror</replaceable><literal>/</literal><replaceable>hash-type</replaceable><literal>/</literal><replaceable>hash</replaceable>.
There is currently only one content-addressable mirror (<link
xlink:href="http://tarballs.nixos.org"/>), but more can be
specified in the <varname>hashedMirrors</varname> attribute in
<filename>pkgs/build-support/fetchurl/mirrors.nix</filename>, or by
setting the <envar>NIX_HASHED_MIRRORS</envar> environment variable
to a whitespace-separated list of URLs.</para>
<para>Second, <function>fetchurl</function> has support for
widely-mirrored distribution sites such as SourceForge or the Linux
kernel archives. Given a URL of the form
<literal>mirror://<replaceable>site</replaceable>/<replaceable>path</replaceable></literal>,
it will try to download <replaceable>path</replaceable> from a
configurable list of mirrors for <replaceable>site</replaceable>.
(This idea was borrowed from Gentoo Linux.) Example:
<programlisting>
fetchurl {
url = mirror://gnu/gcc/gcc-4.2.0/gcc-core-4.2.0.tar.bz2;
sha256 = "0ykhzxhr8857dr97z0j9wyybfz1kjr71xk457cfapfw5fjas4ny1";
}</programlisting>
Currently <replaceable>site</replaceable> can be
<literal>sourceforge</literal>, <literal>gnu</literal> and
<literal>kernel</literal>. The list of mirrors is defined in
<filename>pkgs/build-support/fetchurl/mirrors.nix</filename>. You
can override the list of mirrors for a particular site by setting
the environment variable
<envar>NIX_MIRRORS_<replaceable>site</replaceable></envar>, e.g.
<programlisting>
export NIX_MIRRORS_sourceforge=http://osdn.dl.sourceforge.net/sourceforge/</programlisting>
</para>
</listitem>
<listitem><para>Important updates:
<itemizedlist>
<listitem><para>Glibc 2.5.</para></listitem>
<listitem><para>GCC 4.1.2.</para></listitem>
<listitem><para>Gnome 2.16.3.</para></listitem>
<listitem><para>X11R7.2.</para></listitem>
<listitem><para>Linux 2.6.21.7 and 2.6.22.6.</para></listitem>
<listitem><para>Emacs 22.1.</para></listitem>
</itemizedlist>
</para></listitem>
<listitem><para>Major new packages:
<itemizedlist>
<listitem><para>KDE 3.5.6 Base.</para></listitem>
<listitem><para>Wine 0.9.43.</para></listitem>
<listitem><para>OpenOffice 2.2.1.</para></listitem>
<listitem><para>Many Linux system packages to support
NixOS.</para></listitem>
</itemizedlist>
</para></listitem>
</itemizedlist>
</para>
<para>The following people contributed to this release:
Andres Löh,
Arie Middelkoop,
Armijn Hemel,
Eelco Dolstra,
Marc Weber,
Mart Kolthof,
Martin Bravenboer,
Michael Raskin,
Wouter den Breejen and
Yury G. Kudryashov.
</para>
</section>
<section><title>Release 0.10 (October 12, 2006)</title>
<note><para>This release of Nixpkgs requires <link
xlink:href='http://nixos.org/releases/nix/nix-0.10/'>Nix
0.10</link> or higher.</para></note>
<para>This release has the following improvements:</para>
<itemizedlist>
<listitem><para><filename>pkgs/system/all-packages-generic.nix</filename>
is gone, we now just have
<filename>pkgs/top-level/all-packages.nix</filename> that contains
all available packages. This should cause much less confusion with
users. <filename>all-packages.nix</filename> is a function that by
default returns packages for the current platform, but you can
override this by specifying a different <varname>system</varname>
argument.</para></listitem>
<listitem><para>Certain packages in Nixpkgs are now
user-configurable through a configuration file, i.e., without having
to edit the Nix expressions in Nixpkgs. For instance, the Firefox
provided in the Nixpkgs channel is built without the RealPlayer
plugin (for legal reasons). Previously, you could easily enable
RealPlayer support by editing the call to the Firefox function in
<filename>all-packages.nix</filename>, but such changes are not
respected when Firefox is subsequently updated through the Nixpkgs
channel.</para>
<para>The Nixpkgs configuration file (found in
<filename>~/.nixpkgs/config.nix</filename> or through the
<envar>NIXPKGS_CONFIG</envar> environment variable) is an attribute
set that contains configuration options that
<filename>all-packages.nix</filename> reads and uses for certain
packages. For instance, the following configuration file:
<programlisting>
{
firefox = {
enableRealPlayer = true;
};
}</programlisting>
persistently enables RealPlayer support in the Firefox
build.</para>
<para>(Actually, <literal>firefox.enableRealPlayer</literal> is the
<emphasis>only</emphasis> configuration option currently available,
but more are sure to be added.)</para></listitem>
<listitem><para>Support for new platforms:
<itemizedlist>
<listitem><para><literal>i686-cygwin</literal>, i.e., Windows
(using <link xlink:href="http://www.cygwin.com/">Cygwin</link>).
The standard environment on <literal>i686-cygwin</literal> by
default builds binaries for the Cygwin environment (i.e., it
uses Cygwin tools and produces executables that use the Cygwin
library). However, there is also a standard environment that
produces binaries that use <link
xlink:href="http://www.mingw.org/">MinGW</link>. You can use it
by calling <filename>all-package.nix</filename> with the
<varname>stdenvType</varname> argument set to
<literal>"i686-mingw"</literal>.</para></listitem>
<listitem><para><literal>i686-darwin</literal>, i.e., Mac OS X
on Intel CPUs.</para></listitem>
<listitem><para><literal>powerpc-linux</literal>.</para></listitem>
<listitem><para><literal>x86_64-linux</literal>, i.e., Linux on
64-bit AMD/Intel CPUs. Unlike <literal>i686-linux</literal>,
this platform doesnt have a pure <literal>stdenv</literal>
yet.</para></listitem>
</itemizedlist>
</para>
</listitem>
<listitem><para>The default compiler is now GCC 4.1.1.</para></listitem>
<listitem><para>X11 updated to X.orgs X11R7.1.</para></listitem>
<listitem><para>Notable new packages:
<itemizedlist>
<listitem><para>Opera.</para></listitem>
<listitem><para>Microsoft Visual C++ 2005 Express Edition and
the Windows SDK.</para></listitem>
</itemizedlist>
In total there are now around 809 packages in Nixpkgs.</para>
</listitem>
<listitem><para>It is now <emphasis>much</emphasis> easier to
override the default C compiler and other tools in
<literal>stdenv</literal> for specific packages.
<filename>all-packages.nix</filename> provides two utility
functions for this purpose: <function>overrideGCC</function> and
<function>overrideInStdenv</function>. Both take a
<literal>stdenv</literal> and return an augmented
<literal>stdenv</literal>; the formed changes the C compiler, and
the latter adds additional packages to the front of
<literal>stdenv</literal>s initial <envar>PATH</envar>, allowing
tools to be overridden.</para>
<para>For instance, the package <varname>strategoxt</varname>
doesnt build with the GNU Make in <literal>stdenv</literal>
(version 3.81), so we call it with an augmented
<literal>stdenv</literal> that uses GNU Make 3.80:
<programlisting>
strategoxt = (import ../development/compilers/strategoxt) {
inherit fetchurl pkgconfig sdf aterm;
stdenv = overrideInStdenv stdenv [gnumake380];
};
gnumake380 = <replaceable>...</replaceable>;</programlisting>
Likewise, there are many packages that dont compile with the
default GCC (4.1.1), but thats easily fixed:
<programlisting>
exult = import ../games/exult {
inherit fetchurl SDL SDL_mixer zlib libpng unzip;
stdenv = overrideGCC stdenv gcc34;
};</programlisting>
</para></listitem>
<listitem><para>It has also become much easier to experiment with
changes to the <literal>stdenv</literal> setup script (which notably
contains the generic builder). Since edits to
<filename>pkgs/stdenv/generic/setup.sh</filename> trigger a rebuild
of <emphasis>everything</emphasis>, this was formerly quite painful.
But now <literal>stdenv</literal> contains a function to
“regenerate” <literal>stdenv</literal> with a different setup
script, allowing the use of a different setup script for specific
packages:
<programlisting>
pkg = import <replaceable>...</replaceable> {
stdenv = stdenv.regenerate ./my-setup.sh;
<replaceable>...</replaceable>
}</programlisting>
</para></listitem>
<listitem><para>Packages can now have a human-readable
<emphasis>description</emphasis> field. Package descriptions are
shown by <literal>nix-env -qa --description</literal>. In addition,
theyre shown on the Nixpkgs release page. A description can be
added to a package as follows:
<programlisting>
stdenv.mkDerivation {
name = "exult-1.2";
<replaceable>...</replaceable>
meta = {
description = "A reimplementation of the Ultima VII game engine";
};
}</programlisting>
The <varname>meta</varname> attribute is not passed to the builder,
so changes to the description do not trigger a rebuild. Additional
<varname>meta</varname> attributes may be defined in the future
(such as the URL of the packages homepage, the license,
etc.).</para></listitem>
</itemizedlist>
<para>The following people contributed to this release:
Andres Löh,
Armijn Hemel,
Christof Douma,
Eelco Dolstra,
Eelco Visser,
Mart Kolthof,
Martin Bravenboer,
Merijn de Jonge,
Rob Vermaas and
Roy van den Broek.
</para>
</section>
<section><title>Release 0.9 (January 31, 2006)</title>
<para>There have been zillions of changes since the last release of
Nixpkgs. Many packages have been added or updated. The following are
some of the more notable changes:</para>
<itemizedlist>
<listitem><para>Distribution files have been moved to <link
xlink:href="http://nixos.org/" />.</para></listitem>
<listitem><para>The C library on Linux, Glibc, has been updated to
version 2.3.6.</para></listitem>
<listitem><para>The default compiler is now GCC 3.4.5. GCC 4.0.2 is
also available.</para></listitem>
<listitem><para>The old, unofficial Xlibs has been replaced by the
official modularised X11 distribution from X.org, i.e., X11R7.0.
X11R7.0 consists of 287 (!) packages, all of which are in Nixpkgs
though not all have been tested. It is now possible to build a
working X server (previously we only had X client libraries). We
use a fully Nixified X server on NixOS.</para></listitem>
<listitem><para>The Sun JDK 5 has been purified, i.e., it doesnt
require any non-Nix components such as
<filename>/lib/ld-linux.so.2</filename>. This means that Java
applications such as Eclipse and Azureus can run on
NixOS.</para></listitem>
<listitem><para>Hardware-accelerated OpenGL support, used by games
like Quake 3 (which is now built from source).</para></listitem>
<listitem><para>Improved support for FreeBSD on
x86.</para></listitem>
<listitem><para>Improved Haskell support; e.g., the GHC build is now
pure.</para></listitem>
<listitem><para>Some support for cross-compilation: cross-compiling
builds of GCC and Binutils, and cross-compiled builds of the C
library uClibc.</para></listitem>
<listitem><para>Notable new packages:
<itemizedlist>
<listitem><para>teTeX, including support for building LaTeX
documents using Nix (with automatic dependency
determination).</para></listitem>
<listitem><para>Ruby.</para></listitem>
<listitem><para>System-level packages to support NixOS,
e.g. Grub, GNU <literal>parted</literal> and so
on.</para></listitem>
<listitem><para><literal>ecj</literal>, the Eclipse Compiler for
Java, so we finally have a freely distributable compiler that
supports Java 5.0.</para></listitem>
<listitem><para><literal>php</literal>.</para></listitem>
<listitem><para>The GIMP.</para></listitem>
<listitem><para>Inkscape.</para></listitem>
<listitem><para>GAIM.</para></listitem>
<listitem><para><literal>kdelibs</literal>. This allows us to
add KDE-based packages (such as
<literal>kcachegrind</literal>).</para></listitem>
</itemizedlist>
</para></listitem>
</itemizedlist>
<para>The following people contributed to this release:
Andres Löh,
Armijn Hemel,
Bogdan Dumitriu,
Christof Douma,
Eelco Dolstra,
Eelco Visser,
Mart Kolthof,
Martin Bravenboer,
Rob Vermaas and
Roy van den Broek.
</para>
</section>
<section><title>Release 0.8 (April 11, 2005)</title>
<para>This release is mostly to remain synchronised with the changed
hashing scheme in Nix 0.8.</para>
<para>Notable updates:
<itemizedlist>
<listitem><para>Adobe Reader 7.0</para></listitem>
<listitem><para>Various security updates (zlib 1.2.2, etc.)</para></listitem>
</itemizedlist>
</para>
</section>
<section><title>Release 0.7 (March 14, 2005)</title>
<itemizedlist>
<listitem>
<para>The bootstrap process for the standard build
environment on Linux (stdenv-linux) has been improved. It is no
longer dependent in its initial bootstrap stages on the system
Glibc, GCC, and other tools. Rather, Nixpkgs contains a statically
linked bash and curl, and uses that to download other statically
linked tools. These are then used to build a Glibc and dynamically
linked versions of all other tools.</para>
<para>This change also makes the bootstrap process faster. For
instance, GCC is built only once instead of three times.</para>
<para>(Contributed by Armijn Hemel.)</para>
</listitem>
<listitem>
<para>Tarballs used by Nixpkgs are now obtained from the same server
that hosts Nixpkgs (<link
xlink:href="http://catamaran.labs.cs.uu.nl/" />). This reduces the
risk of packages being unbuildable due to moved or deleted files on
various servers.</para>
</listitem>
<listitem>
<para>There now is a generic mechanism for building Perl modules.
See the various Perl modules defined in
pkgs/system/all-packages-generic.nix.</para>
</listitem>
<listitem>
<para>Notable new packages:
<itemizedlist>
<listitem><para>Qt 3</para></listitem>
<listitem><para>MySQL</para></listitem>
<listitem><para>MythTV</para></listitem>
<listitem><para>Mono</para></listitem>
<listitem><para>MonoDevelop (alpha)</para></listitem>
<listitem><para>Xine</para></listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>Notable updates:
<itemizedlist>
<listitem><para>GCC 3.4.3</para></listitem>
<listitem><para>Glibc 2.3.4</para></listitem>
<listitem><para>GTK 2.6</para></listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</section>
</article>

File diff suppressed because it is too large Load Diff

View File

@@ -1,255 +0,0 @@
/* Copied from http://bakefile.sourceforge.net/, which appears
licensed under the GNU GPL. */
/***************************************************************************
Basic headers and text:
***************************************************************************/
body
{
font-family: "Nimbus Sans L", sans-serif;
background: white;
margin: 2em 1em 2em 1em;
}
h1, h2, h3, h4
{
color: #005aa0;
}
h1 /* title */
{
font-size: 200%;
}
h2 /* chapters, appendices, subtitle */
{
font-size: 180%;
}
/* Extra space between chapters, appendices. */
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
{
margin-top: 1.5em;
}
div.section > div.titlepage h2 /* sections */
{
font-size: 150%;
margin-top: 1.5em;
}
h3 /* subsections */
{
font-size: 125%;
}
div.simplesect h2
{
font-size: 110%;
}
div.appendix h3
{
font-size: 150%;
margin-top: 1.5em;
}
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
{
margin-top: 1.4em;
font-size: 125%;
}
div.refsection h3
{
font-size: 110%;
}
/***************************************************************************
Examples:
***************************************************************************/
div.example
{
border: 1px solid #b0b0b0;
padding: 6px 6px;
margin-left: 1.5em;
margin-right: 1.5em;
background: #f4f4f8;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example p.title
{
margin-top: 0em;
}
div.example pre
{
box-shadow: none;
}
/***************************************************************************
Screen dumps:
***************************************************************************/
pre.screen, pre.programlisting
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
color: #600000;
background: #f4f4f8;
font-family: monospace;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example pre.programlisting
{
border: 0px;
padding: 0 0;
margin: 0 0 0 0;
}
/***************************************************************************
Notes, warnings etc:
***************************************************************************/
.note, .warning
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
margin-bottom: 1em;
padding: 0.3em 0.3em 0.3em 0.3em;
background: #fffff5;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.note, div.warning
{
font-style: italic;
}
div.note h3, div.warning h3
{
color: red;
font-size: 100%;
padding-right: 0.5em;
display: inline;
}
div.note p, div.warning p
{
margin-bottom: 0em;
}
div.note h3 + p, div.warning h3 + p
{
display: inline;
}
div.note h3
{
color: blue;
font-size: 100%;
}
div.navfooter *
{
font-size: 90%;
}
/***************************************************************************
Links colors and highlighting:
***************************************************************************/
a { text-decoration: none; }
a:hover { text-decoration: underline; }
a:link { color: #0048b3; }
a:visited { color: #002a6a; }
/***************************************************************************
Table of contents:
***************************************************************************/
div.toc
{
font-size: 90%;
}
div.toc dl
{
margin-top: 0em;
margin-bottom: 0em;
}
/***************************************************************************
Special elements:
***************************************************************************/
tt, code
{
color: #400000;
}
.term
{
font-weight: bold;
}
div.variablelist dd p, div.glosslist dd p
{
margin-top: 0em;
}
div.variablelist dd, div.glosslist dd
{
margin-left: 1.5em;
}
div.glosslist dt
{
font-style: italic;
}
.varname
{
color: #400000;
}
span.command strong
{
font-weight: normal;
color: #400000;
}
div.calloutlist table
{
box-shadow: none;
}
table
{
border-collapse: collapse;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.affiliation
{
font-style: italic;
}

View File

@@ -1,328 +0,0 @@
# Operations on attribute sets.
with {
inherit (builtins) head tail;
inherit (import ./trivial.nix) or;
inherit (import ./default.nix) fold;
inherit (import ./strings.nix) concatStringsSep;
inherit (import ./lists.nix) concatMap concatLists all deepSeqList;
inherit (import ./misc.nix) maybeAttr;
};
rec {
inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr;
/* Return an attribute from nested attribute sets. For instance
["x" "y"] applied to some set e returns e.x.y, if it exists. The
default value is returned otherwise. */
attrByPath = attrPath: default: e:
let attr = head attrPath;
in
if attrPath == [] then e
else if hasAttr attr e
then attrByPath (tail attrPath) default (getAttr attr e)
else default;
/* Return nested attribute set in which an attribute is set. For instance
["x" "y"] applied with some value v returns `x.y = v;' */
setAttrByPath = attrPath: value:
if attrPath == [] then value
else listToAttrs
[ { name = head attrPath; value = setAttrByPath (tail attrPath) value; } ];
getAttrFromPath = attrPath: set:
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
in attrByPath attrPath (abort errorMsg) set;
/* Return the specified attributes from a set.
Example:
attrVals ["a" "b" "c"] as
=> [as.a as.b as.c]
*/
attrVals = nameList: set:
map (x: getAttr x set) nameList;
/* Return the values of all attributes in the given set, sorted by
attribute name.
Example:
attrValues {c = 3; a = 1; b = 2;}
=> [1 2 3]
*/
attrValues = attrs: attrVals (attrNames attrs) attrs;
/* Collect each attribute named `attr' from a list of attribute
sets. Sets that don't contain the named attribute are ignored.
Example:
catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
=> [1 2]
*/
catAttrs = attr: l: concatLists (map (s: if hasAttr attr s then [(getAttr attr s)] else []) l);
/* Filter an attribute set by removing all attributes for which the
given predicate return false.
Example:
filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
=> { foo = 1; }
*/
filterAttrs = pred: set:
listToAttrs (fold (n: ys: let v = getAttr n set; in if pred n v then [(nameValuePair n v)] ++ ys else ys) [] (attrNames set));
/* foldAttrs: apply fold functions to values grouped by key. Eg accumulate values as list:
foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
=> { a = [ 2 3 ]; }
*/
foldAttrs = op: nul: list_of_attrs:
fold (n: a:
fold (name: o:
o // (listToAttrs [{inherit name; value = op (getAttr name n) (maybeAttr name nul a); }])
) a (attrNames n)
) {} list_of_attrs;
/* Recursively collect sets that verify a given predicate named `pred'
from the set `attrs'. The recursion is stopped when the predicate is
verified.
Type:
collect ::
(AttrSet -> Bool) -> AttrSet -> AttrSet
Example:
collect isList { a = { b = ["b"]; }; c = [1]; }
=> [["b"] [1]]
collect (x: x ? outPath)
{ a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
=> [{ outPath = "a/"; } { outPath = "b/"; }]
*/
collect = pred: attrs:
if pred attrs then
[ attrs ]
else if isAttrs attrs then
concatMap (collect pred) (attrValues attrs)
else
[];
/* Utility function that creates a {name, value} pair as expected by
builtins.listToAttrs. */
nameValuePair = name: value: { inherit name value; };
/* Apply a function to each element in an attribute set. The
function takes two arguments --- the attribute name and its value
--- and returns the new value for the attribute. The result is a
new attribute set.
Example:
mapAttrs (name: value: name + "-" + value)
{ x = "foo"; y = "bar"; }
=> { x = "x-foo"; y = "y-bar"; }
*/
mapAttrs = f: set:
listToAttrs (map (attr: { name = attr; value = f attr (getAttr attr set); }) (attrNames set));
/* Like `mapAttrs', but allows the name of each attribute to be
changed in addition to the value. The applied function should
return both the new name and value as a `nameValuePair'.
Example:
mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
{ x = "a"; y = "b"; }
=> { foo_x = "bar-a"; foo_y = "bar-b"; }
*/
mapAttrs' = f: set:
listToAttrs (map (attr: f attr (getAttr attr set)) (attrNames set));
/* Call a function for each attribute in the given set and return
the result in a list.
Example:
mapAttrsToList (name: value: name + value)
{ x = "a"; y = "b"; }
=> [ "xa" "yb" ]
*/
mapAttrsToList = f: attrs:
map (name: f name (getAttr name attrs)) (attrNames attrs);
/* Like `mapAttrs', except that it recursively applies itself to
attribute sets. Also, the first argument of the argument
function is a *list* of the names of the containing attributes.
Type:
mapAttrsRecursive ::
([String] -> a -> b) -> AttrSet -> AttrSet
Example:
mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value]))
{ n = { a = "A"; m = { b = "B"; c = "C"; }; }; d = "D"; }
=> { n = { a = "n-a-A"; m = { b = "n-m-b-B"; c = "n-m-c-C"; }; }; d = "d-D"; }
*/
mapAttrsRecursive = mapAttrsRecursiveCond (as: true);
/* Like `mapAttrsRecursive', but it takes an additional predicate
function that tells it whether to recursive into an attribute
set. If it returns false, `mapAttrsRecursiveCond' does not
recurse, but does apply the map function. It is returns true, it
does recurse, and does not apply the map function.
Type:
mapAttrsRecursiveCond ::
(AttrSet -> Bool) -> ([String] -> a -> b) -> AttrSet -> AttrSet
Example:
# To prevent recursing into derivations (which are attribute
# sets with the attribute "type" equal to "derivation"):
mapAttrsRecursiveCond
(as: !(as ? "type" && as.type == "derivation"))
(x: ... do something ...)
attrs
*/
mapAttrsRecursiveCond = cond: f: set:
let
recurse = path: set:
let
g =
name: value:
if isAttrs value && cond value
then recurse (path ++ [name]) value
else f (path ++ [name]) value;
in mapAttrs g set;
in recurse [] set;
/* Generate an attribute set by mapping a function over a list of
attribute names.
Example:
genAttrs [ "foo" "bar" ] (name: "x_" + name)
=> { foo = "x_foo"; bar = "x_bar"; }
*/
genAttrs = names: f:
listToAttrs (map (n: nameValuePair n (f n)) names);
/* Check whether the argument is a derivation. */
isDerivation = x: isAttrs x && x ? type && x.type == "derivation";
/* If the Boolean `cond' is true, return the attribute set `as',
otherwise an empty attribute set. */
optionalAttrs = cond: as: if cond then as else {};
/* Merge sets of attributes and use the function f to merge attributes
values. */
zipAttrsWithNames = names: f: sets:
listToAttrs (map (name: {
inherit name;
value = f name (catAttrs name sets);
}) names);
# implentation note: Common names appear multiple times in the list of
# names, hopefully this does not affect the system because the maximal
# laziness avoid computing twice the same expression and listToAttrs does
# not care about duplicated attribute names.
zipAttrsWith = f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets;
zipAttrs = zipAttrsWith (name: values: values);
/* backward compatibility */
zipWithNames = zipAttrsWithNames;
zip = builtins.trace "lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
/* Does the same as the update operator '//' except that attributes are
merged until the given pedicate is verified. The predicate should
accept 3 arguments which are the path to reach the attribute, a part of
the first attribute set and a part of the second attribute set. When
the predicate is verified, the value of the first attribute set is
replaced by the value of the second attribute set.
Example:
recursiveUpdateUntil (path: l: r: path == ["foo"]) {
# first attribute set
foo.bar = 1;
foo.baz = 2;
bar = 3;
} {
#second attribute set
foo.bar = 1;
foo.quz = 2;
baz = 4;
}
returns: {
foo.bar = 1; # 'foo.*' from the second set
foo.quz = 2; #
bar = 3; # 'bar' from the first set
baz = 4; # 'baz' from the second set
}
*/
recursiveUpdateUntil = pred: lhs: rhs:
let f = attrPath:
zipAttrsWith (n: values:
if tail values == []
|| pred attrPath (head (tail values)) (head values) then
head values
else
f (attrPath ++ [n]) values
);
in f [] [rhs lhs];
/* A recursive variant of the update operator //. The recusion
stops when one of the attribute values is not an attribute set,
in which case the right hand side value takes precedence over the
left hand side value.
Example:
recursiveUpdate {
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/hda";
} {
boot.loader.grub.device = "";
}
returns: {
boot.loader.grub.enable = true;
boot.loader.grub.device = "";
}
*/
recursiveUpdate = lhs: rhs:
recursiveUpdateUntil (path: lhs: rhs:
!(isAttrs lhs && isAttrs rhs)
) lhs rhs;
matchAttrs = pattern: attrs:
fold or false (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
let pat = head values; val = head (tail values); in
if length values == 1 then false
else if isAttrs pat then isAttrs val && matchAttrs head values
else pat == val
) [pattern attrs]));
# override only the attributes that are already present in the old set
# useful for deep-overriding
overrideExisting = old: new:
old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] (getAttr attr old) new)) (attrNames old));
deepSeqAttrs = x: y: deepSeqList (attrValues x) y;
}

View File

@@ -1,54 +0,0 @@
{lib, pkgs} :
let inherit (lib) nv nvs; in
{
# see for example:
# - development/interpreters/php_configurable/default.nix
# - .. search composableDerivation in all-packages.nix ..
#
# You should be able to override anything you like easily
# grep the mailinglist by title "python proposal" (dec 08)
# -> http://mail.cs.uu.nl/pipermail/nix-dev/2008-December/001571.html
# to see why this got complicated when using all its features
# TODO add newer example using new syntax (kernel derivation proposal -> mailinglist)
composableDerivation = {
mkDerivation ? pkgs.stdenv.mkDerivation,
# list of functions to be applied before defaultOverridableDelayableArgs removes removeAttrs names
# prepareDerivationArgs handles derivation configurations
applyPreTidy ? [ lib.prepareDerivationArgs ],
# consider adding addtional elements by derivation.merge { removeAttrs = ["elem"]; };
removeAttrs ? ["cfg" "flags"]
}: (lib.defaultOverridableDelayableArgs ( a: mkDerivation a)
{
inherit applyPreTidy removeAttrs;
}).merge;
# some utility functions
# use this function to generate flag attrs for prepareDerivationArgs
# E nable D isable F eature
edf = {name, feat ? name, enable ? {}, disable ? {} , value ? ""}:
nvs name {
set = {
configureFlags = ["--enable-${feat}${if value == "" then "" else "="}${value}"];
} // enable;
unset = {
configureFlags = ["--disable-${feat}"];
} // disable;
};
# same for --with and --without-
# W ith or W ithout F eature
wwf = {name, feat ? name, enable ? {}, disable ? {}, value ? ""}:
nvs name {
set = enable // {
configureFlags = ["--with-${feat}${if value == "" then "" else "="}${value}"]
++ lib.maybeAttr "configureFlags" [] enable;
};
unset = disable // {
configureFlags = ["--without-${feat}"]
++ lib.maybeAttr "configureFlags" [] disable;
};
};
}

View File

@@ -1,116 +0,0 @@
let lib = import ./default.nix;
inherit (builtins) getAttr attrNames isFunction;
in
rec {
/* `overrideDerivation drv f' takes a derivation (i.e., the result
of a call to the builtin function `derivation') and returns a new
derivation in which the attributes of the original are overriden
according to the function `f'. The function `f' is called with
the original derivation attributes.
`overrideDerivation' allows certain "ad-hoc" customisation
scenarios (e.g. in ~/.nixpkgs/config.nix). For instance, if you
want to "patch" the derivation returned by a package function in
Nixpkgs to build another version than what the function itself
provides, you can do something like this:
mySed = overrideDerivation pkgs.gnused (oldAttrs: {
name = "sed-4.2.2-pre";
src = fetchurl {
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
};
patches = [];
});
For another application, see build-support/vm, where this
function is used to build arbitrary derivations inside a QEMU
virtual machine. */
overrideDerivation = drv: f:
let
newDrv = derivation (drv.drvAttrs // (f drv));
in addPassthru newDrv (
{ meta = drv.meta or {};
passthru = if drv ? passthru then drv.passthru else {};
}
//
(drv.passthru or {})
//
(if (drv ? crossDrv && drv ? nativeDrv)
then {
crossDrv = overrideDerivation drv.crossDrv f;
nativeDrv = overrideDerivation drv.nativeDrv f;
}
else { }));
# usage: (you can use override multiple times)
# let d = makeOverridable stdenv.mkDerivation { name = ..; buildInputs; }
# noBuildInputs = d.override { buildInputs = []; }
# additionalBuildInputs = d.override ( args : args // { buildInputs = args.buildInputs ++ [ additional ]; } )
makeOverridable = f: origArgs:
let
ff = f origArgs;
in
if builtins.isAttrs ff then (ff //
{ override = newArgs:
makeOverridable f (origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs));
deepOverride = newArgs:
makeOverridable f (lib.overrideExisting (lib.mapAttrs (deepOverrider newArgs) origArgs) newArgs);
})
else ff;
deepOverrider = newArgs: name: x: if builtins.isAttrs x then (
if x ? deepOverride then (x.deepOverride newArgs) else
if x ? override then (x.override newArgs) else
x) else x;
/* Call the package function in the file `fn' with the required
arguments automatically. The function is called with the
arguments `args', but any missing arguments are obtained from
`autoArgs'. This function is intended to be partially
parameterised, e.g.,
callPackage = callPackageWith pkgs;
pkgs = {
libfoo = callPackage ./foo.nix { };
libbar = callPackage ./bar.nix { };
};
If the `libbar' function expects an argument named `libfoo', it is
automatically passed as an argument. Overrides or missing
arguments can be supplied in `args', e.g.
libbar = callPackage ./bar.nix {
libfoo = null;
enableX11 = true;
};
*/
callPackageWith = autoArgs: fn: args:
let f = if builtins.isFunction fn then fn else import fn; in
makeOverridable f ((builtins.intersectAttrs (builtins.functionArgs f) autoArgs) // args);
/* Add attributes to each output of a derivation without changing the derivation itself */
addPassthru = drv: passthru:
let
outputs = drv.outputs or [ "out" ];
commonAttrs = drv // (builtins.listToAttrs outputsList) //
({ all = map (x: x.value) outputsList; }) // passthru;
outputToAttrListElement = outputName:
{ name = outputName;
value = commonAttrs // {
inherit (builtins.getAttr outputName drv) outPath drvPath type outputName;
};
};
outputsList = map outputToAttrListElement outputs;
in builtins.getAttr drv.outputName commonAttrs;
}

View File

@@ -1,119 +0,0 @@
let lib = import ./default.nix;
inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt
isString isBool head substring attrNames;
inherit (lib) all id mapAttrsFlatten elem;
in
rec {
# Wrapper aroung the primop `addErrorContext', which shouldn't used
# directly. It evaluates and returns `val', but if an evaluation
# error occurs, the text in `msg' is added to the error context
# (stack trace) printed by Nix.
addErrorContext =
if builtins ? addErrorContext
then builtins.addErrorContext
else msg: val: val;
addErrorContextToAttrs = lib.mapAttrs (a : v : lib.addErrorContext "while evaluating ${a}" v);
traceVal = if builtins ? trace then x: (builtins.trace x x) else x: x;
traceXMLVal = if builtins ? trace then x: (builtins.trace (builtins.toXML x) x) else x: x;
traceXMLValMarked = str: if builtins ? trace then x: (builtins.trace ( str + builtins.toXML x) x) else x: x;
# this can help debug your code as well - designed to not produce thousands of lines
traceShowVal = x : trace (showVal x) x;
traceShowValMarked = str: x: trace (str + showVal x) x;
attrNamesToStr = a : lib.concatStringsSep "; " (map (x : "${x}=") (attrNames a));
showVal = x :
if isAttrs x then
if x ? outPath then "x is a derivation, name ${if x ? name then x.name else "<no name>"}, { ${attrNamesToStr x} }"
else "x is attr set { ${attrNamesToStr x} }"
else if isFunction x then "x is a function"
else if x == [] then "x is an empty list"
else if isList x then "x is a list, first element is: ${showVal (head x)}"
else if x == true then "x is boolean true"
else if x == false then "x is boolean false"
else if x == null then "x is null"
else if isInt x then "x is an integer `${toString x}'"
else if isString x then "x is a string `${substring 0 50 x}...'"
else "x is probably a path `${substring 0 50 (toString x)}...'";
# trace the arguments passed to function and its result
# maybe rewrite these functions in a traceCallXml like style. Then one function is enough
traceCall = n : f : a : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a));
traceCall2 = n : f : a : b : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b));
traceCall3 = n : f : a : b : c : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b) (t "arg 3" c));
traceValIfNot = c: x:
if c x then true else trace (showVal x) false;
/* Evaluate a set of tests. A test is an attribute set {expr,
expected}, denoting an expression and its expected result. The
result is a list of failed tests, each represented as {name,
expected, actual}, denoting the attribute name of the failing
test and its expected and actual results. Used for regression
testing of the functions in lib; see tests.nix for an example.
Only tests having names starting with "test" are run.
Add attr { tests = ["testName"]; } to run these test only
*/
runTests = tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test:
let testsToRun = if tests ? tests then tests.tests else [];
in if (substring 0 4 name == "test" || elem name testsToRun)
&& ((testsToRun == []) || elem name tests.tests)
&& (test.expr != test.expected)
then [ { inherit name; expected = test.expected; result = test.expr; } ]
else [] ) tests));
# create a test assuming that list elements are true
# usage: { testX = allTrue [ true ]; }
testAllTrue = expr : { inherit expr; expected = map (x: true) expr; };
# evaluate everything once so that errors will occur earlier
# hacky: traverse attrs by adding a dummy
# ignores functions (should this behavior change?) See strictf
#
# Note: This should be a primop! Something like seq of haskell would be nice to
# have as well. It's used fore debugging only anyway
strict = x :
let
traverse = x :
if isString x then true
else if isAttrs x then
if x ? outPath then true
else all id (mapAttrsFlatten (n: traverse) x)
else if isList x then
all id (map traverse x)
else if isBool x then true
else if isFunction x then true
else if isInt x then true
else if x == null then true
else true; # a (store) path?
in if traverse x then x else throw "else never reached";
# example: (traceCallXml "myfun" id 3) will output something like
# calling myfun arg 1: 3 result: 3
# this forces deep evaluation of all arguments and the result!
# note: if result doesn't evaluate you'll get no trace at all (FIXME)
# args should be printed in any case
traceCallXml = a:
if !isInt a then
traceCallXml 1 "calling ${a}\n"
else
let nr = a;
in (str: expr:
if isFunction expr then
(arg:
traceCallXml (builtins.add 1 nr) "${str}\n arg ${builtins.toString nr} is \n ${builtins.toXML (strict arg)}" (expr arg)
)
else
let r = strict expr;
in builtins.trace "${str}\n result:\n${builtins.toXML r}" r
);
}

View File

@@ -1,30 +0,0 @@
let
trivial = import ./trivial.nix;
lists = import ./lists.nix;
strings = import ./strings.nix;
stringsWithDeps = import ./strings-with-deps.nix;
attrsets = import ./attrsets.nix;
sources = import ./sources.nix;
modules = import ./modules.nix;
options = import ./options.nix;
types = import ./types.nix;
meta = import ./meta.nix;
debug = import ./debug.nix;
misc = import ./misc.nix;
maintainers = import ./maintainers.nix;
platforms = import ./platforms.nix;
systems = import ./systems.nix;
customisation = import ./customisation.nix;
licenses = import ./licenses.nix;
in
{ inherit trivial lists strings stringsWithDeps attrsets sources options
modules types meta debug maintainers licenses platforms systems;
}
# !!! don't include everything at top-level; perhaps only the most
# commonly used functions.
// trivial // lists // strings // stringsWithDeps // attrsets // sources
// options // types // meta // debug // misc // modules
// systems
// customisation

View File

@@ -1,263 +0,0 @@
{
/* License identifiers loosely based on: http://fedoraproject.org/wiki/Licensing
* If you cannot find your license here, then look for a similar license or
* add it to this list. The URL mentioned above is a good source for inspiration.
*/
artistic2 = {
shortName = "Artistic 2.0";
fullName = "Artistic 2.0";
url = "http://opensource.org/licenses/artistic-license-2.0.php";
};
agpl3 = {
shortName = "AGPLv3";
fullName = "GNU Affero General Public License version 3 only";
url = https://www.gnu.org/licenses/agpl.html;
};
agpl3Plus = {
shortName = "AGPLv3+";
fullName = "GNU Affero General Public License version 3 or later";
url = https://www.gnu.org/licenses/agpl.html;
};
amd = {
shortName = "amd";
fullName = "AMD License Agreement";
url = http://developer.amd.com/amd-license-agreement/;
};#
apsl20 = {
shortName = "APSL 2.0";
fullName = "Apple Public Source License 2.0";
url = http://opensource.org/licenses/APSL-2.0;
};
asl20 = {
shortName = "ASL2.0";
fullName = "Apache Software License 2.0";
url = http://www.apache.org/licenses/LICENSE-2.0;
};
boost = {
shortName = "boost";
fullName = "Boost Software License";
url = http://www.boost.org/LICENSE_1_0.txt;
};
bsd2 = {
shortName = "BSD-2";
fullName = "BSD license (2 clause)";
url = http://opensource.org/licenses/BSD-2-Clause;
};
bsd3 = {
shortName = "BSD-3";
fullName = "BSD license (3 clause)";
url = http://opensource.org/licenses/BSD-3-Clause;
};
bsdOriginal = {
shortName = "BSD-original";
fullName = "Original BSD license with advertising clause";
url = https://fedoraproject.org/wiki/Licensing/BSD;
};
cc-by-30 = {
shortName = "CC BY 3.0";
fullName = "Creative Commons Attribution 3.0";
url = http://creativecommons.org/licenses/by/3.0;
};
cddl = {
shortName = "CDDL";
fullName = "Common Development Distribution License ";
url = http://www.opensolaris.org/os/licensing/cddllicense.txt;
};
cpl10 = {
shortName = "CPL 1.0";
fullName = "Common Public License version 1.0";
url = http://www.eclipse.org/legal/cpl-v10.html;
};
epl10 = {
shortName = "EPL 1.0";
fullName = "Eclipse Public License version 1.0";
url = http://www.eclipse.org/legal/epl-v10.html;
};
gpl2 = {
shortName = "GPLv2";
fullName = "GNU General Public License version 2";
url = http://www.gnu.org/licenses/old-licenses/gpl-2.0.html;
};
gpl2Oss = {
shortName = "GPLv2+OSS";
fullName = "GNU General Public License version 2 only (with OSI approved licenses linking exception)";
url = http://www.mysql.com/about/legal/licensing/foss-exception;
};
gpl2Plus = {
shortName = "GPLv2+";
fullName = "GNU General Public License version 2 or later";
url = http://www.gnu.org/licenses/old-licenses/gpl-2.0.html;
};
gpl3 = {
shortName = "GPLv3";
fullName = "GNU General Public License version 3 only";
url = http://www.fsf.org/licensing/licenses/gpl.html;
};
gpl3Plus = {
shortName = "GPLv3+";
fullName = "GNU General Public License version 3 or later";
url = http://www.fsf.org/licensing/licenses/gpl.html;
};
gpl3ClasspathPlus = {
shortName = "GPLv3+classpath+";
fullName = "GNU General Public License version 3 or later (with Classpath exception)";
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
};
isc = {
shortName = "ISC";
fullName = "Internet Systems Consortium License";
url = http://www.opensource.org/licenses/ISC;
};
ipl10 = {
shortName = "IPL 1.0";
fullName = "IBM Public License Version 1.0";
url = http://www.ibm.com/developerworks/opensource/library/os-i18n2/os-ipl.html;
};
ijg = {
shortName = "IJG";
fullName = "Independent JPEG Group License";
url = https://fedoraproject.org/wiki/Licensing/IJG;
};
libtiff = {
shortName = "libtiff";
fullName = "libtiff license";
url = https://fedoraproject.org/wiki/Licensing/libtiff;
};
lgpl2 = {
shortName = "LGPLv2";
fullName = "GNU Library General Public License version 2";
url = http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html;
};
lgpl2Plus = {
shortName = "LGPLv2+";
fullName = "GNU Library General Public License version 2 or later";
url = http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html;
};
lgpl21 = {
shortName = "LGPLv2.1";
fullName = "GNU Lesser General Public License version 2.1";
url = http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html;
};
lgpl21Plus = {
shortName = "LGPLv2.1+";
fullName = "GNU Lesser General Public License version 2.1 or later";
url = http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html;
};
llgpl21 = {
shortName = "LLGPLv2.1";
fullName = "Lisp LGPL; GNU Lesser General Public License version 2.1 with Franz Inc. preamble for clarification of LGPL terms in context of Lisp";
url = http://opensource.franz.com/preamble.html;
};
lgpl3 = {
shortName = "LGPLv3";
fullName = "GNU Lesser General Public License version 3 only";
url = http://www.fsf.org/licensing/licenses/lgpl.html;
};
lgpl3Plus = {
shortName = "LGPLv3+";
fullName = "GNU Lesser General Public License version 3 or later";
url = http://www.fsf.org/licensing/licenses/lgpl.html;
};
mit = {
shortName = "MIT";
fullName = "MIT/X11 license";
url = http://www.opensource.org/licenses/mit-license.php;
};
mpl11 = {
shortName = "MPL1.1";
fullName = "Mozilla Public License version 1.1";
url = http://www.mozilla.org/MPL/MPL-1.1.html;
};
mpl20 = {
shortName = "MPL2.0";
fullName = "Mozilla Public License version 2.0";
url = https://www.mozilla.org/MPL/2.0;
};
openssl = {
shortName = "openssl";
fullName = "OpenSSL license";
url = http://www.openssl.org/source/license.html;
};
publicDomain = {
shortName = "Public Domain";
fullname = "Public Domain";
};
psfl = {
shortName = "PSFL";
fullName = "Python Software Foundation License";
url = http://docs.python.org/license.html;
};
tcltk = {
shortName = "Tcl/Tk";
fullName = "Tcl/Tk license";
url = http://www.tcl.tk/software/tcltk/license.html;
};
unfree = "unfree";
unfreeRedistributable = "unfree-redistributable";
unfreeRedistributableFirmware = "unfree-redistributable-firmware";
zlib = {
shortName = "zlib";
fullName = "zlib license";
url = http://www.gzip.org/zlib/zlib_license.html;
};
zpt20 = {
shortName = "ZPT2.0";
fullName = "Zope Public License 2.0";
url = "http://old.zope.org/Resources/License/ZPL-2.0";
};
zpt21 = {
shortName = "ZPT2.1";
fullName = "Zope Public License 2.1";
url = "http://old.zope.org/Resources/License/ZPL-2.1";
};
sleepycat = {
shortName = "Sleepycat";
fullName = "Sleepycat Public License";
url = "https://en.wikipedia.org/wiki/Sleepycat_License";
};
}

View File

@@ -1,230 +0,0 @@
# General list operations.
with import ./trivial.nix;
let
inc = builtins.add 1;
dec = n: builtins.sub n 1;
in rec {
inherit (builtins) head tail length isList elemAt concatLists filter elem;
# Create a list consisting of a single element. `singleton x' is
# sometimes more convenient with respect to indentation than `[x]'
# when x spans multiple lines.
singleton = x: [x];
# "Fold" a binary function `op' between successive elements of
# `list' with `nul' as the starting value, i.e., `fold op nul [x_1
# x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'. (This is
# Haskell's foldr).
fold = op: nul: list:
let
len = length list;
fold' = n:
if n == len
then nul
else op (elemAt list n) (fold' (inc n));
in fold' 0;
# Left fold: `fold op nul [x_1 x_2 ... x_n] == op (... (op (op nul
# x_1) x_2) ... x_n)'.
foldl = op: nul: list:
let
len = length list;
foldl' = n:
if n == minus1
then nul
else op (foldl' (dec n)) (elemAt list n);
in foldl' (dec (length list));
minus1 = dec 0;
# map with index: `imap (i: v: "${v}-${toString i}") ["a" "b"] ==
# ["a-1" "b-2"]'
imap = f: list:
let
len = length list;
imap' = n:
if n == len
then []
else [ (f (inc n) (elemAt list n)) ] ++ imap' (inc n);
in imap' 0;
# Map and concatenate the result.
concatMap = f: list: concatLists (map f list);
# Flatten the argument into a single list; that is, nested lists are
# spliced into the top-level lists. E.g., `flatten [1 [2 [3] 4] 5]
# == [1 2 3 4 5]' and `flatten 1 == [1]'.
flatten = x:
if isList x
then fold (x: y: (flatten x) ++ y) [] x
else [x];
# Remove elements equal to 'e' from a list. Useful for buildInputs.
remove = e: filter (x: x != e);
# Find the sole element in the list matching the specified
# predicate, returns `default' if no such element exists, or
# `multiple' if there are multiple matching elements.
findSingle = pred: default: multiple: list:
let found = filter pred list; len = length found;
in if len == 0 then default
else if len != 1 then multiple
else head found;
# Find the first element in the list matching the specified
# predicate or returns `default' if no such element exists.
findFirst = pred: default: list:
let found = filter pred list;
in if found == [] then default else head found;
# Return true iff function `pred' returns true for at least element
# of `list'.
any = pred: fold (x: y: if pred x then true else y) false;
# Return true iff function `pred' returns true for all elements of
# `list'.
all = pred: fold (x: y: if pred x then y else false) true;
# Count how many times function `pred' returns true for the elements
# of `list'.
count = pred: fold (x: c: if pred x then inc c else c) 0;
# Return a singleton list or an empty list, depending on a boolean
# value. Useful when building lists with optional elements
# (e.g. `++ optional (system == "i686-linux") flashplayer').
optional = cond: elem: if cond then [elem] else [];
# Return a list or an empty list, dependening on a boolean value.
optionals = cond: elems: if cond then elems else [];
# If argument is a list, return it; else, wrap it in a singleton
# list. If you're using this, you should almost certainly
# reconsider if there isn't a more "well-typed" approach.
toList = x: if isList x then x else [x];
# Return a list of integers from `first' up to and including `last'.
range = first: last:
if lessThan last first
then []
else [first] ++ range (add first 1) last;
# Partition the elements of a list in two lists, `right' and
# `wrong', depending on the evaluation of a predicate.
partition = pred:
fold (h: t:
if pred h
then { right = [h] ++ t.right; wrong = t.wrong; }
else { right = t.right; wrong = [h] ++ t.wrong; }
) { right = []; wrong = []; };
zipListsWith = f: fst: snd:
let
len1 = length fst;
len2 = length snd;
len = if lessThan len1 len2 then len1 else len2;
zipListsWith' = n:
if n != len then
[ (f (elemAt fst n) (elemAt snd n)) ]
++ zipListsWith' (inc n)
else [];
in zipListsWith' 0;
zipLists = zipListsWith (fst: snd: { inherit fst snd; });
# Reverse the order of the elements of a list. FIXME: O(n^2)!
reverseList = fold (e: acc: acc ++ [ e ]) [];
# Sort a list based on a comparator function which compares two
# elements and returns true if the first argument is strictly below
# the second argument. The returned list is sorted in an increasing
# order. The implementation does a quick-sort.
sort = strictLess: list:
let
len = length list;
first = head list;
pivot' = n: acc@{ left, right }: let el = elemAt list n; next = pivot' (inc n); in
if n == len
then acc
else if strictLess first el
then next { inherit left; right = [ el ] ++ right; }
else
next { left = [ el ] ++ left; inherit right; };
pivot = pivot' 1 { left = []; right = []; };
in
if lessThan len 2 then list
else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right);
# Return the first (at most) N elements of a list.
take = count: list:
let
len = length list;
take' = n:
if n == len || n == count
then []
else
[ (elemAt list n) ] ++ take' (inc n);
in take' 0;
# Remove the first (at most) N elements of a list.
drop = count: list:
let
len = length list;
drop' = n:
if n == minus1 || lessThan n count
then []
else
drop' (dec n) ++ [ (elemAt list n) ];
in drop' (dec len);
# Return the last element of a list.
last = list:
assert list != []; elemAt list (dec (length list));
# Zip two lists together.
zipTwoLists = xs: ys:
let
len1 = length xs;
len2 = length ys;
len = if lessThan len1 len2 then len1 else len2;
zipTwoLists' = n:
if n != len then
[ { first = elemAt xs n; second = elemAt ys n; } ]
++ zipTwoLists' (inc n)
else [];
in zipTwoLists' 0;
deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y;
crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f];
}

View File

@@ -1,101 +0,0 @@
/* -*- coding: utf-8; -*- */
{
/* Add your name and email address here. Keep the list
alphabetically sorted. */
_1126 = "Christian Lask <mail@elfsechsundzwanzig.de>";
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
akc = "Anders Claesson <akc@akc.is>";
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
all = "Nix Committers <nix-commits@lists.science.uu.nl>";
amiddelk = "Arie Middelkoop <amiddelk@gmail.com>";
amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>";
AndersonTorres = "Anderson Torres <torres.anderson.85@gmail.com>";
andres = "Andres Loeh <ksnixos@andres-loeh.de>";
antono = "Antono Vasiljev <self@antono.info>";
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
aszlig = "aszlig <aszlig@redmoonstudios.org>";
bbenoist = "Baptist BENOIST <return_0@live.com>";
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
berdario = "Dario Bertini <berdario@gmail.com>";
bjg = "Brian Gough <bjg@gnu.org>";
bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>";
bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>";
bodil = "Bodil Stokke <nix@bodil.org>";
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
coroa = "Jonas Hörsch <jonas@chaoflow.net>";
cstrahan = "Charles Strahan <charles.c.strahan@gmail.com>";
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
eelco = "Eelco Dolstra <eelco.dolstra@logicblox.com>";
emery = "Emery Hemingawy <emery@vfemail.net>";
ertes = "Ertugrul Söylemez <ertesx@gmx.de>";
falsifian = "James Cook <james.cook@utoronto.ca>";
fuuzetsu = "Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>";
garbas = "Rok Garbas <rok@garbas.si>";
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
guibert = "David Guibert <david.guibert@gmail.com>";
hinton = "Tom Hinton <t@larkery.com>";
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
iElectric = "Domen Kozar <domen@dev.si>";
iyzsong = "Song Wenwu <iyzsong@gmail.com>";
jcumming = "Jack Cummings <jack@mudshark.org>";
jwiegley = "John Wiegley <johnw@newartisans.com>";
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
lethalman = "Luca Bruno <lucabru@src.gnome.org>";
linquize = "Linquize <linquize@yahoo.com.hk>";
lovek323 = "Jason O'Conal <jason@oconal.id.au>";
ludo = "Ludovic Courtès <ludo@gnu.org>";
madjar = "Georges Dubus <georges.dubus@compiletoi.net>";
marcweber = "Marc Weber <marco-oweber@gmx.de>";
matejc = "Matej Cotman <cotman.matej@gmail.com>";
modulistic = "Pablo Costa <modulistic@gmail.com>";
mornfall = "Petr Ročkai <me@mornfall.net>";
msackman = "Matthew Sackman <matthew@wellquite.org>";
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
page = "Carles Pagès <page@cubata.homelinux.net>";
phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>";
pierron = "Nicolas B. Pierron <nixos@nbp.name>";
piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>";
pkmx = "Chih-Mao Chen <pkmx.tw@gmail.com>";
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
qknight = "Joachim Schiele <js@lastlog.de>";
raskin = "Michael Raskin <7c6f434c@mail.ru>";
redbaron = "Maxim Ivanov <ivanov.maxim@gmail.com>";
relrod = "Ricky Elrod <ricky@elrod.me>";
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
roelof = "Roelof Wobben <rwobben@hotmail.com>";
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
rszibele = "Richard Szibele <richard_szibele@hotmail.com>";
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
shlevy = "Shea Levy <shea@shealevy.com>";
simons = "Peter Simons <simons@cryp.to>";
smironov = "Sergey Mironov <ierton@gmail.com>";
sprock = "Roger Mason <rmason@mun.ca>";
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
thoughtpolice = "Austin Seipp <aseipp@pobox.com>";
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
ttuegel = "Thomas Tuegel <ttuegel@gmail.com>";
urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>";
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
viric = "Lluís Batlle i Rossell <viric@viric.name>";
vizanto = "Danny Wilson <danny@prime.vc>";
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
wizeman = "Ricardo M. Correia <rcorreia@wizy.org>";
wmertens = "Wout Mertens <Wout.Mertens@gmail.com>";
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
zef = "Zef Hemel <zef@zef.me>";
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
}

View File

@@ -1,66 +0,0 @@
/* Some functions for manipulating meta attributes, as well as the
name attribute. */
let lib = import ./default.nix;
in
rec {
/* Add to or override the meta attributes of the given
derivation.
Example:
addMetaAttrs {description = "Bla blah";} somePkg
*/
addMetaAttrs = newAttrs: drv:
drv // { meta = (drv.meta or {}) // newAttrs; };
/* Change the symbolic name of a package for presentation purposes
(i.e., so that nix-env users can tell them apart).
*/
setName = name: drv: drv // {inherit name;};
/* Like `setName', but takes the previous name as an argument.
Example:
updateName (oldName: oldName + "-experimental") somePkg
*/
updateName = updater: drv: drv // {name = updater (drv.name);};
/* Append a suffix to the name of a package (before the version
part). */
appendToName = suffix: updateName (name:
let x = builtins.parseDrvName name; in "${x.name}-${suffix}-${x.version}");
/* Apply a function to each derivation and only to derivations in an attrset
*/
mapDerivationAttrset = f: set: lib.mapAttrs (name: pkg: if lib.isDerivation pkg then (f pkg) else pkg) set;
/* Decrease the nix-env priority of the package, i.e., other
versions/variants of the package will be preferred.
*/
lowPrio = drv: addMetaAttrs { priority = "10"; } drv;
/* Apply lowPrio to an attrset with derivations
*/
lowPrioSet = set: mapDerivationAttrset lowPrio set;
/* Increase the nix-env priority of the package, i.e., this
version/variant of the package will be preferred.
*/
hiPrio = drv: addMetaAttrs { priority = "-10"; } drv;
/* Apply hiPrio to an attrset with derivations
*/
hiPrioSet = set: mapDerivationAttrset hiPrio set;
}

View File

@@ -1,429 +0,0 @@
let lib = import ./default.nix;
inherit (builtins) isFunction hasAttr getAttr head tail isList isAttrs isInt attrNames;
in
with import ./lists.nix;
with import ./attrsets.nix;
with import ./strings.nix;
rec {
# returns default if env var is not set
maybeEnv = name: default:
let value = builtins.getEnv name; in
if value == "" then default else value;
defaultMergeArg = x : y: if builtins.isAttrs y then
y
else
(y x);
defaultMerge = x: y: x // (defaultMergeArg x y);
foldArgs = merger: f: init: x:
let arg=(merger init (defaultMergeArg init x));
# now add the function with composed args already applied to the final attrs
base = (setAttrMerge "passthru" {} (f arg)
( z : z // rec {
function = foldArgs merger f arg;
args = (lib.attrByPath ["passthru" "args"] {} z) // x;
} ));
withStdOverrides = base // {
override = base.passthru.function;
deepOverride = a : (base.passthru.function ((lib.mapAttrs (lib.deepOverrider a) base.passthru.args) // a));
} ;
in
withStdOverrides;
# predecessors: proposed replacement for applyAndFun (which has a bug cause it merges twice)
# the naming "overridableDelayableArgs" tries to express that you can
# - override attr values which have been supplied earlier
# - use attr values before they have been supplied by accessing the fix point
# name "fixed"
# f: the (delayed overridden) arguments are applied to this
#
# initial: initial attrs arguments and settings. see defaultOverridableDelayableArgs
#
# returns: f applied to the arguments // special attributes attrs
# a) merge: merge applied args with new args. Wether an argument is overridden depends on the merge settings
# b) replace: this let's you replace and remove names no matter which merge function has been set
#
# examples: see test cases "res" below;
overridableDelayableArgs =
f : # the function applied to the arguments
initial : # you pass attrs, the functions below are passing a function taking the fix argument
let
takeFixed = if isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument
tidy = args :
let # apply all functions given in "applyPreTidy" in sequence
applyPreTidyFun = fold ( n : a : x : n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
in removeAttrs (applyPreTidyFun args) ( ["applyPreTidy"] ++ (maybeAttr "removeAttrs" [] args) ); # tidy up args before applying them
fun = n : x :
let newArgs = fixed :
let args = takeFixed fixed;
mergeFun = getAttr n args;
in if isAttrs x then (mergeFun args x)
else assert isFunction x;
mergeFun args (x ( args // { inherit fixed; }));
in overridableDelayableArgs f newArgs;
in
(f (tidy (lib.fix takeFixed))) // {
merge = fun "mergeFun";
replace = fun "keepFun";
};
defaultOverridableDelayableArgs = f :
let defaults = {
mergeFun = mergeAttrByFunc; # default merge function. merge strategie (concatenate lists, strings) is given by mergeAttrBy
keepFun = a : b : { inherit (a) removeAttrs mergeFun keepFun mergeAttrBy; } // b; # even when using replace preserve these values
applyPreTidy = []; # list of functions applied to args before args are tidied up (usage case : prepareDerivationArgs)
mergeAttrBy = mergeAttrBy // {
applyPreTidy = a : b : a ++ b;
removeAttrs = a : b: a ++ b;
};
removeAttrs = ["mergeFun" "keepFun" "mergeAttrBy" "removeAttrs" "fixed" ]; # before applying the arguments to the function make sure these names are gone
};
in (overridableDelayableArgs f defaults).merge;
# rec { # an example of how composedArgsAndFun can be used
# a = composedArgsAndFun (x : x) { a = ["2"]; meta = { d = "bar";}; };
# # meta.d will be lost ! It's your task to preserve it (eg using a merge function)
# b = a.passthru.function { a = [ "3" ]; meta = { d2 = "bar2";}; };
# # instead of passing/ overriding values you can use a merge function:
# c = b.passthru.function ( x: { a = x.a ++ ["4"]; }); # consider using (maybeAttr "a" [] x)
# }
# result:
# {
# a = { a = ["2"]; meta = { d = "bar"; }; passthru = { function = .. }; };
# b = { a = ["3"]; meta = { d2 = "bar2"; }; passthru = { function = .. }; };
# c = { a = ["3" "4"]; meta = { d2 = "bar2"; }; passthru = { function = .. }; };
# # c2 is equal to c
# }
composedArgsAndFun = f: foldArgs defaultMerge f {};
# shortcut for attrByPath ["name"] default attrs
maybeAttrNullable = name: default: attrs:
if attrs == null then default else
if __hasAttr name attrs then (__getAttr name attrs) else default;
# shortcut for attrByPath ["name"] default attrs
maybeAttr = name: default: attrs:
if __hasAttr name attrs then (__getAttr name attrs) else default;
# Return the second argument if the first one is true or the empty version
# of the second argument.
ifEnable = cond: val:
if cond then val
else if builtins.isList val then []
else if builtins.isAttrs val then {}
# else if builtins.isString val then ""
else if val == true || val == false then false
else null;
# Return true only if there is an attribute and it is true.
checkFlag = attrSet: name:
if name == "true" then true else
if name == "false" then false else
if (elem name (attrByPath ["flags"] [] attrSet)) then true else
attrByPath [name] false attrSet ;
# Input : attrSet, [ [name default] ... ], name
# Output : its value or default.
getValue = attrSet: argList: name:
( attrByPath [name] (if checkFlag attrSet name then true else
if argList == [] then null else
let x = builtins.head argList; in
if (head x) == name then
(head (tail x))
else (getValue attrSet
(tail argList) name)) attrSet );
# Input : attrSet, [[name default] ...], [ [flagname reqs..] ... ]
# Output : are reqs satisfied? It's asserted.
checkReqs = attrSet : argList : condList :
(
fold lib.and true
(map (x: let name = (head x) ; in
((checkFlag attrSet name) ->
(fold lib.and true
(map (y: let val=(getValue attrSet argList y); in
(val!=null) && (val!=false))
(tail x))))) condList)) ;
# This function has O(n^2) performance.
uniqList = {inputList, acc ? []} :
let go = xs : acc :
if xs == []
then []
else let x = head xs;
y = if elem x acc then [] else [x];
in y ++ go (tail xs) (y ++ acc);
in go inputList acc;
uniqListExt = {inputList, outputList ? [],
getter ? (x : x), compare ? (x: y: x==y)}:
if inputList == [] then outputList else
let x=head inputList;
isX = y: (compare (getter y) (getter x));
newOutputList = outputList ++
(if any isX outputList then [] else [x]);
in uniqListExt {outputList=newOutputList;
inputList = (tail inputList);
inherit getter compare;
};
condConcat = name: list: checker:
if list == [] then name else
if checker (head list) then
condConcat
(name + (head (tail list)))
(tail (tail list))
checker
else condConcat
name (tail (tail list)) checker;
lazyGenericClosure = {startSet, operator}:
let
work = list: doneKeys: result:
if list == [] then
result
else
let x = head list; key = x.key; in
if elem key doneKeys then
work (tail list) doneKeys result
else
work (tail list ++ operator x) ([key] ++ doneKeys) ([x] ++ result);
in
work startSet [] [];
genericClosure = builtins.genericClosure or lazyGenericClosure;
innerModifySumArgs = f: x: a: b: if b == null then (f a b) // x else
innerModifySumArgs f x (a // b);
modifySumArgs = f: x: innerModifySumArgs f x {};
innerClosePropagation = acc : xs :
if xs == []
then acc
else let y = head xs;
ys = tail xs;
in if ! isAttrs y
then innerClosePropagation acc ys
else let acc' = [y] ++ acc;
in innerClosePropagation
acc'
(uniqList { inputList = (maybeAttrNullable "propagatedBuildInputs" [] y)
++ (maybeAttrNullable "propagatedNativeBuildInputs" [] y)
++ ys;
acc = acc';
}
);
closePropagation = list: (uniqList {inputList = (innerClosePropagation [] list);});
# calls a function (f attr value ) for each record item. returns a list
mapAttrsFlatten = f : r : map (attr: f attr (builtins.getAttr attr r) ) (attrNames r);
# attribute set containing one attribute
nvs = name : value : listToAttrs [ (nameValuePair name value) ];
# adds / replaces an attribute of an attribute set
setAttr = set : name : v : set // (nvs name v);
# setAttrMerge (similar to mergeAttrsWithFunc but only merges the values of a particular name)
# setAttrMerge "a" [] { a = [2];} (x : x ++ [3]) -> { a = [2 3]; }
# setAttrMerge "a" [] { } (x : x ++ [3]) -> { a = [ 3]; }
setAttrMerge = name : default : attrs : f :
setAttr attrs name (f (maybeAttr name default attrs));
# Using f = a : b = b the result is similar to //
# merge attributes with custom function handling the case that the attribute
# exists in both sets
mergeAttrsWithFunc = f : set1 : set2 :
fold (n: set : if (__hasAttr n set)
then setAttr set n (f (__getAttr n set) (__getAttr n set2))
else set )
(set2 // set1) (__attrNames set2);
# merging two attribute set concatenating the values of same attribute names
# eg { a = 7; } { a = [ 2 3 ]; } becomes { a = [ 7 2 3 ]; }
mergeAttrsConcatenateValues = mergeAttrsWithFunc ( a : b : (toList a) ++ (toList b) );
# merges attributes using //, if a name exisits in both attributes
# an error will be triggered unless its listed in mergeLists
# so you can mergeAttrsNoOverride { buildInputs = [a]; } { buildInputs = [a]; } {} to get
# { buildInputs = [a b]; }
# merging buildPhase does'nt really make sense. The cases will be rare where appending /prefixing will fit your needs?
# in these cases the first buildPhase will override the second one
# ! deprecated, use mergeAttrByFunc instead
mergeAttrsNoOverride = { mergeLists ? ["buildInputs" "propagatedBuildInputs"],
overrideSnd ? [ "buildPhase" ]
} : attrs1 : attrs2 :
fold (n: set :
setAttr set n ( if (__hasAttr n set)
then # merge
if elem n mergeLists # attribute contains list, merge them by concatenating
then (__getAttr n attrs2) ++ (__getAttr n attrs1)
else if elem n overrideSnd
then __getAttr n attrs1
else throw "error mergeAttrsNoOverride, attribute ${n} given in both attributes - no merge func defined"
else __getAttr n attrs2 # add attribute not existing in attr1
)) attrs1 (__attrNames attrs2);
# example usage:
# mergeAttrByFunc {
# inherit mergeAttrBy; # defined below
# buildInputs = [ a b ];
# } {
# buildInputs = [ c d ];
# };
# will result in
# { mergeAttrsBy = [...]; buildInputs = [ a b c d ]; }
# is used by prepareDerivationArgs, defaultOverridableDelayableArgs and can be used when composing using
# foldArgs, composedArgsAndFun or applyAndFun. Example: composableDerivation in all-packages.nix
mergeAttrByFunc = x : y :
let
mergeAttrBy2 = { mergeAttrBy=lib.mergeAttrs; }
// (maybeAttr "mergeAttrBy" {} x)
// (maybeAttr "mergeAttrBy" {} y); in
fold lib.mergeAttrs {} [
x y
(mapAttrs ( a : v : # merge special names using given functions
if (hasAttr a x)
then if (hasAttr a y)
then v (getAttr a x) (getAttr a y) # both have attr, use merge func
else (getAttr a x) # only x has attr
else (getAttr a y) # only y has attr)
) (removeAttrs mergeAttrBy2
# don't merge attrs which are neither in x nor y
(filter (a : (! hasAttr a x) && (! hasAttr a y) )
(attrNames mergeAttrBy2))
)
)
];
mergeAttrsByFuncDefaults = foldl mergeAttrByFunc { inherit mergeAttrBy; };
mergeAttrsByFuncDefaultsClean = list: removeAttrs (mergeAttrsByFuncDefaults list) ["mergeAttrBy"];
# merge attrs based on version key into mkDerivation args, see mergeAttrBy to learn about smart merge defaults
#
# This function is best explained by an example:
#
# {version ? "2.x"} :
#
# mkDerivation (mergeAttrsByVersion "package-name" version
# { # version specific settings
# "git" = { src = ..; preConfigre = "autogen.sh"; buildInputs = [automake autoconf libtool]; };
# "2.x" = { src = ..; };
# }
# { // shared settings
# buildInputs = [ common build inputs ];
# meta = { .. }
# }
# )
#
# Please note that e.g. Eelco Dolstra usually prefers having one file for
# each version. On the other hand there are valuable additional design goals
# - readability
# - do it once only
# - try to avoid duplication
#
# Marc Weber and Michael Raskin sometimes prefer keeping older
# versions around for testing and regression tests - as long as its cheap to
# do so.
#
# Very often it just happens that the "shared" code is the bigger part.
# Then using this function might be appropriate.
#
# Be aware that its easy to cause recompilations in all versions when using
# this function - also if derivations get too complex splitting into multiple
# files is the way to go.
#
# See misc.nix -> versionedDerivation
# discussion: nixpkgs: pull/310
mergeAttrsByVersion = name: version: attrsByVersion: base:
mergeAttrsByFuncDefaultsClean [ { name = "${name}-${version}"; } base (maybeAttr version (throw "bad version ${version} for ${name}") attrsByVersion)];
# sane defaults (same name as attr name so that inherit can be used)
mergeAttrBy = # { buildInputs = concatList; [...]; passthru = mergeAttr; [..]; }
listToAttrs (map (n : nameValuePair n lib.concat)
[ "nativeBuildInputs" "buildInputs" "propagatedBuildInputs" "configureFlags" "prePhases" "postAll" "patches" ])
// listToAttrs (map (n : nameValuePair n lib.mergeAttrs) [ "passthru" "meta" "cfg" "flags" ])
// listToAttrs (map (n : nameValuePair n (a: b: "${a}\n${b}") ) [ "preConfigure" "postInstall" ])
;
# prepareDerivationArgs tries to make writing configurable derivations easier
# example:
# prepareDerivationArgs {
# mergeAttrBy = {
# myScript = x : y : x ++ "\n" ++ y;
# };
# cfg = {
# readlineSupport = true;
# };
# flags = {
# readline = {
# set = {
# configureFlags = [ "--with-compiler=${compiler}" ];
# buildInputs = [ compiler ];
# pass = { inherit compiler; READLINE=1; };
# assertion = compiler.dllSupport;
# myScript = "foo";
# };
# unset = { configureFlags = ["--without-compiler"]; };
# };
# };
# src = ...
# buildPhase = '' ... '';
# name = ...
# myScript = "bar";
# };
# if you don't have need for unset you can omit the surrounding set = { .. } attr
# all attrs except flags cfg and mergeAttrBy will be merged with the
# additional data from flags depending on config settings
# It's used in composableDerivation in all-packages.nix. It's also used
# heavily in the new python and libs implementation
#
# should we check for misspelled cfg options?
# TODO use args.mergeFun here as well?
prepareDerivationArgs = args:
let args2 = { cfg = {}; flags = {}; } // args;
flagName = name : "${name}Support";
cfgWithDefaults = (listToAttrs (map (n : nameValuePair (flagName n) false) (attrNames args2.flags)))
// args2.cfg;
opts = attrValues (mapAttrs (a : v :
let v2 = if v ? set || v ? unset then v else { set = v; };
n = if (getAttr (flagName a) cfgWithDefaults) then "set" else "unset";
attr = maybeAttr n {} v2; in
if (maybeAttr "assertion" true attr)
then attr
else throw "assertion of flag ${a} of derivation ${args.name} failed"
) args2.flags );
in removeAttrs
(mergeAttrsByFuncDefaults ([args] ++ opts ++ [{ passthru = cfgWithDefaults; }]))
["flags" "cfg" "mergeAttrBy" ];
nixType = x:
if isAttrs x then
if x ? outPath then "derivation"
else "aattrs"
else if isFunction x then "function"
else if isList x then "list"
else if x == true then "bool"
else if x == false then "bool"
else if x == null then "null"
else if isInt x then "int"
else "string";
}

View File

@@ -1,338 +0,0 @@
with import ./lists.nix;
with import ./trivial.nix;
with import ./attrsets.nix;
with import ./options.nix;
with import ./debug.nix;
with import ./types.nix;
rec {
/* Evaluate a set of modules. The result is a set of two
attributes: options: the nested set of all option declarations,
and config: the nested set of all option values. */
evalModules = { modules, prefix ? [], args ? {}, check ? true }:
let
args' = args // { lib = import ./.; } // result;
closed = closeModules modules args';
# Note: the list of modules is reversed to maintain backward
# compatibility with the old module system. Not sure if this is
# the most sensible policy.
options = mergeModules prefix (reverseList closed);
# Traverse options and extract the option values into the final
# config set. At the same time, check whether all option
# definitions have matching declarations.
config = yieldConfig prefix options;
yieldConfig = prefix: set:
let res = removeAttrs (mapAttrs (n: v:
if isOption v then v.value
else yieldConfig (prefix ++ [n]) v) set) ["_definedNames"];
in
if check && set ? _definedNames then
fold (m: res:
fold (name: res:
if hasAttr name set then res else throw "The option `${showOption (prefix ++ [name])}' defined in `${m.file}' does not exist.")
res m.names)
res set._definedNames
else
res;
result = { inherit options config; };
in result;
/* Close a set of modules under the imports relation. */
closeModules = modules: args:
let
toClosureList = file: parentKey: imap (n: x:
if isAttrs x || isFunction x then
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args)
else
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
in
builtins.genericClosure {
startSet = toClosureList unknownModule "" modules;
operator = m: toClosureList m.file m.key m.imports;
};
/* Massage a module into canonical form, that is, a set consisting
of options, config and imports attributes. */
unifyModuleSyntax = file: key: m:
if m ? config || m ? options then
let badAttrs = removeAttrs m ["imports" "options" "config" "key" "_file"]; in
if badAttrs != {} then
throw "Module `${key}' has an unsupported attribute `${head (attrNames badAttrs)}'."
else
{ file = m._file or file;
key = toString m.key or key;
imports = m.imports or [];
options = m.options or {};
config = m.config or {};
}
else
{ file = m._file or file;
key = toString m.key or key;
imports = m.require or [] ++ m.imports or [];
options = {};
config = removeAttrs m ["key" "_file" "require" "imports"];
};
applyIfFunction = f: arg: if isFunction f then f arg else f;
/* Merge a list of modules. This will recurse over the option
declarations in all modules, combining them into a single set.
At the same time, for each option declaration, it will merge the
corresponding option definitions in all machines, returning them
in the value attribute of each option. */
mergeModules = prefix: modules:
mergeModules' prefix modules
(concatMap (m: map (config: { inherit (m) file; inherit config; }) (pushDownProperties m.config)) modules);
mergeModules' = prefix: options: configs:
listToAttrs (map (name: {
# We're descending into attribute name.
inherit name;
value =
let
loc = prefix ++ [name];
# Get all submodules that declare name.
decls = concatLists (map (m:
if hasAttr name m.options
then [ { inherit (m) file; options = getAttr name m.options; } ]
else []
) options);
# Get all submodules that define name.
defns = concatLists (map (m:
if hasAttr name m.config
then map (config: { inherit (m) file; inherit config; })
(pushDownProperties (getAttr name m.config))
else []
) configs);
nrOptions = count (m: isOption m.options) decls;
# Process mkMerge and mkIf properties.
defns' = concatMap (m:
if hasAttr name m.config
then map (m': { inherit (m) file; value = m'; }) (dischargeProperties (getAttr name m.config))
else []
) configs;
in
if nrOptions == length decls then
let opt = fixupOptionType loc (mergeOptionDecls loc decls);
in evalOptionValue loc opt defns'
else if nrOptions != 0 then
let
firstOption = findFirst (m: isOption m.options) "" decls;
firstNonOption = findFirst (m: !isOption m.options) "" decls;
in
throw "The option `${showOption loc}' in `${firstOption.file}' is a prefix of options in `${firstNonOption.file}'."
else
mergeModules' loc decls defns;
}) (concatMap (m: attrNames m.options) options))
// { _definedNames = map (m: { inherit (m) file; names = attrNames m.config; }) configs; };
/* Merge multiple option declarations into a single declaration. In
general, there should be only one declaration of each option.
The exception is the options attribute, which specifies
sub-options. These can be specified multiple times to allow one
module to add sub-options to an option declared somewhere else
(e.g. multiple modules define sub-options for fileSystems). */
mergeOptionDecls = loc: opts:
fold (opt: res:
if opt.options ? default && res ? default ||
opt.options ? example && res ? example ||
opt.options ? description && res ? description ||
opt.options ? apply && res ? apply ||
opt.options ? type && res ? type
then
throw "The option `${showOption loc}' in `${opt.file}' is already declared in ${showFiles res.declarations}."
else
opt.options // res //
{ declarations = [opt.file] ++ res.declarations;
options = if opt.options ? options then [(toList opt.options.options ++ res.options)] else [];
}
) { inherit loc; declarations = []; options = []; } opts;
/* Merge all the definitions of an option to produce the final
config value. */
evalOptionValue = loc: opt: defs:
let
# Process mkOverride properties, adding in the default
# value specified in the option declaration (if any).
defsFinal' = filterOverrides
((if opt ? default then [{ file = head opt.declarations; value = mkOptionDefault opt.default; }] else []) ++ defs);
# Sort mkOrder properties.
defsFinal =
# Avoid sorting if we don't have to.
if any (def: def.value._type or "" == "order") defsFinal'
then sortProperties defsFinal'
else defsFinal';
files = map (def: def.file) defsFinal;
# Type-check the remaining definitions, and merge them if
# possible.
merged =
if defsFinal == [] then
throw "The option `${showOption loc}' is used but not defined."
else
fold (def: res:
if opt.type.check def.value then res
else throw "The option value `${showOption loc}' in `${def.file}' is not a ${opt.type.name}.")
(opt.type.merge loc defsFinal) defsFinal;
# Finally, apply the apply function to the merged
# value. This allows options to yield a value computed
# from the definitions.
value = (opt.apply or id) merged;
in opt //
{ value = addErrorContext "while evaluating the option `${showOption loc}':" value;
definitions = map (def: def.value) defsFinal;
isDefined = defsFinal != [];
inherit files;
};
/* Given a config set, expand mkMerge properties, and push down the
other properties into the children. The result is a list of
config sets that do not have properties at top-level. For
example,
mkMerge [ { boot = set1; } (mkIf cond { boot = set2; services = set3; }) ]
is transformed into
[ { boot = set1; } { boot = mkIf cond set2; services mkIf cond set3; } ].
This transform is the critical step that allows mkIf conditions
to refer to the full configuration without creating an infinite
recursion.
*/
pushDownProperties = cfg:
if cfg._type or "" == "merge" then
concatMap pushDownProperties cfg.contents
else if cfg._type or "" == "if" then
map (mapAttrs (n: v: mkIf cfg.condition v)) (pushDownProperties cfg.content)
else if cfg._type or "" == "override" then
map (mapAttrs (n: v: mkOverride cfg.priority v)) (pushDownProperties cfg.content)
else # FIXME: handle mkOrder?
[ cfg ];
/* Given a config value, expand mkMerge properties, and discharge
any mkIf conditions. That is, this is the place where mkIf
conditions are actually evaluated. The result is a list of
config values. For example, mkIf false x yields [],
mkIf true x yields [x], and
mkMerge [ 1 (mkIf true 2) (mkIf true (mkIf false 3)) ]
yields [ 1 2 ].
*/
dischargeProperties = def:
if def._type or "" == "merge" then
concatMap dischargeProperties def.contents
else if def._type or "" == "if" then
if def.condition then
dischargeProperties def.content
else
[ ]
else
[ def ];
/* Given a list of config values, process the mkOverride properties,
that is, return the values that have the highest (that is,
numerically lowest) priority, and strip the mkOverride
properties. For example,
[ { file = "/1"; value = mkOverride 10 "a"; }
{ file = "/2"; value = mkOverride 20 "b"; }
{ file = "/3"; value = "z"; }
{ file = "/4"; value = mkOverride 10 "d"; }
]
yields
[ { file = "/1"; value = "a"; }
{ file = "/4"; value = "d"; }
]
Note that "z" has the default priority 100.
*/
filterOverrides = defs:
let
defaultPrio = 100;
getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPrio;
min = x: y: if builtins.lessThan x y then x else y;
highestPrio = fold (def: prio: min (getPrio def) prio) 9999 defs;
strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def;
in concatMap (def: if getPrio def == highestPrio then [(strip def)] else []) defs;
/* Sort a list of properties. The sort priority of a property is
1000 by default, but can be overriden by wrapping the property
using mkOrder. */
sortProperties = defs:
let
strip = def:
if def.value._type or "" == "order"
then def // { value = def.value.content; inherit (def.value) priority; }
else def;
defs' = map strip defs;
compare = a: b: (a.priority or 1000) < (b.priority or 1000);
in sort compare defs';
/* Hack for backward compatibility: convert options of type
optionSet to configOf. FIXME: remove eventually. */
fixupOptionType = loc: opt:
let
options' = opt.options or
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute.");
coerce = x:
if isFunction x then x
else { config, ... }: { options = x; };
options = map coerce (flatten options');
f = tp:
if tp.name == "option set" then types.submodule options
else if tp.name == "attribute set of option sets" then types.attrsOf (types.submodule options)
else if tp.name == "list or attribute set of option sets" then types.loaOf (types.submodule options)
else if tp.name == "list of option sets" then types.listOf (types.submodule options)
else if tp.name == "null or option set" then types.nullOr (types.submodule options)
else tp;
in opt // { type = f (opt.type or types.unspecified); };
/* Properties. */
mkIf = condition: content:
{ _type = "if";
inherit condition content;
};
mkAssert = assertion: message: content:
mkIf
(if assertion then true else throw "\nFailed assertion: ${message}")
content;
mkMerge = contents:
{ _type = "merge";
inherit contents;
};
mkOverride = priority: content:
{ _type = "override";
inherit priority content;
};
mkOptionDefault = mkOverride 1001; # priority of option defaults
mkDefault = mkOverride 1000; # used in config sections of non-user modules to set a default
mkForce = mkOverride 50;
mkVMOverride = mkOverride 10; # used by nixos-rebuild build-vm
mkStrict = builtins.trace "`mkStrict' is obsolete; use `mkOverride 0' instead." (mkOverride 0);
mkFixStrictness = id; # obsolete, no-op
mkOrder = priority: content:
{ _type = "order";
inherit priority content;
};
mkBefore = mkOrder 500;
mkAfter = mkOrder 1500;
/* Compatibility. */
fixMergeModules = modules: args: evalModules { inherit modules args; check = false; };
}

View File

@@ -1,120 +0,0 @@
# Nixpkgs/NixOS option handling.
let lib = import ./default.nix; in
with import ./trivial.nix;
with import ./lists.nix;
with import ./misc.nix;
with import ./attrsets.nix;
with import ./strings.nix;
rec {
isOption = lib.isType "option";
mkOption =
{ default ? null # Default value used when no definition is given in the configuration.
, defaultText ? null # Textual representation of the default, for in the manual.
, example ? null # Example value used in the manual.
, description ? null # String describing the option.
, type ? null # Option type, providing type-checking and value merging.
, apply ? null # Function that converts the option value to something else.
, internal ? null # Whether the option is for NixOS developers only.
, visible ? null # Whether the option shows up in the manual.
, options ? null # Obsolete, used by types.optionSet.
} @ attrs:
attrs // { _type = "option"; };
mkEnableOption = name: mkOption {
default = false;
example = true;
description = "Whether to enable ${name}.";
type = lib.types.bool;
};
mergeDefaultOption = loc: defs:
let list = getValues defs; in
if length list == 1 then head list
else if all isFunction list then x: mergeDefaultOption loc (map (f: f x) list)
else if all isList list then concatLists list
else if all isAttrs list then fold lib.mergeAttrs {} list
else if all isBool list then fold lib.or false list
else if all isString list then lib.concatStrings list
else if all isInt list && all (x: x == head list) list then head list
else throw "Cannot merge definitions of `${showOption loc}' given in ${showFiles (getFiles defs)}.";
/* Obsolete, will remove soon. Specify an option type or apply
function instead. */
mergeTypedOption = typeName: predicate: merge: loc: list:
let list' = map (x: x.value) list; in
if all predicate list then merge list'
else throw "Expected a ${typeName}.";
mergeEnableOption = mergeTypedOption "boolean"
(x: true == x || false == x) (fold lib.or false);
mergeListOption = mergeTypedOption "list" isList concatLists;
mergeStringOption = mergeTypedOption "string" isString lib.concatStrings;
mergeOneOption = loc: defs:
if defs == [] then abort "This case should never happen."
else if length defs != 1 then
throw "The unique option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}."
else (head defs).value;
getValues = map (x: x.value);
getFiles = map (x: x.file);
# Generate documentation template from the list of option declaration like
# the set generated with filterOptionSets.
optionAttrSetToDocList = optionAttrSetToDocList' [];
optionAttrSetToDocList' = prefix: options:
fold (opt: rest:
let
docOption = rec {
name = showOption opt.loc;
description = opt.description or (throw "Option `${name}' has no description.");
declarations = filter (x: x != unknownModule) opt.declarations;
internal = opt.internal or false;
visible = opt.visible or true;
}
// optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; }
// optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }
// optionalAttrs (opt ? defaultText) { default = opt.defaultText; };
subOptions =
let ss = opt.type.getSubOptions opt.loc;
in if ss != {} then optionAttrSetToDocList' opt.loc ss else [];
in
# FIXME: expensive, O(n^2)
[ docOption ] ++ subOptions ++ rest) [] (collect isOption options);
/* This function recursively removes all derivation attributes from
`x' except for the `name' attribute. This is to make the
generation of `options.xml' much more efficient: the XML
representation of derivations is very large (on the order of
megabytes) and is not actually used by the manual generator. */
scrubOptionValue = x:
if isDerivation x then
{ type = "derivation"; drvPath = x.name; outPath = x.name; name = x.name; }
else if isList x then map scrubOptionValue x
else if isAttrs x then mapAttrs (n: v: scrubOptionValue v) (removeAttrs x ["_args"])
else x;
/* For use in the example option attribute. It causes the given
text to be included verbatim in documentation. This is necessary
for example values that are not simple values, e.g.,
functions. */
literalExample = text: { _type = "literalExample"; inherit text; };
/* Helper functions. */
showOption = concatStringsSep ".";
showFiles = files: concatStringsSep " and " (map (f: "`${f}'") files);
unknownModule = "<unknown-file>";
}

View File

@@ -1,16 +0,0 @@
let lists = import ./lists.nix; in
rec {
gnu = linux; /* ++ hurd ++ kfreebsd ++ ... */
linux = ["i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "mips64el-linux"];
darwin = ["x86_64-darwin"];
freebsd = ["i686-freebsd" "x86_64-freebsd"];
openbsd = ["i686-openbsd" "x86_64-openbsd"];
netbsd = ["i686-netbsd" "x86_64-netbsd"];
cygwin = ["i686-cygwin"];
unix = linux ++ darwin ++ freebsd ++ openbsd;
all = linux ++ darwin ++ cygwin ++ freebsd ++ openbsd;
none = [];
allBut = platform: lists.filter (x: platform != x) all;
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux"];
}

View File

@@ -1,32 +0,0 @@
# Functions for copying sources to the Nix store.
let lib = import ./default.nix; in
rec {
# Bring in a path as a source, filtering out all Subversion and CVS
# directories, as well as backup files (*~).
cleanSource =
let filter = name: type: let baseName = baseNameOf (toString name); in ! (
# Filter out Subversion and CVS directories.
(type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
# Filter out backup files.
lib.hasSuffix "~" baseName ||
# Filter out generates files.
lib.hasSuffix ".o" baseName ||
lib.hasSuffix ".so" baseName
);
in src: builtins.filterSource filter src;
# Get all files ending with the specified suffices from the given
# directory. E.g. `sourceFilesBySuffices ./dir [".xml" ".c"]'.
sourceFilesBySuffices = path: exts:
let filter = name: type:
let base = baseNameOf (toString name);
in type != "directory" && lib.any (ext: lib.hasSuffix ext base) exts;
in builtins.filterSource filter path;
}

View File

@@ -1,78 +0,0 @@
/*
Usage:
You define you custom builder script by adding all build steps to a list.
for example:
builder = writeScript "fsg-4.4-builder"
(textClosure [doUnpack addInputs preBuild doMake installPhase doForceShare]);
a step is defined by noDepEntry, fullDepEntry or packEntry.
To ensure that prerequisite are met those are added before the task itself by
textClosureDupList. Duplicated items are removed again.
See trace/nixpkgs/trunk/pkgs/top-level/builder-defs.nix for some predefined build steps
Attention:
let
pkgs = (import /etc/nixos/nixpkgs/pkgs/top-level/all-packages.nix) {};
in let
inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap;
inherit (pkgs.lib) id;
nameA = noDepEntry "Text a";
nameB = fullDepEntry "Text b" ["nameA"];
nameC = fullDepEntry "Text c" ["nameA"];
stages = {
nameHeader = noDepEntry "#! /bin/sh \n";
inherit nameA nameB nameC;
};
in
textClosureMap id stages
[ "nameHeader" "nameA" "nameB" "nameC"
nameC # <- added twice. add a dep entry if you know that it will be added once only [1]
"nameB" # <- this will not be added again because the attr name (reference) is used
]
# result: Str("#! /bin/sh \n\nText a\nText b\nText c\nText c",[])
[1] maybe this behaviour should be removed to keep things simple (?)
*/
with import ./lists.nix;
with import ./attrsets.nix;
with import ./strings.nix;
rec {
/* !!! The interface of this function is kind of messed up, since
it's way too overloaded and almost but not quite computes a
topological sort of the depstrings. */
textClosureList = predefined: arg:
let
f = done: todo:
if todo == [] then {result = []; inherit done;}
else
let entry = head todo; in
if isAttrs entry then
let x = f done entry.deps;
y = f x.done (tail todo);
in { result = x.result ++ [entry.text] ++ y.result;
done = y.done;
}
else if hasAttr entry done then f done (tail todo)
else f (done // listToAttrs [{name = entry; value = 1;}]) ([(builtins.getAttr entry predefined)] ++ tail todo);
in (f {} arg).result;
textClosureMap = f: predefined: names:
concatStringsSep "\n" (map f (textClosureList predefined names));
noDepEntry = text: {inherit text; deps = [];};
fullDepEntry = text: deps: {inherit text deps;};
packEntry = deps: {inherit deps; text="";};
stringAfter = deps: text: { inherit text deps; };
}

View File

@@ -1,201 +0,0 @@
/* String manipulation functions. */
let lib = import ./default.nix;
inherit (builtins) add sub lessThan length;
in
rec {
inherit (builtins) stringLength substring head tail isString;
# Concatenate a list of strings.
concatStrings = lib.fold (x: y: x + y) "";
# Map a function over a list and concatenate the resulting strings.
concatMapStrings = f: list: concatStrings (map f list);
concatImapStrings = f: list: concatStrings (lib.imap f list);
# Place an element between each element of a list, e.g.,
# `intersperse "," ["a" "b" "c"]' returns ["a" "," "b" "," "c"].
intersperse = separator: list:
if list == [] || length list == 1
then list
else [(head list) separator]
++ (intersperse separator (tail list));
# Concatenate a list of strings with a separator between each element, e.g.
# concatStringsSep " " ["foo" "bar" "xyzzy"] == "foo bar xyzzy"
concatStringsSep = separator: list:
concatStrings (intersperse separator list);
# Construct a Unix-style search path consisting of each `subDir"
# directory of the given list of packages. For example,
# `makeSearchPath "bin" ["x" "y" "z"]' returns "x/bin:y/bin:z/bin".
makeSearchPath = subDir: packages:
concatStringsSep ":" (map (path: path + "/" + subDir) packages);
# Construct a library search path (such as RPATH) containing the
# libraries for a set of packages, e.g. "${pkg1}/lib:${pkg2}/lib:...".
makeLibraryPath = makeSearchPath "lib";
# Idem for Perl search paths.
makePerlPath = makeSearchPath "lib/perl5/site_perl";
# Dependening on the boolean `cond', return either the given string
# or the empty string.
optionalString = cond: string: if cond then string else "";
# Determine whether a filename ends in the given suffix.
hasSuffix = ext: fileName:
let lenFileName = stringLength fileName;
lenExt = stringLength ext;
in !(lessThan lenFileName lenExt) &&
substring (sub lenFileName lenExt) lenFileName fileName == ext;
# Convert a string to a list of characters (i.e. singleton strings).
# For instance, "abc" becomes ["a" "b" "c"]. This allows you to,
# e.g., map a function over each character. However, note that this
# will likely be horribly inefficient; Nix is not a general purpose
# programming language. Complex string manipulations should, if
# appropriate, be done in a derivation.
stringToCharacters = s: let l = stringLength s; in
if l == 0
then []
else map (p: substring p 1 s) (lib.range 0 (sub l 1));
# Manipulate a string charcater by character and replace them by strings
# before concatenating the results.
stringAsChars = f: s:
concatStrings (
map f (stringToCharacters s)
);
# same as vim escape function.
# Each character contained in list is prefixed by "\"
escape = list : string :
stringAsChars (c: if lib.elem c list then "\\${c}" else c) string;
# still ugly slow. But more correct now
# [] for zsh
escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]");
# replace characters by their substitutes. This function is equivalent to
# the `tr' command except that one character can be replace by multiple
# ones. e.g.,
# replaceChars ["<" ">"] ["&lt;" "&gt;"] "<foo>" returns "&lt;foo&gt;".
replaceChars = del: new: s:
let
subst = c:
(lib.fold
(sub: res: if sub.fst == c then sub else res)
{fst = c; snd = c;} (lib.zipLists del new)
).snd;
in
stringAsChars subst s;
# Case conversion utilities
lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz";
upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
toLower = replaceChars upperChars lowerChars;
toUpper = replaceChars lowerChars upperChars;
# Compares strings not requiring context equality
# Obviously, a workaround but works on all Nix versions
eqStrings = a: b: (a+(substring 0 0 b)) == ((substring 0 0 a)+b);
# Cut a string with a separator and produces a list of strings which were
# separated by this separator. e.g.,
# `splitString "." "foo.bar.baz"' returns ["foo" "bar" "baz"].
splitString = sep: s:
let
sepLen = stringLength sep;
sLen = stringLength s;
lastSearch = sub sLen sepLen;
startWithSep = startAt:
substring startAt sepLen s == sep;
recurse = index: startAt:
let cutUntil = i: [(substring startAt (sub i startAt) s)]; in
if lessThan index lastSearch then
if startWithSep index then
let restartAt = add index sepLen; in
cutUntil index ++ recurse restartAt restartAt
else
recurse (add index 1) startAt
else
cutUntil sLen;
in
recurse 0 0;
# return the suffix of the second argument if the first argument match its
# prefix. e.g.,
# `removePrefix "foo." "foo.bar.baz"' returns "bar.baz".
removePrefix = pre: s:
let
preLen = stringLength pre;
sLen = stringLength s;
in
if pre == substring 0 preLen s then
substring preLen (sub sLen preLen) s
else
s;
removeSuffix = suf: s:
let
sufLen = stringLength suf;
sLen = stringLength s;
in
if sufLen <= sLen && suf == substring (sLen - sufLen) sufLen s then
substring 0 (sLen - sufLen) s
else
s;
# Return true iff string v1 denotes a version older than v2.
versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1;
# Return true iff string v1 denotes a version equal to or newer than v2.
versionAtLeast = v1: v2: !versionOlder v1 v2;
# Get the version of the specified derivation, as specified in its
# name attribute.
getVersion = drv: (builtins.parseDrvName drv.name).version;
# Extract name with version from URL. Ask for separator which is
# supposed to start extension
nameFromURL = url: sep: let
components = splitString "/" url;
filename = lib.last components;
name = builtins.head (splitString sep filename);
in
assert ! eqStrings name filename;
name;
# Create an --{enable,disable}-<feat> string that can be passed to
# standard GNU Autoconf scripts.
enableFeature = enable: feat: "--${if enable then "enable" else "disable"}-${feat}";
}

View File

@@ -1,126 +0,0 @@
# Define the list of system with their properties. Only systems tested for
# Nixpkgs are listed below
with import ./lists.nix;
with import ./types.nix;
with import ./attrsets.nix;
let
lib = import ./default.nix;
setTypes = type:
mapAttrs (name: value:
setType type ({inherit name;} // value)
);
in
rec {
isSignificantByte = isType "significant-byte";
significantBytes = setTypes "significant-byte" {
bigEndian = {};
littleEndian = {};
};
isCpuType = x: isType "cpu-type" x
&& elem x.bits [8 16 32 64 128]
&& (builtins.lessThan 8 x.bits -> isSignificantByte x.significantByte);
cpuTypes = with significantBytes;
setTypes "cpu-type" {
arm = { bits = 32; significantByte = littleEndian; };
armv5tel = { bits = 32; significantByte = littleEndian; };
armv7l = { bits = 32; significantByte = littleEndian; };
i686 = { bits = 32; significantByte = littleEndian; };
powerpc = { bits = 32; significantByte = bigEndian; };
x86_64 = { bits = 64; significantByte = littleEndian; };
};
isExecFormat = isType "exec-format";
execFormats = setTypes "exec-format" {
aout = {}; # a.out
elf = {};
macho = {};
pe = {};
unknow = {};
};
isKernel = isType "kernel";
kernels = with execFormats;
setTypes "kernel" {
cygwin = { execFormat = pe; };
darwin = { execFormat = macho; };
freebsd = { execFormat = elf; };
linux = { execFormat = elf; };
netbsd = { execFormat = elf; };
none = { execFormat = unknow; };
openbsd = { execFormat = elf; };
win32 = { execFormat = pe; };
};
isArchitecture = isType "architecture";
architectures = setTypes "architecture" {
apple = {};
pc = {};
unknow = {};
};
isSystem = x: isType "system" x
&& isCpuType x.cpu
&& isArchitecture x.arch
&& isKernel x.kernel;
mkSystem = {
cpu ? cpuTypes.i686,
arch ? architectures.pc,
kernel ? kernels.linux,
name ? "${cpu.name}-${arch.name}-${kernel.name}"
}: setType "system" {
inherit name cpu arch kernel;
};
isDarwin = matchAttrs { kernel = kernels.darwin; };
isLinux = matchAttrs { kernel = kernels.linux; };
isi686 = matchAttrs { cpu = cpuTypes.i686; };
is64Bit = matchAttrs { cpu = { bits = 64; }; };
# This should revert the job done by config.guess from the gcc compiler.
mkSystemFromString = s: let
l = lib.splitString "-" s;
getCpu = name:
attrByPath [name] (throw "Unknow cpuType `${name}'.")
cpuTypes;
getArch = name:
attrByPath [name] (throw "Unknow architecture `${name}'.")
architectures;
getKernel = name:
attrByPath [name] (throw "Unknow kernel `${name}'.")
kernels;
system =
if builtins.length l == 2 then
mkSystem rec {
name = s;
cpu = getCpu (head l);
arch =
if isDarwin system
then architectures.apple
else architectures.pc;
kernel = getKernel (head (tail l));
}
else
mkSystem {
name = s;
cpu = getCpu (head l);
arch = getArch (head (tail l));
kernel = getKernel (head (tail (tail l)));
};
in assert isSystem system; system;
}

View File

@@ -1,113 +0,0 @@
let inherit (builtins) add; in
with import ./default.nix;
runTests {
testId = {
expr = id 1;
expected = 1;
};
testConst = {
expr = const 2 3;
expected = 2;
};
/*
testOr = {
expr = or true false;
expected = true;
};
*/
testAnd = {
expr = and true false;
expected = false;
};
testFix = {
expr = fix (x: {a = if x ? a then "a" else "b";});
expected = {a = "a";};
};
testConcatMapStrings = {
expr = concatMapStrings (x: x + ";") ["a" "b" "c"];
expected = "a;b;c;";
};
testConcatStringsSep = {
expr = concatStringsSep "," ["a" "b" "c"];
expected = "a,b,c";
};
testFilter = {
expr = filter (x: x != "a") ["a" "b" "c" "a"];
expected = ["b" "c"];
};
testFold = {
expr = fold (builtins.add) 0 (range 0 100);
expected = 5050;
};
testTake = testAllTrue [
([] == (take 0 [ 1 2 3 ]))
([1] == (take 1 [ 1 2 3 ]))
([ 1 2 ] == (take 2 [ 1 2 3 ]))
([ 1 2 3 ] == (take 3 [ 1 2 3 ]))
([ 1 2 3 ] == (take 4 [ 1 2 3 ]))
];
testFoldAttrs = {
expr = foldAttrs (n: a: [n] ++ a) [] [
{ a = 2; b = 7; }
{ a = 3; c = 8; }
];
expected = { a = [ 2 3 ]; b = [7]; c = [8];};
};
testOverridableDelayableArgsTest = {
expr =
let res1 = defaultOverridableDelayableArgs id {};
res2 = defaultOverridableDelayableArgs id { a = 7; };
res3 = let x = defaultOverridableDelayableArgs id { a = 7; };
in (x.merge) { b = 10; };
res4 = let x = defaultOverridableDelayableArgs id { a = 7; };
in (x.merge) ( x: { b = 10; });
res5 = let x = defaultOverridableDelayableArgs id { a = 7; };
in (x.merge) ( x: { a = add x.a 3; });
res6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = add; }; };
y = x.merge {};
in (y.merge) { a = 10; };
resRem7 = res6.replace (a : removeAttrs a ["a"]);
resReplace6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = add; }; };
x2 = x.merge { a = 20; }; # now we have 27
in (x2.replace) { a = 10; }; # and override the value by 10
# fixed tests (delayed args): (when using them add some comments, please)
resFixed1 =
let x = defaultOverridableDelayableArgs id ( x : { a = 7; c = x.fixed.b; });
y = x.merge (x : { name = "name-${builtins.toString x.fixed.c}"; });
in (y.merge) { b = 10; };
strip = attrs : removeAttrs attrs ["merge" "replace"];
in all id
[ ((strip res1) == { })
((strip res2) == { a = 7; })
((strip res3) == { a = 7; b = 10; })
((strip res4) == { a = 7; b = 10; })
((strip res5) == { a = 10; })
((strip res6) == { a = 17; })
((strip resRem7) == {})
((strip resFixed1) == { a = 7; b = 10; c =10; name = "name-10"; })
];
expected = true;
};
testSort = {
expr = sort builtins.lessThan [ 40 2 30 42 ];
expected = [2 30 40 42];
};
}

View File

@@ -1,53 +0,0 @@
with {
inherit (import ./lists.nix) deepSeqList;
inherit (import ./attrsets.nix) deepSeqAttrs;
};
rec {
# Identity function.
id = x: x;
# Constant function.
const = x: y: x;
# Named versions corresponding to some builtin operators.
concat = x: y: x ++ y;
or = x: y: x || y;
and = x: y: x && y;
mergeAttrs = x: y: x // y;
# Take a function and evaluate it with its own returned value.
fix = f: let result = f result; in result;
# Flip the order of the arguments of a binary function.
flip = f: a: b: f b a;
# `seq x y' evaluates x, then returns y. That is, it forces strict
# evaluation of its first argument.
seq = x: y: if x == null then y else y;
# Like `seq', but recurses into lists and attribute sets to force evaluation
# of all list elements/attributes.
deepSeq = x: y:
if builtins.isList x
then deepSeqList x y
else if builtins.isAttrs x
then deepSeqAttrs x y
else seq x y;
# Pull in some builtins not included elsewhere.
inherit (builtins)
pathExists readFile isBool isFunction
isInt add sub lessThan;
# Return the Nixpkgs version number.
nixpkgsVersion =
let suffixFile = ../.version-suffix; in
readFile ../.version
+ (if pathExists suffixFile then readFile suffixFile else "pre-git");
# Whether we're being called by nix-shell. This is useful to
inNixShell = builtins.getEnv "IN_NIX_SHELL" == "1";
}

View File

@@ -1,221 +0,0 @@
# Definitions related to run-time type checking. Used in particular
# to type-check NixOS configurations.
with import ./lists.nix;
with import ./attrsets.nix;
with import ./options.nix;
with import ./trivial.nix;
with import ./strings.nix;
rec {
isType = type: x: (x._type or "") == type;
setType = typeName: value: value // {
_type = typeName;
};
isOptionType = isType "option-type";
mkOptionType =
{ # Human-readable representation of the type.
name
, # Function applied to each definition that should return true if
# its type-correct, false otherwise.
check ? (x: true)
, # Merge a list of definitions together into a single value.
# This function is called with two arguments: the location of
# the option in the configuration as a list of strings
# (e.g. ["boot" "loader "grub" "enable"]), and a list of
# definition values and locations (e.g. [ { file = "/foo.nix";
# value = 1; } { file = "/bar.nix"; value = 2 } ]).
merge ? mergeDefaultOption
, # Return a flat list of sub-options. Used to generate
# documentation.
getSubOptions ? prefix: {}
}:
{ _type = "option-type";
inherit name check merge getSubOptions;
};
types = rec {
unspecified = mkOptionType {
name = "unspecified";
};
bool = mkOptionType {
name = "boolean";
check = isBool;
merge = loc: fold (x: y: x.value || y) false;
};
int = mkOptionType {
name = "integer";
check = isInt;
merge = mergeOneOption;
};
str = mkOptionType {
name = "string";
check = isString;
merge = mergeOneOption;
};
# Merge multiple definitions by concatenating them (with the given
# separator between the values).
separatedString = sep: mkOptionType {
name = "string";
check = isString;
merge = loc: defs: concatStringsSep sep (getValues defs);
};
lines = separatedString "\n";
commas = separatedString ",";
envVar = separatedString ":";
# Deprecated; should not be used because it quietly concatenates
# strings, which is usually not what you want.
string = separatedString "";
attrs = mkOptionType {
name = "attribute set";
check = isAttrs;
merge = loc: fold (def: mergeAttrs def.value) {};
};
# derivation is a reserved keyword.
package = mkOptionType {
name = "derivation";
check = isDerivation;
merge = mergeOneOption;
};
path = mkOptionType {
name = "path";
# Hacky: there is no isPath primop.
check = x: builtins.unsafeDiscardStringContext (builtins.substring 0 1 (toString x)) == "/";
merge = mergeOneOption;
};
# drop this in the future:
list = builtins.trace "`types.list' is deprecated; use `types.listOf' instead" types.listOf;
listOf = elemType: mkOptionType {
name = "list of ${elemType.name}s";
check = value: isList value && all elemType.check value;
merge = loc: defs:
concatLists (imap (n: def: imap (m: def':
elemType.merge (loc ++ ["[${toString n}-${toString m}]"])
[{ inherit (def) file; value = def'; }]) def.value) defs);
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]);
};
attrsOf = elemType: mkOptionType {
name = "attribute set of ${elemType.name}s";
check = x: isAttrs x && all elemType.check (attrValues x);
merge = loc: defs:
zipAttrsWith (name: elemType.merge (loc ++ [name]))
# Push down position info.
(map (def: listToAttrs (mapAttrsToList (n: def':
{ name = n; value = { inherit (def) file; value = def'; }; }) def.value)) defs);
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]);
};
# List or attribute set of ...
loaOf = elemType:
let
convertIfList = defIdx: def:
if isList def.value then
{ inherit (def) file;
value = listToAttrs (
imap (elemIdx: elem:
{ name = elem.name or "unnamed-${toString defIdx}.${toString elemIdx}";
value = elem;
}) def.value);
}
else
def;
listOnly = listOf elemType;
attrOnly = attrsOf elemType;
in mkOptionType {
name = "list or attribute set of ${elemType.name}s";
check = x:
if isList x then listOnly.check x
else if isAttrs x then attrOnly.check x
else false;
merge = loc: defs: attrOnly.merge loc (imap convertIfList defs);
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
};
uniq = elemType: mkOptionType {
inherit (elemType) name check;
merge = mergeOneOption;
getSubOptions = elemType.getSubOptions;
};
nullOr = elemType: mkOptionType {
name = "null or ${elemType.name}";
check = x: builtins.isNull x || elemType.check x;
merge = loc: defs:
let nrNulls = count (def: isNull def.value) defs; in
if nrNulls == length defs then null
else if nrNulls != 0 then
throw "The option `${showOption loc}' is defined both null and not null, in ${showFiles (getFiles defs)}."
else elemType.merge loc defs;
getSubOptions = elemType.getSubOptions;
};
functionTo = elemType: mkOptionType {
name = "function that evaluates to a(n) ${elemType.name}";
check = isFunction;
merge = loc: defs:
fnArgs: elemType.merge loc (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs);
getSubOptions = elemType.getSubOptions;
};
submodule = opts:
let
opts' = toList opts;
inherit (import ./modules.nix) evalModules;
in
mkOptionType rec {
name = "submodule";
check = x: isAttrs x || isFunction x;
merge = loc: defs:
let
coerce = def: if isFunction def then def else { config = def; };
modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs;
in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config;
getSubOptions = prefix: (evalModules
{ modules = opts'; inherit prefix;
# FIXME: hack to get shit to evaluate.
args = { name = ""; }; }).options;
};
enum = values: mkOptionType {
name = "one of ${concatStringsSep ", " values}";
check = flip elem values;
merge = mergeOneOption;
};
either = t1: t2: mkOptionType {
name = "${t1.name} or ${t2.name}";
check = x: t1.check x || t2.check x;
merge = mergeOneOption;
};
# Obsolete alternative to configOf. It takes its option
# declarations from the options attribute of containing option
# declaration.
optionSet = mkOptionType {
name = /* builtins.trace "types.optionSet is deprecated; use types.submodule instead" */ "option set";
};
# Augment the given type with an additional type check function.
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
};
}

View File

@@ -1,97 +0,0 @@
#! /run/current-system/sw/bin/perl -w
use strict;
use XML::Simple;
use File::Basename;
use File::Path;
use File::Copy 'cp';
use IPC::Open2;
use Nix::Store;
my $myDir = dirname($0);
my $tarballsCache = $ENV{'NIX_TARBALLS_CACHE'} // "/tarballs";
my $xml = `nix-instantiate --eval-only --xml --strict '<nixpkgs/maintainers/scripts/find-tarballs.nix>'`;
die "$0: evaluation failed\n" if $? != 0;
my $data = XMLin($xml) or die;
mkpath($tarballsCache);
mkpath("$tarballsCache/md5");
mkpath("$tarballsCache/sha1");
mkpath("$tarballsCache/sha256");
foreach my $file (@{$data->{list}->{attrs}}) {
my $url = $file->{attr}->{url}->{string}->{value};
my $algo = $file->{attr}->{type}->{string}->{value};
my $hash = $file->{attr}->{hash}->{string}->{value};
if ($url !~ /^http:/ && $url !~ /^https:/ && $url !~ /^ftp:/ && $url !~ /^mirror:/) {
print STDERR "skipping $url (unsupported scheme)\n";
next;
}
$url =~ /([^\/]+)$/;
my $fn = $1;
if (!defined $fn) {
print STDERR "skipping $url (no file name)\n";
next;
}
if ($fn =~ /[&?=%]/ || $fn =~ /^\./) {
print STDERR "skipping $url (bad character in file name)\n";
next;
}
if ($fn !~ /[a-zA-Z]/) {
print STDERR "skipping $url (no letter in file name)\n";
next;
}
if ($fn !~ /[0-9]/) {
print STDERR "skipping $url (no digit in file name)\n";
next;
}
if ($fn !~ /[-_\.]/) {
print STDERR "skipping $url (no dash/dot/underscore in file name)\n";
next;
}
my $dstPath = "$tarballsCache/$fn";
next if -e $dstPath;
print "downloading $url to $dstPath...\n";
next if $ENV{DRY_RUN};
$ENV{QUIET} = 1;
$ENV{PRINT_PATH} = 1;
my $fh;
my $pid = open($fh, "-|", "nix-prefetch-url", "--type", $algo, $url, $hash) or die;
waitpid($pid, 0) or die;
if ($? != 0) {
print STDERR "failed to fetch $url: $?\n";
next;
}
<$fh>; my $storePath = <$fh>; chomp $storePath;
die unless -e $storePath;
cp($storePath, $dstPath) or die;
my $md5 = hashFile("md5", 0, $storePath) or die;
symlink("../$fn", "$tarballsCache/md5/$md5");
my $sha1 = hashFile("sha1", 0, $storePath) or die;
symlink("../$fn", "$tarballsCache/sha1/$sha1");
my $sha256 = hashFile("sha256", 0, $storePath) or die;
symlink("../$fn", "$tarballsCache/sha256/$sha256");
$sha256 = hashFile("sha256", 1, $storePath) or die;
symlink("../$fn", "$tarballsCache/sha256/$sha256");
}

View File

@@ -1,32 +0,0 @@
#!/bin/sh
# Download patches from debian project
# Usage $0 debian-patches.txt debian-patches.nix
# An example input and output files can be found in applications/graphics/xara/
DEB_URL=http://patch-tracker.debian.org/patch/series/dl
declare -a deb_patches
mapfile -t deb_patches < $1
prefix="${DEB_URL}/${deb_patches[0]}"
if [[ -n "$2" ]]; then
exec 1> $2
fi
cat <<EOF
# Generated by $(basename $0) from $(basename $1)
let
prefix = "${prefix}";
in
[
EOF
for ((i=1;i < ${#deb_patches[@]}; ++i)); do
url="${prefix}/${deb_patches[$i]}"
sha256=$(nix-prefetch-url $url)
echo " {"
echo " url = \"\${prefix}/${deb_patches[$i]}\";"
echo " sha256 = \"$sha256\";"
echo " }"
done
echo "]"

View File

@@ -1,57 +0,0 @@
#!/bin/sh
attr=$1
: ${NIXPKGS=/etc/nixos/nixpkgs}
tmp=$(mktemp --tmpdir -d nixpkgs-dep-license.XXXXXX)
exitHandler() {
exitCode=$?
rm -rf "$tmp"
exit $exitCode
}
trap "exitHandler" EXIT
# fetch the trace and the drvPath of the attribute.
nix-instantiate $NIXPKGS -A $attr --show-trace > "$tmp/drvPath" 2> "$tmp/trace" || {
cat 1>&2 - "$tmp/trace" <<EOF
An error occured while evaluating $attr.
EOF
exit 1
}
# generate a sed script based on the trace output.
sed '
\,@:.*:@, {
# \1 *.drv file
# \2 License terms
s,.*@:drv:\(.*\):\(.*\):@.*,s!\1!\1: \2!; t;,
s!Str(\\\"\([^,]*\)\\\",\[\])!\1!g
b
}
d
' "$tmp/trace" > "$tmp/filter.sed"
if test $(wc -l "$tmp/filter.sed" | sed 's/ .*//') == 0; then
echo 1>&2 "
No derivation mentionned in the stack trace. Either your derivation does
not use stdenv.mkDerivation or you forgot to use the stdenv adapter named
traceDrvLicenses.
- defaultStdenv = allStdenvs.stdenv;
+ defaultStdenv = traceDrvLicenses allStdenvs.stdenv;
"
exit 1
fi
# remove all dependencies which are using stdenv.mkDerivation
echo '
d
' >> "$tmp/filter.sed"
nix-store -q --tree $(cat "$tmp/drvPath") | sed -f "$tmp/filter.sed"
exit 0;

View File

@@ -1,24 +0,0 @@
# Evaluate `release.nix' like Hydra would. Too bad nix-instantiate
# can't to do this.
with import ../../lib;
let
trace = if builtins.getEnv "VERBOSE" == "1" then builtins.trace else (x: y: y);
rel = removeAttrs (import ../../pkgs/top-level/release.nix { }) [ "tarball" "unstable" "xbursttools" ];
# Add the recurseForDerivations attribute to ensure that
# nix-instantiate recurses into nested attribute sets.
recurse = path: attrs:
if (builtins.tryEval attrs).success then
if isDerivation attrs
then
if (builtins.tryEval attrs.drvPath).success
then { inherit (attrs) name drvPath; }
else { failed = true; }
else { recurseForDerivations = true; } //
mapAttrs (n: v: let path' = path ++ [n]; in trace path' (recurse path' v)) attrs
else { };
in recurse [] rel

View File

@@ -1,45 +0,0 @@
# This expression returns a list of all fetchurl calls used by all
# packages reachable from release.nix.
with import ../.. { };
with lib;
let
root = removeAttrs (import ../../pkgs/top-level/release.nix { }) [ "tarball" "unstable" ];
uniqueUrls = map (x: x.file) (genericClosure {
startSet = map (file: { key = file.url; inherit file; }) urls;
operator = const [ ];
});
urls = map (drv: { url = head drv.urls; hash = drv.outputHash; type = drv.outputHashAlgo; }) fetchurlDependencies;
fetchurlDependencies = filter (drv: drv.outputHash or "" != "" && drv ? urls) dependencies;
dependencies = map (x: x.value) (genericClosure {
startSet = map keyDrv (derivationsIn' root);
operator = { key, value }: map keyDrv (immediateDependenciesOf value);
});
derivationsIn' = x:
if !canEval x then []
else if isDerivation x then optional (canEval x.drvPath) x
else if isList x then concatLists (map derivationsIn' x)
else if isAttrs x then concatLists (mapAttrsToList (n: v: derivationsIn' v) x)
else [ ];
keyDrv = drv: if canEval drv.drvPath then { key = drv.drvPath; value = drv; } else { };
immediateDependenciesOf = drv:
concatLists (mapAttrsToList (n: v: derivationsIn v) (removeAttrs drv ["meta" "passthru"]));
derivationsIn = x:
if !canEval x then []
else if isDerivation x then optional (canEval x.drvPath) x
else if isList x then concatLists (map derivationsIn x)
else [ ];
canEval = val: (builtins.tryEval val).success;
in uniqueUrls

View File

@@ -1,95 +0,0 @@
#!/bin/sh
GNOME_FTP="ftp.gnome.org/pub/GNOME/sources"
project=$1
if [ "$project" == "--help" ]; then
echo "Usage: $0 project [major.minor]"
exit 0
fi
baseVersion=$2
if [ -z "$project" ]; then
echo "No project specified, exiting"
exit 1
fi
# 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 -l "$1"/
}
fi
if [ -z "$baseVersion" ]; then
echo "Looking for available versions..." >&2
available_baseversions=( `ls_ftp ftp://${GNOME_FTP}/${project} | grep '[0-9]\.[0-9]' | sort -t. -k1,1n -k 2,2n` )
echo -e "The following versions are available:\n ${available_baseversions[@]}" >&2
echo -en "Choose one of them: " >&2
read baseVersion
fi
FTPDIR="${GNOME_FTP}/${project}/${baseVersion}"
#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.
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"
;;
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`
echo "Latest version is: ${version}" >&2
name=${project}-${version}
echo "Fetching .sha256 file" >&2
curl -O http://${FTPDIR}/${name}.sha256sum
extensions=( "xz" "bz2" "gz" )
echo "Choosing archive extension (known are ${extensions[@]})..." >&2
for ext in ${extensions[@]}; do
if grep "\\.tar\\.${ext}$" ${name}.sha256sum >& /dev/null; then
ext_pref=$ext
sha256=$(grep "\\.tar\\.${ext}$" ${name}.sha256sum | cut -f1 -d\ )
break
fi
done
sha256=`nix-hash --to-base32 --type sha256 $sha256`
echo "Chosen ${ext_pref}, hash is ${sha256}" >&2
cat <<EOF
name = "${project}-${version}";
src = fetchurl {
url = mirror://gnome/sources/${project}/${baseVersion}/${project}-${version}.tar.${ext_pref};
sha256 = "${sha256}";
};
EOF
rm -v ${name}.sha256sum >&2

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +0,0 @@
#! /bin/sh
# give absolute path of release.nix as argument
hydra_eval_jobs \
--argstr system x86_64-linux \
--argstr system i686-linux \
--argstr system x86_64-darwin \
--argstr system i686-cygwin \
--argstr system i686-freebsd \
--arg officialRelease false \
--arg nixpkgs "{ outPath = builtins.storePath ./. ; rev = 1234; }" \
$@

View File

@@ -1,22 +0,0 @@
#! /usr/bin/perl -w
use strict;
my %map;
open LIST1, "<$ARGV[0]" or die;
while (<LIST1>) {
/^(\S+)\s+(.*)$/;
$map{$1} = $2;
}
open LIST1, "<$ARGV[1]" or die;
while (<LIST1>) {
/^(\S+)\s+(.*)$/;
if (!defined $map{$1}) {
print STDERR "missing file: $2\n";
next;
}
print "$2\n";
print "$map{$1}\n";
}

View File

@@ -1,5 +0,0 @@
#! /bin/sh
echo "let pkgs = import /etc/nixos/nixpkgs$2 {}; x = pkgs.callPackage $1 { $3 }; in ${4:-x}" |
nix-instantiate --show-trace - |
xargs nix-store -r -K

View File

@@ -1,22 +0,0 @@
{ stdenv, makeWrapper, perl, perlPackages }:
stdenv.mkDerivation {
name = "nix-generate-from-cpan-1";
buildInputs = [ makeWrapper perl perlPackages.YAMLLibYAML perlPackages.JSON ];
unpackPhase = "true";
buildPhase = "true";
installPhase =
''
mkdir -p $out/bin
cp ${./nix-generate-from-cpan.pl} $out/bin/nix-generate-from-cpan
wrapProgram $out/bin/nix-generate-from-cpan --set PERL5LIB $PERL5LIB
'';
meta = {
maintainers = [ stdenv.lib.maintainers.eelco ];
description = "Utility to generate a Nix expression for a Perl package from CPAN";
};
}

View File

@@ -1,176 +0,0 @@
#! /run/current-system/sw/bin/perl -w
use strict;
use CPANPLUS::Backend;
use YAML::XS;
use JSON;
my $module_name = $ARGV[0];
die "syntax: $0 <MODULE-NAME>\n" unless defined $module_name;
my $cb = CPANPLUS::Backend->new;
my @modules = $cb->search(type => "name", allow => [$module_name]);
die "module $module_name not found\n" if scalar @modules == 0;
die "multiple packages that match module $module_name\n" if scalar @modules > 1;
my $module = $modules[0];
sub pkg_to_attr {
my ($pkg_name) = @_;
my $attr_name = $pkg_name;
$attr_name =~ s/-\d.*//; # strip version
return "LWP" if $attr_name eq "libwww-perl";
$attr_name =~ s/-//g;
return $attr_name;
}
sub get_pkg_name {
my ($module) = @_;
my $pkg_name = $module->package;
$pkg_name =~ s/\.tar.*//;
$pkg_name =~ s/\.zip//;
return $pkg_name;
}
my $pkg_name = get_pkg_name $module;
my $attr_name = pkg_to_attr $pkg_name;
print STDERR "attribute name: ", $attr_name, "\n";
print STDERR "module: ", $module->module, "\n";
print STDERR "version: ", $module->version, "\n";
print STDERR "package: ", $module->package, , " (", $pkg_name, ", ", $attr_name, ")\n";
print STDERR "path: ", $module->path, "\n";
my $tar_path = $module->fetch();
print STDERR "downloaded to: $tar_path\n";
print STDERR "sha-256: ", $module->status->checksum_value, "\n";
my $pkg_path = $module->extract();
print STDERR "unpacked to: $pkg_path\n";
my $meta;
if (-e "$pkg_path/META.yml") {
eval {
$meta = YAML::XS::LoadFile("$pkg_path/META.yml");
};
if ($@) {
system("iconv -f windows-1252 -t utf-8 '$pkg_path/META.yml' > '$pkg_path/META.yml.tmp'");
$meta = YAML::XS::LoadFile("$pkg_path/META.yml.tmp");
}
} elsif (-e "$pkg_path/META.json") {
local $/;
open(my $fh, '<', "$pkg_path/META.json") or die;
$meta = decode_json(<$fh>);
} else {
warn "package has no META.yml or META.json\n";
}
print STDERR "metadata: ", encode_json($meta), "\n" if defined $meta;
# Map a module to the attribute corresponding to its package
# (e.g. HTML::HeadParser will be mapped to HTMLParser, because that
# module is in the HTML-Parser package).
sub module_to_pkg {
my ($module_name) = @_;
my @modules = $cb->search(type => "name", allow => [$module_name]);
if (scalar @modules == 0) {
# Fallback.
$module_name =~ s/:://g;
return $module_name;
}
my $module = $modules[0];
my $attr_name = pkg_to_attr(get_pkg_name $module);
print STDERR "mapped dep $module_name to $attr_name\n";
return $attr_name;
}
sub get_deps {
my ($type) = @_;
my $deps;
if (defined $meta->{prereqs}) {
die "unimplemented";
} elsif ($type eq "runtime") {
$deps = $meta->{requires};
} elsif ($type eq "configure") {
$deps = $meta->{configure_requires};
} elsif ($type eq "build") {
$deps = $meta->{build_requires};
}
my @res;
foreach my $n (keys %{$deps}) {
next if $n eq "perl";
# Hacky way to figure out if this module is part of Perl.
if ($n !~ /^JSON/ && $n !~ /^YAML/) {
eval "use $n;";
if (!$@) {
print STDERR "skipping Perl-builtin module $n\n";
next;
}
}
push @res, module_to_pkg($n);
}
return @res;
}
sub uniq {
return keys %{{ map { $_ => 1 } @_ }};
}
my @build_deps = sort(uniq(get_deps("configure"), get_deps("build"), get_deps("test")));
print STDERR "build deps: @build_deps\n";
my @runtime_deps = sort(uniq(get_deps("runtime")));
print STDERR "runtime deps: @runtime_deps\n";
my $homepage = $meta->{resources}->{homepage};
print STDERR "homepage: $homepage\n" if defined $homepage;
my $description = $meta->{abstract};
if (defined $description) {
$description = uc(substr($description, 0, 1)) . substr($description, 1); # capitalise first letter
$description =~ s/\.$//; # remove period at the end
$description =~ s/\s*$//;
$description =~ s/^\s*//;
print STDERR "description: $description\n";
}
my $license = $meta->{license};
if (defined $license) {
$license = "perl5" if $license eq "perl_5";
print STDERR "license: $license\n";
}
my $build_fun = -e "$pkg_path/Build.PL" && ! -e "$pkg_path/Makefile.PL" ? "buildPerlModule" : "buildPerlPackage";
print STDERR "===\n";
print <<EOF;
$attr_name = $build_fun {
name = "$pkg_name";
src = fetchurl {
url = mirror://cpan/${\$module->path}/${\$module->package};
sha256 = "${\$module->status->checksum_value}";
};
EOF
print <<EOF if scalar @build_deps > 0;
buildInputs = [ @build_deps ];
EOF
print <<EOF if scalar @runtime_deps > 0;
propagatedBuildInputs = [ @runtime_deps ];
EOF
print <<EOF;
meta = {
EOF
print <<EOF if defined $homepage;
homepage = $homepage;
EOF
print <<EOF if defined $description;
description = "$description";
EOF
print <<EOF if defined $license;
license = "$license";
EOF
print <<EOF;
};
};
EOF

View File

@@ -1,22 +0,0 @@
{ stdenv, makeWrapper, perl, perlPackages }:
stdenv.mkDerivation {
name = "nixpkgs-lint-1";
buildInputs = [ makeWrapper perl perlPackages.XMLSimple ];
unpackPhase = "true";
buildPhase = "true";
installPhase =
''
mkdir -p $out/bin
cp ${./nixpkgs-lint.pl} $out/bin/nixpkgs-lint
wrapProgram $out/bin/nixpkgs-lint --set PERL5LIB $PERL5LIB
'';
meta = {
maintainers = [ stdenv.lib.maintainers.eelco ];
description = "A utility for Nixpkgs contributors to check Nixpkgs for common errors";
};
}

View File

@@ -1,172 +0,0 @@
#! /run/current-system/sw/bin/perl -w
use strict;
use List::Util qw(min);
use XML::Simple qw(:strict);
use Getopt::Long qw(:config gnu_getopt);
# Parse the command line.
my $path = "<nixpkgs>";
my $filter = "*";
my $maintainer;
sub showHelp {
print <<EOF;
Usage: $0 [--package=NAME] [--maintainer=REGEXP] [--file=PATH]
Check Nixpkgs for common errors/problems.
-p, --package filter packages by name (default is *)
-m, --maintainer filter packages by maintainer (case-insensitive regexp)
-f, --file path to Nixpkgs (default is <nixpkgs>)
Examples:
\$ nixpkgs-lint -f /my/nixpkgs -p firefox
\$ nixpkgs-lint -f /my/nixpkgs -m eelco
EOF
exit 0;
}
GetOptions("package|p=s" => \$filter,
"maintainer|m=s" => \$maintainer,
"file|f=s" => \$path,
"help" => sub { showHelp() }
) or exit 1;
# Evaluate Nixpkgs into an XML representation.
my $xml = `nix-env -f '$path' -qa '$filter' --xml --meta --drv-path`;
die "$0: evaluation of $path failed\n" if $? != 0;
my $info = XMLin($xml, KeyAttr => { 'item' => '+attrPath', 'meta' => 'name' }, ForceArray => 1, SuppressEmpty => '' ) or die "cannot parse XML output";
# Check meta information.
print "=== Package meta information ===\n\n";
my $nrBadNames = 0;
my $nrMissingMaintainers = 0;
my $nrMissingPlatforms = 0;
my $nrMissingDescriptions = 0;
my $nrBadDescriptions = 0;
my $nrMissingLicenses = 0;
foreach my $attr (sort keys %{$info->{item}}) {
my $pkg = $info->{item}->{$attr};
my $pkgName = $pkg->{name};
my $pkgVersion = "";
if ($pkgName =~ /(.*)(-[0-9].*)$/) {
$pkgName = $1;
$pkgVersion = $2;
}
# Check the maintainers.
my @maintainers;
my $x = $pkg->{meta}->{maintainers};
if (defined $x && $x->{type} eq "strings") {
@maintainers = map { $_->{value} } @{$x->{string}};
} elsif (defined $x->{value}) {
@maintainers = ($x->{value});
}
if (defined $maintainer && scalar(grep { $_ =~ /$maintainer/i } @maintainers) == 0) {
delete $info->{item}->{$attr};
next;
}
if (scalar @maintainers == 0) {
print "$attr: Lacks a maintainer\n";
$nrMissingMaintainers++;
}
# Check the platforms.
if (!defined $pkg->{meta}->{platforms}) {
print "$attr: Lacks a platform\n";
$nrMissingPlatforms++;
}
# Package names should not be capitalised.
if ($pkgName =~ /^[A-Z]/) {
print "$attr: package name $pkgName should not be capitalised\n";
$nrBadNames++;
}
if ($pkgVersion eq "") {
print "$attr: package has no version\n";
$nrBadNames++;
}
# Check the license.
if (!defined $pkg->{meta}->{license}) {
print "$attr: Lacks a license\n";
$nrMissingLicenses++;
}
# Check the description.
my $description = $pkg->{meta}->{description}->{value};
if (!$description) {
print "$attr: Lacks a description\n";
$nrMissingDescriptions++;
} else {
my $bad = 0;
if ($description =~ /^\s/) {
print "$attr: Description starts with whitespace\n";
$bad = 1;
}
if ($description =~ /\s$/) {
print "$attr: Description ends with whitespace\n";
$bad = 1;
}
if ($description =~ /\.$/) {
print "$attr: Description ends with a period\n";
$bad = 1;
}
if (index(lc($description), lc($attr)) != -1) {
print "$attr: Description contains package name\n";
$bad = 1;
}
$nrBadDescriptions++ if $bad;
}
}
print "\n";
# Find packages that have the same name.
print "=== Package name collisions ===\n\n";
my %pkgsByName;
foreach my $attr (sort keys %{$info->{item}}) {
my $pkg = $info->{item}->{$attr};
#print STDERR "attr = $attr, name = $pkg->{name}\n";
$pkgsByName{$pkg->{name}} //= [];
push @{$pkgsByName{$pkg->{name}}}, $pkg;
}
my $nrCollisions = 0;
foreach my $name (sort keys %pkgsByName) {
my @pkgs = @{$pkgsByName{$name}};
# Filter attributes that are aliases of each other (e.g. yield the
# same derivation path).
my %drvsSeen;
@pkgs = grep { my $x = $drvsSeen{$_->{drvPath}}; $drvsSeen{$_->{drvPath}} = 1; !defined $x } @pkgs;
# Filter packages that have a lower priority.
my $highest = min (map { $_->{meta}->{priority}->{value} // 0 } @pkgs);
@pkgs = grep { ($_->{meta}->{priority}->{value} // 0) == $highest } @pkgs;
next if scalar @pkgs == 1;
$nrCollisions++;
print "The following attributes evaluate to a package named $name:\n";
print " ", join(", ", map { $_->{attrPath} } @pkgs), "\n\n";
}
print "=== Bottom line ===\n";
print "Number of packages: ", scalar(keys %{$info->{item}}), "\n";
print "Number of bad names: $nrBadNames\n";
print "Number of missing maintainers: $nrMissingMaintainers\n";
print "Number of missing platforms: $nrMissingPlatforms\n";
print "Number of missing licenses: $nrMissingLicenses\n";
print "Number of missing descriptions: $nrMissingDescriptions\n";
print "Number of bad descriptions: $nrBadDescriptions\n";
print "Number of name collisions: $nrCollisions\n";

View File

@@ -1,84 +0,0 @@
usage() {
echo "
$0 <path to unpacked binary distribution directory>
This program return the list of libraries and where to find them based on
your currently installed programs.
";
exit 1
}
if test $# -ne 1; then
usage
fi
binaryDist=$1
hasBinaries=false
for bin in $(find $binaryDist -executable -type f) :; do
if test $bin = ":"; then
$hasBinaries || \
echo "No patchable found in this directory."
break
fi
hasBinaries=true
echo ""
echo "$bin:"
hasLibraries=false
unset interpreter
unset addRPath
for lib in $(strings $bin | grep '^\(/\|\)lib.*\.so' | sort | uniq) :; do
if test $lib = ":"; then
$hasLibraries || \
echo " This program is a script or it is statically linked."
break
fi
hasLibraries=true
echo " $lib:";
libPath=$lib
lib=$(basename $lib)
#versionLessLib=$(echo $lib | sed 's,[.][.0-9]*$,,')
libs="$(
find /nix/store/*/lib* \( -type f -or -type l \) -name $lib |
grep -v '\(bootstrap-tools\|system-path\|user-environment\|extra-utils\)'
)"
echo "$libs" |
sed 's,^/nix/store/[a-z0-9]*-\([^/]*\)/.*/\([^/]*\)$, \1 -> \2,' |
sort |
uniq;
names=$(
echo "$libs" |
sed 's,^/nix/store/[a-z0-9]*-\([^/]*\)-[.0-9]*/.*$,\1,' |
sort |
uniq;
)
if test "$names" = "glibc"; then names="stdenv.glibc"; fi
if echo $names | grep -c "gcc" &> /dev/null; then names="stdenv.gcc.gcc"; fi
if test $lib != $libPath; then
interpreter="--interpreter \${$names}/lib/$lib"
elif echo $addRPath | grep -c "$names" &> /dev/null; then
:
else
addRPath=${addRPath+$addRPath:}"\${$names}/lib"
fi
done;
$hasLibraries && \
echo "
Patchelf command:
patchelf $interpreter \\
${addRPath+--set-rpath $addRPath \\
} \$out/$bin
"
done;

View File

@@ -1,260 +0,0 @@
#!/bin/sh
usage () {
echo 1>&2 "
usage:
$0
[--git commit..commit | --git commit]
[--svn rev:rev | --svn rev]
[--path path[:path]*]
[--help]
This program is used to investigate how any changes inside your nixpkgs
repository may hurt. With these kind of information you may choose wisely
where you should commit your changes.
This program adapts it-self to your versionning system to avoid too much
effort on your Internet bandwidth. If you need to check more than one
commits / revisions, you may use the following commands:
--git remotes/trunk..master
--svn 17670:17677
Check the differences between each commit separating the first and the
last commit.
--path /etc/nixos/nixpkgs:/tmp/nixpkgs_1:/tmp/nixpkgs_2
Check the differences between multiple directories containing different
versions of nixpkgs.
All these options exist with one commit / revision argument. Such options
are used to compare your \$NIXPKGS path with the specified version.
If you omit to mention any other commit / revision, then your \$NIXPKGS path
is compared with its last update. This command is useful to test code from
a dirty repository.
"
exit 1;
}
#####################
# Process Arguments #
#####################
: ${NIXPKGS=/etc/nixos/nixpkgs/}
vcs=""
gitCommits=""
svnRevisions=""
pathLocations=""
verbose=false
argfun=""
for arg; do
if test -z "$argfun"; then
case $arg in
--git) vcs="git"; argfun="set_gitCommits";;
--svn) vcs="svn"; argfun="set_svnRevisions";;
--path) vcs="path"; argfun="set_pathLocations";;
--verbose) verbose=true;;
--help) usage;;
*) usage;;
esac
else
case $argfun in
set_*)
var=$(echo $argfun | sed 's,^set_,,')
eval $var=$arg
;;
esac
argfun=""
fi
done
if $verbose; then
set -x
else
set +x
fi
############################
# Find the repository type #
############################
if test -z "$vcs"; then
if test -x "$NIXPKGS/.git"; then
if git --git-dir="$NIXPKGS/.git" branch > /dev/null 2>&1; then
vcs="git"
gitCommits=$(git --git-dir="$NIXPKGS/.git" log -n 1 --pretty=format:%H 2> /dev/null)
fi
elif test -x "$NIXPKGS/.svn"; then
cd "$NIXPKGS"
if svn info > /dev/null 2>&1; then
vcs="svn";
svnRevisions=$(svn info | sed -n 's,Revision: ,,p')
fi
cd -
else
usage
fi
fi
###############################
# Define a storage directory. #
###############################
pkgListDir=""
exitCode=1
cleanup(){
test -e "$pkgListDir" && rm -rf "$pkgListDir"
exit $exitCode;
}
trap cleanup EXIT SIGINT SIGQUIT ERR
pkgListDir=$(mktemp --tmpdir -d rebuild-amount-XXXXXXXX)
vcsDir="$pkgListDir/.vcs"
###########################
# Versionning for Dummies #
###########################
path_init() {
if test "${pathLocations#*:}" = "$pathLocations"; then
pathLocations="$NIXPKGS:$pathLocations"
fi
pathLocations="${pathLocations}:"
}
path_getNext() {
pathLoc="${pathLocations%%:*}"
pathLocations="${pathLocations#*:}"
}
path_setPath() {
path="$pathLoc"
}
path_setName() {
name=$(echo "$pathLoc" | tr '/' '_')
}
################
# Git Commands #
################
git_init() {
git clone "$NIXPKGS/.git" "$vcsDir" > /dev/null 2>&1
if echo "gitCommits" | grep -c "\.\." > /dev/null 2>&1; then
gitCommits=$(git --git-dir="$vcsDir/.git" log --reverse --pretty=format:%H $gitCommits 2> /dev/null)
else
pathLocations="$vcsDir:$NIXPKGS"
vcs="path"
path_init
fi
}
git_getNext() {
git --git-dir="$vcsDir/.git" checkout $(echo "$gitCommits" | head -n 1) > /dev/null 2>&1
gitCommits=$(echo "$gitCommits" | sed '1 d')
}
git_setPath() {
path="$vcsDir"
}
git_setName() {
name=$(git --git-dir="$vcsDir/.git" log -n 1 --pretty=format:%H 2> /dev/null)
}
#######################
# Subversion Commands #
#######################
svn_init() {
cp -r "$NIXPKGS" "$vcsDir" > /dev/null 2>&1
if echo "svnRevisions" | grep -c ":" > /dev/null 2>&1; then
svnRevisions=$(seq ${svnRevisions%:*} ${svnRevisions#*:})
else
pathLocations="$vcsDir:$NIXPKGS"
vcs="path"
path_init
fi
}
svn_getNext() {
cd "$vcsDir"
svn checkout $(echo "$svnRevisions" | head -n 1) > /dev/null 2>&1
cd -
svnRevisions=$(echo "$svnRevisions" | sed '1 d')
}
svn_setPath() {
path="$vcsDir"
}
svn_setName() {
name=$(svn info 2> /dev/null | sed -n 's,Revision: ,,p')
}
####################
# Logical Commands #
####################
init () { ${vcs}_init; }
getNext () { ${vcs}_getNext; }
setPath () { ${vcs}_setPath; }
setName () { ${vcs}_setName; }
#####################
# Check for Rebuild #
#####################
# Generate the list of all derivations that could be build from a nixpkgs
# respository. This list of derivation hashes is compared with previous
# lists and a brief summary is produced on the output.
compareNames () {
nb=$(diff -y --suppress-common-lines --speed-large-files "$pkgListDir/$1.drvs" "$pkgListDir/$2.drvs" 2> /dev/null | wc -l)
echo "$1 -> $2: $nb"
}
echo "Please wait, this may take some minutes ..."
init
first=""
oldPrev=""
prev=""
curr=""
while true; do
getNext
setPath # set path=...
setName # set name=...
curr="$name"
test -z "$curr" && break || true
nix-instantiate "$path" > "$pkgListDir/$curr.drvs" > /dev/null 2>&1 || true
if test -n "$prev"; then
compareNames "$prev" "$curr"
else
echo "Number of package to rebuild:"
first="$curr"
fi
oldPrev="$prev"
prev="$curr"
done
if test "$first" != "$oldPrev"; then
echo "Number of package to rebuild (first -> last):"
compareNames "$first" "$curr"
fi
exitCode=0

View File

@@ -1,146 +0,0 @@
/* Tool to sort attribute sets. Primarily useful for keeping
all-packages.nix tidy.
To compile:
$ strc -i ../../maintainers/scripts/sort-attrs.str -la stratego-lib
Typical invocation:
$ sglr -m -p ~/Dev/nix/src/libexpr/nix.tbl -i all-packages.nix \
| implode-asfix --lex \
| ../../maintainers/scripts/sort-attrs \
| asfix-yield
*/
module sort-attrs
imports
libstratego-lib
libstratego-sglr
strategies
no-wsp = !appl(prod([], cf(opt(layout())), no-attrs()), [])
rules
list-sep(s): [] -> []
list-sep(s): [x | xs] -> [[x | before] | <list-sep(s)> [split | after]]
where
<split-fetch-keep(s)> xs => (before, split, after)
list-sep(s): [x | xs] -> [[x | xs]]
where
<not(split-fetch-keep(s))> xs
list-sep-end(s): xs -> [<conc> (before, [split]) | <list-sep-end(s)> after]
where
<split-fetch-keep(s)> xs => (before, split, after)
list-sep-end(s): xs -> [xs]
where
<not(split-fetch-keep(s))> xs
sort-attrs:
appl(p@prod(_, _, attrs([term(cons("Attrs"))])),
[ lit("{")
, ws1
, appl(p2@list(cf(iter-star(sort("Bind")))), attrs)
, ws2
, lit("}")
]
) ->
appl(p, [lit("{"), <no-wsp>, appl(p2, <concat> attrs'), ws2, lit("}")])
where
<debug> "found it";
<attach-wsp> [ws1 | attrs] => withWSP;
<list-sep(starts-section)> withWSP => groups;
<length; debug> groups;
<map({x', x'', x''', xs', starts, starts': \[x | xs] -> [x''' | xs']
where
<remove-section-start> x => (x', starts);
<map(regularise-empty-lines); if !starts; debug; sortable-section; debug then qsort(compare-attrs) else id end> [x' | xs] => [x'' | xs'];
<[] <+ \x -> ["\n\n\n" | x]\ > starts => starts';
<prepend-layout> (starts', x'') => x'''
\ })> groups => attrs';
<debug> "did it"
attach-wsp: [a, b | cs] -> [(a, b) | <attach-wsp> cs]
attach-wsp: [] -> []
strategies
starts-section =
?x@(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr);
<implode-string; is-substring(!"###")> cs;
!x
rules
sortable-section = ?[s]; !s; explode-string; not(fetch({x: ?x; !(x, 97); geq}))
remove-section-start:
(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr) ->
((appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs'), attr), starts)
where
!cs;
list-sep-end(?10); // separate into lines, keeping the \n
map(implode-string);
partition(where(is-substring(!"###"))) => (starts, rest);
<map(explode-string); concat> rest => cs'
regularise-empty-lines:
(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr) ->
(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs''), attr)
where
// separate into lines, keeping the \n
// last whitespace is significant, keep
<list-sep-end(?10); split-init-last> cs => (init, last);
<regularise-empty-lines'> init => cs'; // remove whitespace-only lines
<concat> [<explode-string> "\n\n", <concat> cs', last] => cs'' // add one empty line
/* Dirty hack: *do* keep the first empty line following a non-empty line. !!! order matters */
regularise-empty-lines': [] -> []
regularise-empty-lines': [x, y | xs] -> [x, y | <regularise-empty-lines'> xs]
where
<fetch-elem(not(?10 <+ ?32))> x;
<not(fetch-elem(not(?10 <+ ?32)))> y
regularise-empty-lines': [x | xs] -> [x | <regularise-empty-lines'> xs]
where <fetch-elem(not(?10 <+ ?32))> x
regularise-empty-lines': [x | xs] -> <regularise-empty-lines'> xs
where <not(fetch-elem(not(?10 <+ ?32)))> x
prepend-layout:
(text, (appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr)) ->
(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs''), attr)
where
<implode-string> cs => cs';
<conc-strings; explode-string> (<concat-strings> text, cs') => cs''
compare-attrs:
x@
( (_, appl(p1@prod(_, _, attrs([term(cons("Bind"))])), [id1 | xs1]))
, (_, appl(p2@prod(_, _, attrs([term(cons("Bind"))])), [id2 | xs2]))
)
-> x
where
<string-lt> (id1, id2)
strategies
main = io-wrap(
oncetd(sort-attrs)
)

View File

@@ -1,7 +0,0 @@
#! /bin/sh
if [[ -z "$VERBOSE" ]]; then
echo "You may set VERBOSE=1 to see debug output or to any other non-empty string to make this script completely silent"
fi
unset HOME NIXPKGS_CONFIG # Force empty config
nix-instantiate --strict --eval-only --xml --show-trace "$(dirname "$0")"/eval-release.nix 2>&1 > /dev/null

View File

@@ -1,42 +0,0 @@
#! /usr/bin/env bash
set -e
export NIX_CURL_FLAGS=-sS
if [[ $1 == nix ]]; then
echo "=== Installing Nix..."
# Install Nix
bash <(curl -sS https://nixos.org/nix/install)
source $HOME/.nix-profile/etc/profile.d/nix.sh
# Make sure we can use hydra's binary cache
sudo mkdir /etc/nix
sudo tee /etc/nix/nix.conf <<EOF >/dev/null
binary-caches = http://cache.nixos.org http://hydra.nixos.org
trusted-binary-caches = http://hydra.nixos.org
build-max-jobs = 4
EOF
# Verify evaluation
echo "=== Verifying that nixpkgs evaluates..."
nix-env -f. -qa --json >/dev/null
elif [[ $1 == nox ]]; then
echo "=== Installing nox..."
git clone -q https://github.com/madjar/nox
pip --quiet install -e nox
elif [[ $1 == build ]]; then
source $HOME/.nix-profile/etc/profile.d/nix.sh
if [[ $TRAVIS_PULL_REQUEST == false ]]; then
echo "===> Not a pull request, checking evaluation"
nix-build pkgs/top-level/release.nix -A tarball
else
echo "=== Checking PR"
# The current HEAD is the PR merged into origin/master, so we compare
# against origin/master
nox-review wip --against origin/master
fi
else
echo "$0: Unknown option $1" >&2
false
fi

View File

@@ -1,18 +0,0 @@
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,5 +0,0 @@
*** NixOS ***
NixOS is a Linux distribution based on the purely functional package
management system Nix. More information can be found at
http://nixos.org/nixos and in the manual in doc/manual.

View File

@@ -1,43 +0,0 @@
{ configuration ? import ./lib/from-env.nix "NIXOS_CONFIG" <nixos-config>
, system ? builtins.currentSystem
}:
let
eval = import ./lib/eval-config.nix {
inherit system;
modules = [ configuration ];
};
inherit (eval) pkgs;
# This is for `nixos-rebuild build-vm'.
vmConfig = (import ./lib/eval-config.nix {
inherit system;
modules = [ configuration ./modules/virtualisation/qemu-vm.nix ];
}).config;
# This is for `nixos-rebuild build-vm-with-bootloader'.
vmWithBootLoaderConfig = (import ./lib/eval-config.nix {
inherit system;
modules =
[ configuration
./modules/virtualisation/qemu-vm.nix
{ virtualisation.useBootLoader = true; }
];
}).config;
in
{
inherit (eval) config options;
system = eval.config.system.build.toplevel;
vm = vmConfig.system.build.vm;
vmWithBootLoader = vmWithBootLoaderConfig.system.build.vm;
# The following are used by nixos-rebuild.
nixFallback = pkgs.nixUnstable;
}

View File

@@ -1,21 +0,0 @@
{
boot = {
loader.grub.device = "/dev/sda";
};
fileSystems = [
{ mountPoint = "/";
device = "/dev/sda1";
}
];
swapDevices = [
{ device = "/dev/sdb1"; }
];
services = {
openssh = {
enable = true;
};
};
}

View File

@@ -1,32 +0,0 @@
{
boot = {
loader.grub.device = "/dev/sda";
copyKernels = true;
bootMount = "(hd0,0)";
};
fileSystems = [
{ mountPoint = "/";
device = "/dev/sda3";
}
{ mountPoint = "/boot";
device = "/dev/sda1";
neededForBoot = true;
}
];
swapDevices = [
{ device = "/dev/sda2"; }
];
services = {
sshd = {
enable = true;
};
};
fonts = {
enableFontConfig = false;
};
}

View File

@@ -1,27 +0,0 @@
# This configuration has / on a LVM volume. Since Grub
# doesn't know about LVM, a separate /boot is therefore
# needed.
#
# In this example, labels are used for file systems and
# swap devices: "boot" might be /dev/sda1, "root" might be
# /dev/my-volume-group/root, and "swap" might be /dev/sda2.
# In particular there is no specific reference to the fact
# that / is on LVM; that's figured out automatically.
{
boot.loader.grub.device = "/dev/sda";
boot.initrd.kernelModules = ["ata_piix"];
fileSystems = [
{ mountPoint = "/";
label = "root";
}
{ mountPoint = "/boot";
label = "boot";
}
];
swapDevices = [
{ label = "swap"; }
];
}

View File

@@ -1,36 +0,0 @@
{
boot = {
loader.grub.device = "/dev/sda";
};
fileSystems = [
{ mountPoint = "/";
device = "/dev/sda1";
}
];
services = {
sshd = {
enable = true;
};
httpd = {
enable = true;
adminAddr = "admin@example.org";
subservices = {
subversion = {
enable = true;
dataDir = "/data/subversion";
notificationSender = "svn@example.org";
};
};
};
};
}

View File

@@ -1,20 +0,0 @@
# Configuration file used to install NixOS-x86_64 on a USB stick.
{
boot = {
loader.grub.device = "/dev/sda";
initrd = {
kernelModules = ["usb_storage" "ehci_hcd" "ohci_hcd"];
};
};
fileSystems = [
{ mountPoint = "/";
label = "nixos-usb";
}
];
fonts = {
enableFontConfig = false;
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,242 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="ch-containers">
<title>Containers</title>
<para>NixOS allows you to easily run other NixOS instances as
<emphasis>containers</emphasis>. Containers are a light-weight
approach to virtualisation that runs software in the container at the
same speed as in the host system. NixOS containers share the Nix store
of the host, making container creation very efficient.</para>
<warning><para>Currently, NixOS containers are not perfectly isolated
from the host system. This means that a user with root access to the
container can do things that affect the host. So you should not give
container root access to untrusted users.</para></warning>
<para>NixOS containers can be created in two ways: imperatively, using
the command <command>nixos-container</command>, and declaratively, by
specifying them in your <filename>configuration.nix</filename>. The
declarative approach implies that containers get upgraded along with
your host system when you run <command>nixos-rebuild</command>, which
is often not what you want. By contrast, in the imperative approach,
containers are configured and updated independently from the host
system.</para>
<section><title>Imperative container management</title>
<para>Well cover imperative container management using
<command>nixos-container</command> first. You create a container with
identifier <literal>foo</literal> as follows:
<screen>
$ nixos-container create foo
</screen>
This creates the containers root directory in
<filename>/var/lib/containers/foo</filename> and a small configuration
file in <filename>/etc/containers/foo.conf</filename>. It also builds
the containers initial system configuration and stores it in
<filename>/nix/var/nix/profiles/per-container/foo/system</filename>. You
can modify the initial configuration of the container on the command
line. For instance, to create a container that has
<command>sshd</command> running, with the given public key for
<literal>root</literal>:
<screen>
$ nixos-container create foo --config 'services.openssh.enable = true; \
users.extraUsers.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];'
</screen>
</para>
<para>Creating a container does not start it. To start the container,
run:
<screen>
$ nixos-container start foo
</screen>
This command will return as soon as the container has booted and has
reached <literal>multi-user.target</literal>. On the host, the
container runs within a systemd unit called
<literal>container@<replaceable>container-name</replaceable>.service</literal>.
Thus, if something went wrong, you can get status info using
<command>systemctl</command>:
<screen>
$ systemctl status container@foo
</screen>
</para>
<para>If the container has started succesfully, you can log in as
root using the <command>root-login</command> operation:
<screen>
$ nixos-container root-login foo
[root@foo:~]#
</screen>
Note that only root on the host can do this (since there is no
authentication). You can also get a regular login prompt using the
<command>login</command> operation, which is available to all users on
the host:
<screen>
$ nixos-container login foo
foo login: alice
Password: ***
</screen>
With <command>nixos-container run</command>, you can execute arbitrary
commands in the container:
<screen>
$ nixos-container run foo -- uname -a
Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
</screen>
</para>
<para>There are several ways to change the configuration of the
container. First, on the host, you can edit
<literal>/var/lib/container/<replaceable>name</replaceable>/etc/nixos/configuration.nix</literal>,
and run
<screen>
$ nixos-container update foo
</screen>
This will build and activate the new configuration. You can also
specify a new configuration on the command line:
<screen>
$ nixos-container update foo --config 'services.httpd.enable = true; \
services.httpd.adminAddr = "foo@example.org";'
$ curl http://$(nixos-container show-ip foo)/
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
</screen>
However, note that this will overwrite the containers
<filename>/etc/nixos/configuration.nix</filename>.</para>
<para>Alternatively, you can change the configuration from within the
container itself by running <command>nixos-rebuild switch</command>
inside the container. Note that the container by default does not have
a copy of the NixOS channel, so you should run <command>nix-channel
--update</command> first.</para>
<para>Containers can be stopped and started using
<literal>nixos-container stop</literal> and <literal>nixos-container
start</literal>, respectively, or by using
<command>systemctl</command> on the containers service unit. To
destroy a container, including its file system, do
<screen>
$ nixos-container destroy foo
</screen>
</para>
</section>
<section><title>Declarative container specification</title>
<para>You can also specify containers and their configuration in the
hosts <filename>configuration.nix</filename>. For example, the
following specifies that there shall be a container named
<literal>database</literal> running PostgreSQL:
<programlisting>
containers.database =
{ config =
{ config, pkgs, ... }:
{ services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql92;
};
};
</programlisting>
If you run <literal>nixos-rebuild switch</literal>, the container will
be built and started. If the container was already running, it will be
updated in place, without rebooting.</para>
<para>By default, declarative containers share the network namespace
of the host, meaning that they can listen on (privileged)
ports. However, they cannot change the network configuration. You can
give a container its own network as follows:
<programlisting>
containers.database =
{ privateNetwork = true;
hostAddress = "192.168.100.10";
localAddress = "192.168.100.11";
};
</programlisting>
This gives the container a private virtual Ethernet interface with IP
address <literal>192.168.100.11</literal>, which is hooked up to a
virtual Ethernet interface on the host with IP address
<literal>192.168.100.10</literal>. (See the next section for details
on container networking.)</para>
<para>To disable the container, just remove it from
<filename>configuration.nix</filename> and run <literal>nixos-rebuild
switch</literal>. Note that this will not delete the root directory of
the container in <literal>/var/lib/containers</literal>.</para>
</section>
<section><title>Networking</title>
<para>When you create a container using <literal>nixos-container
create</literal>, it gets it own private IPv4 address in the range
<literal>10.233.0.0/16</literal>. You can get the containers IPv4
address as follows:
<screen>
$ nixos-container show-ip foo
10.233.4.2
$ ping -c1 10.233.4.2
64 bytes from 10.233.4.2: icmp_seq=1 ttl=64 time=0.106 ms
</screen>
</para>
<para>Networking is implemented using a pair of virtual Ethernet
devices. The network interface in the container is called
<literal>eth0</literal>, while the matching interface in the host is
called <literal>c-<replaceable>container-name</replaceable></literal>
(e.g., <literal>c-foo</literal>). The container has its own network
namespace and the <literal>CAP_NET_ADMIN</literal> capability, so it
can perform arbitrary network configuration such as setting up
firewall rules, without affecting or having access to the hosts
network.</para>
<para>By default, containers cannot talk to the outside network. If
you want that, you should set up Network Address Translation (NAT)
rules on the host to rewrite container traffic to use your external
IP address. This can be accomplished using the following configuration
on the host:
<programlisting>
networking.nat.enable = true;
networking.nat.internalInterfaces = ["c-+"];
networking.nat.externalInterface = "eth0";
</programlisting>
where <literal>eth0</literal> should be replaced with the desired
external interface. Note that <literal>c-+</literal> is a wildcard
that matches all container interfaces.</para>
</section>
</chapter>

View File

@@ -1,146 +0,0 @@
{ pkgs, options, version, revision }:
with pkgs.lib;
let
# Remove invisible and internal options.
optionsList = filter (opt: opt.visible && !opt.internal) (optionAttrSetToDocList options);
# Replace functions by the string <function>
substFunction = x:
if builtins.isAttrs x then mapAttrs (name: substFunction) x
else if builtins.isList x then map substFunction x
else if builtins.isFunction x then "<function>"
else x;
# Clean up declaration sites to not refer to the NixOS source tree.
optionsList' = flip map optionsList (opt: opt // {
declarations = map (fn: stripPrefix fn) opt.declarations;
}
// optionalAttrs (opt ? example) { example = substFunction opt.example; }
// optionalAttrs (opt ? default) { default = substFunction opt.default; });
prefix = toString ../../..;
stripPrefix = fn:
if substring 0 (stringLength prefix) fn == prefix then
substring (stringLength prefix + 1) 1000 fn
else
fn;
optionsXML = builtins.toFile "options.xml" (builtins.unsafeDiscardStringContext (builtins.toXML optionsList'));
optionsDocBook = pkgs.runCommand "options-db.xml" {} ''
if grep /nixpkgs/nixos/modules ${optionsXML}; then
echo "The manual appears to depend on the location of Nixpkgs, which is bad"
echo "since this prevents sharing via the NixOS channel. This is typically"
echo "caused by an option default that refers to a relative path (see above"
echo "for hints about the offending path)."
exit 1
fi
${pkgs.libxslt}/bin/xsltproc \
--stringparam revision '${revision}' \
-o $out ${./options-to-docbook.xsl} ${optionsXML}
'';
in rec {
# The NixOS options in JSON format.
optionsJSON = pkgs.stdenv.mkDerivation {
name = "options-json";
buildCommand = ''
# Export list of options in different format.
dst=$out/share/doc/nixos
mkdir -p $dst
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
(listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList'))))
} $dst/options.json
mkdir -p $out/nix-support
echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
''; # */
meta.description = "List of NixOS options in JSON format";
};
# Generate the NixOS manual.
manual = pkgs.stdenv.mkDerivation {
name = "nixos-manual";
sources = sourceFilesBySuffices ./. [".xml"];
buildInputs = [ pkgs.libxml2 pkgs.libxslt ];
xsltFlags = ''
--param section.autolabel 1
--param section.label.includes.component.label 1
--param html.stylesheet 'style.css'
--param xref.with.number.and.title 1
--param toc.section.depth 3
--param admon.style '''
--param callout.graphics.extension '.gif'
'';
buildCommand = ''
ln -s $sources/*.xml . # */
ln -s ${optionsDocBook} options-db.xml
echo "${version}" > version
# Check the validity of the manual sources.
xmllint --noout --nonet --xinclude --noxincludenode \
--relaxng ${pkgs.docbook5}/xml/rng/docbook/docbook.rng \
manual.xml
# Generate the HTML manual.
dst=$out/share/doc/nixos
ensureDir $dst
xsltproc $xsltFlags --nonet --xinclude \
--output $dst/manual.html \
${pkgs.docbook5_xsl}/xml/xsl/docbook/xhtml/docbook.xsl \
./manual.xml
mkdir -p $dst/images/callouts
cp ${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
cp ${./style.css} $dst/style.css
mkdir -p $out/nix-support
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
echo "doc manual $dst manual.html" >> $out/nix-support/hydra-build-products
''; # */
meta.description = "The NixOS manual in HTML format";
};
# Generate the NixOS manpages.
manpages = pkgs.stdenv.mkDerivation {
name = "nixos-manpages";
sources = sourceFilesBySuffices ./. [".xml"];
buildInputs = [ pkgs.libxml2 pkgs.libxslt ];
buildCommand = ''
ln -s $sources/*.xml . # */
ln -s ${optionsDocBook} options-db.xml
# Check the validity of the manual sources.
xmllint --noout --nonet --xinclude --noxincludenode \
--relaxng ${pkgs.docbook5}/xml/rng/docbook/docbook.rng \
./man-pages.xml
# Generate manpages.
mkdir -p $out/share/man
xsltproc --nonet --xinclude \
--param man.output.in.separate.dir 1 \
--param man.output.base.dir "'$out/share/man/'" \
--param man.endnotes.are.numbered 0 \
${pkgs.docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
./man-pages.xml
'';
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,549 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="ch-installation">
<title>Installing NixOS</title>
<!--===============================================================-->
<section xml:id="sec-obtaining">
<title>Obtaining NixOS</title>
<para>NixOS ISO images can be downloaded from the <link
xlink:href="http://nixos.org/nixos/download.html">NixOS
homepage</link>. These can be burned onto a CD. It is also possible
to copy them onto a USB stick and install NixOS from there. For
details, see the <link
xlink:href="https://nixos.org/wiki/Installing_NixOS_from_a_USB_stick">NixOS
Wiki</link>.</para>
<para>As an alternative to installing NixOS yourself, you can get a
running NixOS system through several other means:
<itemizedlist>
<listitem>
<para>Using virtual appliances in Open Virtualization Format (OVF)
that can be imported into VirtualBox. These are available from
the <link xlink:href="http://nixos.org/nixos/download.html">NixOS
homepage</link>.</para>
</listitem>
<listitem>
<para>Using AMIs for Amazons EC2. To find one for your region
and instance type, please refer to the <link
xlink:href="https://github.com/NixOS/nixops/blob/master/nix/ec2-amis.nix">list
of most recent AMIs</link>.</para>
</listitem>
<listitem>
<para>Using NixOps, the NixOS-based cloud deployment tool, which
allows you to provision VirtualBox and EC2 NixOS instances from
declarative specifications. Check out the <link
xlink:href="https://github.com/NixOS/nixops">NixOps
homepage</link> for details.</para>
</listitem>
</itemizedlist>
</para>
</section>
<!--===============================================================-->
<section xml:id="sec-installation">
<title>Installation</title>
<orderedlist>
<listitem><para>Boot from the CD.</para></listitem>
<listitem><para>The CD contains a basic NixOS installation. (It
also contains Memtest86+, useful if you want to test new hardware.)
When its finished booting, it should have detected most of your
hardware and brought up networking (check
<command>ifconfig</command>). Networking is necessary for the
installer, since it will download lots of stuff (such as source
tarballs or Nixpkgs channel binaries). Its best if you have a DHCP
server on your network. Otherwise configure networking manually
using <command>ifconfig</command>.</para></listitem>
<listitem><para>The NixOS manual is available on virtual console 8
(press Alt+F8 to access).</para></listitem>
<listitem><para>Login as <literal>root</literal> and the empty
password.</para></listitem>
<listitem><para>If you downloaded the graphical ISO image, you can
run <command>start display-manager</command> to start KDE.</para></listitem>
<listitem><para>The NixOS installer doesnt do any partitioning or
formatting yet, so you need to that yourself. Use the following
commands:
<itemizedlist>
<listitem><para>For partitioning:
<command>fdisk</command>.</para></listitem>
<listitem><para>For initialising Ext4 partitions:
<command>mkfs.ext4</command>. It is recommended that you assign a
unique symbolic label to the file system using the option
<option>-L <replaceable>label</replaceable></option>, since this
makes the file system configuration independent from device
changes. For example:
<screen>
$ mkfs.ext4 -L nixos /dev/sda1</screen>
</para></listitem>
<listitem><para>For creating swap partitions:
<command>mkswap</command>. Again its recommended to assign a
label to the swap partition: <option>-L
<replaceable>label</replaceable></option>.</para></listitem>
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
<screen>
$ pvcreate /dev/sda1 /dev/sdb1
$ vgcreate MyVolGroup /dev/sda1 /dev/sdb1
$ lvcreate --size 2G --name bigdisk MyVolGroup
$ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
</para></listitem>
<listitem><para>For creating software RAID devices, use
<command>mdadm</command>.</para></listitem>
</itemizedlist>
</para></listitem>
<listitem><para>Mount the target file system on which NixOS should
be installed on <filename>/mnt</filename>, e.g.
<screen>
$ mount /dev/disk/by-label/nixos /mnt
</screen>
</para></listitem>
<listitem><para>If your machine has a limited amount of memory, you
may want to activate swap devices now (<command>swapon
<replaceable>device</replaceable></command>). The installer (or
rather, the build actions that it may spawn) may need quite a bit of
RAM, depending on your configuration.</para></listitem>
<listitem>
<para>You now need to create a file
<filename>/mnt/etc/nixos/configuration.nix</filename> that
specifies the intended configuration of the system. This is
because NixOS has a <emphasis>declarative</emphasis> configuration
model: you create or edit a description of the desired
configuration of your system, and then NixOS takes care of making
it happen. The syntax of the NixOS configuration file is
described in <xref linkend="sec-configuration-syntax"/>, while a
list of available configuration options appears in <xref
linkend="ch-options"/>. A minimal example is shown in <xref
linkend="ex-config"/>.</para>
<para>The command <command>nixos-generate-config</command> can
generate an initial configuration file for you:
<screen>
$ nixos-generate-config --root /mnt</screen>
You should then edit
<filename>/mnt/etc/nixos/configuration.nix</filename> to suit your
needs:
<screen>
$ nano /mnt/etc/nixos/configuration.nix
</screen>
The <command>vim</command> text editor is also available.</para>
<para>You <emphasis>must</emphasis> set the option
<option>boot.loader.grub.device</option> to specify on which disk
the GRUB boot loader is to be installed. Without it, NixOS cannot
boot.</para>
<para>Another critical option is <option>fileSystems</option>,
specifying the file systems that need to be mounted by NixOS.
However, you typically dont need to set it yourself, because
<command>nixos-generate-config</command> sets it automatically in
<filename>/mnt/etc/nixos/hardware-configuration.nix</filename>
from your currently mounted file systems. (The configuration file
<filename>hardware-configuration.nix</filename> is included from
<filename>configuration.nix</filename> and will be overwritten by
future invocations of <command>nixos-generate-config</command>;
thus, you generally should not modify it.)</para>
<note><para>Depending on your hardware configuration or type of
file system, you may need to set the option
<option>boot.initrd.kernelModules</option> to include the kernel
modules that are necessary for mounting the root file system,
otherwise the installed system will not be able to boot. (If this
happens, boot from the CD again, mount the target file system on
<filename>/mnt</filename>, fix
<filename>/mnt/etc/nixos/configuration.nix</filename> and rerun
<filename>nixos-install</filename>.) In most cases,
<command>nixos-generate-config</command> will figure out the
required modules.</para></note>
<para>Examples of real-world NixOS configuration files can be
found at <link
xlink:href="https://nixos.org/repos/nix/configurations/trunk/"/>.</para>
</listitem>
<listitem><para>Do the installation:
<screen>
$ nixos-install</screen>
Cross fingers. If this fails due to a temporary problem (such as
a network issue while downloading binaries from the NixOS binary
cache), you can just re-run <command>nixos-install</command>.
Otherwise, fix your <filename>configuration.nix</filename> and
then re-run <command>nixos-install</command>.</para></listitem>
<listitem><para>If everything went well:
<screen>
$ reboot</screen>
</para></listitem>
<listitem>
<para>You should now be able to boot into the installed NixOS.
The GRUB boot menu shows a list of <emphasis>available
configurations</emphasis> (initially just one). Every time you
change the NixOS configuration (see <xref
linkend="sec-changing-config" />), a new item appears in the menu.
This allows you to easily roll back to another configuration if
something goes wrong.</para>
<para>You should log in and change the <literal>root</literal>
password with <command>passwd</command>.</para>
<para>Youll probably want to create some user accounts as well,
which can be done with <command>useradd</command>:
<screen>
$ useradd -c 'Eelco Dolstra' -m eelco
$ passwd eelco</screen>
</para>
<para>You may also want to install some software. For instance,
<screen>
$ nix-env -qa \*</screen>
shows what packages are available, and
<screen>
$ nix-env -i w3m</screen>
install the <literal>w3m</literal> browser.</para>
</listitem>
</orderedlist>
<para>To summarise, <xref linkend="ex-install-sequence" /> shows a
typical sequence of commands for installing NixOS on an empty hard
drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
/> shows a corresponding configuration Nix expression.</para>
<example xml:id='ex-install-sequence'><title>Commands for installing NixOS on <filename>/dev/sda</filename></title>
<screen>
$ fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
$ mkfs.ext4 -L nixos /dev/sda1
$ mkswap -L swap /dev/sda2
$ swapon /dev/sda2
$ mount /dev/disk/by-label/nixos /mnt
$ nixos-generate-config --root /mnt
$ nano /mnt/etc/nixos/configuration.nix
$ nixos-install
$ reboot</screen>
</example>
<example xml:id='ex-config'><title>NixOS configuration</title>
<screen>
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
boot.loader.grub.device = "/dev/sda";
# Note: setting fileSystems is generally not
# necessary, since nixos-generate-config figures them out
# automatically in hardware-configuration.nix.
#fileSystems."/".device = "/dev/disk/by-label/nixos";
# Enable the OpenSSH server.
services.sshd.enable = true;
}</screen>
</example>
<section 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).</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>You must set <option>boot.loader.gummiboot.enable</option> to
<literal>true</literal>. <command>nixos-generate-config</command>
should do this automatically for new configurations when booted in
UEFI mode.</para>
</listitem>
<listitem>
<para>You may want to look at the options starting with
<option>boot.loader.efi</option> and <option>boot.loader.gummiboot</option>
as well.</para>
</listitem>
<listitem>
<para>To see console messages during early boot, add <literal>"fbcon"</literal>
to your <option>boot.initrd.kernelModules</option>.</para>
</listitem>
</itemizedlist>
</para>
</section>
<section>
<title xml:id="sec-booting-from-usb">Booting from a USB stick</title>
<para>For systems withoua CD drive, the NixOS livecd can be booted from
a usb stick. For non-UEFI installations,
<link xlink:href="http://unetbootin.sourceforge.net/">unetbootin</link>
will work. For UEFI installations, you should mount the ISO, copy its contents
verbatim to your drive, then either:
<itemizedlist>
<listitem>
<para>Change the label of the disk partition to the label of the ISO
(visible with the blkid command), or</para>
</listitem>
<listitem>
<para>Edit <filename>loader/entries/nixos-livecd.conf</filename> on the drive
and change the <literal>root=</literal> field in the <literal>options</literal>
line to point to your drive (see the documentation on <literal>root=</literal>
in <link xlink:href="https://www.kernel.org/doc/Documentation/kernel-parameters.txt">
the kernel documentation</link> for more details).</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<!--===============================================================-->
<section xml:id="sec-changing-config">
<title>Changing the configuration</title>
<para>The file <filename>/etc/nixos/configuration.nix</filename>
contains the current configuration of your machine. Whenever youve
changed something to that file, you should do
<screen>
$ nixos-rebuild switch</screen>
to build the new configuration, make it the default configuration for
booting, and try to realise the configuration in the running system
(e.g., by restarting system services).</para>
<warning><para>These commands must be executed as root, so you should
either run them from a root shell or by prefixing them with
<literal>sudo -i</literal>.</para></warning>
<para>You can also do
<screen>
$ nixos-rebuild test</screen>
to build the configuration and switch the running system to it, but
without making it the boot default. So if (say) the configuration
locks up your machine, you can just reboot to get back to a working
configuration.</para>
<para>There is also
<screen>
$ nixos-rebuild boot</screen>
to build the configuration and make it the boot default, but not
switch to it now (so it will only take effect after the next
reboot).</para>
<para>You can make your configuration show up in a different submenu
of the GRUB 2 boot screen by giving it a different <emphasis>profile
name</emphasis>, e.g.
<screen>
$ nixos-rebuild switch -p test </screen>
which causes the new configuration (and previous ones created using
<literal>-p test</literal>) to show up in the GRUB submenu “NixOS -
Profile 'test'”. This can be useful to separate test configurations
from “stable” configurations.</para>
<para>Finally, you can do
<screen>
$ nixos-rebuild build</screen>
to build the configuration but nothing more. This is useful to see
whether everything compiles cleanly.</para>
<para>If you have a machine that supports hardware virtualisation, you
can also test the new configuration in a sandbox by building and
running a QEMU <emphasis>virtual machine</emphasis> that contains the
desired configuration. Just do
<screen>
$ nixos-rebuild build-vm
$ ./result/bin/run-*-vm
</screen>
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
forward ports on the host to the guest. For instance, the following
will forward host port 2222 to guest port 22 (SSH):
<screen>
$ QEMU_NET_OPTS="hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
</screen>
allowing you to log in via SSH (assuming you have set the appropriate
passwords or SSH authorized keys):
<screen>
$ ssh -p 2222 localhost
</screen>
</para>
</section>
<!--===============================================================-->
<section xml:id="sec-upgrading">
<title>Upgrading NixOS</title>
<para>The best way to keep your NixOS installation up to date is to
use one of the NixOS <emphasis>channels</emphasis>. A channel is a
Nix mechanism for distributing Nix expressions and associated
binaries. The NixOS channels are updated automatically from NixOSs
Git repository after certain tests have passed and all packages have
been built. These channels are:
<itemizedlist>
<listitem>
<para>Stable channels, such as <literal
xlink:href="http://nixos.org/channels/nixos-14.04">nixos-14.04</literal>.
These only get conservative bug fixes and package upgrades. For
instance, a channel update may cause the Linux kernel on your
system to be upgraded from 3.4.66 to 3.4.67 (a minor bug fix), but
not from 3.4.<replaceable>x</replaceable> to
3.11.<replaceable>x</replaceable> (a major change that has the
potential to break things). Stable channels are generally
maintained until the next stable branch is created.</para>
</listitem>
<listitem>
<para>The unstable channel, <literal
xlink:href="http://nixos.org/channels/nixos-unstable">nixos-unstable</literal>.
This corresponds to NixOSs main development branch, and may thus
see radical changes between channel updates. Its not recommended
for production systems.</para>
</listitem>
</itemizedlist>
To see what channels are available, go to <link
xlink:href="http://nixos.org/channels"/>. (Note that the URIs of the
various channels redirect to a directory that contains the channels
latest version and includes ISO images and VirtualBox
appliances.)</para>
<para>When you first install NixOS, youre automatically subscribed to
the NixOS channel that corresponds to your installation source. For
instance, if you installed from a 14.04 ISO, you will be subscribed to
the <literal>nixos-14.04</literal> channel. To see which NixOS
channel youre subscribed to, run the following as root:
<screen>
$ nix-channel --list | grep nixos
nixos https://nixos.org/channels/nixos-unstable
</screen>
To switch to a different NixOS channel, do
<screen>
$ nix-channel --add http://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
</screen>
(Be sure to include the <literal>nixos</literal> parameter at the
end.) For instance, to use the NixOS 14.04 stable channel:
<screen>
$ nix-channel --add http://nixos.org/channels/nixos-14.04 nixos
</screen>
But it you want to live on the bleeding edge:
<screen>
$ nix-channel --add http://nixos.org/channels/nixos-unstable nixos
</screen>
</para>
<para>You can then upgrade NixOS to the latest version in your chosen
channel by running
<screen>
$ nixos-rebuild switch --upgrade
</screen>
which is equivalent to the more verbose <literal>nix-channel --update
nixos; nixos-rebuild switch</literal>.</para>
<warning><para>It is generally safe to switch back and forth between
channels. The only exception is that a newer NixOS may also have a
newer Nix version, which may involve an upgrade of Nixs database
schema. This cannot be undone easily, so in that case you will not be
able to go back to your original channel.</para></warning>
</section>
</chapter>

View File

@@ -1,38 +0,0 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><filename>configuration.nix</filename></refentrytitle>
<manvolnum>5</manvolnum>
<refmiscinfo class="source">NixOS</refmiscinfo>
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
</refmeta>
<refnamediv>
<refname><filename>configuration.nix</filename></refname>
<refpurpose>NixOS system configuration specification</refpurpose>
</refnamediv>
<refsection><title>Description</title>
<para>The file <filename>/etc/nixos/configuration.nix</filename>
contains the declarative specification of your NixOS system
configuration. The command <command>nixos-rebuild</command> takes
this file and realises the system configuration specified
therein.</para>
</refsection>
<refsection><title>Options</title>
<para>You can use the following options in
<filename>configuration.nix</filename>.</para>
<xi:include href="options-db.xml" />
</refsection>
</refentry>

View File

@@ -1,110 +0,0 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>nixos-build-vms</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-build-vms</command></refname>
<refpurpose>build a network of virtual machines from a network of NixOS configurations</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-build-vms</command>
<arg><option>--show-trace</option></arg>
<arg><option>--no-out-link</option></arg>
<arg><option>--help</option></arg>
<arg choice="plain"><replaceable>network.nix</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>This command builds a network of QEMU-KVM virtual machines of a Nix expression
specifying a network of NixOS machines. The virtual network can be started by
executing the <filename>bin/run-vms</filename> shell script that is generated by
this command. By default, a <filename>result</filename> symlink is produced that
points to the generated virtual network.
</para>
<para>A network Nix expression has the following structure:
<screen>
{
test1 = {pkgs, config, ...}:
{
services.openssh.enable = true;
nixpkgs.system = "i686-linux";
deployment.targetHost = "test1.example.net";
# Other NixOS options
};
test2 = {pkgs, config, ...}:
{
services.openssh.enable = true;
services.httpd.enable = true;
environment.systemPackages = [ pkgs.lynx ];
nixpkgs.system = "x86_64-linux";
deployment.targetHost = "test2.example.net";
# Other NixOS options
};
}
</screen>
Each attribute in the expression represents a machine in the network
(e.g. <varname>test1</varname> and <varname>test2</varname>)
referring to a function defining a NixOS configuration.
In each NixOS configuration, two attributes have a special meaning.
The <varname>deployment.targetHost</varname> specifies the address
(domain name or IP address)
of the system which is used by <command>ssh</command> to perform
remote deployment operations. The <varname>nixpkgs.system</varname>
attribute can be used to specify an architecture for the target machine,
such as <varname>i686-linux</varname> which builds a 32-bit NixOS
configuration. Omitting this property will build the configuration
for the same architecture as the host system.
</para>
</refsection>
<refsection><title>Options</title>
<para>This command accepts the following options:</para>
<variablelist>
<varlistentry>
<term><option>--show-trace</option></term>
<listitem>
<para>Shows a trace of the output.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--no-out-link</option></term>
<listitem>
<para>Do not create a 'result' symlink.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-h</option>, <option>--help</option></term>
<listitem>
<para>Shows the usage of this command to the user.</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
</refentry>

View File

@@ -1,208 +0,0 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>nixos-generate-config</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-generate-config</command></refname>
<refpurpose>generate NixOS configuration modules</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-generate-config</command>
<arg><option>--force</option></arg>
<arg>
<arg choice='plain'><option>--root</option></arg>
<replaceable>root</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--dir</option></arg>
<replaceable>dir</replaceable>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>This command writes two NixOS configuration modules:
<variablelist>
<varlistentry>
<term><option>/etc/nixos/hardware-configuration.nix</option></term>
<listitem>
<para>This module sets NixOS configuration options based on your
current hardware configuration. In particular, it sets the
<option>fileSystem</option> option to reflect all currently
mounted file systems, the <option>swapDevices</option> option to
reflect active swap devices, and the
<option>boot.initrd.*</option> options to ensure that the
initial ramdisk contains any kernel modules necessary for
mounting the root file system.</para>
<para>If this file already exists, it is overwritten. Thus, you
should not modify it manually. Rather, you should include it
from your <filename>/etc/nixos/configuration.nix</filename>, and
re-run <command>nixos-generate-config</command> to update it
whenever your hardware configuration changes.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>/etc/nixos/configuration.nix</option></term>
<listitem>
<para>This is the main NixOS system configuration module. If it
already exists, its left unchanged. Otherwise,
<command>nixos-generate-config</command> will write a template
for you to customise.</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsection>
<refsection><title>Options</title>
<para>This command accepts the following options:</para>
<variablelist>
<varlistentry>
<term><option>--root</option></term>
<listitem>
<para>If this option is given, treat the directory
<replaceable>root</replaceable> as the root of the file system.
This means that configuration files will be written to
<filename><replaceable>root</replaceable>/etc/nixos</filename>,
and that any file systems outside of
<replaceable>root</replaceable> are ignored for the purpose of
generating the <option>fileSystems</option> option.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--dir</option></term>
<listitem>
<para>If this option is given, write the configuration files to
the directory <replaceable>dir</replaceable> instead of
<filename>/etc/nixos</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--force</option></term>
<listitem>
<para>Overwrite
<filename>/etc/nixos/configuration.nix</filename> if it already
exists.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--no-filesystems</option></term>
<listitem>
<para>Omit everything concerning file system information
(which includes swap devices) from the hardware configuration.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--show-hardware-config</option></term>
<listitem>
<para>Don't generate <filename>configuration.nix</filename> or
<filename>hardware-configuration.nix</filename> and print the
hardware configuration to stdout only.</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Examples</title>
<para>This command is typically used during NixOS installation to
write initial configuration modules. For example, if you created and
mounted the target file systems on <filename>/mnt</filename> and
<filename>/mnt/boot</filename>, you would run:
<screen>
$ nixos-generate-config --root /mnt
</screen>
The resulting file
<filename>/mnt/etc/nixos/hardware-configuration.nix</filename> might
look like this:
<programlisting>
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, pkgs, ... }:
{
imports =
[ &lt;nixos/modules/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [ "ehci_hcd" "ahci" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-label/nixos";
fsType = "ext3";
options = "rw,data=ordered,relatime";
};
fileSystems."/boot" =
{ device = "/dev/sda1";
fsType = "ext3";
options = "rw,errors=continue,user_xattr,acl,barrier=1,data=writeback,relatime";
};
swapDevices =
[ { device = "/dev/sda2"; }
];
nix.maxJobs = 8;
}
</programlisting>
It will also create a basic
<filename>/mnt/etc/nixos/configuration.nix</filename>, which you
should edit to customise the logical configuration of your system.
This file includes the result of the hardware scan as follows:
<programlisting>
imports = [ ./hardware-configuration.nix ];
</programlisting>
</para>
<para>After installation, if your hardware configuration changes, you
can run:
<screen>
$ nixos-generate-config
</screen>
to update <filename>/etc/nixos/hardware-configuration.nix</filename>.
Your <filename>/etc/nixos/configuration.nix</filename> will
<emphasis>not</emphasis> be overwritten.</para>
</refsection>
</refentry>

View File

@@ -1,78 +0,0 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>nixos-install</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-install</command></refname>
<refpurpose>install NixOS</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-install</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>This command installs NixOS in the file system mounted on
<filename>/mnt</filename>, based on the NixOS configuration specified
in <filename>/mnt/etc/nixos/configuration.nix</filename>. It performs
the following steps:
<itemizedlist>
<listitem><para>It copies Nix and its dependencies to
<filename>/mnt/nix/store</filename>.</para></listitem>
<listitem><para>It runs Nix in <filename>/mnt</filename> to build
the NixOS configuration specified in
<filename>/mnt/etc/nixos/configuration.nix</filename>.</para></listitem>
<listitem><para>It installs the GRUB boot loader on the device
specified in the option <option>boot.loader.grub.device</option>,
and generates a GRUB configuration file that boots into the NixOS
configuration just installed.</para></listitem>
</itemizedlist>
</para>
<para>This command is idempotent: if it is interrupted or fails due to
a temporary problem (e.g. a network issue), you can safely re-run
it.</para>
</refsection>
<refsection><title>Examples</title>
<para>A typical NixOS installation is done by creating and mounting a
file system on <filename>/mnt</filename>, generating a NixOS
configuration in
<filename>/mnt/etc/nixos/configuration.nix</filename>, and running
<command>nixos-install</command>. For instance, if we want to install
NixOS on an <literal>ext4</literal> file system created in
<filename>/dev/sda1</filename>:
<screen>
$ mkfs.ext4 /dev/sda1
$ mount /dev/sda1 /mnt
$ nixos-generate-config --root /mnt
$ # edit /mnt/etc/nixos/configuration.nix
$ nixos-install
</screen>
</para>
</refsection>
</refentry>

View File

@@ -1,138 +0,0 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>nixos-option</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-option</command></refname>
<refpurpose>inspect a NixOS configuration</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-option</command>
<group choice="opt">
<option>-v</option>
<option>-d</option>
<option>-l</option>
</group>
<arg choice='plain'><replaceable>option.name</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>This command evaluates the configuration specified in
<filename>/etc/nixos/configuration.nix</filename> and returns the properties
of the option name given as argument. By default, it returns the value of
the option.</para>
<para>When the option name is not an option, the command prints the list of
attributes contained in the attribute set.</para>
</refsection>
<refsection><title>Options</title>
<para>This command accepts the following options:</para>
<variablelist>
<varlistentry>
<term><option>--value</option>, <option>-v</option></term>
<listitem>
<para>Returns the value of the option. This is the default operation
if no other options are defined.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--description</option>, <option>-d</option></term>
<listitem>
<para>Return the default value, the example and the description of the
option when available.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--lookup</option>, <option>-l</option></term>
<listitem>
<para>Return the locations where the option is declared and where it
is defined. This is extremely useful to find sources of errors in
your configuration.</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Environment</title>
<variablelist>
<varlistentry>
<term><envar>NIXOS_CONFIG</envar></term>
<listitem>
<para>Path to the main NixOS configuration module. Defaults to
<filename>/etc/nixos/configuration.nix</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Examples</title>
<para>Investigate option values:
<screen>$ nixos-option boot.loader
This attribute set contains:
generationsDir
grub
initScript
$ nixos-option boot.loader.grub.enable
true</screen></para>
<para>Prints option information:
<screen>$ nixos-option -d networking.hostName
Default: "nixos"
Description:
The name of the machine. Leave it empty if you want to obtain
it from a DHCP server (if using DHCP).</screen></para>
<para>Find the locations which are declaring and defining an option:
<screen>$ nixos-option -l hardware.firmware
Declared by:
/mnt/data/nix-sources/nixos/modules/services/hardware/udev.nix
Defined by:
/path/to/nixpkgs/nixos/modules/system/boot/kernel.nix
/path/to/nixpkgs/nixos/modules/hardware/network/rt73.nix
/path/to/nixpkgs/nixos/modules/hardware/network/intel-3945abg.nix
/path/to/nixpkgs/nixos/modules/hardware/network/intel-2200bg.nix</screen></para>
</refsection>
<refsection><title>Bugs</title>
<para>The author listed in the following section is wrong. If there is any
other bug, please report to Nicolas Pierron.</para>
</refsection>
</refentry>

View File

@@ -1,335 +0,0 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>nixos-rebuild</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-rebuild</command></refname>
<refpurpose>reconfigure a NixOS machine</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-rebuild</command>
<group choice='req'>
<arg choice='plain'><option>switch</option></arg>
<arg choice='plain'><option>boot</option></arg>
<arg choice='plain'><option>test</option></arg>
<arg choice='plain'><option>build</option></arg>
<arg choice='plain'><option>dry-run</option></arg>
<arg choice='plain'><option>build-vm</option></arg>
<arg choice='plain'><option>build-vm-with-bootloader</option></arg>
</group>
<sbr />
<arg><option>--upgrade</option></arg>
<arg><option>--install-grub</option></arg>
<arg><option>--no-build-nix</option></arg>
<arg><option>--fast</option></arg>
<arg><option>--rollback</option></arg>
<sbr />
<arg>
<group choice='req'>
<arg choice='plain'><option>--profile-name</option></arg>
<arg choice='plain'><option>-p</option></arg>
</group>
<replaceable>name</replaceable>
</arg>
<sbr />
<arg><option>--show-trace</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>This command updates the system so that it corresponds to the
configuration specified in
<filename>/etc/nixos/configuration.nix</filename>. Thus, every time
you modify <filename>/etc/nixos/configuration.nix</filename> or any
NixOS module, you must run <command>nixos-rebuild</command> to make
the changes take effect. It builds the new system in
<filename>/nix/store</filename>, runs its activation script, and stop
and (re)starts any system services if needed.</para>
<para>This command has one required argument, which specifies the
desired operation. It must be one of the following:
<variablelist>
<varlistentry>
<term><option>switch</option></term>
<listitem>
<para>Build and activate the new configuration, and make it the
boot default. That is, the configuration is added to the GRUB
boot menu as the default meny entry, so that subsequent reboots
will boot the system into the new configuration. Previous
configurations activated with <command>nixos-rebuild
switch</command> or <command>nixos-rebuild boot</command> remain
available in the GRUB menu.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>boot</option></term>
<listitem>
<para>Build the new configuration and make it the boot default
(as with <command>nixos-rebuild switch</command>), but do not
activate it. That is, the system continues to run the previous
configuration until the next reboot.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>test</option></term>
<listitem>
<para>Build and activate the new configuration, but do not add
it to the GRUB boot menu. Thus, if you reboot the system (or if
it crashes), you will automatically revert to the default
configuration (i.e. the configuration resulting from the last
call to <command>nixos-rebuild switch</command> or
<command>nixos-rebuild boot</command>).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>build</option></term>
<listitem>
<para>Build the new configuration, but neither activate it nor
add it to the GRUB boot menu. It leaves a symlink named
<filename>result</filename> in the current directory, which
points to the output of the top-level “system” derivation. This
is essentially the same as doing
<screen>
$ nix-build /path/to/nixpkgs/nixos -A system
</screen>
Note that you do not need to be <literal>root</literal> to run
<command>nixos-rebuild build</command>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>dry-run</option></term>
<listitem>
<para>Simply show what store paths would be built or downloaded
by any of the operations above.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>build-vm</option></term>
<listitem>
<para>Build a script that starts a NixOS virtual machine with
the desired configuration. It leaves a symlink
<filename>result</filename> in the current directory that points
(under
<filename>result/bin/run-<replaceable>hostname</replaceable>-vm</filename>)
at the script that starts the VM. Thus, to test a NixOS
configuration in a virtual machine, you should do the following:
<screen>
$ nixos-rebuild build-vm
$ ./result/bin/run-*-vm
</screen></para>
<para>The VM is implemented using the <literal>qemu</literal>
package. For best performance, you should load the
<literal>kvm-intel</literal> or <literal>kvm-amd</literal>
kernel modules to get hardware virtualisation.</para>
<para>The VM mounts the Nix store of the host through the 9P
file system. The host Nix store is read-only, so Nix commands
that modify the Nix store will not work in the VM. This
includes commands such as <command>nixos-rebuild</command>; to
change the VMs configuration, you must halt the VM and re-run
the commands above.
</para>
<para>The VM has its own <literal>ext3</literal> root file
system, which is automatically created when the VM is first
started, and is persistent across reboots of the VM. It is
stored in
<literal>./<replaceable>hostname</replaceable>.qcow2</literal>.
<!-- The entire file system hierarchy of the host is available in
the VM under <filename>/hostfs</filename>.--></para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>build-vm-with-bootloader</option></term>
<listitem>
<para>Like <option>build-vm</option>, but boots using the
regular boot loader of your configuration (e.g., GRUB 1 or 2),
rather than booting directly into the kernel and initial ramdisk
of the system. This allows you to test whether the boot loader
works correctly. However, it does not guarantee that your NixOS
configuration will boot successfully on the host hardware (i.e.,
after running <command>nixos-rebuild switch</command>), because
the hardware and boot loader configuration in the VM are
different. The boot loader is installed on an automatically
generated virtual disk containing a <filename>/boot</filename>
partition, which is mounted read-only in the VM.</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsection>
<refsection><title>Options</title>
<para>This command accepts the following options:</para>
<variablelist>
<varlistentry>
<term><option>--upgrade</option></term>
<listitem>
<para>Fetch the latest version of NixOS from the NixOS
channel.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--install-grub</option></term>
<listitem>
<para>Causes the GRUB boot loader to be (re)installed on the
device specified by the
<varname>boot.loader.grub.device</varname> configuration
option.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--no-build-nix</option></term>
<listitem>
<para>Normally, <command>nixos-rebuild</command> first builds
the <varname>nixUnstable</varname> attribute in Nixpkgs, and
uses the resulting instance of the Nix package manager to build
the new system configuration. This is necessary if the NixOS
modules use features not provided by the currently installed
version of Nix. This option disables building a new Nix.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--fast</option></term>
<listitem>
<para>Equivalent to <option>--no-build-nix</option>
<option>--show-trace</option>. This option is useful if you
call <command>nixos-rebuild</command> frequently (e.g. if youre
hacking on a NixOS module).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--rollback</option></term>
<listitem>
<para>Instead of building a new configuration as specified by
<filename>/etc/nixos/configuration.nix</filename>, roll back to
the previous configuration. (The previous configuration is
defined as the one before the “current” generation of the
Nix profile <filename>/nix/var/nix/profiles/system</filename>.)</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--profile-name</option></term>
<term><option>-p</option></term>
<listitem>
<para>Instead of using the Nix profile
<filename>/nix/var/nix/profiles/system</filename> to keep track
of the current and previous system configurations, use
<filename>/nix/var/nix/profiles/system-profiles/<replaceable>name</replaceable></filename>.
When you use GRUB 2, for every system profile created with this
flag, NixOS will create a submenu named “NixOS - Profile
'<replaceable>name</replaceable>'” in GRUBs boot menu,
containing the current and previous configurations of this
profile.</para>
<para>For instance, if you want to test a configuration file
named <filename>test.nix</filename> without affecting the
default system profile, you would do:
<screen>
$ nixos-rebuild switch -p test -I nixos-config=./test.nix
</screen>
The new configuration will appear in the GRUB 2 submenu “NixOS - Profile
'test'”.</para>
</listitem>
</varlistentry>
</variablelist>
<para>In addition, <command>nixos-rebuild</command> accepts various
Nix-related flags, including <option>--max-jobs</option> /
<option>-j</option>, <option>--show-trace</option>,
<option>--keep-failed</option>, <option>--keep-going</option> and
<option>--verbose</option> / <option>-v</option>. See
the Nix manual for details.</para>
</refsection>
<refsection><title>Environment</title>
<variablelist>
<varlistentry>
<term><envar>NIXOS_CONFIG</envar></term>
<listitem>
<para>Path to the main NixOS configuration module. Defaults to
<filename>/etc/nixos/configuration.nix</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Files</title>
<variablelist>
<varlistentry>
<term><filename>/run/current-system</filename></term>
<listitem>
<para>A symlink to the currently active system configuration in
the Nix store.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>/nix/var/nix/profiles/system</filename></term>
<listitem>
<para>The Nix profile that contains the current and previous
system configurations. Used to generate the GRUB boot
menu.</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Bugs</title>
<para>This command should be renamed to something more
descriptive.</para>
</refsection>
</refentry>

View File

@@ -1,31 +0,0 @@
<reference xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<title>NixOS Reference Pages</title>
<info>
<author>
<personname>
<firstname>Eelco</firstname>
<surname>Dolstra</surname>
</personname>
<contrib>Author</contrib>
</author>
<copyright>
<year>2007-2013</year>
<holder>Eelco Dolstra</holder>
</copyright>
</info>
<xi:include href="man-configuration.xml" />
<xi:include href="man-nixos-build-vms.xml" />
<xi:include href="man-nixos-generate-config.xml" />
<xi:include href="man-nixos-install.xml" />
<xi:include href="man-nixos-option.xml" />
<xi:include href="man-nixos-rebuild.xml" />
</reference>

View File

@@ -1,67 +0,0 @@
<book xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<info>
<title>NixOS Manual</title>
<subtitle>Version <xi:include href="version" parse="text" /></subtitle>
<author>
<personname>
<firstname>Eelco</firstname>
<surname>Dolstra</surname>
</personname>
</author>
<author>
<personname>
<firstname>Nicolas</firstname>
<surname>Pierron</surname>
</personname>
</author>
<copyright>
<year>2007-2013</year>
<holder>Eelco Dolstra</holder>
</copyright>
</info>
<preface>
<title>Preface</title>
<para>This manual describes how to install, use and extend NixOS,
a Linux distribution based on the purely functional package
management system Nix.</para>
<para>If you encounter problems, please report them on the
<literal
xlink:href="http://lists.science.uu.nl/mailman/listinfo/nix-dev">nix-dev@lists.science.uu.nl</literal>
mailing list or on the <link
xlink:href="irc://irc.freenode.net/#nixos">
<literal>#nixos</literal> channel on Freenode</link>. Bugs should
be reported in <link
xlink:href="https://github.com/NixOS/nixpkgs/issues">NixOS GitHub
issue tracker</link>.</para>
</preface>
<xi:include href="installation.xml" />
<xi:include href="configuration.xml" />
<xi:include href="running.xml" />
<!-- <xi:include href="userconfiguration.xml" /> -->
<xi:include href="troubleshooting.xml" />
<xi:include href="containers.xml" />
<xi:include href="development.xml" />
<xi:include href="release-notes.xml" />
<appendix xml:id="ch-options">
<title>Configuration options</title>
<xi:include href="options-db.xml" />
</appendix>
</book>

View File

@@ -1,205 +0,0 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://docbook.org/ns/docbook"
extension-element-prefixes="str"
>
<xsl:output method='xml' encoding="UTF-8" />
<xsl:param name="revision" />
<xsl:template match="/expr/list">
<variablelist>
<xsl:for-each select="attrs">
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '&lt;', '_'), '>', '_'), '?', '_'))" />
<varlistentry>
<term xlink:href="#{$id}">
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
<option>
<xsl:value-of select="attr[@name = 'name']/string/@value" />
</option>
</term>
<listitem>
<para>
<xsl:value-of disable-output-escaping="yes"
select="attr[@name = 'description']/string/@value" />
</para>
<xsl:if test="attr[@name = 'default']">
<para>
<emphasis>Default:</emphasis>
<xsl:text> </xsl:text>
<xsl:apply-templates select="attr[@name = 'default']" mode="top" />
</para>
</xsl:if>
<xsl:if test="attr[@name = 'example']">
<para>
<emphasis>Example:</emphasis>
<xsl:text> </xsl:text>
<xsl:choose>
<xsl:when test="attr[@name = 'example']/attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
<programlisting><xsl:value-of select="attr[@name = 'example']/attrs/attr[@name = 'text']/string/@value" /></programlisting>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="attr[@name = 'example']" mode="top" />
</xsl:otherwise>
</xsl:choose>
</para>
</xsl:if>
<xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
<para>
<emphasis>Declared by:</emphasis>
</para>
<xsl:apply-templates select="attr[@name = 'declarations']" />
</xsl:if>
<xsl:if test="count(attr[@name = 'definitions']/list/*) != 0">
<para>
<emphasis>Defined by:</emphasis>
</para>
<xsl:apply-templates select="attr[@name = 'definitions']" />
</xsl:if>
</listitem>
</varlistentry>
</xsl:for-each>
</variablelist>
</xsl:template>
<xsl:template match="*" mode="top">
<xsl:choose>
<xsl:when test="string[contains(@value, '&#010;')]">
<programlisting>
<xsl:text>''
</xsl:text><xsl:value-of select='str:replace(string/@value, "${", "&apos;&apos;${")' /><xsl:text>''</xsl:text></programlisting>
</xsl:when>
<xsl:otherwise>
<literal><xsl:apply-templates /></literal>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="null">
<xsl:text>null</xsl:text>
</xsl:template>
<xsl:template match="string">
<xsl:choose>
<xsl:when test="(contains(@value, '&quot;') or contains(@value, '\')) and not(contains(@value, '&#010;'))">
<xsl:text>''</xsl:text><xsl:value-of select='str:replace(@value, "${", "&apos;&apos;${")' /><xsl:text>''</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>"</xsl:text><xsl:value-of select="str:replace(str:replace(str:replace(str:replace(@value, '\', '\\'), '&quot;', '\&quot;'), '&#010;', '\n'), '$', '\$')" /><xsl:text>"</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="int">
<xsl:value-of select="@value" />
</xsl:template>
<xsl:template match="bool[@value = 'true']">
<xsl:text>true</xsl:text>
</xsl:template>
<xsl:template match="bool[@value = 'false']">
<xsl:text>false</xsl:text>
</xsl:template>
<xsl:template match="list">
[
<xsl:for-each select="*">
<xsl:apply-templates select="." />
<xsl:text> </xsl:text>
</xsl:for-each>
]
</xsl:template>
<xsl:template match="attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
<xsl:value-of select="attr[@name = 'text']/string/@value" />
</xsl:template>
<xsl:template match="attrs">
{
<xsl:for-each select="attr">
<xsl:value-of select="@name" />
<xsl:text> = </xsl:text>
<xsl:apply-templates select="*" /><xsl:text>; </xsl:text>
</xsl:for-each>
}
</xsl:template>
<xsl:template match="derivation">
<replaceable>(build of <xsl:value-of select="attr[@name = 'name']/string/@value" />)</replaceable>
</xsl:template>
<xsl:template match="attr[@name = 'declarations' or @name = 'definitions']">
<simplelist>
<xsl:for-each select="list/string">
<member><filename>
<!-- Hyperlink the filename either to the NixOS Subversion
repository (if its a module and we have a revision number),
or to the local filesystem. -->
<xsl:choose>
<xsl:when test="not(starts-with(@value, '/'))">
<xsl:choose>
<xsl:when test="$revision = 'local'">
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/master/<xsl:value-of select="@value"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$revision != 'local' and contains(@value, 'nixops') and contains(@value, '/nix/')">
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixops/blob/<xsl:value-of select="$revision"/>/nix/<xsl:value-of select="substring-after(@value, '/nix/')"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="xlink:href">file://<xsl:value-of select="@value"/></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<!-- Print the filename and make it user-friendly by replacing the
/nix/store/<hash> prefix by the default location of nixos
sources. -->
<xsl:choose>
<xsl:when test="not(starts-with(@value, '/'))">
&lt;nixpkgs/<xsl:value-of select="@value"/>&gt;
</xsl:when>
<xsl:when test="contains(@value, 'nixops') and contains(@value, '/nix/')">
&lt;nixops/<xsl:value-of select="substring-after(@value, '/nix/')"/>&gt;
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@value" />
</xsl:otherwise>
</xsl:choose>
</filename></member>
</xsl:for-each>
</simplelist>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,176 +0,0 @@
<appendix xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="ch-release-notes">
<title>Release notes</title>
<!--==================================================================-->
<section xml:id="sec-release-14.04">
<title>Release 14.04 (“Baboon”, 2014/04/30)</title>
<para>This is the second stable release branch of NixOS. In addition
to numerous new and upgraded packages and modules, this release has
the following highlights:
<itemizedlist>
<listitem><para>Installation on UEFI systems is now supported. See
<xref linkend="sec-uefi-installation"/> for
details.</para></listitem>
<listitem><para>Systemd has been updated to version 212, which has
<link xlink:href="http://cgit.freedesktop.org/systemd/systemd/plain/NEWS?id=v212">numerous
improvements</link>. NixOS now automatically starts systemd user
instances when you log in. You can define global user units through
the <option>systemd.unit.*</option> options.</para></listitem>
<listitem><para>NixOS is now based on Glibc 2.19 and GCC
4.8.</para></listitem>
<listitem><para>The default Linux kernel has been updated to
3.12.</para></listitem>
<listitem><para>KDE has been updated to 4.12.</para></listitem>
<listitem><para>GNOME 3.10 experimental support has been added.</para></listitem>
<listitem><para>Nix has been updated to 1.7 (<link
xlink:href="http://nixos.org/nix/manual/#ssec-relnotes-1.7">details</link>).</para></listitem>
<listitem><para>NixOS now supports fully declarative management of
users and groups. If you set <option>users.mutableUsers</option> to
<literal>false</literal>, then the contents of
<filename>/etc/passwd</filename> and <filename>/etc/group</filename>
will be <link
xlink:href="https://www.usenix.org/legacy/event/lisa02/tech/full_papers/traugott/traugott_html/">congruent</link>
to your NixOS configuration. For instance, if you remove a user from
<option>users.extraUsers</option> and run
<command>nixos-rebuild</command>, the user account will cease to
exist. Also, imperative commands for managing users and groups, such
as <command>useradd</command>, are no longer available. If
<option>users.mutableUsers</option> is <literal>true</literal> (the
default), then behaviour is unchanged from NixOS
13.10.</para></listitem>
<listitem><para>NixOS now has basic container support, meaning you
can easily run a NixOS instance as a container in a NixOS host
system. These containers are suitable for testing and
experimentation but not production use, since theyre not fully
isolated from the host. See <xref linkend="ch-containers"/> for
details.</para></listitem>
<listitem><para>Systemd units provided by packages can now be
overridden from the NixOS configuration. For instance, if a package
<literal>foo</literal> provides systemd units, you can say:
<programlisting>
systemd.packages = [ pkgs.foo ];
</programlisting>
to enable those units. You can then set or override unit options in
the usual way, e.g.
<programlisting>
systemd.services.foo.wantedBy = [ "multi-user.target" ];
systemd.services.foo.serviceConfig.MemoryLimit = "512M";
</programlisting>
</para></listitem>
</itemizedlist>
</para>
<para>When upgrading from a previous release, please be aware of the
following incompatible changes:
<itemizedlist>
<listitem><para>Nixpkgs no longer exposes unfree packages by
default. If your NixOS configuration requires unfree packages from
Nixpkgs, you need to enable support for them explicitly by setting:
<programlisting>
nixpkgs.config.allowUnfree = true;
</programlisting>
Otherwise, you get an error message such as:
<screen>
error: package nvidia-x11-331.49-3.12.17 in ‘…/nvidia-x11/default.nix:56
has an unfree license, refusing to evaluate
</screen>
</para></listitem>
<listitem><para>The Adobe Flash player is no longer enabled by
default in the Firefox and Chromium wrappers. To enable it, you must
set:
<programlisting>
nixpkgs.config.allowUnfree = true;
nixpkgs.config.firefox.enableAdobeFlash = true; # for Firefox
nixpkgs.config.chromium.enableAdobeFlash = true; # for Chromium
</programlisting>
</para></listitem>
<listitem><para>The firewall is now enabled by default. If you dont
want this, you need to disable it explicitly:
<programlisting>
networking.firewall.enable = false;
</programlisting>
</para></listitem>
<listitem><para>The option
<option>boot.loader.grub.memtest86</option> has been renamed to
<option>boot.loader.grub.memtest86.enable</option>.</para></listitem>
<listitem><para>The <literal>mysql55</literal> service has been
merged into the <literal>mysql</literal> service, which no longer
sets a default for the option
<option>services.mysql.package</option>.</para></listitem>
<listitem><para>Package variants are now differentiated by suffixing
the name, rather than the version. For instance,
<filename>sqlite-3.8.4.3-interactive</filename> is now called
<filename>sqlite-interactive-3.8.4.3</filename>. This ensures that
<literal>nix-env -i sqlite</literal> is unambiguous, and that
<literal>nix-env -u</literal> wont “upgrade”
<literal>sqlite</literal> to <literal>sqlite-interactive</literal>
or vice versa. Notably, this change affects the Firefox wrapper
(which provides plugins), as it is now called
<literal>firefox-wrapper</literal>. So when using
<command>nix-env</command>, you should do <literal>nix-env -e
firefox; nix-env -i firefox-wrapper</literal> if you want to keep
using the wrapper. This change does not affect declarative package
management, since attribute names like
<literal>pkgs.firefoxWrapper</literal> were already
unambiguous.</para></listitem>
<listitem><para>The symlink <filename>/etc/ca-bundle.crt</filename>
is gone. Programs should instead use the environment variable
<envar>OPENSSL_X509_CERT_FILE</envar> (which points to
<filename>/etc/ssl/certs/ca-bundle.crt</filename>).</para></listitem>
</itemizedlist>
</para>
</section>
<!--==================================================================-->
<section xml:id="sec-release-13.10">
<title>Release 13.10 (“Aardvark”, 2013/10/31)</title>
<para>This is the first stable release branch of NixOS.</para>
</section>
</appendix>

View File

@@ -1,369 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="ch-running">
<title>Running NixOS</title>
<para>This chapter describes various aspects of managing a running
NixOS system, such as how to use the <command>systemd</command>
service manager.</para>
<!--===============================================================-->
<section xml:id="sec-systemctl"><title>Service management</title>
<para>In NixOS, all system services are started and monitored using
the systemd program. Systemd is the “init” process of the system
(i.e. PID 1), the parent of all other processes. It manages a set of
so-called “units”, which can be things like system services
(programs), but also mount points, swap files, devices, targets
(groups of units) and more. Units can have complex dependencies; for
instance, one unit can require that another unit must be successfully
started before the first unit can be started. When the system boots,
it starts a unit named <literal>default.target</literal>; the
dependencies of this unit cause all system services to be started,
file systems to be mounted, swap files to be activated, and so
on.</para>
<para>The command <command>systemctl</command> is the main way to
interact with <command>systemd</command>. Without any arguments, it
shows the status of active units:
<screen>
$ systemctl
-.mount loaded active mounted /
swapfile.swap loaded active active /swapfile
sshd.service loaded active running SSH Daemon
graphical.target loaded active active Graphical Interface
<replaceable>...</replaceable>
</screen>
</para>
<para>You can ask for detailed status information about a unit, for
instance, the PostgreSQL database service:
<screen>
$ systemctl status postgresql.service
postgresql.service - PostgreSQL Server
Loaded: loaded (/nix/store/pn3q73mvh75gsrl8w7fdlfk3fq5qm5mw-unit/postgresql.service)
Active: active (running) since Mon, 2013-01-07 15:55:57 CET; 9h ago
Main PID: 2390 (postgres)
CGroup: name=systemd:/system/postgresql.service
├─2390 postgres
├─2418 postgres: writer process
├─2419 postgres: wal writer process
├─2420 postgres: autovacuum launcher process
├─2421 postgres: stats collector process
└─2498 postgres: zabbix zabbix [local] idle
Jan 07 15:55:55 hagbard postgres[2394]: [1-1] LOG: database system was shut down at 2013-01-07 15:55:05 CET
Jan 07 15:55:57 hagbard postgres[2390]: [1-1] LOG: database system is ready to accept connections
Jan 07 15:55:57 hagbard postgres[2420]: [1-1] LOG: autovacuum launcher started
Jan 07 15:55:57 hagbard systemd[1]: Started PostgreSQL Server.
</screen>
Note that this shows the status of the unit (active and running), all
the processes belonging to the service, as well as the most recent log
messages from the service.
</para>
<para>Units can be stopped, started or restarted:
<screen>
$ systemctl stop postgresql.service
$ systemctl start postgresql.service
$ systemctl restart postgresql.service
</screen>
These operations are synchronous: they wait until the service has
finished starting or stopping (or has failed). Starting a unit will
cause the dependencies of that unit to be started as well (if
necessary).</para>
<!-- - cgroups: each service and user session is a cgroup
- cgroup resource management -->
</section>
<!--===============================================================-->
<section xml:id="sec-rebooting"><title>Rebooting and shutting down</title>
<para>The system can be shut down (and automatically powered off) by
doing:
<screen>
$ shutdown
</screen>
This is equivalent to running <command>systemctl
poweroff</command>.</para>
<para>To reboot the system, run
<screen>
$ reboot
</screen>
which is equivalent to <command>systemctl reboot</command>.
Alternatively, you can quickly reboot the system using
<literal>kexec</literal>, which bypasses the BIOS by directly loading
the new kernel into memory:
<screen>
$ systemctl kexec
</screen>
</para>
<para>The machine can be suspended to RAM (if supported) using
<command>systemctl suspend</command>, and suspended to disk using
<command>systemctl hibernate</command>.</para>
<para>These commands can be run by any user who is logged in locally,
i.e. on a virtual console or in X11; otherwise, the user is asked for
authentication.</para>
</section>
<!--===============================================================-->
<section xml:id="sec-user-sessions"><title>User sessions</title>
<para>Systemd keeps track of all users who are logged into the system
(e.g. on a virtual console or remotely via SSH). The command
<command>loginctl</command> allows querying and manipulating user
sessions. For instance, to list all user sessions:
<screen>
$ loginctl
SESSION UID USER SEAT
c1 500 eelco seat0
c3 0 root seat0
c4 500 alice
</screen>
This shows that two users are logged in locally, while another is
logged in remotely. (“Seats” are essentially the combinations of
displays and input devices attached to the system; usually, there is
only one seat.) To get information about a session:
<screen>
$ loginctl session-status c3
c3 - root (0)
Since: Tue, 2013-01-08 01:17:56 CET; 4min 42s ago
Leader: 2536 (login)
Seat: seat0; vc3
TTY: /dev/tty3
Service: login; type tty; class user
State: online
CGroup: name=systemd:/user/root/c3
├─ 2536 /nix/store/10mn4xip9n7y9bxqwnsx7xwx2v2g34xn-shadow-4.1.5.1/bin/login --
├─10339 -bash
└─10355 w3m nixos.org
</screen>
This shows that the user is logged in on virtual console 3. It also
lists the processes belonging to this session. Since systemd keeps
track of this, you can terminate a session in a way that ensures that
all the sessions processes are gone:
<screen>
$ loginctl terminate-session c3
</screen>
</para>
</section>
<!--===============================================================-->
<section xml:id="sec-cgroups"><title>Control groups</title>
<para>To keep track of the processes in a running system, systemd uses
<emphasis>control groups</emphasis> (cgroups). A control group is a
set of processes used to allocate resources such as CPU, memory or I/O
bandwidth. There can be multiple control group hierarchies, allowing
each kind of resource to be managed independently.</para>
<para>The command <command>systemd-cgls</command> lists all control
groups in the <literal>systemd</literal> hierarchy, which is what
systemd uses to keep track of the processes belonging to each service
or user session:
<screen>
$ systemd-cgls
├─user
│ └─eelco
│ └─c1
│ ├─ 2567 -:0
│ ├─ 2682 kdeinit4: kdeinit4 Running...
│ ├─ <replaceable>...</replaceable>
│ └─10851 sh -c less -R
└─system
├─httpd.service
│ ├─2444 httpd -f /nix/store/3pyacby5cpr55a03qwbnndizpciwq161-httpd.conf -DNO_DETACH
│ └─<replaceable>...</replaceable>
├─dhcpcd.service
│ └─2376 dhcpcd --config /nix/store/f8dif8dsi2yaa70n03xir8r653776ka6-dhcpcd.conf
└─ <replaceable>...</replaceable>
</screen>
Similarly, <command>systemd-cgls cpu</command> shows the cgroups in
the CPU hierarchy, which allows per-cgroup CPU scheduling priorities.
By default, every systemd service gets its own CPU cgroup, while all
user sessions are in the top-level CPU cgroup. This ensures, for
instance, that a thousand run-away processes in the
<literal>httpd.service</literal> cgroup cannot starve the CPU for one
process in the <literal>postgresql.service</literal> cgroup. (By
contrast, it they were in the same cgroup, then the PostgreSQL process
would get 1/1001 of the cgroups CPU time.) You can limit a services
CPU share in <filename>configuration.nix</filename>:
<programlisting>
systemd.services.httpd.serviceConfig.CPUShares = 512;
</programlisting>
By default, every cgroup has 1024 CPU shares, so this will halve the
CPU allocation of the <literal>httpd.service</literal> cgroup.</para>
<para>There also is a <literal>memory</literal> hierarchy that
controls memory allocation limits; by default, all processes are in
the top-level cgroup, so any service or session can exhaust all
available memory. Per-cgroup memory limits can be specified in
<filename>configuration.nix</filename>; for instance, to limit
<literal>httpd.service</literal> to 512 MiB of RAM (excluding swap)
and 640 MiB of RAM (including swap):
<programlisting>
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ];
</programlisting>
</para>
<para>The command <command>systemd-cgtop</command> shows a
continuously updated list of all cgroups with their CPU and memory
usage.</para>
</section>
<!--===============================================================-->
<section xml:id="sec-logging"><title>Logging</title>
<para>System-wide logging is provided by systemds
<emphasis>journal</emphasis>, which subsumes traditional logging
daemons such as syslogd and klogd. Log entries are kept in binary
files in <filename>/var/log/journal/</filename>. The command
<literal>journalctl</literal> allows you to see the contents of the
journal. For example,
<screen>
$ journalctl -b
</screen>
shows all journal entries since the last reboot. (The output of
<command>journalctl</command> is piped into <command>less</command> by
default.) You can use various options and match operators to restrict
output to messages of interest. For instance, to get all messages
from PostgreSQL:
<screen>
$ journalctl -u postgresql.service
-- Logs begin at Mon, 2013-01-07 13:28:01 CET, end at Tue, 2013-01-08 01:09:57 CET. --
...
Jan 07 15:44:14 hagbard postgres[2681]: [2-1] LOG: database system is shut down
-- Reboot --
Jan 07 15:45:10 hagbard postgres[2532]: [1-1] LOG: database system was shut down at 2013-01-07 15:44:14 CET
Jan 07 15:45:13 hagbard postgres[2500]: [1-1] LOG: database system is ready to accept connections
</screen>
Or to get all messages since the last reboot that have at least a
“critical” severity level:
<screen>
$ journalctl -b -p crit
Dec 17 21:08:06 mandark sudo[3673]: pam_unix(sudo:auth): auth could not identify password for [alice]
Dec 29 01:30:22 mandark kernel[6131]: [1053513.909444] CPU6: Core temperature above threshold, cpu clock throttled (total events = 1)
</screen>
</para>
<para>The system journal is readable by root and by users in the
<literal>wheel</literal> and <literal>systemd-journal</literal>
groups. All users have a private journal that can be read using
<command>journalctl</command>.</para>
</section>
<!--===============================================================-->
<section xml:id="sec-nix-gc"><title>Cleaning up the Nix store</title>
<para>Nix has a purely functional model, meaning that packages are
never upgraded in place. Instead new versions of packages end up in a
different location in the Nix store (<filename>/nix/store</filename>).
You should periodically run Nixs <emphasis>garbage
collector</emphasis> to remove old, unreferenced packages. This is
easy:
<screen>
$ nix-collect-garbage
</screen>
Alternatively, you can use a systemd unit that does the same in the
background:
<screen>
$ systemctl start nix-gc.service
</screen>
You can tell NixOS in <filename>configuration.nix</filename> to run
this unit automatically at certain points in time, for instance, every
night at 03:15:
<programlisting>
nix.gc.automatic = true;
nix.gc.dates = "03:15";
</programlisting>
</para>
<para>The commands above do not remove garbage collector roots, such
as old system configurations. Thus they do not remove the ability to
roll back to previous configurations. The following command deletes
old roots, removing the ability to roll back to them:
<screen>
$ nix-collect-garbage -d
</screen>
You can also do this for specific profiles, e.g.
<screen>
$ nix-env -p /nix/var/nix/profiles/per-user/eelco/profile --delete-generations old
</screen>
Note that NixOS system configurations are stored in the profile
<filename>/nix/var/nix/profiles/system</filename>.</para>
<para>Another way to reclaim disk space (often as much as 40% of the
size of the Nix store) is to run Nixs store optimiser, which seeks
out identical files in the store and replaces them with hard links to
a single copy.
<screen>
$ nix-store --optimise
</screen>
Since this command needs to read the entire Nix store, it can take
quite a while to finish.</para>
</section>
</chapter>

View File

@@ -1,268 +0,0 @@
/* Copied from http://bakefile.sourceforge.net/, which appears
licensed under the GNU GPL. */
/***************************************************************************
Basic headers and text:
***************************************************************************/
body
{
font-family: "Nimbus Sans L", sans-serif;
background: white;
margin: 2em 1em 2em 1em;
}
h1, h2, h3, h4
{
color: #005aa0;
}
h1 /* title */
{
font-size: 200%;
}
h2 /* chapters, appendices, subtitle */
{
font-size: 180%;
}
/* Extra space between chapters, appendices. */
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
{
margin-top: 1.5em;
}
div.section > div.titlepage h2 /* sections */
{
font-size: 150%;
margin-top: 1.5em;
}
h3 /* subsections */
{
font-size: 125%;
}
div.simplesect h2
{
font-size: 110%;
}
div.appendix h3
{
font-size: 150%;
margin-top: 1.5em;
}
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
{
margin-top: 1.4em;
font-size: 125%;
}
div.refsection h3
{
font-size: 110%;
}
/***************************************************************************
Examples:
***************************************************************************/
div.example
{
border: 1px solid #b0b0b0;
padding: 6px 6px;
margin-left: 1.5em;
margin-right: 1.5em;
background: #f4f4f8;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example p.title
{
margin-top: 0em;
}
div.example pre
{
box-shadow: none;
}
/***************************************************************************
Screen dumps:
***************************************************************************/
pre.screen, pre.programlisting
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
color: #600000;
background: #f4f4f8;
font-family: monospace;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example pre.programlisting
{
border: 0px;
padding: 0 0;
margin: 0 0 0 0;
}
/***************************************************************************
Notes, warnings etc:
***************************************************************************/
.note, .warning
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
margin-bottom: 1em;
padding: 0.3em 0.3em 0.3em 0.3em;
background: #fffff5;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.note, div.warning
{
font-style: italic;
}
div.note h3, div.warning h3
{
color: red;
font-size: 100%;
padding-right: 0.5em;
display: inline;
}
div.note p, div.warning p
{
margin-bottom: 0em;
}
div.note h3 + p, div.warning h3 + p
{
display: inline;
}
div.note h3
{
color: blue;
font-size: 100%;
}
div.navfooter *
{
font-size: 90%;
}
/***************************************************************************
Links colors and highlighting:
***************************************************************************/
a { text-decoration: none; }
a:hover { text-decoration: underline; }
a:link { color: #0048b3; }
a:visited { color: #002a6a; }
/***************************************************************************
Table of contents:
***************************************************************************/
div.toc
{
font-size: 90%;
}
div.toc dl
{
margin-top: 0em;
margin-bottom: 0em;
}
/***************************************************************************
Special elements:
***************************************************************************/
tt, code
{
color: #400000;
}
.term
{
font-weight: bold;
}
div.variablelist dd p, div.glosslist dd p
{
margin-top: 0em;
}
div.variablelist dd, div.glosslist dd
{
margin-left: 1.5em;
}
div.glosslist dt
{
font-style: italic;
}
.varname
{
color: #400000;
}
span.command strong
{
font-weight: normal;
color: #400000;
}
div.calloutlist table
{
box-shadow: none;
}
table
{
border-collapse: collapse;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
table.simplelist
{
text-align: left;
color: #005aa0;
border: 0;
padding: 5px;
background: #fffff5;
font-weight: normal;
font-style: italic;
box-shadow: none;
margin-bottom: 1em;
}
div.affiliation
{
font-style: italic;
}

View File

@@ -1,199 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="ch-troubleshooting">
<title>Troubleshooting</title>
<!--===============================================================-->
<section xml:id="sec-boot-problems"><title>Boot problems</title>
<para>If NixOS fails to boot, there are a number of kernel command
line parameters that may help you to identify or fix the issue. You
can add these parameters in the GRUB boot menu by pressing “e” to
modify the selected boot entry and editing the line starting with
<literal>linux</literal>. The following are some useful kernel command
line parameters that are recognised by the NixOS boot scripts or by
systemd:
<variablelist>
<varlistentry><term><literal>boot.shell_on_fail</literal></term>
<listitem><para>Start a root shell if something goes wrong in
stage 1 of the boot process (the initial ramdisk). This is
disabled by default because there is no authentication for the
root shell.</para></listitem>
</varlistentry>
<varlistentry><term><literal>boot.debug1</literal></term>
<listitem><para>Start an interactive shell in stage 1 before
anything useful has been done. That is, no modules have been
loaded and no file systems have been mounted, except for
<filename>/proc</filename> and
<filename>/sys</filename>.</para></listitem>
</varlistentry>
<varlistentry><term><literal>boot.trace</literal></term>
<listitem><para>Print every shell command executed by the stage 1
and 2 boot scripts.</para></listitem>
</varlistentry>
<varlistentry><term><literal>single</literal></term>
<listitem><para>Boot into rescue mode (a.k.a. single user mode).
This will cause systemd to start nothing but the unit
<literal>rescue.target</literal>, which runs
<command>sulogin</command> to prompt for the root password and
start a root login shell. Exiting the shell causes the system to
continue with the normal boot process.</para></listitem>
</varlistentry>
<varlistentry><term><literal>systemd.log_level=debug systemd.log_target=console</literal></term>
<listitem><para>Make systemd very verbose and send log messages to
the console instead of the journal.</para></listitem>
</varlistentry>
</variablelist>
For more parameters recognised by systemd, see
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
<para>If no login prompts or X11 login screens appear (e.g. due to
hanging dependencies), you can press Alt+ArrowUp. If youre lucky,
this will start rescue mode (described above). (Also note that since
most units have a 90-second timeout before systemd gives up on them,
the <command>agetty</command> login prompts should appear eventually
unless something is very wrong.)</para>
</section>
<!--===============================================================-->
<section xml:id="sec-maintenance-mode"><title>Maintenance mode</title>
<para>You can enter rescue mode by running:
<screen>
$ systemctl rescue</screen>
This will eventually give you a single-user root shell. Systemd will
stop (almost) all system services. To get out of maintenance mode,
just exit from the rescue shell.</para>
</section>
<!--===============================================================-->
<section xml:id="sec-rollback"><title>Rolling back configuration changes</title>
<para>After running <command>nixos-rebuild</command> to switch to a
new configuration, you may find that the new configuration doesnt
work very well. In that case, there are several ways to return to a
previous configuration.</para>
<para>First, the GRUB boot manager allows you to boot into any
previous configuration that hasnt been garbage-collected. These
configurations can be found under the GRUB submenu “NixOS - All
configurations”. This is especially useful if the new configuration
fails to boot. After the system has booted, you can make the selected
configuration the default for subsequent boots:
<screen>
$ /run/current-system/bin/switch-to-configuration boot</screen>
</para>
<para>Second, you can switch to the previous configuration in a running
system:
<screen>
$ nixos-rebuild switch --rollback</screen>
This is equivalent to running:
<screen>
$ /nix/var/nix/profiles/system-<replaceable>N</replaceable>-link/bin/switch-to-configuration switch</screen>
where <replaceable>N</replaceable> is the number of the NixOS system
configuration. To get a list of the available configurations, do:
<screen>
$ ls -l /nix/var/nix/profiles/system-*-link
<replaceable>...</replaceable>
lrwxrwxrwx 1 root root 78 Aug 12 13:54 /nix/var/nix/profiles/system-268-link -> /nix/store/202b...-nixos-13.07pre4932_5a676e4-4be1055
</screen>
</para>
</section>
<!--===============================================================-->
<section xml:id="sec-nix-store-corruption"><title>Nix store corruption</title>
<para>After a system crash, its possible for files in the Nix store
to become corrupted. (For instance, the Ext4 file system has the
tendency to replace un-synced files with zero bytes.) NixOS tries
hard to prevent this from happening: it performs a
<command>sync</command> before switching to a new configuration, and
Nixs database is fully transactional. If corruption still occurs,
you may be able to fix it automatically.</para>
<para>If the corruption is in a path in the closure of the NixOS
system configuration, you can fix it by doing
<screen>
$ nixos-rebuild switch --repair
</screen>
This will cause Nix to check every path in the closure, and if its
cryptographic hash differs from the hash recorded in Nixs database,
the path is rebuilt or redownloaded.</para>
<para>You can also scan the entire Nix store for corrupt paths:
<screen>
$ nix-store --verify --check-contents --repair
</screen>
Any corrupt paths will be redownloaded if theyre available in a
binary cache; otherwise, they cannot be repaired.</para>
</section>
<!--===============================================================-->
<section xml:id="sec-nix-network-issues"><title>Nix network issues</title>
<para>Nix uses a so-called <emphasis>binary cache</emphasis> to
optimise building a package from source into downloading it as a
pre-built binary. That is, whenever a command like
<command>nixos-rebuild</command> needs a path in the Nix store, Nix
will try to download that path from the Internet rather than build it
from source. The default binary cache is
<uri>http://cache.nixos.org/</uri>. If this cache is unreachable, Nix
operations may take a long time due to HTTP connection timeouts. You
can disable the use of the binary cache by adding <option>--option
use-binary-caches false</option>, e.g.
<screen>
$ nixos-rebuild switch --option use-binary-caches false
</screen>
If you have an alternative binary cache at your disposal, you can use
it instead:
<screen>
$ nixos-rebuild switch --option binary-caches http://my-cache.example.org/
</screen>
</para>
</section>
</chapter>

View File

@@ -1,16 +0,0 @@
This file should become a nix expression. (see modules/installer/tools/tools.nix)
you need to:
- download the latest jQuery from and copy it to chrome/content:
http://code.jquery.com/jquery-1.5.2.js
- install 'xulrunner' with nix:
nix-env -Ai nixpkgs_sys.firefox40Pkgs.xulrunner
- make sure nixos-option in your path
- have /etc/nixos/nixpkgs
- have /etc/nixos/nixos
run it:
- xulrunner /etc/nixos/nixos/gui/application.ini -jsconsole

View File

@@ -1,36 +0,0 @@
[App]
;
; This field specifies your organization's name. This field is recommended,
; but optional.
Vendor=NixOS
;
; This field specifies your application's name. This field is required.
Name=NixOS-gui
;
; This field specifies your application's version. This field is optional.
Version=0.1
;
; This field specifies your application's build ID (timestamp). This field is
; required.
BuildID=20110424
;
; This field specifies a compact copyright notice for your application. This
; field is optional.
;Copyright=
;
; This ID is just an example. Every XUL app ought to have it's own unique ID.
; You can use the microsoft "guidgen" or "uuidgen" tools, or go on
; irc.mozilla.org and /msg botbot uuid. This field is optional.
;ID=
[Gecko]
;
; This field is required. It specifies the minimum Gecko version that this
; application requires.
MinVersion=1.9a5
;
; This field is optional. It specifies the maximum Gecko version that this
; application requires. It should be specified if your application uses
; unfrozen interfaces.
MaxVersion=2.*

View File

@@ -1 +0,0 @@
manifest chrome/chrome.manifest

View File

@@ -1 +0,0 @@
content nixos-gui content/

View File

@@ -1,137 +0,0 @@
function inspect(obj, maxLevels, level)
{
var str = '', type, msg;
// Start Input Validations
// Don't touch, we start iterating at level zero
if(level == null) level = 0;
// At least you want to show the first level
if(maxLevels == null) maxLevels = 1;
if(maxLevels < 1)
return '<font color="red">Error: Levels number must be > 0</font>';
// We start with a non null object
if(obj == null)
return '<font color="red">Error: Object <b>NULL</b></font>';
// End Input Validations
// Each Iteration must be indented
str += '<ul>';
// Start iterations for all objects in obj
for(property in obj)
{
try
{
// Show "property" and "type property"
type = typeof(obj[property]);
str += '<li>(' + type + ') ' + property +
( (obj[property]==null)?(': <b>null</b>'):('')) + '</li>';
// We keep iterating if this property is an Object, non null
// and we are inside the required number of levels
if((type == 'object') && (obj[property] != null) && (level+1 < maxLevels))
str += inspect(obj[property], maxLevels, level+1);
}
catch(err)
{
// Is there some properties in obj we can't access? Print it red.
if(typeof(err) == 'string') msg = err;
else if(err.message) msg = err.message;
else if(err.description) msg = err.description;
else msg = 'Unknown';
str += '<li><font color="red">(Error) ' + property + ': ' + msg +'</font></li>';
}
}
// Close indent
str += '</ul>';
return str;
}
// Run xulrunner application.ini -jsconsole -console, to see messages.
function log(str)
{
Components.classes['@mozilla.org/consoleservice;1']
.getService(Components.interfaces.nsIConsoleService)
.logStringMessage(str);
}
function makeTempFile(prefix)
{
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
file.append(prefix || "xulrunner");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0664);
return file;
}
function writeToFile(file, data)
{
// file is nsIFile, data is a string
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
// use 0x02 | 0x10 to open file for appending.
foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
foStream.write(data, data.length);
foStream.close();
}
function readFromFile(file)
{
// |file| is nsIFile
var data = "";
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
fstream.init(file, -1, 0, 0);
sstream.init(fstream);
var str = sstream.read(4096);
while (str.length > 0) {
data += str;
str = sstream.read(4096);
}
sstream.close();
fstream.close();
return data;
}
function runProgram(commandLine)
{
// create an nsILocalFile for the executable
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("/bin/sh");
// create an nsIProcess
var process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(file);
// Run the process.
// If first param is true, calling thread will be blocked until
// called process terminates.
// Second and third params are used to pass command-line arguments
// to the process.
var args = ["-c", commandLine];
process.run(true, args, args.length);
}
// only for testing...
function testIO()
{
var f = makeTempFile();
writeToFile(f, "essai\ntest");
alert(readFromFile(f));
runProgram("zenity --info");
}

View File

@@ -1,70 +0,0 @@
// global variables.
var gNixOS;
var gOptionView;
/*
var gProgressBar;
function setProgress(current, max)
{
if (gProgressBar) {
gProgressBar.value = 100 * current / max;
log("progress: " + gProgressBar.value + "%");
}
else
log("unknow progress bar");
}
*/
function updateTextbox(id, value)
{
// setting the height cause an overflow which resize the textbox to its
// content due to its onoverflow attribute.
$(id).attr("value", value).attr("height", 1);
};
function updatePanel(options)
{
log("updatePanel: " + options.length);
if (options.length == 0)
return;
// FIXME: ignore the rest of the selection for now.
var o = options[0];
$("#name").attr("label", o.path);
if (o.typename != null)
$("#typename").attr("label", o.typename);
else
$("#typename").attr("label", "");
$("#desc").text(o.description);
if (o.value != null)
updateTextbox("#val", o.value);
else
updateTextbox("#val", "");
if (o.defaultValue != null)
updateTextbox("#def", o.defaultValue);
else
updateTextbox("#def", "");
if (o.example != null)
updateTextbox("#exp", o.example);
else
updateTextbox("#exp", "");
updateTextbox("#decls", o.declarations.join("\n"));
updateTextbox("#defs", o.definitions.join("\n"));
}
function onload()
{
var optionTree = document.getElementById("option-tree");
// gProgressBar = document.getElementById("progress-bar");
// setProgress(0, 1);
gNixOS = new NixOS();
gOptionView = new OptionView(gNixOS.option, updatePanel);
optionTree.view = gOptionView;
}

View File

@@ -1,63 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE window>
<!-- To edit this file I recommend you to use:
http://xulfr.org/outils/xulediteur.xul
-->
<window
id = "nixos-gui"
title = "NixOS gui"
width = "800"
height = "600"
xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="jquery-1.5.2.js"/>
<script src="io.js"/>
<script src="nixos.js"/>
<script src="optionView.js"/>
<script src="main.js"/>
<hbox flex="1">
<vbox width="250">
<tree flex="1" id="option-tree" persist="height" onselect="gOptionView.selectionChanged()">
<treecols>
<treecol persist="hidden width" flex="9" id="opt-name"
label="Option" primary="true"/>
<!-- Uncomment the following column to see the number of option
printed below each options. -->
<!--
<treecol persist="hidden width" flex="1" id="dbg-size"
label="sz"/>
-->
</treecols>
<treechildren id="first-child" flex="1"/>
</tree>
</vbox>
<vbox flex="3" style="overflow: auto">
<caption id="name" label=""/>
<caption id="typename" label=""/>
<separator/>
<description id="desc" hidden="false"></description>
<separator/>
<caption label="Value:"/>
<textbox id="val" readonly="true" multiline="true" value=""
class="plain" hidden="false" onoverflow="this.height =
this.inputField.scrollHeight;" />
<separator/>
<caption label="Default:"/>
<textbox id="def" readonly="true" multiline="true" value="" class="plain" hidden="false" onoverflow="this.height = this.inputField.scrollHeight;" />
<separator/>
<caption label="Example:"/>
<textbox id="exp" readonly="true" multiline="true" value="" class="plain" hidden="false" onoverflow="this.height = this.inputField.scrollHeight;" />
<separator/>
<caption label="Declarations:"/>
<textbox id="decls" readonly="true" multiline="true" value="" class="plain" hidden="false" onoverflow="this.height = this.inputField.scrollHeight;" />
<separator/>
<caption label="Definitions:"/>
<textbox id="defs" readonly="true" multiline="true" value=""
class="plain" hidden="false" onoverflow="this.height = this.inputField.scrollHeight;" />
</vbox>
</hbox>
<!-- <progressmeter id="progress-bar" value="0%"/> -->
</window>

View File

@@ -1,255 +0,0 @@
function NixOS () {
var env = Components.classes["@mozilla.org/process/environment;1"].
getService(Components.interfaces.nsIEnvironment);
if (env.exists("NIXOS"))
this.nixos = env.get("NIXOS");
if (env.exists("NIXOS_CONFIG"))
this.config = env.get("NIXOS_CONFIG");
if (env.exists("NIXPKGS"))
this.nixpkgs = env.get("NIXPKGS");
if (env.exists("mountPoint"))
this.root = env.get("mountPoint");
if (env.exists("NIXOS_OPTION"))
this.optionBin = env.get("NIXOS_OPTION");
this.option = new Option("options", this, null);
};
NixOS.prototype = {
root: "",
nixos: "/etc/nixos/nixos",
nixpkgs: "/etc/nixos/nixpkgs",
config: "/etc/nixos/configuration.nix",
instantiateBin: "/run/current-system/sw/bin/nix-instantiate",
optionBin: "/run/current-system/sw/bin/nixos-option",
tmpFile: "nixos-gui",
option: null
};
function Option (name, context, parent) {
this.name = name;
this.context_ = context;
if (parent == null)
this.path = "";
else if (parent.path == "")
this.path = name;
else
this.path = parent.path + "." + name;
};
Option.prototype = {
load: function () {
var env = "";
env += "'NIXOS=" + this.context_.root + this.context_.nixos + "' ";
env += "'NIXOS_PKGS=" + this.context_.root + this.context_.nixpkgs + "' ";
env += "'NIXOS_CONFIG=" + this.context_.config + "' ";
var out = makeTempFile(this.context_.tmpFile);
var prog = this.context_.optionBin + " 2>&1 >" + out.path + " ";
var args = " --xml " + this.path;
runProgram(/*env + */ prog + args);
var xml = readFromFile(out);
out.remove(false);
// jQuery does a stack overflow when converting a huge XML to a DOM.
var dom = DOMParser().parseFromString(xml, "text/xml");
var xmlAttrs = $("expr > attrs > attr", dom);
this.isOption = xmlAttrs.first().attr("name") == "_isOption";
if (!this.isOption)
this.loadSubOptions(xmlAttrs);
else
this.loadOption(xmlAttrs);
this.isLoaded = true;
},
loadSubOptions: function (xmlAttrs) {
var cur = this;
var attrs = new Array();
xmlAttrs.each(
function (index) {
var name = $(this).attr("name");
var attr = new Option(name, cur.context_, cur);
attrs.push(attr);
}
);
this.subOptions = attrs;
},
optionAttributeMap: {
_isOption: function (cur, v) { },
value: function (cur, v) { cur.value = xml2nix($(v).children().first()); },
default: function (cur, v) { cur.defaultValue = xml2nix($(v).children().first()); },
example: function (cur, v) { cur.example = xml2nix($(v).children().first()); },
description: function (cur, v) { cur.description = this.string(v); },
typename: function (cur, v) { cur.typename = this.string(v); },
options: function (cur, v) { cur.loadSubOptions($("attrs", v).children()); },
declarations: function (cur, v) { cur.declarations = this.pathList(v); },
definitions: function (cur, v) { cur.definitions = this.pathList(v); },
string: function (v) {
return $(v).children("string").first().attr("value");
},
pathList: function (v) {
var list = [];
$(v).children("list").first().children().each(
function (idx) {
list.push($(this).attr("value"));
}
);
return list;
}
},
loadOption: function (attrs) {
var cur = this;
attrs.each(
function (index) {
var name = $(this).attr("name");
log("loadOption: " + name);
cur.optionAttributeMap[name](cur, this);
}
);
},
// keep the context under which this option has been used.
context_: null,
// name of the option.
name: "",
// result of nixos-option.
value: null,
typename: null,
defaultValue: null,
example: null,
description: "",
declarations: [],
definitions: [],
// path to reach this option
path: "",
// list of options accessible from here.
isLoaded: false,
isOption: false,
subOptions: []
};
var xml2nix_pptable = {
attrs: function (node, depth, pp) {
var children = node.children().not(
function () {
var name = $(this).attr("name");
return name.charAt(0) == "_";
}
);
var c = 0;
var out = "";
out += "{";
depth += 1;
children.each(
function (idx) {
c += 1;
out += pp.indent(depth);
out += pp.dispatch($(this), depth, pp);
}
);
depth -= 1;
if (c > 0)
out += this.indent(depth);
else
out += " ";
out += "}";
return out;
},
list: function (node, depth, pp) {
var children = node.children();
var c = 0;
var out = "";
out += "[";
depth += 1;
children.each(
function (idx) {
c += 1;
out += pp.indent(depth);
out += pp.dispatch($(this), depth, pp);
}
);
depth -= 1;
if (c > 0)
out += this.indent(depth);
else
out += " ";
out += "]";
return out;
},
attr: function (node, depth, pp) {
var name = node.attr("name");
var out = "";
var val = "";
out += name + " = ";
depth += 1;
val = pp.dispatch(node.children().first(), depth, pp);
out += val;
depth -= 1;
out += ";";
return out;
},
string: function (node, depth, pp) {
return "\"" + node.attr("value") + "\"";
},
path: function (node, depth, pp) {
return node.attr("value");
},
bool: function (node, depth, pp) {
return node.attr("value");
},
"int": function (node, depth, pp) {
return node.attr("value");
},
null: function (node, depth, pp) {
return "null";
},
derivation: function (node, depth, pp) {
return "<derivation>";
},
function: function (node, depth, pp) {
return "<function>";
},
unevaluated: function (node, depth, pp) {
return "<unevaluated>";
},
dispatch: function (node, depth, pp) {
for (var key in pp)
{
if(node.is(key))
{
// log(this.indent(depth) + "dispatch: " + key);
var out = pp[key](node, depth, pp);
// log(this.indent(depth) + "dispatch: => " + out);
return out;
}
}
return "<dispatch-error>";
},
indent: function (depth) {
var ret = "\n";
while (depth--)
ret += " ";
return ret;
}
};
function xml2nix(node) {
var depth = 0;
var pp = xml2nix_pptable;
var out = pp.dispatch(node, depth, pp);
// log("pretty:\n" + out);
return out;
}

View File

@@ -1,242 +0,0 @@
// extend NixOS options to handle the Tree View. Should be better to keep a
// separation of concern here.
Option.prototype.tv_opened = false;
Option.prototype.tv_size = 1;
Option.prototype.tv_open = function () {
this.tv_opened = true;
this.tv_size = 1;
// load an option if it is not loaded yet, and initialize them to be
// read by the Option view.
if (!this.isLoaded)
this.load();
// If this is not an option, then add it's lits of sub-options size.
if (!this.isOption)
{
for (var i = 0; i < this.subOptions.length; i++)
this.tv_size += this.subOptions[i].tv_size;
}
};
Option.prototype.tv_close = function () {
this.tv_opened = false;
this.tv_size = 1;
};
function OptionView (root, selCallback) {
root.tv_open();
this.rootOption = root;
this.selCallback = selCallback;
}
OptionView.prototype = {
rootOption: null,
selCallback: null,
// This function returns the path to option which is at the specified row.
reach_cache: null,
reachRow: function (row) {
var o = this.rootOption; // Current option.
var r = 0; // Number of rows traversed.
var c = 0; // Child index.
var path = [{ row: r, opt: o }]; // new Array();
// hypothesis: this.rootOption.tv_size is always open and bigger than
// Use the previous returned value to avoid making to many checks and to
// optimize for frequent access of near rows.
if (this.reach_cache != null)
{
for (var i = this.reach_cache.length - 2; i >= 0; i--) {
var p = this.reach_cache[i];
// If we will have to go the same path.
if (row >= p.row && row < p.row + p.opt.tv_size)
{
path.unshift(p);
r = path[0].row;
o = path[0].opt;
}
else
break;
};
}
while (r != row)
{
// Go deeper in the child which contains the requested row. The
// tv_size contains the size of the tree starting from each option.
c = 0;
while (c < o.subOptions.length && r + o.subOptions[c].tv_size < row)
{
r += o.subOptions[c].tv_size;
c += 1;
}
if (c < o.subOptions.length && r + o.subOptions[c].tv_size >= row)
{
// Count the current option as a row.
o = o.subOptions[c];
r += 1;
}
else
alert("WTF: " + o.name + " ask: " + row + " children: " + o.subOptions + " c: " + c);
path.unshift({ row: r, opt: o });
}
this.reach_cache = path;
return path;
},
// needs to return true if there is a /row/ at the same level /after/ a
// given row.
hasNextSibling: function(row, after) {
log("sibling " + row + " after " + after);
var path = reachRow(row);
if (path.length > 1)
{
var last = path[1].row + path[1].opt.tv_size;
// Has a next sibling if the row is not over the size of the
// parent and if the current one is not the last child.
return after + 1 < last && path[0].row + path[0].opt.tv_size < last;
}
else
// The top-level option has no sibling.
return false;
},
// Does the current row contain any sub-options?
isContainer: function(row) {
return !this.reachRow(row)[0].opt.isOption;
},
isContainerEmpty: function(row) {
return this.reachRow(row)[0].opt.subOptions.length == 0;
},
isContainerOpen: function(row) {
return this.reachRow(row)[0].opt.tv_opened;
},
// Open or close an option.
toggleOpenState: function (row) {
var path = this.reachRow(row);
var delta = -path[0].opt.tv_size;
if (path[0].opt.tv_opened)
path[0].opt.tv_close();
else
path[0].opt.tv_open();
delta += path[0].opt.tv_size;
// Parents are alreay opened, but we need to update the tv_size
// counters. Thus we have to invalidate the reach cache.
this.reach_cache = null;
for (var i = 1; i < path.length; i++)
path[i].opt.tv_open();
this.tree.rowCountChanged(row + 1, delta);
},
// Return the identation level of the option at the line /row/. The
// top-level level is 0.
getLevel: function(row) {
return this.reachRow(row).length - 1;
},
// Obtain the index of a parent row. If there is no parent row,
// returns -1.
getParentIndex: function(row) {
var path = this.reachRow(row);
if (path.length > 1)
return path[1].row;
else
return -1;
},
// Return the content of each row base on the column name.
getCellText: function(row, column) {
if (column.id == "opt-name")
return this.reachRow(row)[0].opt.name;
if (column.id == "dbg-size")
return this.reachRow(row)[0].opt.tv_size;
return "";
},
// We have no column with images.
getCellValue: function(row, column) { },
isSelectable: function(row, column) { return true; },
// Get the selection out of the tree and give options to the call back
// function.
selectionChanged: function() {
if (this.selCallback == null)
return;
var opts = [];
var start = new Object();
var end = new Object();
var numRanges = this.tree.view.selection.getRangeCount();
for (var t = 0; t < numRanges; t++) {
this.tree.view.selection.getRangeAt(t,start,end);
for (var v = start.value; v <= end.value; v++) {
var opt = this.reachRow(v)[0].opt;
if (!opt.isLoaded)
opt.load();
if (opt.isOption)
opts.push(opt);
// FIXME: no need to make things slowing down, because our current
// callback do not handle multiple option display.
if (!opts.empty)
break;
}
// FIXME: no need to make things slowing down, because our current
// callback do not handle multiple option display.
if (!opts.empty)
break;
}
if (!opts.empty)
this.selCallback(opts);
},
set rowCount(c) { throw "rowCount is a readonly property"; },
get rowCount() { return this.rootOption.tv_size; },
// refuse drag-n-drop of options.
canDrop: function (index, orientation, dataTransfer) { return false; },
drop: function (index, orientation, dataTransfer) { },
// ?
getCellProperties: function(row, column, prop) { },
getColumnProperties: function(column, prop) { },
getRowProperties: function(row, prop) { },
getImageSrc: function(row, column) { },
// No progress columns are used.
getProgressMode: function(row, column) { },
// Do not add options yet.
isEditable: function(row, column) { return false; },
setCellValue: function(row, column, value) { },
setCellText: function(row, column, value) { },
// ...
isSeparator: function(index) { return false; },
isSorted: function() { return false; },
performAction: function(action) { },
performActionOnCell: function(action, row, column) { },
performActionOnRow: function(action, row) { }, // ??
// ??
cycleCell: function (row, col) { },
cycleHeader: function(col) { },
selection: null,
tree: null,
setTree: function(tree) { this.tree = tree; }
};

View File

@@ -1,154 +0,0 @@
const nsIAppShellService = Components.interfaces.nsIAppShellService;
const nsISupports = Components.interfaces.nsISupports;
const nsICategoryManager = Components.interfaces.nsICategoryManager;
const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
const nsICommandLine = Components.interfaces.nsICommandLine;
const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
const nsIFactory = Components.interfaces.nsIFactory;
const nsIModule = Components.interfaces.nsIModule;
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
// CHANGEME: to the chrome URI of your extension or application
const CHROME_URI = "chrome://nixos-gui/content/myviewer.xul";
// CHANGEME: change the contract id, CID, and category to be unique
// to your application.
const clh_contractID = "@mozilla.org/commandlinehandler/general-startup;1?type=myapp";
// use uuidgen to generate a unique ID
const clh_CID = Components.ID("{2991c315-b871-42cd-b33f-bfee4fcbf682}");
// category names are sorted alphabetically. Typical command-line handlers use a
// category that begins with the letter "m".
const clh_category = "m-myapp";
/**
* Utility functions
*/
/**
* Opens a chrome window.
* @param aChromeURISpec a string specifying the URI of the window to open.
* @param aArgument an argument to pass to the window (may be null)
*/
function openWindow(aChromeURISpec, aArgument)
{
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
getService(Components.interfaces.nsIWindowWatcher);
ww.openWindow(null, aChromeURISpec, "_blank",
"chrome,menubar,toolbar,status,resizable,dialog=no",
aArgument);
}
/**
* The XPCOM component that implements nsICommandLineHandler.
* It also implements nsIFactory to serve as its own singleton factory.
*/
const myAppHandler = {
/* nsISupports */
QueryInterface : function clh_QI(iid)
{
if (iid.equals(nsICommandLineHandler) ||
iid.equals(nsIFactory) ||
iid.equals(nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
/* nsICommandLineHandler */
handle : function clh_handle(cmdLine)
{
openWindow(CHROME_URI, cmdLine);
cmdLine.preventDefault = true;
},
// CHANGEME: change the help info as appropriate, but
// follow the guidelines in nsICommandLineHandler.idl
// specifically, flag descriptions should start at
// character 24, and lines should be wrapped at
// 72 characters with embedded newlines,
// and finally, the string should end with a newline
helpInfo : " <filename> Open the file in the viewer\n",
/* nsIFactory */
createInstance : function clh_CI(outer, iid)
{
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
lockFactory : function clh_lock(lock)
{
/* no-op */
}
};
/**
* The XPCOM glue that implements nsIModule
*/
const myAppHandlerModule = {
/* nsISupports */
QueryInterface : function mod_QI(iid)
{
if (iid.equals(nsIModule) ||
iid.equals(nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
/* nsIModule */
getClassObject : function mod_gch(compMgr, cid, iid)
{
if (cid.equals(clh_CID))
return myAppHandler.QueryInterface(iid);
throw Components.results.NS_ERROR_NOT_REGISTERED;
},
registerSelf : function mod_regself(compMgr, fileSpec, location, type)
{
compMgr.QueryInterface(nsIComponentRegistrar);
compMgr.registerFactoryLocation(clh_CID,
"myAppHandler",
clh_contractID,
fileSpec,
location,
type);
var catMan = Components.classes["@mozilla.org/categorymanager;1"].
getService(nsICategoryManager);
catMan.addCategoryEntry("command-line-handler",
clh_category,
clh_contractID, true, true);
},
unregisterSelf : function mod_unreg(compMgr, location, type)
{
compMgr.QueryInterface(nsIComponentRegistrar);
compMgr.unregisterFactoryLocation(clh_CID, location);
var catMan = Components.classes["@mozilla.org/categorymanager;1"].
getService(nsICategoryManager);
catMan.deleteCategoryEntry("command-line-handler", clh_category);
},
canUnload : function (compMgr)
{
return true;
}
};
/* The NSGetModule function is the magic entry point that XPCOM uses to find what XPCOM objects
* this component provides
*/
function NSGetModule(comMgr, fileSpec)
{
return myAppHandlerModule;
}

View File

@@ -1,11 +0,0 @@
pref("toolkit.defaultChromeURI", "chrome://nixos-gui/content/myviewer.xul");
pref("general.useragent.extra.myviewer", "NixOS gui/0.0");
/* debugging prefs */
pref("browser.dom.window.dump.enabled", true); // enable output to stderr
pref("javascript.options.showInConsole", true); // show javascript errors from chrome: files in the jsconsole
pref("javascript.options.strict", true); // show javascript strict warnings in the jsconsole
/* disable xul cache so that modifications to chrome: files apply without restarting xulrunner */
pref("nglayout.debug.disable_xul_cache", true);
pref("nglayout.debug.disable_xul_fastload", true);

View File

@@ -1,87 +0,0 @@
{ system, minimal ? false }:
let pkgs = import ./nixpkgs.nix { config = {}; inherit system; }; in
with pkgs.lib;
with import ../lib/qemu-flags.nix;
rec {
inherit pkgs;
# Build a virtual network from an attribute set `{ machine1 =
# config1; ... machineN = configN; }', where `machineX' is the
# hostname and `configX' is a NixOS system configuration. Each
# machine is given an arbitrary IP address in the virtual network.
buildVirtualNetwork =
nodes: let nodesOut = mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes); in nodesOut;
buildVM =
nodes: configurations:
import ./eval-config.nix {
inherit system;
modules = configurations ++
[ ../modules/virtualisation/qemu-vm.nix
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
{ key = "no-manual"; services.nixosManual.enable = false; }
] ++ optional minimal ../modules/testing/minimal-kernel.nix;
extraArgs = { inherit nodes; };
};
# Given an attribute set { machine1 = config1; ... machineN =
# configN; }, sequentially assign IP addresses in the 192.168.1.0/24
# range to each machine, and set the hostname to the attribute name.
assignIPAddresses = nodes:
let
machines = attrNames nodes;
machinesNumbered = zipTwoLists machines (range 1 254);
nodes_ = flip map machinesNumbered (m: nameValuePair m.first
[ ( { config, pkgs, nodes, ... }:
let
interfacesNumbered = zipTwoLists config.virtualisation.vlans (range 1 255);
interfaces = flip map interfacesNumbered ({ first, second }:
nameValuePair "eth${toString second}"
{ ipAddress = "192.168.${toString first}.${toString m.second}";
subnetMask = "255.255.255.0";
});
in
{ key = "ip-address";
config =
{ networking.hostName = m.first;
networking.interfaces = listToAttrs interfaces;
networking.primaryIPAddress =
optionalString (interfaces != []) (head interfaces).value.ipAddress;
# Put the IP addresses of all VMs in this machine's
# /etc/hosts file. If a machine has multiple
# interfaces, use the IP address corresponding to
# the first interface (i.e. the first network in its
# virtualisation.vlans option).
networking.extraHosts = flip concatMapStrings machines
(m': let config = (getAttr m' nodes).config; in
optionalString (m.first != m' && config.networking.primaryIPAddress != "")
("${config.networking.primaryIPAddress} " +
"${config.networking.hostName}\n"));
virtualisation.qemu.options =
flip map interfacesNumbered
({ first, second }: qemuNICFlags second first m.second);
};
}
)
(getAttr m.first nodes)
] );
in listToAttrs nodes_;
}

View File

@@ -1,6 +0,0 @@
{ system ? builtins.currentSystem }:
{ pkgs =
(import nixpkgs/default.nix { inherit system; })
// { recurseForDerivations = true; };
}

View File

@@ -1,71 +0,0 @@
# From an end-user configuration file (`configuration'), build a NixOS
# configuration object (`config') from which we can retrieve option
# values.
{ system ? builtins.currentSystem
, pkgs ? null
, baseModules ? import ../modules/module-list.nix
, extraArgs ? {}
, modules
, check ? true
, prefix ? []
}:
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in
rec {
# Merge the option definitions in all modules, forming the full
# system configuration.
inherit (pkgs.lib.evalModules {
inherit prefix;
modules = modules ++ baseModules;
args = extraArgs;
check = check && options.environment.checkConfigurationOptions.value;
}) config options;
# These are the extra arguments passed to every module. In
# particular, Nixpkgs is passed through the "pkgs" argument.
# FIXME: we enable config.allowUnfree to make packages like
# nvidia-x11 available. This isn't a problem because if the user has
# nixpkgs.config.allowUnfree = false, then evaluation will fail on
# the 64-bit package anyway. However, it would be cleaner to respect
# nixpkgs.config here.
extraArgs = extraArgs_ // {
inherit pkgs modules baseModules;
modulesPath = ../modules;
pkgs_i686 = import ./nixpkgs.nix { system = "i686-linux"; config.allowUnfree = true; };
utils = import ./utils.nix pkgs;
};
# Import Nixpkgs, allowing the NixOS option nixpkgs.config to
# specify the Nixpkgs configuration (e.g., to set package options
# such as firefox.enableGeckoMediaPlayer, or to apply global
# overrides such as changing GCC throughout the system), and the
# option nixpkgs.system to override the platform type. This is
# tricky, because we have to prevent an infinite recursion: "pkgs"
# is passed as an argument to NixOS modules, but the value of "pkgs"
# depends on config.nixpkgs.config, which we get from the modules.
# So we call ourselves here with "pkgs" explicitly set to an
# instance that doesn't depend on nixpkgs.config.
pkgs =
if pkgs_ != null
then pkgs_
else import ./nixpkgs.nix (
let
system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_;
nixpkgsOptions = (import ./eval-config.nix {
inherit system extraArgs modules prefix;
# For efficiency, leave out most NixOS modules; they don't
# define nixpkgs.config, so it's pointless to evaluate them.
baseModules = [ ../modules/misc/nixpkgs.nix ../modules/config/no-x-libs.nix ];
pkgs = import ./nixpkgs.nix { system = system_; config = {}; };
check = false;
}).config.nixpkgs;
in
{
inherit system;
inherit (nixpkgsOptions) config;
});
}

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