Zero Install

the antidote to app-stores

0install 2.0 release notes

[ see the main news page for other news ]

2013-03-05

  1. About 0install
  2. Overview of changes in 2.0
  3. Extensions to the XML feed format
  4. Distribution support
  5. Changes to the 0install tool
  6. Internals
  7. Updates to related tools

About 0install

Zero Install is a decentralised cross-platform software installation system available under the LGPL. It allows software developers to publish programs directly from their own web-sites, while supporting features familiar from centralised distribution repositories such as shared libraries, automatic updates and digital signatures. It is intended to complement, rather than replace, the operating system's package management. 0install packages never interfere with those provided by the distribution.

0desktop --manage

0install does not define a new packaging format; unmodified tarballs or zip archives can be used. Instead, it defines an XML metadata format to describe these packages and the dependencies between them. A single metadata file can be used on multiple platforms (e.g. Ubuntu, Debian, Fedora, openSUSE, Mac OS X and Windows), assuming binary or source archives are available that work on those systems.

0install also has some interesting features not often found in traditional package managers. For example, while it will share libraries whenever possible, it can always install multiple versions of a package in parallel when there are conflicting requirements. Installation is always side-effect-free (each package is unpacked to its own directory and will not touch shared directories such as /usr/bin), making it ideal for use with sandboxing technologies and virtualisation.

The XML file describing the program's requirements can also be included in a source-code repository, allowing full dependency handling for unreleased developer versions. For example, a user can clone a Git repository and build and test the program, automatically downloading newer versions of libraries where necessary, without interfering with the versions of those libraries installed by their distribution, which continue to be used for other software.

Started in 2003, 0install is developed by volunteers from around the world; contributors include Aleksey Lim, Anders F Björklund, Bastian Eicher, Chris Leick, Daniel Tschan, Dave Abrahams, Frank Richter, Mark Seaborn, Michel Alexandre Salim, Pino Toscano, Rene Lopez, Thomas Leonard, Tim Cuthbertson and Tim Diels.

More than one thousand packages are currently available and you can easily publish your own programs. Zero Install itself is available from the official repositories of most Linux distributions (including Debian, Fedora, Gentoo, Mint, openSUSE and Ubuntu) as well as MacPorts. See the Downloads page for details.

Overview of changes in 2.0

0install 2.0 brings many enhancements to the XML metadata syntax used to describe packages and their dependencies, allowing a more precise specification of their requirements. Support for using distribution-provided packages as dependencies was extended and now covers Arch Linux, Cygwin, Darwin, Debian, Fink, FreeBSD Ports, Gentoo, MacPorts, Mint, openSUSE, Red Hat, Slackware and Windows. The 0install software now supports apps, an easier way to manage 0install applications, improved diagnostics when no compatible versions can be selected, improved usability, and better support for use on headless servers.

The Ryppl project is using 0install as the package manager for a modular C++ build system, starting with a modularised C++ Boost library. This has driven many of the enhancements in 2.0, such as support compiling 0install packages on Windows. We hope that 0install will one day replace many of the language-specific packaging systems currently in use.

Extensions to the XML feed format

The 2.0 feed format is 100% backwards compatible with the 1.0 format (all software distributed for 1.0 will also work with 2.0). The new features are:

Optional dependencies
We try to select the best available version of the dependency, but it's OK if nothing can be selected (this is useful if a dependency isn't available on all platforms):
<requires ... importance='optional'>...</requires>
OS-specific dependencies
For dependencies that are only needed on Windows, etc:
<requires ... os='Windows'>...</requires>
Restrict-only dependencies
These let you specify constraints/conflicts on the acceptable versions of another interface without requiring that interface to be selected at all:
<restricts interface='...' version='...'>
Dependencies for native packages
These are useful when a distribution package is only for a particular major version of another interface:
<package-implementation distributions="Debian" package="python3-gi">
  <restricts interface="http://repo.roscidus.com/python/python">
    <version not-before="3" before="4"/>
  </restricts>
</package-implementation>
Restrictions on distribution type
Some native packages only work with other packages from the same distribution. For example, MacPorts Python libraries only work with the MacPorts Python:
<restricts interface='...' distribution='MacPorts'>
The value can be any valid distribution name (e.g. 'RPM'), or '0install' to force a 0install implementation, not a package implementation.
More flexible version syntax
The new 'version' attribute provides a shorter and more flexible way to specify the compatible versions:
<requires interface='...' version='2.6..!3 | 3.2..'>
This allows any version from 2.6 up to (but excluding) 3, or version 3.2 or later. However, the previous syntax using <version> should be used where possible, since it works with all versions of 0install.
Executable bindings
Two new bindings make it easy to depend on executable commands (not just on libraries). This is necessary on Windows, since it doesn't support #! lines, but it is also useful on other platforms. For example, if a program requires the "make" command in $PATH:
<requires interface='http://repo.roscidus.com/devel/make'>
  <executable-in-path name='make'/>
</requires>
Or, if it requires the make command in $MAKE:
<requires interface='http://repo.roscidus.com/devel/make'>
  <executable-in-var name='MAKE'/>
</requires>
As always, these declarations only affect the program being run (they do not put "make" into /usr/bin, ~/bin or similar).
Custom path separators in environment bindings
The path separator can now be specified in environment bindings (previously, it was either ":" or ";", depending on the platform):
<environment name='OPTIONS' value='foo' separator=','>
Replaced interfaces
Obsolete interfaces can be flagged as such. Various tools will warn about the use of obsolete interfaces, and 0install knows that interfaces conflict with their replacements. For example, the "openjdk-6-jre" interface was replaced by the more general "openjdk-jre" (which covers versions 6 and 7):
<replaced-by interface="http://repo.roscidus.com/java/openjdk-jre"/>
Bindings inside <command>
This allows for bindings which are only needed when testing, etc.
New "POSIX" architecture
This matches everything except Windows.
New digest algorithm to avoid the "=" character
The new sha256new algorithm is the same as sha256, except that the digest is encoded with base 32 rather than base 16 (for shorter strings), and the separator is '_' rather than '=', since '=' causes problems for some programs (e.g. cmake) if it appears in pathnames.
Allow renaming files when unpacking
<recipe>
 <archive href="..."/>
 <rename source="run.sh" dest="start.sh"/>
