Compare commits

...

38 Commits

Author SHA1 Message Date
Eelco Dolstra
d566ad9d61 * Tagged Nix 0.13. 2009-11-05 22:23:15 +00:00
Eelco Dolstra
e8bad77c7c 2009-11-05 15:20:19 +00:00
Eelco Dolstra
7680904839 * Build on Karmic. 2009-11-05 14:53:01 +00:00
Eelco Dolstra
58f3338bfa * The Nix .deb package depends on curl. 2009-11-05 14:40:42 +00:00
Eelco Dolstra
268d90a03e * Various updates. 2009-11-05 09:07:43 +00:00
Eelco Dolstra
1ff8758f76 * Manual updates. 2009-11-04 16:52:35 +00:00
Eelco Dolstra
8520542071 * When building in a chroot, make a copy of a file if hard-linking
fails.  This is likely to happen after a `nix-store --optimise',
  because some files may have 32000 links (NIX-111).
2009-10-22 08:28:33 +00:00
Eelco Dolstra
6b9f6b0222 * Remove a prototype for a function that no longer exists. 2009-10-22 08:12:38 +00:00
Eelco Dolstra
deb342fb08 * builtins.trace: in the common case that the value is a string, then
show the string, not the ATerm, so we get `trace: bla' instead of
  `trace: Str("bla",[])'.
2009-10-22 08:10:12 +00:00
Eelco Dolstra
437077c39d * Added a primop unsafeDiscardOutputDependency needed by Disnix to
pass derivation paths to a builder without actually building them.
2009-10-21 15:05:30 +00:00
Eelco Dolstra
6f7d7bc1de * Give a useful error message when an evaluation error occurs while
trying to upgrade a package.
2009-10-13 09:30:17 +00:00
Sander van der Burg
53a4981fa2 Added optional parameter which adds -lnsl -lsocket to make the Nix package manager work on OpenSolaris 2009-10-08 14:50:37 +00:00
Peter Simons
18f0ff003d configure.ac: use AC_SYS_LARGEFILE to determine how to enable 64-bit file size support
Defining -D_FILE_OFFSET_BITS=64 works on most platforms, but not on all (i.e.
Solaris). Also, the Autoconf macro offers the user a switch to disable the
functionality in case of problems.
2009-10-06 09:14:06 +00:00
Eelco Dolstra
96f1517831 * Support platforms that don't have O_ASYNC (e.g. OpenSolaris
apparently).
2009-09-30 11:32:04 +00:00
Eelco Dolstra
1a8f8fd86f * OpenSolaris compatibility. 2009-09-30 09:54:29 +00:00
Eelco Dolstra
0f79ad47c5 2009-09-25 12:36:03 +00:00
Eelco Dolstra
c7057fc1f2 * And some more. 2009-09-24 07:39:55 +00:00
Eelco Dolstra
193f59e077 * Fix a build failure on Fedora 11. rename() needs <stdio.h>. 2009-09-24 07:21:29 +00:00
Eelco Dolstra
0ae2be5692 2009-09-24 07:05:06 +00:00
Eelco Dolstra
1332dd1ed3 * tryEval shouldn't catch all exceptions of type Error, since not all
of them leave the evaluator in a continuable state.  Also, it should
  be less chatty.
2009-09-23 19:19:26 +00:00
Eelco Dolstra
63a17d4bd5 * Don't build against BDB on Cygwin, it's been broken for unknown
reasons for a while (e.g. http://hydra.nixos.org/build/79164).
2009-09-23 18:52:18 +00:00
Eelco Dolstra
676e07902e * Darwin hack. 2009-09-23 18:04:55 +00:00
Eelco Dolstra
64e89980e8 * Create some state directories automatically as a convenience. 2009-09-23 17:05:51 +00:00
Rob Vermaas
48b58617e9 * include wait.h for WEXITSTATUS 2009-09-23 12:57:15 +00:00
Eelco Dolstra
51ad64cc07 * Use xmllint (>= 2.7.4) for RelaxNG validation instead of Jing. 2009-09-18 11:45:56 +00:00
Eelco Dolstra
df05a759e4 * In "make init-state", ignore errors creating /nix/store. Hack to
get the Debian VM builds to work (where /nix/store is a mount point
  containing the store of the host).
2009-09-18 11:01:30 +00:00
Eelco Dolstra
d3de71efc9 2009-09-17 17:44:13 +00:00
Eelco Dolstra
e1df4ef73c 2009-09-17 17:02:14 +00:00
Eelco Dolstra
86408b3f47 * build-remote.pl: Pick machines in a round-robin order, rather than
giving jobs to the first machine until it hits its job limit, then
  the second machine and so on.  This should improve utilisation of
  the Hydra build farm a lot.  Also take an optional speed factor
  into account to cause fast machines to be preferred over slower
  machines with a similar load.
2009-09-17 15:48:17 +00:00
Eelco Dolstra
57e0d73c77 * build-remote.pl: allow the system type to be a comma-separated list
of system types.  Don't treat the x86_64-linux system type
  specially.
2009-09-17 13:51:04 +00:00
Eelco Dolstra
0dbd4638e0 * Two primops: builtins.intersectAttrs and builtins.functionArgs.
intersectAttrs returns the (right-biased) intersection between two
  attribute sets, e.g. every attribute from the second set that also
  exists in the first.  functionArgs returns the set of attributes
  expected by a function.

  The main goal of these is to allow the elimination of most of
  all-packages.nix.  Most package instantiations in all-packages.nix
  have this form:

    foo = import ./foo.nix {
      inherit a b c;
    };

  With intersectAttrs and functionArgs, this can be written as:

    foo = callPackage (import ./foo.nix) { };

  where

   callPackage = f: args:
     f ((builtins.intersectAttrs (builtins.functionArgs f) pkgs) // args);

  I.e., foo.nix is called with all attributes from "pkgs" that it
  actually needs (e.g., pkgs.a, pkgs.b and pkgs.c).  (callPackage can
  do any other generic package-level stuff we might want, such as
  applying makeOverridable.)  Of course, the automatically supplied
  arguments can be overriden if needed, e.g.

    foo = callPackage (import ./foo.nix) {
      c = c_version_2;
    };

  but for the vast majority of packages, this won't be needed.

  The advantages are to reduce the amount of typing needed to add a
  dependency (from three sites to two), and to reduce the number of
  trivial commits to all-packages.nix.  For the former, there have
  been two previous attempts:

    - Use "args: with args;" in the package's function definition.
      This however obscures the actual expected arguments of a
      function, which is very bad.

    - Use "{ arg1, arg2, ... }:" in the package's function definition
      (i.e. use the ellipis "..." to allow arbitrary additional
      arguments), and then call the function with all of "pkgs" as an
      argument.  But this inhibits error detection if you call it with
      an misspelled (or obsolete) argument.
2009-09-15 13:01:46 +00:00
Michael Raskin
3bca8931e8 Adding tryEval builtin. It allows to catch presence of errors in an expression. 2009-08-25 16:06:46 +00:00
Eelco Dolstra
5e9a4e5101 2009-08-03 13:32:13 +00:00
Eelco Dolstra
9b46d1ae6f 2009-08-03 12:24:20 +00:00
Eelco Dolstra
20b6f94b65 * nix-build: pass the --show-trace flag. 2009-07-15 09:10:38 +00:00
Eelco Dolstra
d413612029 * Remove the redundant <sections> around refentries. 2009-07-14 14:58:12 +00:00
Eelco Dolstra
1f169f43b3 * Leave out the collaborators / revision history page. 2009-07-10 13:42:12 +00:00
Eelco Dolstra
5e2e2f10ef 2009-07-10 11:48:49 +00:00
44 changed files with 608 additions and 333 deletions

View File

@@ -33,7 +33,7 @@ init-state:
$(INSTALL) $(INIT_FLAGS) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/gcroots/channels
ln -sfn $(localstatedir)/nix/profiles $(DESTDIR)$(localstatedir)/nix/gcroots/profiles
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix/userpool
$(INSTALL) $(INIT_FLAGS) -m 1777 -d $(DESTDIR)$(storedir)
-$(INSTALL) $(INIT_FLAGS) -m 1777 -d $(DESTDIR)$(storedir)
$(INSTALL) $(INIT_FLAGS) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/manifests
ln -sfn $(localstatedir)/nix/manifests $(DESTDIR)$(localstatedir)/nix/gcroots/manifests

View File

@@ -55,7 +55,7 @@ test "$localstatedir" = '${prefix}/var' && localstatedir=/nix/var
# except that it requires the ATerm "lib" directory to be in $PATH, as
# Windows doesn't have anything like an RPATH embedded in executable.
# Since this is kind of annoying, we use static libraries for now.
AC_ARG_ENABLE(static-nix, AC_HELP_STRING([--enable-static-nix],
[produce statically linked binaries]),
static_nix=$enableval, static_nix=no)
@@ -63,19 +63,25 @@ AC_ARG_ENABLE(static-nix, AC_HELP_STRING([--enable-static-nix],
if test "$sys_name" = cygwin; then
static_nix=yes
fi
if test "$static_nix" = yes; then
AC_DISABLE_SHARED
AC_ENABLE_STATIC
fi
# Windows-specific stuff.
if test "$sys_name" = "cygwin"; then
# We cannot delete open files.
AC_DEFINE(CANNOT_DELETE_OPEN_FILES, 1, [Whether it is impossible to delete open files.])
fi
# Solaris-specific stuff.
if test "$sys_name" = "sunos"; then
# Solaris requires -lsocket -lnsl for network functions
ADDITIONAL_NETWORK_LIBS="-lsocket -lnsl"
AC_SUBST(ADDITIONAL_NETWORK_LIBS)
fi
AC_PROG_CC
AC_PROG_CXX
@@ -88,8 +94,7 @@ AC_PROG_LIBTOOL
# Use 64-bit file system calls so that we can support files > 2 GiB.
CFLAGS="-D_FILE_OFFSET_BITS=64 $CFLAGS"
CXXFLAGS="-D_FILE_OFFSET_BITS=64 $CXXFLAGS"
AC_SYS_LARGEFILE
# Check for pubsetbuf.
@@ -140,7 +145,6 @@ NEED_PROG(bash, bash)
NEED_PROG(patch, patch)
AC_PATH_PROG(xmllint, xmllint, false)
AC_PATH_PROG(xsltproc, xsltproc, false)
AC_PATH_PROG(jing, jing, false) # needed because xmllint --relaxng seems broken
AC_PATH_PROG(w3m, w3m, false)
AC_PATH_PROG(flex, flex, false)
AC_PATH_PROG(bison, bison, false)
@@ -260,7 +264,7 @@ else
bzip2_include="-I$bzip2/include"
bzip2_bin="$bzip2/bin"
bzip2_bin_test="$bzip2/bin"
fi
fi
AC_SUBST(bzip2_lib)
AC_SUBST(bzip2_include)
AC_SUBST(bzip2_bin)

View File

@@ -6,7 +6,12 @@ XSLTPROC = $(xsltproc) $(xmlflags) \
--param xref.with.number.and.title 1 \
--param toc.section.depth 3 \
--param admon.style \'\' \
--param callout.graphics.extension \'.gif\'
--param callout.graphics.extension \'.gif\' \
--param contrib.inline.enabled 0
dblatex_opts = \
-P doc.collab.show=0 \
-P latex.output.revhistory=0
# Note: we use GIF for now, since the PNGs shipped with Docbook aren't
# transparent.
@@ -29,13 +34,9 @@ MANUAL_SRCS = manual.xml introduction.xml installation.xml \
conf-file.xml release-notes.xml \
style.css images
# Note: RelaxNG validation requires xmllint >= 2.7.4.
manual.is-valid: $(MANUAL_SRCS) version.txt
# $(XMLLINT) --xinclude $< | $(XMLLINT) --noout --nonet --relaxng $(docbookrng)/docbook.rng -
if test "$(jing)" != "false"; then \
$(XMLLINT) --xinclude $< | $(jing) $(docbookrng)/docbook.rng /dev/fd/0; \
else \
echo "Not validating."; \
fi
$(XMLLINT) --noout --nonet --xinclude --noxincludenode --relaxng $(docbookrng)/docbook.rng $<
touch $@
version.txt:
@@ -50,7 +51,7 @@ manual.html: $(MANUAL_SRCS) manual.is-valid images
manual.pdf: $(MANUAL_SRCS) manual.is-valid images
if test "$(dblatex)" != ""; then \
$(dblatex) manual.xml; \
$(dblatex) $(dblatex_opts) manual.xml; \
else \
echo "Please install dblatex and rerun configure."; \
exit 1; \

View File

@@ -324,6 +324,16 @@ x: x + 456</programlisting>
</varlistentry>
<varlistentry><term><function>builtins.intersectAttrs</function>
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
<listitem><para>Return an attribute set consisting of the
attributes in the set <replaceable>e2</replaceable> that also
exist in the set <replaceable>e1</replaceable>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.isAttrs</function>
<replaceable>e</replaceable></term>

View File

@@ -140,16 +140,25 @@ $ ./bootstrap</screen>
<para>The installation path can be specified by passing the
<option>--prefix=<replaceable>prefix</replaceable></option> to
<command>configure</command>. The default installation directory is
<filename>/nix</filename>. You can change this to any location you
like. You must have write permission to the
<filename>/usr/local</filename>. You can change this to any location
you like. You must have write permission to the
<replaceable>prefix</replaceable> path.</para>
<warning><para>It is best <emphasis>not</emphasis> to change the
installation prefix from its default, since doing so makes it
impossible to use pre-built binaries from the standard Nixpkgs
channels.</para></warning>
<para>Nix keeps its <emphasis>store</emphasis> (the place where
packages are stored) in <filename>/nix/store</filename> by default.
This can be changed using
<option>--with-store-dir=<replaceable>path</replaceable></option>.</para>
<para>If you want to rebuilt the documentation, pass the full path to
<warning><para>It is best <emphasis>not</emphasis> to change the Nix
store from its default, since doing so makes it impossible to use
pre-built binaries from the standard Nixpkgs channels — that is, all
packages will need to be built from source.</para></warning>
<para>Nix keeps state (such as its database and log files) in
<filename>/nix/var</filename> by default. This can be changed using
<option>--localstatedir=<replaceable>path</replaceable></option>.</para>
<para>If you want to rebuild the documentation, pass the full path to
the DocBook RELAX NG schemas and to the DocBook XSL stylesheets using
the
<option>--with-docbook-rng=<replaceable>path</replaceable></option>
@@ -160,27 +169,26 @@ options.</para>
</section>
<section><title>Installing from RPMs</title>
<section><title>Installing a binary distribution</title>
<para>RPM packages of Nix can be downloaded from <link
xlink:href="http://nixos.org/" />. These RPMs should work for most
fairly recent releases of SuSE and Red Hat Linux. They have been
known to work work on SuSE Linux 8.1 and 9.0, and Red Hat 9.0. In
fact, it should work on any RPM-based Linux distribution based on
<literal>glibc</literal> 2.3 or later.</para>
<para>Once downloaded, the RPMs can be installed or upgraded using
<command>rpm -U</command>. For example,
<para>RPM and Deb packages of Nix for a number of different versions
of Fedora, openSUSE, Debian and Ubuntu can be downloaded from <link
xlink:href="http://nixos.org/" />. Once downloaded, the RPMs can be
installed or upgraded using <command>rpm -U</command>. For example,
<screen>
$ rpm -U nix-0.5pre664-1.i386.rpm</screen>
$ rpm -U nix-0.13pre18104-1.i386.rpm</screen>
Likewise, for a Deb package:
<screen>
$ dpkg -i nix_0.13pre18104-1_amd64.deb</screen>
</para>
<para>The RPMs install into the directory <filename>/nix</filename>.
Nix can be uninstalled using <command>rpm -e nix</command>. After
this it will be necessary to manually remove the Nix store and other
auxiliary data:
<para>Nix can be uninstalled using <command>rpm -e nix</command> or
<command>dpkg -r nix</command>. After this you should manually remove
the Nix store and other auxiliary data, if desired:
<screen>
$ rm -rf /nix/store
@@ -191,6 +199,7 @@ $ rm -rf /nix/var</screen>
</section>
<!-- TODO: should be updated
<section><title>Upgrading Nix through Nix</title>
<para>You can install the latest stable version of Nix through Nix
@@ -203,6 +212,7 @@ installation</link> by clicking on the package links at <link
xlink:href="http://nixos.org/releases/full-index-nix.html" />.</para>
</section>
-->
<section><title>Security</title>

View File

@@ -320,7 +320,7 @@ overview of NixOS is given in the HotOS XI paper <citetitle
xlink:href="http://www.st.ewi.tudelft.nl/~dolstra/pubs/hotos-final.pdf">Purely
Functional System Configuration Management</citetitle>. The Nix
homepage has <link
xlink:href="http://nix.cs.uu.nl/docs/papers.html">an up-to-date list
xlink:href="http://nixos.org/docs/papers.html">an up-to-date list
of Nix-related papers</link>.</para>
<para>Nix is the subject of Eelco Dolstras PhD thesis <citetitle

View File

@@ -17,6 +17,7 @@
<orgname>Delft University of Technology</orgname>
<orgdiv>Department of Software Technology</orgdiv>
</affiliation>
<contrib>Author</contrib>
</author>
<copyright>
@@ -25,10 +26,11 @@
<year>2006</year>
<year>2007</year>
<year>2008</year>
<year>2009</year>
<holder>Eelco Dolstra</holder>
</copyright>
<date>November 2008</date>
<date>September 2009</date>
</info>
@@ -49,64 +51,25 @@
<section>
<title>Main commands</title>
<section xml:id="sec-nix-env">
<title>nix-env</title>
<xi:include href="nix-env.xml" />
</section>
<section xml:id="sec-nix-instantiate">
<title>nix-instantiate</title>
<xi:include href="nix-instantiate.xml" />
</section>
<section xml:id="sec-nix-store">
<title>nix-store</title>
<xi:include href="nix-store.xml" />
</section>
<xi:include href="nix-env.xml" />
<xi:include href="nix-instantiate.xml" />
<xi:include href="nix-store.xml" />
</section>
<section>
<title>Utilities</title>
<section xml:id="sec-nix-build">
<title>nix-build</title>
<xi:include href="nix-build.xml" />
</section>
<section xml:id="sec-nix-channel">
<title>nix-channel</title>
<xi:include href="nix-channel.xml" />
</section>
<section xml:id="sec-nix-collect-garbage">
<title>nix-collect-garbage</title>
<xi:include href="nix-collect-garbage.xml" />
</section>
<section xml:id="sec-nix-copy-closure">
<title>nix-copy-closure</title>
<xi:include href="nix-copy-closure.xml" />
</section>
<section xml:id="sec-nix-hash">
<title>nix-hash</title>
<xi:include href="nix-hash.xml" />
</section>
<section xml:id="sec-nix-install-package">
<title>nix-install-package</title>
<xi:include href="nix-install-package.xml" />
</section>
<section xml:id="sec-nix-prefetch-url">
<title>nix-prefetch-url</title>
<xi:include href="nix-prefetch-url.xml" />
</section>
<section xml:id="sec-nix-pull">
<title>nix-pull</title>
<xi:include href="nix-pull.xml" />
</section>
<section xml:id="sec-nix-push">
<title>nix-push</title>
<xi:include href="nix-push.xml" />
</section>
<section xml:id="sec-nix-worker">
<title>nix-worker</title>
<xi:include href="nix-worker.xml" />
</section>
<xi:include href="nix-build.xml" />
<xi:include href="nix-channel.xml" />
<xi:include href="nix-collect-garbage.xml" />
<xi:include href="nix-copy-closure.xml" />
<xi:include href="nix-hash.xml" />
<xi:include href="nix-install-package.xml" />
<xi:include href="nix-prefetch-url.xml" />
<xi:include href="nix-pull.xml" />
<xi:include href="nix-push.xml" />
<xi:include href="nix-worker.xml" />
</section>
</appendix>
<xi:include href="troubleshooting.xml" />

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-build">
<refmeta>
<refentrytitle>nix-build</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-channel">
<refmeta>
<refentrytitle>nix-channel</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-collect-garbage">
<refmeta>
<refentrytitle>nix-collect-garbage</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-copy-closure">
<refmeta>
<refentrytitle>nix-copy-closure</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-env">
<refmeta>
<refentrytitle>nix-env</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-hash">
<refmeta>
<refentrytitle>nix-hash</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-install-package">
<refmeta>
<refentrytitle>nix-install-package</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-instantiate">
<refmeta>
<refentrytitle>nix-instantiate</refentrytitle>

View File

@@ -178,100 +178,5 @@
</productionset>
</sect1>
<sect1>
<title>Semantics</title>
<sect2>
<title>Built-in functions</title>
<para>
The Nix language provides the following built-in function
(<quote>primops</quote>):
</para>
<variablelist>
<varlistentry>
<term><function>import</function>
<replaceable>e</replaceable></term>
<listitem>
<para>
Evaluates the expression <replaceable>e</replaceable>,
which must yield a path value. The Nix expression
stored at this path in the file system is then read,
parsed, and evaluated. Returns the result of the
evaluation of the Nix expression just read.
</para>
<para>
Example: <literal>import ./foo.nix</literal> evaluates
the expression stored in <filename>foo.nix</filename>
(in the directory containing the expression in which the
<function>import</function> occurs).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>derivation</function>
<replaceable>e</replaceable></term>
<listitem>
<para>
Evaluates the expression <replaceable>e</replaceable>,
which must yield an attribute set. [...]
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>baseNameOf</function>
<replaceable>e</replaceable></term>
<listitem>
<para>
Evaluates the expression <replaceable>e</replaceable>,
which must yield a string value, and returns a string
representing its <emphasis>base name</emphasis>. This
is the substring following the last path separator
(<literal>/</literal>).
</para>
<para>
Example: <literal>baseNameOf "/foo/bar"</literal>
returns <literal>"bar"</literal>, and
<literal>baseNameOf "/foo/bar/"</literal> returns
<literal>""</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>toString</function>
<replaceable>e</replaceable></term>
<listitem>
<para>
Evaluates the expression <replaceable>e</replaceable>
and coerces it into a string, if possible. Only
strings, paths, and URIs can be so coerced.
</para>
<para>
Example: <literal>toString
http://www.cs.uu.nl/</literal> returns
<literal>"http://www.cs.uu.nl/"</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
</sect1>
</appendix>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-prefetch-url">
<refmeta>
<refentrytitle>nix-prefetch-url</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-pull">
<refmeta>
<refentrytitle>nix-pull</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-push">
<refmeta>
<refentrytitle>nix-push</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-store">
<refmeta>
<refentrytitle>nix-store</refentrytitle>

View File

@@ -1,6 +1,7 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-worker">
<refmeta>
<refentrytitle>nix-worker</refentrytitle>

View File

@@ -331,7 +331,7 @@ default profile, respectively. If the profile doesnt exist, it will
be created automatically. You should be careful about storing a
profile in another location than the <filename>profiles</filename>
directory, since otherwise it might not be used as a root of the
garbage collector (see section <xref linkend='sec-garbage-collection'
garbage collector (see <xref linkend='sec-garbage-collection'
/>).</para>
<para>All <command>nix-env</command> operations work on the profile
@@ -507,19 +507,16 @@ click on it, and it will be installed with all the necessary
dependencies.</para>
<para>For instance, you can go to <link
xlink:href="http://nixos.org/releases/nixpkgs/nixpkgs-unstable/" />
or to any older release of Nix Packages — and click on any link for
the individual packages for your platform (say, <link
xlink:href='http://nix.cs.uu.nl/dist/nix/nixpkgs-0.10pre6622/pkgs/subversion-1.4.0-i686-linux.nixpkg'><literal>subversion-1.4.0</literal>
for <literal>i686-linux</literal></link>). The first time you do
this, your browser will ask what to do with
<literal>application/nix-package</literal> files. You should open
them with <filename>/nix/bin/nix-install-package</filename>. This
will open a window that asks you to confirm that you want to install
the package. When you answer <literal>Y</literal>, the package and
all its dependencies will be installed. This is a binary deployment
mechanism — you get packages pre-compiled for the selected platform
type.</para>
xlink:href="http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest"
/> and click on any link for the individual packages for your
platform. The first time you do this, your browser will ask what to
do with <literal>application/nix-package</literal> files. You should
open them with <filename>/nix/bin/nix-install-package</filename>.
This will open a window that asks you to confirm that you want to
install the package. When you answer <literal>Y</literal>, the
package and all its dependencies will be installed. This is a binary
deployment mechanism — you get packages pre-compiled for the selected
platform type.</para>
<para>You can also install <literal>application/nix-package</literal>
files from the command line directly. See <xref

View File

@@ -1,5 +1,6 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-quick-start">
<title>Quick Start</title>
@@ -10,9 +11,9 @@ to the following chapters.</para>
<orderedlist>
<listitem><para>Download a source tarball or RPM from <link
xlink:href='http://nixos.org/'/>. Build source
distributions using the regular sequence:
<listitem><para>Download a source tarball, RPM or Deb from <link
xlink:href='http://nixos.org/'/>. Build source distributions using
the regular sequence:
<screen>
$ tar xvfj nix-<replaceable>version</replaceable>.tar.bz2
@@ -20,13 +21,21 @@ $ ./configure
$ make
$ make install <lineannotation>(as root)</lineannotation></screen>
This will install Nix in <filename>/nix</filename>. You shouldn't
change the prefix if at all possible since that will make it
impossible to use pre-built binaries from the Nixpkgs channel and
other channels. Alternatively, you could grab an RPM if you're on an
RPM-based system. You should also add
<filename>/nix/etc/profile.d/nix.sh</filename> to your
<filename>~/.bashrc</filename> (or some other login
This will install the Nix binaries in <filename>/usr/local</filename>
and keep the Nix store and other state in <filename>/nix</filename>.
You can change the former by specifying
<option>--prefix=<replaceable>path</replaceable></option>. The
location of the store can be changed using
<option>--with-store-dir=<replaceable>path</replaceable></option>.
However, you shouldn't change the store location, if at all possible,
since that will make it impossible to use pre-built binaries from the
Nixpkgs channel and other channels. The location of the state can be
changed using
<option>--localstatedir=<replaceable>path</replaceable>.</option></para></listitem>
<listitem><para>You should add
<filename><replaceable>prefix</replaceable>/etc/profile.d/nix.sh</filename>
to your <filename>~/.bashrc</filename> (or some other login
file).</para></listitem>
<listitem><para>Subscribe to the Nix Packages channel.
@@ -99,7 +108,7 @@ numbers).</para></listitem>
<listitem><para>You can also install specific packages directly from
your web browser. For instance, you can go to <link
xlink:href="http://nix.cs.uu.nl/dist/nix/nixpkgs-unstable-latest/" />
xlink:href="http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest" />
and click on any link for the individual packages for your platform.
Associate <literal>application/nix-package</literal> with the program
<filename>/nix/bin/nix-install-package</filename>. A window should

View File

@@ -8,7 +8,7 @@
<!--==================================================================-->
<section xml:id="ssec-relnotes-0.13"><title>Release 0.13 (April NN,
<section xml:id="ssec-relnotes-0.13"><title>Release 0.13 (November 5,
2009)</title>
<para>This is primarily a bug fix release. It has some new
@@ -85,7 +85,25 @@ features:</para>
add a string to stack traces — useful for debugging),
<varname>builtins.isBool</varname>,
<varname>builtins.isString</varname>,
<varname>builtins.isInt</varname>.</para>
<varname>builtins.isInt</varname>,
<varname>builtins.intersectAttrs</varname>.</para>
</listitem>
<listitem>
<para>OpenSolaris support (Sander van der Burg).</para>
</listitem>
<listitem>
<para>Stack traces are no longer displayed unless the
<option>--show-trace</option> option is used.</para>
</listitem>
<listitem>
<para>The scoping rules for <literal>inherit
(<replaceable>e</replaceable>) ...</literal> in recursive
attribute sets have changed. The expression
<replaceable>e</replaceable> can now refer to the attributes
defined in the containing set.</para>
</listitem>
</itemizedlist>

View File

@@ -1106,7 +1106,7 @@ used in the Nix expression for Subversion.</para>
incompatibility might occur.</para>
</callout>
<callout arearefs='ex-subversion-nix-co-2'>
<callout arearefs='ex-subversion-nix-co-3'>
<para>This assertion says that in order for Subversion to have SSL
support (so that it can access <literal>https</literal> URLs), an
OpenSSL library must be passed. Additionally, it says that

View File

@@ -18,7 +18,10 @@ let
src = nix;
inherit officialRelease;
buildInputs = [curl bison flex2533 perl libxml2 libxslt w3m bzip2 jing_tools tetex dblatex];
buildInputs =
[ curl bison flex2533 perl libxml2 libxslt w3m bzip2
tetex dblatex nukeReferences
];
configureFlags = ''
--with-docbook-rng=${docbook5}/xml/rng/docbook
@@ -47,6 +50,9 @@ let
stripHash ${bzip2.src}
cp -pv ${bzip2.src} externals/$strippedName
# TeX needs a writable font cache.
export VARTEXFONTS=$TMPDIR/texfonts
'';
preDist = ''
@@ -54,6 +60,14 @@ let
make -C doc/manual manual.pdf prefix=$out
cp doc/manual/manual.pdf $out/manual.pdf
# The PDF containes filenames of included graphics (see
# http://www.tug.org/pipermail/pdftex/2007-August/007290.html).
# This causes a retained dependency on dblatex, which Hydra
# doesn't like (the output of the tarball job is distributed
# to Windows and Macs, so there should be no Linux binaries
# in the closure).
nuke-refs $out/manual.pdf
echo "doc manual $out/share/doc/nix/manual" >> $out/nix-support/hydra-build-products
echo "doc-pdf manual $out/manual.pdf" >> $out/nix-support/hydra-build-products
@@ -77,11 +91,13 @@ let
configureFlags = ''
--disable-init-state
--with-bdb=${db45} --with-aterm=${aterm242fixes} --with-bzip2=${bzip2}
${if system == "i686-cygwin" then "--disable-old-db-compat" else "--with-bdb=${db45}"}
--with-aterm=${aterm242fixes} --with-bzip2=${bzip2}
'';
};
/*
static =
{ tarball ? jobs.tarball {}
, system ? "i686-linux"
@@ -101,6 +117,7 @@ let
--enable-static-nix
'';
};
*/
coverage =
@@ -134,21 +151,29 @@ let
rpm_fedora5i386 = makeRPM_i686 (diskImages: diskImages.fedora5i386) 20;
rpm_fedora9i386 = makeRPM_i686 (diskImages: diskImages.fedora9i386) 50;
rpm_fedora9x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora9x86_64) 50;
rpm_fedora9i386 = makeRPM_i686 (diskImages: diskImages.fedora9i386) 30;
rpm_fedora9x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora9x86_64) 30;
rpm_fedora10i386 = makeRPM_i686 (diskImages: diskImages.fedora10i386) 40;
rpm_fedora10x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora10x86_64) 40;
rpm_fedora11i386 = makeRPM_i686 (diskImages: diskImages.fedora11i386) 50;
rpm_fedora11x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora11x86_64) 50;
rpm_opensuse103i386 = makeRPM_i686 (diskImages: diskImages.opensuse103i386) 40;
rpm_opensuse110i386 = makeRPM_i686 (diskImages: diskImages.opensuse110i386) 50;
rpm_opensuse110x86_64 = makeRPM_x86_64 (diskImages: diskImages.opensuse110x86_64) 50;
deb_debian40i386 = makeDeb_i686 (diskImages: diskImages.debian40i386) 40;
deb_debian40x86_64 = makeDeb_x86_64 (diskImages: diskImages.debian40x86_64) 40;
deb_debian50i386 = makeDeb_i686 (diskImages: diskImages.debian50i386) 30;
deb_debian50x86_64 = makeDeb_x86_64 (diskImages: diskImages.debian50x86_64) 30;
deb_ubuntu804i386 = makeDeb_i686 (diskImages: diskImages.ubuntu804i386) 50;
deb_ubuntu804x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu804x86_64) 50;
deb_ubuntu810i386 = makeDeb_i686 (diskImages: diskImages.ubuntu810i386) 40;
deb_ubuntu810x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu810x86_64) 40;
deb_debian50i386 = makeDeb_i686 (diskImages: diskImages.debian50i386) 50;
deb_debian50x86_64 = makeDeb_x86_64 (diskImages: diskImages.debian50x86_64) 50;
deb_ubuntu804i386 = makeDeb_i686 (diskImages: diskImages.ubuntu804i386) 20;
deb_ubuntu804x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu804x86_64) 20;
deb_ubuntu810i386 = makeDeb_i686 (diskImages: diskImages.ubuntu810i386) 30;
deb_ubuntu810x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu810x86_64) 30;
deb_ubuntu904i386 = makeDeb_i686 (diskImages: diskImages.ubuntu904i386) 40;
deb_ubuntu904x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu904x86_64) 40;
deb_ubuntu910i386 = makeDeb_i686 (diskImages: diskImages.ubuntu910i386) 50;
deb_ubuntu910x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu910x86_64) 50;
};
@@ -190,6 +215,7 @@ let
memSize = 1024;
meta = { schedulingPriority = toString prio; };
configureFlags = "--sysconfdir=/etc";
debRequires = ["curl"];
};

View File

@@ -47,24 +47,21 @@ decline if !defined $conf || ! -e $conf;
my $canBuildLocally = $amWilling && ($localSystem eq $neededSystem);
# Otherwise find a willing remote machine.
my @machines;
my %curJobs;
# Read the list of machines.
my @machines;
open CONF, "< $conf" or die;
while (<CONF>) {
chomp;
s/\#.*$//g;
next if /^\s*$/;
/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s*$/ or die;
/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\d+)(\s+([0-9\.]+))?\s*$/ or die;
push @machines,
{ hostName => $1
, systemType => $2
, systemTypes => [split(/,/, $2)]
, sshKeys => $3
, maxJobs => $4
, speedFactor => 1.0 * ($6 || 1)
};
}
@@ -77,39 +74,53 @@ open MAINLOCK, ">>$mainLock" or die;
flock(MAINLOCK, LOCK_EX) or die;
# Find a suitable system.
sub openSlotLock {
my ($machine, $slot) = @_;
my $slotLockFn = "$currentLoad/" . (join '+', @{$machine->{systemTypes}}) . "-" . $machine->{hostName} . "-$slot";
my $slotLock = new IO::Handle;
open $slotLock, ">>$slotLockFn" or die;
return $slotLock;
}
# Find all machine that can execute this build, i.e., that support
# builds for the given platform and are not at their job limit.
my $rightType = 0;
my $machine;
my $slotLock;
my @available = ();
LOOP: foreach my $cur (@machines) {
if ($neededSystem eq $cur->{systemType}
|| ($neededSystem eq "i686-linux" && $cur->{systemType} eq "x86_64-linux"))
{
if (grep { $neededSystem eq $_ } @{$cur->{systemTypes}}) {
$rightType = 1;
# We have a machine of the right type. Try to get a lock on
# one of the machine's lock files.
# We have a machine of the right type. Determine the load on
# the machine.
my $slot = 0;
my $load = 0;
my $free;
while ($slot < $cur->{maxJobs}) {
my $slotLockFn = "$currentLoad/" . $cur->{systemType} . "-" . $cur->{hostName} . "-$slot";
$slotLock = new IO::Handle;
open $slotLock, ">>$slotLockFn" or die;
my $slotLock = openSlotLock($cur, $slot);
if (flock($slotLock, LOCK_EX | LOCK_NB)) {
utime undef, undef, $slotLock;
$machine = $cur;
last LOOP;
$free = $slot unless defined $free;
flock($slotLock, LOCK_UN) or die;
} else {
$load++;
}
close $slotLock;
$slot++;
}
push @available, { machine => $cur, load => $load, free => $free }
if $load < $cur->{maxJobs};
}
}
close MAINLOCK;
if (defined $ENV{NIX_DEBUG_HOOK}) {
print STDERR "load on " . $_->{machine}->{hostName} . " = " . $_->{load} . "\n"
foreach @available;
}
# Didn't find one? Then decline or postpone.
if (!defined $machine) {
# Didn't find any available machine? Then decline or postpone.
if (scalar @available == 0) {
# Postpone if we have a machine of the right type, except if the
# local system can and wants to do the build.
if ($rightType && !$canBuildLocally) {
@@ -120,8 +131,41 @@ if (!defined $machine) {
}
}
# Yes we did, accept.
# Prioritise the available machines as follows:
# - First by load divided by speed factor, rounded to the nearest
# integer. This causes fast machines to be preferred over slow
# machines with similar loads.
# - Then by speed factor.
# - Finally by load.
sub lf { my $x = shift; return int($x->{load} / $x->{machine}->{speedFactor} + 0.4999); }
@available = sort
{ lf($a) <=> lf($b)
|| $b->{machine}->{speedFactor} <=> $a->{machine}->{speedFactor}
|| $a->{load} <=> $b->{load}
} @available;
# Select the best available machine and lock a free slot.
my $selected = $available[0];
my $machine = $selected->{machine};
my $slotLock = openSlotLock($machine, $selected->{free});
flock($slotLock, LOCK_EX | LOCK_NB) or die;
utime undef, undef, $slotLock;
close MAINLOCK;
# Tell Nix we've accepted the build.
sendReply "accept";
if (defined $ENV{NIX_DEBUG_HOOK}) {
my $hostName = $machine->{hostName};
my $sp = $machine->{speedFactor};
print STDERR "building `$drvPath' on `$hostName' - $sp - " . $selected->{free} . "\n";
sleep 10;
exit 0;
}
my $x = <STDIN>;
chomp $x;
@@ -130,7 +174,7 @@ if ($x ne "okay") {
}
# Do the actual job.
# Do the actual build.
my $hostName = $machine->{hostName};
print STDERR "building `$drvPath' on `$hostName'\n";

