mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 04:00:59 +01:00
Nix, the purely functional package manager
we combine closures built by different users, the resulting set may
contain multiple paths from the same output path equivalence class.
For instance, if we do
$ NIX_USER_ID=foo nix-env -i libXext
$ NIX_USER_ID=root nix-env -i libXt
$ NIX_USER_ID=foo nix-env -i libXmu
(where libXmu depends on libXext and libXt, who both depend on
libX11), then the following will happen:
* User foo builds libX11 and libXext because they don't exist
yet.
* User root builds libX11 and libXt because the latter doesn't
exist yet, while the former *does* exist but cannot be trusted.
The instance of libX11 built by root will almost certainly
differ from the one built by foo, so they are stored in separate
locations.
* User foo builds libXmu, which requires libXext and libXt. Foo
has trusted copies of both (libXext was built by himself, while
libXt was built by root, who is trusted by foo). So libXmu is
built with foo's libXext and root's libXt as inputs.
* The resulting libXmu will link against two copies of libX11,
namely the one used by foo's libXext and the one used by root's
libXt. This is bad semantically (it's observable behaviour, and
might well lead to build time or runtime failure (e.g.,
duplicate definitions of symbols)) and in terms of efficiency
(the closure of libXmu contains two copies of libX11, so both
must be deployed).
The problem is to apply hash rewriting to "consolidate" the set of
input paths to a build. The invariant we wish to maintain is that
any closure may contain at most one path from each equivalence
class.
So in the case of a collision, we select one path from each class,
and *rewrite* all paths in that set to point only to paths in that
set. For instance, in the example above, we can rewrite foo's
libXext to link against root's libX11. That is, the hash part of
foo's libX11 is replaced by the hash part of root's libX11.
The hard part is to figure out which path to select from each
class. Some selections may be cheaper than others (i.e., require
fewer rewrites). The current implementation is rather dumb: it
tries all possible selections, and picks the cheapest. This is an
exponential time algorithm.
There certainly are more efficient common-case (heuristical)
approaches. But I don't know yet if there is a worst-case
polynomial time algorithm.
|
||
|---|---|---|
| blacklisting | ||
| corepkgs | ||
| doc | ||
| externals | ||
| make | ||
| misc | ||
| scripts | ||
| src | ||
| tests | ||
| AUTHORS | ||
| bootstrap.sh | ||
| ChangeLog | ||
| configure.ac | ||
| COPYING | ||
| INSTALL | ||
| Makefile.am | ||
| NEWS | ||
| nix.conf.example | ||
| nix.spec.in | ||
| README | ||
| substitute.mk | ||
For installation and usage instructions, please read the manual, which can be found in `docs/manual/manual.html', and additionally at the Nix website at <http://www.cs.uu.nl/groups/ST/Trace/Nix>. Acknowledgments This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)