</recipe>
Expand environment variables to multiple arguments
This is useful for variables which contain e.g. a list of options:
<for-each item-from="EXTRA_OPTIONS" separator=" ">
  <arg>-X</arg>
  <arg>${item}</arg>
</for-each>
This is needed to support SWT on OS X with Java 7.
Hide elements from certain versions of 0install
To avoid breaking older versions of 0install when adding new features, any element in a feed can be tagged with a version expression, and only those versions will look at it. For example, to add a requirement element that would confuse current versions of 0install, you might one day write:
<requires if-0install-version="2.7.." .../>

Distribution support

As well as being able to download and manage 0install packages, 0install also allows programs to depend on native packages from the user's distribution. Enhancements here include:

  • Improved support for detecting native Java packages (on Arch, Debian, openSUSE, Fedora, OS X and Windows).
  • Support for detecting .NET Framework installations on Windows.
  • Support for new distributions: Arch, Cygwin, Darwin, Fink and MacPorts.

Changes to the 0install tool

App support
Apps are a new system to replace 0install 1.0's aliases. The main difference between apps and aliases is that apps store their current selections (in ~/.config/0install.net/apps/NAME/selections.xml). This means that they start faster, because the solver isn't needed. They also store historical selections, making it easy to roll-back to a previous set of selected versions. The commands are:
0install add NAME URI
0install run NAME
0install update NAME
0install show NAME
0install whatchanged NAME
0install destroy NAME
Specifying versions
The new range syntax can be used on the command line with the new --version attribute, e.g.
$ 0install run --version=2.11 \
  http://rox.sourceforge.net/2005/interfaces/ROX-Filer --version
ROX-Filer 2.11
As "!" is often a shell special character, remember to quote it when specifying ranges. The new --version-for option allows you to constrain the version of dependencies too, not just the root. e.g. to force the use of Python 2.6 with Edit:
$ 0install select http://rox.sourceforge.net/2005/interfaces/Edit \
    --version-for http://repo.roscidus.com/python/python '2.6..!2.7'

When using "0install add" or "0install update" these restrictions are saved for later. So you could, for example, make separate apps for Edit with Python 2.6 and Python 2.7:

$ 0install add edit-py26 http://rox.sourceforge.net/2005/interfaces/Edit \
           --version-for http://repo.roscidus.com/python/python '2.6..!2.7'

$ 0install add edit-py27 http://rox.sourceforge.net/2005/interfaces/Edit \
           --version-for http://repo.roscidus.com/python/python '2.7..!2.8'
Diagnostics
0install 2.0 provides hugely improved diagnostics when a solve fails (or fails to select the expected version).
Tab completion
There is now very complete support for shell tab completion for the "0install" command.
New --dry-run feature
This replaces the old broken one. Instead of telling you the first URL it would have fetched, which isn't helpful, it actually does the downloads and shows the changes that it would have made to the system (saving things in the cache, trusting GPG keys, creating short-cuts, etc), as an educational aid.
Site-local packages
This makes things easier for 0compile: instead of putting builds in the cache and registering them with the interface, 0compile can now just drop a build in ~/.local/share/0install.net/site-packages/URI/VERSION and 0install will find it and add it automatically. The build can be removed by simply deleting the directory.
0install digest
This replaces "0store manifest", but has a saner syntax. It can also be used directly on an archive.
0install man
This is similar to the old '0alias --manpage', but also copes with app launchers. So, to make man(1) work with 0install launchers, do:
alias man="0install man --"
0install update
This now notifies the user if there is a newer unselected version, and suggests turning on help_with_testing if that might help.
Mirroring of archives
0install 1.0 can use a mirror service as a fallback to get the XML feeds; 0install 2.0 can also use the mirror to get missing archives. Note however that our default public mirror server does not actually mirror any archives by default.
Better headless use
We used to assume that a GUI was available whenever $DISPLAY was set. However, there could be other reasons why the GUI can't be used, such as missing Python modules, which we now cope with. There are new split Debian packages for headless servers, to avoid pulling in any GUI dependencies.
Translations
There's a new German translation, and a Transifex project to support new translations.

Internals

  • Internally, 0install can now run with Python 2 or 3, with PyGTK or PyGObject, and with GTK 2 or GTK 3.
  • We batch up queries to PackageKit for better performance.
  • The GUI no longer slows to a crawl when showing download progress for a package with hundreds of dependencies.
  • We use threads, not processes, for downloads. This is slightly faster and uses less memory. We also now limit the number of concurrent downloads from a single site, as opening a large number of simultaneous connections causes problems for some networks and servers.

Updates to related tools

0compile
0compile now works on Windows, not just POSIX systems. It gained support for <command name='compile'> to give the compile command, allowing the use of <runner>. It also now allows you to provide a template for the binary's XML.
0downstream
The new 0downstream tool makes it easy to generate feeds and keep them up to date based on an existing upstream project.
0env
The new 0env tool makes it easy to step into a shell session with a particular library available.
0install for Windows
The Windows port has also been very active; see the separate Windows version news page for details.
Packaging guide
The Packaging guide has been improved and a set of template projects have been created to help developers learn to use 0install.