View File

@@ -112,6 +112,10 @@ EOF
$dryRun = 1;
}
elsif ($arg eq "--show-trace") {
push @instArgs, $arg;
}
elsif (substr($arg, 0, 1) eq "-") {
push @buildArgs, $arg;
}

View File

@@ -223,6 +223,23 @@ static Expr prim_addErrorContext(EvalState & state, const ATermVector & args)
}
}
/* Try evaluating the argument. Success => {success=true; value=something;},
* else => {success=false; value=false;} */
static Expr prim_tryEval(EvalState & state, const ATermVector & args)
{
ATermMap res = ATermMap();
try {
Expr val = evalExpr(state, args[0]);
res.set(toATerm("value"), makeAttrRHS(val, makeNoPos()));
res.set(toATerm("success"), makeAttrRHS(eTrue, makeNoPos()));
} catch (AssertionError & e) {
printMsg(lvlDebug, format("tryEval caught an error: %1%: %2%") % e.prefix() % e.msg());
res.set(toATerm("value"), makeAttrRHS(eFalse, makeNoPos()));
res.set(toATerm("success"), makeAttrRHS(eFalse, makeNoPos()));
}
return makeAttrs(res);
}
/* Return an environment variable. Use with care. */
static Expr prim_getEnv(EvalState & state, const ATermVector & args)
@@ -239,7 +256,12 @@ static Expr prim_getEnv(EvalState & state, const ATermVector & args)
static Expr prim_trace(EvalState & state, const ATermVector & args)
{
Expr e = evalExpr(state, args[0]);
printMsg(lvlError, format("trace: %1%") % e);
string s;
PathSet context;
if (matchStr(e, s, context))
printMsg(lvlError, format("trace: %1%") % s);
else
printMsg(lvlError, format("trace: %1%") % e);
return evalExpr(state, args[1]);
}
@@ -418,10 +440,18 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
drv.inputDrvs[*j] = singleton<StringSet>("out");
}
}
debug(format("derivation uses `%1%'") % path);
/* See prim_unsafeDiscardOutputDependency. */
bool useDrvAsSrc = false;
if (path.at(0) == '~') {
path = string(path, 1);
useDrvAsSrc = true;
}
assert(isStorePath(path));
if (isDerivation(path))
debug(format("derivation uses `%1%'") % path);
if (!useDrvAsSrc && isDerivation(path))
drv.inputDrvs[path] = singleton<StringSet>("out");
else
drv.inputSrcs.insert(path);
@@ -795,6 +825,70 @@ static Expr prim_isAttrs(EvalState & state, const ATermVector & args)
}
/* Return the right-biased intersection of two attribute sets as1 and
as2, i.e. a set that contains every attribute from as2 that is also
a member of as1. */
static Expr prim_intersectAttrs(EvalState & state, const ATermVector & args)
{
ATermMap as1, as2;
queryAllAttrs(evalExpr(state, args[0]), as1, true);
queryAllAttrs(evalExpr(state, args[1]), as2, true);
ATermMap res;
foreach (ATermMap::const_iterator, i, as2)
if (as1[i->key]) res.set(i->key, i->value);
return makeAttrs(res);
}
static void attrsInPattern(ATermMap & map, Pattern pat)
{
ATerm name;
ATermList formals;
Pattern pat1, pat2;
ATermBool ellipsis;
if (matchAttrsPat(pat, formals, ellipsis)) {
for (ATermIterator i(formals); i; ++i) {
ATerm def;
if (!matchFormal(*i, name, def)) abort();
map.set(name, makeAttrRHS(makeBool(def != constNoDefaultValue), makeNoPos()));
}
}
else if (matchAtPat(pat, pat1, pat2)) {
attrsInPattern(map, pat1);
attrsInPattern(map, pat2);
}
}
/* Return a set containing the names of the formal arguments expected
by the function `f'. The value of each attribute is a Boolean
denoting whether has a default value. For instance,
functionArgs ({ x, y ? 123}: ...)
=> { x = false; y = true; }
"Formal argument" here refers to the attributes pattern-matched by
the function. Plain lambdas are not included, e.g.
functionArgs (x: ...)
=> { }
*/
static Expr prim_functionArgs(EvalState & state, const ATermVector & args)
{
Expr f = evalExpr(state, args[0]);
ATerm pat, body, pos;
if (!matchFunction(f, pat, body, pos))
throw TypeError("`functionArgs' required a function");
ATermMap as;
attrsInPattern(as, pat);
return makeAttrs(as);
}
/*************************************************************
* Lists
*************************************************************/
@@ -946,6 +1040,28 @@ static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector
}
/* Sometimes we want to pass a derivation path (i.e. pkg.drvPath) to a
builder without causing the derivation to be built (for instance,
in the derivation that builds NARs in nix-push, when doing
source-only deployment). This primop marks the string context so
that builtins.derivation adds the path to drv.inputSrcs rather than
drv.inputDrvs. */
static Expr prim_unsafeDiscardOutputDependency(EvalState & state, const ATermVector & args)
{
PathSet context;
string s = coerceToString(state, args[0], context);
PathSet context2;
foreach (PathSet::iterator, i, context) {
Path p = *i;
if (p.at(0) == '=') p = "~" + string(p, 1);
context2.insert(p);
}
return makeStr(s, context2);
}
/* Expression serialization/deserialization */
@@ -1020,6 +1136,7 @@ void EvalState::addPrimOps()
addPrimOp("abort", 1, prim_abort);
addPrimOp("throw", 1, prim_throw);
addPrimOp("__addErrorContext", 2, prim_addErrorContext);
addPrimOp("__tryEval", 1, prim_tryEval);
addPrimOp("__getEnv", 1, prim_getEnv);
addPrimOp("__trace", 2, prim_trace);
@@ -1052,6 +1169,8 @@ void EvalState::addPrimOps()
addPrimOp("__isAttrs", 1, prim_isAttrs);
addPrimOp("removeAttrs", 2, prim_removeAttrs);
addPrimOp("__listToAttrs", 1, prim_listToAttrs);
addPrimOp("__intersectAttrs", 2, prim_intersectAttrs);
addPrimOp("__functionArgs", 1, prim_functionArgs);
// Lists
addPrimOp("__isList", 1, prim_isList);
@@ -1072,6 +1191,7 @@ void EvalState::addPrimOps()
addPrimOp("__substring", 3, prim_substring);
addPrimOp("__stringLength", 1, prim_stringLength);
addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext);
addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency);
// Versions
addPrimOp("__parseDrvName", 1, prim_parseDrvName);

View File

@@ -10,7 +10,7 @@ pkginclude_HEADERS = \
globals.hh db.hh references.hh pathlocks.hh \
worker-protocol.hh
libstore_la_LIBADD = ../libutil/libutil.la ../boost/format/libformat.la
libstore_la_LIBADD = ../libutil/libutil.la ../boost/format/libformat.la @ADDITIONAL_NETWORK_LIBS@
BUILT_SOURCES = derivations-ast.cc derivations-ast.hh

View File

@@ -4,6 +4,7 @@
#include "globals.hh"
#include "local-store.hh"
#include "util.hh"
#include "archive.hh"
#include <map>
#include <iostream>
@@ -15,11 +16,13 @@
#include <time.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
@@ -466,6 +469,8 @@ void UserLock::acquire()
if (!pw)
throw Error(format("the user `%1%' in the group `%2%' does not exist")
% *i % buildUsersGroup);
createDirs(nixStateDir + "/userpool");
fnUserLock = (format("%1%/userpool/%2%") % nixStateDir % pw->pw_uid).str();
@@ -1600,8 +1605,18 @@ void DerivationGoal::startBuilder()
dirsInChroot.insert(*i);
else {
Path p = chrootRootDir + *i;
if (link(i->c_str(), p.c_str()) == -1)
throw SysError(format("linking `%1%' to `%2%'") % p % *i);
if (link(i->c_str(), p.c_str()) == -1) {
/* Hard-linking fails if we exceed the maximum
link count on a file (e.g. 32000 of ext3),
which is quite possible after a `nix-store
--optimise'. Make a copy instead. */
if (errno != EMLINK)
throw SysError(format("linking `%1%' to `%2%'") % p % *i);
StringSink sink;
dumpPath(*i, sink);
StringSource source(sink.s);
restorePath(p, source);
}
}
}

View File

@@ -16,6 +16,7 @@
#include <utime.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
namespace nix {
@@ -47,8 +48,21 @@ LocalStore::LocalStore()
if (readOnlyMode) return;
/* Create missing state directories if they don't already exist. */
createDirs(nixStore);
createDirs(nixDBPath + "/info");
createDirs(nixDBPath + "/referrer");
createDirs(nixDBPath + "/failed");
Path profilesDir = nixStateDir + "/profiles";
createDirs(nixStateDir + "/profiles");
createDirs(nixStateDir + "/temproots");
Path gcRootsDir = nixStateDir + "/gcroots";
if (!pathExists(gcRootsDir)) {
createDirs(gcRootsDir);
if (symlink(profilesDir.c_str(), (gcRootsDir + "/profiles").c_str()) == -1)
throw SysError(format("creating symlink to `%1%'") % profilesDir);
}
checkStoreNotSymlink();
try {
@@ -64,11 +78,7 @@ LocalStore::LocalStore()
printMsg(lvlError, "waiting for the big Nix store lock...");
lockFile(globalLock, ltRead, true);
}
createDirs(nixDBPath + "/info");
createDirs(nixDBPath + "/referrer");
createDirs(nixDBPath + "/failed");
int curSchema = getSchema();
if (curSchema > nixSchemaVersion)
throw Error(format("current Nix store schema is version %1%, but I only support %2%")
@@ -509,6 +519,13 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter &
case 0: /* child */
try {
/* Hack to let "make check" succeed on Darwin. The
libtool wrapper script sets DYLD_LIBRARY_PATH to our
libutil (among others), but Perl also depends on a
library named libutil. As a result, substituters
written in Perl (i.e. all of them) fail. */
unsetenv("DYLD_LIBRARY_PATH");
fromPipe.readSide.close();
toPipe.writeSide.close();
if (dup2(toPipe.readSide, STDIN_FILENO) == -1)

View File

@@ -185,9 +185,6 @@ private:
};
/* Copy a path recursively. */
void copyPath(const Path & src, const Path & dst);
/* "Fix", or canonicalise, the meta-data of the files in a store path
after it has been built. In particular:
- the last modification date on each file is set to 1 (i.e.,

View File

@@ -5,6 +5,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
namespace nix {

View File

@@ -302,7 +302,12 @@ struct RestoreSink : ParseSink
#if HAVE_POSIX_FALLOCATE
if (len) {
errno = posix_fallocate(fd, 0, len);
if (errno) throw SysError(format("preallocating file of %1% bytes") % len);
/* Note that EINVAL may indicate that the underlying
filesystem doesn't support preallocation (e.g. on
OpenSolaris). Since preallocation is just an
optimisation, ignore it. */
if (errno && errno != EINVAL)
throw SysError(format("preallocating file of %1% bytes") % len);
}
#endif
}

View File

@@ -3,7 +3,7 @@ bin_PROGRAMS = nix-env
nix_env_SOURCES = nix-env.cc profiles.cc profiles.hh help.txt
nix_env_LDADD = ../libmain/libmain.la ../libexpr/libexpr.la \
../libstore/libstore.la ../libutil/libutil.la \
../boost/format/libformat.la ${bdb_lib} ${aterm_lib}
../boost/format/libformat.la ${bdb_lib} ${aterm_lib} @ADDITIONAL_NETWORK_LIBS@
nix-env.o: help.txt.hh

View File

@@ -704,52 +704,59 @@ static void upgradeDerivations(Globals & globals,
foreach (DrvInfos::iterator, i, installedElems) {
DrvName drvName(i->name);
MetaInfo meta = i->queryMetaInfo(globals.state);
if (keep(meta)) {
newElems.push_back(*i);
continue;
}
try {
/* Find the derivation in the input Nix expression with
the same name that satisfies the version constraints
specified by upgradeType. If there are multiple
matches, take the one with the highest priority. If
there are still multiple matches, take the one with the
highest version. */
DrvInfos::iterator bestElem = availElems.end();
DrvName bestName;
foreach (DrvInfos::iterator, j, availElems) {
DrvName newName(j->name);
if (newName.name == drvName.name) {
int d = comparePriorities(globals.state, *i, *j);
if (d == 0) d = compareVersions(drvName.version, newName.version);
if ((upgradeType == utLt && d < 0) ||
(upgradeType == utLeq && d <= 0) ||
(upgradeType == utEq && d == 0) ||
upgradeType == utAlways)
{
int d2 = -1;
if (bestElem != availElems.end()) {
d2 = comparePriorities(globals.state, *bestElem, *j);
if (d2 == 0) d2 = compareVersions(bestName.version, newName.version);
}
if (d2 < 0) {
bestElem = j;
bestName = newName;
MetaInfo meta = i->queryMetaInfo(globals.state);
if (keep(meta)) {
newElems.push_back(*i);
continue;
}
/* Find the derivation in the input Nix expression
with the same name that satisfies the version
constraints specified by upgradeType. If there are
multiple matches, take the one with the highest
priority. If there are still multiple matches,
take the one with the highest version. */
DrvInfos::iterator bestElem = availElems.end();
DrvName bestName;
foreach (DrvInfos::iterator, j, availElems) {
DrvName newName(j->name);
if (newName.name == drvName.name) {
int d = comparePriorities(globals.state, *i, *j);
if (d == 0) d = compareVersions(drvName.version, newName.version);
if ((upgradeType == utLt && d < 0) ||
(upgradeType == utLeq && d <= 0) ||
(upgradeType == utEq && d == 0) ||
upgradeType == utAlways)
{
int d2 = -1;
if (bestElem != availElems.end()) {
d2 = comparePriorities(globals.state, *bestElem, *j);
if (d2 == 0) d2 = compareVersions(bestName.version, newName.version);
}
if (d2 < 0) {
bestElem = j;
bestName = newName;
}
}
}
}
}
if (bestElem != availElems.end() &&
i->queryOutPath(globals.state) !=
bestElem->queryOutPath(globals.state))
{
printMsg(lvlInfo,
format("upgrading `%1%' to `%2%'")
% i->name % bestElem->name);
newElems.push_back(*bestElem);
} else newElems.push_back(*i);
if (bestElem != availElems.end() &&
i->queryOutPath(globals.state) !=
bestElem->queryOutPath(globals.state))
{
printMsg(lvlInfo,
format("upgrading `%1%' to `%2%'")
% i->name % bestElem->name);
newElems.push_back(*bestElem);
} else newElems.push_back(*i);
} catch (Error & e) {
e.addPrefix(format("while trying to find an upgrade for `%1%':\n") % i->name);
throw;
}
}
printMissing(globals.state, newElems);

View File

@@ -2,7 +2,7 @@ bin_PROGRAMS = nix-hash
nix_hash_SOURCES = nix-hash.cc help.txt
nix_hash_LDADD = ../libmain/libmain.la ../libstore/libstore.la ../libutil/libutil.la \
../boost/format/libformat.la ${bdb_lib} ${aterm_lib}
../boost/format/libformat.la ${bdb_lib} ${aterm_lib} @ADDITIONAL_NETWORK_LIBS@
nix-hash.o: help.txt.hh

View File

@@ -3,7 +3,7 @@ bin_PROGRAMS = nix-instantiate
nix_instantiate_SOURCES = nix-instantiate.cc help.txt
nix_instantiate_LDADD = ../libmain/libmain.la ../libexpr/libexpr.la \
../libstore/libstore.la ../libutil/libutil.la \
../boost/format/libformat.la ${bdb_lib} ${aterm_lib}
../boost/format/libformat.la ${bdb_lib} ${aterm_lib} @ADDITIONAL_NETWORK_LIBS@
nix-instantiate.o: help.txt.hh

View File

@@ -2,7 +2,7 @@ bin_PROGRAMS = nix-store
nix_store_SOURCES = nix-store.cc dotgraph.cc dotgraph.hh help.txt
nix_store_LDADD = ../libmain/libmain.la ../libstore/libstore.la ../libutil/libutil.la \
../boost/format/libformat.la ${bdb_lib} ${aterm_lib}
../boost/format/libformat.la ${bdb_lib} ${aterm_lib} @ADDITIONAL_NETWORK_LIBS@
nix-store.o: help.txt.hh

View File

@@ -2,7 +2,7 @@ bin_PROGRAMS = nix-worker
nix_worker_SOURCES = nix-worker.cc help.txt
nix_worker_LDADD = ../libmain/libmain.la ../libstore/libstore.la ../libutil/libutil.la \
../boost/format/libformat.la ${bdb_lib} ${aterm_lib}
../boost/format/libformat.la ${bdb_lib} ${aterm_lib} @ADDITIONAL_NETWORK_LIBS@
nix-worker.o: help.txt.hh

View File

@@ -20,9 +20,18 @@
using namespace nix;
/* On platforms that have O_ASYNC, we can detect when a client
disconnects and immediately kill any ongoing builds. On platforms
that lack it, we only notice the disconnection the next time we try
to write to the client. So if you have a builder that never
generates output on stdout/stderr, the worker will never notice
that the client has disconnected until the builder terminates. */
#ifdef O_ASYNC
#define HAVE_HUP_NOTIFICATION
#ifndef SIGPOLL
#define SIGPOLL SIGIO
#endif
#endif
static FdSource from(STDIN_FILENO);
@@ -90,7 +99,7 @@ static bool isFarSideClosed(int socket)
/* A SIGPOLL signal is received when data is available on the client
communication scoket, or when the client has closed its side of the
communication socket, or when the client has closed its side of the
socket. This handler is enabled at precisely those moments in the
protocol when we're doing work and the client is supposed to be
quiet. Thus, if we get a SIGPOLL signal, it means that the client
@@ -131,12 +140,14 @@ static void sigPollHandler(int sigNo)
static void setSigPollAction(bool enable)
{
#ifdef HAVE_HUP_NOTIFICATION
struct sigaction act, oact;
act.sa_handler = enable ? sigPollHandler : SIG_IGN;
sigfillset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGPOLL, &act, &oact))
throw SysError("setting handler for SIGPOLL");
#endif
}
@@ -520,12 +531,14 @@ static void processConnection()
myPid = getpid();
writeToStderr = tunnelStderr;
#ifdef HAVE_HUP_NOTIFICATION
/* Allow us to receive SIGPOLL for events on the client socket. */
setSigPollAction(false);
if (fcntl(from.fd, F_SETOWN, getpid()) == -1)
throw SysError("F_SETOWN");
if (fcntl(from.fd, F_SETFL, fcntl(from.fd, F_GETFL, 0) | FASYNC) == -1)
if (fcntl(from.fd, F_SETFL, fcntl(from.fd, F_GETFL, 0) | O_ASYNC) == -1)
throw SysError("F_SETFL");
#endif
/* Exchange the greeting. */
unsigned int magic = readInt(from);
@@ -663,11 +676,12 @@ static void daemonLoop()
AutoCloseFD remote = accept(fdSocket,
(struct sockaddr *) &remoteAddr, &remoteAddrLen);
checkInterrupt();
if (remote == -1)
if (remote == -1) {
if (errno == EINTR)
continue;
else
throw SysError("accepting connection");
}
printMsg(lvlInfo, format("accepted connection %1%") % remote);

View File

@@ -0,0 +1,15 @@
<?xml version='1.0' encoding='utf-8'?>
<expr>
<list>
<string value="stdenv" />
<string value="fetchurl" />
<string value="aterm-stdenv" />
<string value="aterm-stdenv2" />
<string value="libX11" />
<string value="libXv" />
<string value="mplayer-stdenv2.libXv-libX11" />
<string value="mplayer-stdenv2.libXv-libX11_2" />
<string value="nix-stdenv-aterm-stdenv" />
<string value="nix-stdenv2-aterm2-stdenv2" />
</list>
</expr>

View File

@@ -0,0 +1,80 @@
let
stdenvFun = { }: { name = "stdenv"; };
stdenv2Fun = { }: { name = "stdenv2"; };
fetchurlFun = { stdenv }: assert stdenv.name == "stdenv"; { name = "fetchurl"; };
atermFun = { stdenv, fetchurl }: { name = "aterm-${stdenv.name}"; };
aterm2Fun = { stdenv, fetchurl }: { name = "aterm2-${stdenv.name}"; };
nixFun = { stdenv, fetchurl, aterm }: { name = "nix-${stdenv.name}-${aterm.name}"; };
mplayerFun =
{ stdenv, fetchurl, enableX11 ? false, xorg ? null, enableFoo ? true, foo ? null }:
assert stdenv.name == "stdenv2";
assert enableX11 -> xorg.libXv.name == "libXv";
assert enableFoo -> foo != null;
{ name = "mplayer-${stdenv.name}.${xorg.libXv.name}-${xorg.libX11.name}"; };
makeOverridable = f: origArgs: f origArgs //
{ override = newArgs:
makeOverridable f (origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs));
};
callPackage_ = pkgs: f: args:
makeOverridable f ((builtins.intersectAttrs (builtins.functionArgs f) pkgs) // args);
allPackages =
{ overrides ? (pkgs: pkgsPrev: { }) }:
let
callPackage = callPackage_ pkgs;
pkgs = pkgsStd // (overrides pkgs pkgsStd);
pkgsStd = {
inherit pkgs;
stdenv = callPackage stdenvFun { };
stdenv2 = callPackage stdenv2Fun { };
fetchurl = callPackage fetchurlFun { };
aterm = callPackage atermFun { };
xorg = callPackage xorgFun { };
mplayer = callPackage mplayerFun { stdenv = pkgs.stdenv2; enableFoo = false; };
nix = callPackage nixFun { };
};
in pkgs;
libX11Fun = { stdenv, fetchurl }: { name = "libX11"; };
libX11_2Fun = { stdenv, fetchurl }: { name = "libX11_2"; };
libXvFun = { stdenv, fetchurl, libX11 }: { name = "libXv"; };
xorgFun =
{ pkgs }:
let callPackage = callPackage_ (pkgs // pkgs.xorg); in
{
libX11 = callPackage libX11Fun { };
libXv = callPackage libXvFun { };
};
in
let
pkgs = allPackages { };
pkgs2 = allPackages {
overrides = pkgs: pkgsPrev: {
stdenv = pkgs.stdenv2;
nix = pkgsPrev.nix.override { aterm = aterm2Fun { inherit (pkgs) stdenv fetchurl; }; };
xorg = pkgsPrev.xorg // { libX11 = libX11_2Fun { inherit (pkgs) stdenv fetchurl; }; };
};
};
in
[ pkgs.stdenv.name
pkgs.fetchurl.name
pkgs.aterm.name
pkgs2.aterm.name
pkgs.xorg.libX11.name
pkgs.xorg.libXv.name
pkgs.mplayer.name
pkgs2.mplayer.name
pkgs.nix.name
pkgs2.nix.name
]