System Overview
Autopackage is, essentially, a framework for building files that install and configure your software for the users system. It is designed to abstract differences between Linux distributions behind an API designed specifically for installing files.
Having said that, it also provides functionality to the user, developer and system administrator. This document will introduce you to the key concepts behind how autopackage works, and will show you the basics of how to operate it. It's targetted at developers.
Key concepts
The first thing that you must understand is that autopackage is designed for portability between forms of Linux. In fact, any reasonably Linux-like system will do, with some work it could probably, for instance, work on FreeBSD as well.
This is achieved by providing an API that allows the packager to
specify how their software is to be installed, in a way that lets
autopackage take care of the obscure differences. The API provides
functions such as installLib(), which takes care of
copying the ELF shared library file, updating the linker cache,
ensuring the necessary symlinks are present, and potentially
updating the linker configuration file, if the prefix to be
installed to is non-standard.
It also provides APIs for specifying dependencies. Dependencies in autopackage are heavyweight, that is, they are backed by what are called skeleton files. These files describe a dependency, how to detect it, and how to fulfil it if it missing on the users system.
A dependency that a package has is typically a dependency on an interface. Software meant to be reused by other software exposes a set of interfaces. For ELF shared libraries, that interface is the ABI of the library. There are strict rules about what can and cannot change, and how to version them. However, other packages have interfaces too. For instance, XMMS exposes a plugin interface to other software. Programs written in emacs lisp take advantage of the interface emacs provides. An interface can be something as simple as the location of a file.
Versions and root names
Packages are identified using root names. A root name has two different forms:
| Example root name | Type | Comments |
|---|---|---|
| @autopackage.org/libfoobar | Unversioned root name | This type of root name represents a particular set of software, namely all possible versions of the libprefixdb library. |
| @autopackage.org/libfoobar:1.0.0:2 | Versioned root name | The number after the first colon is what we call a software version (see below). |
Version numbers
Autopackage distinguishes between several different kinds of version numbers. Here is a list of them:
- Software Version: This is the version number the project assigns itself. It's entirely arbitrary, it could be something as mundane as "1.0", or it could be "2003", in the case of, for instance, Windows 2003. It can include letters too, but there are limits - autopackage has to be able to figure out, given two software version numbers, which is higher. As such "XP" would be an illegal version number (but who in their right mind would use such a stupid version number to begin with ;), for "0.9r4" would be valid. The exact rules for what are and are not valid software versions aren't described here, but the algorithms used are pretty flexible. Most sane projects, at least those that expose an interface, will make their software version the same as the interface version.
- Interface Version: Interface versions describe compatibility,
and may not be equal to the associated software versions.
Unlike the software version, the
rules for an interface version are far more strict. They are
somewhat similar to libtool versions, except with no micro
part. They take the form of two integers, separated by a period. For
instance:
2.1. Interface versions are typically used in the dependencies system, rather than by software itself. The purpose of skeleton files is to examine the system, and produce a list of interface versions representing the interfaces available. The actual packages the user installs do not have any information related to interface versions in them.The standard rules apply. If you add to an interface, but in a backwards compatible fasion, then increment the second integer. If you break backwards compatability, increment the first integer and set the second to zero.
There does not need to be a One True set of interface versions. It's up to the skeleton how they are calculated, and how interface versions map to the actual software. There is info on how that works in the Notes section of the skeleton file. As there should ideally be only one skeleton file for the software, this is normally the canonical source.
- Package version: This corresponds to package releases. Useful for when you make a mistake or an improvement in the package scripts themselves, you can release a new package with the same software version. They appear after the 2nd colon in a versioned root name. These are always positive integers.
Skeleton Files
Skeletons are identified by an unversioned root name. They are also versioned, but by a simple integer. The latest version of a skeleton always takes precedence, they cannot break backwards compatability.
They typically consist of a small amount of metadata, followed by a test script, and a retrieval script. The test script examines the system and produces a list of interfaces supported by the system, and stores them in the INTERFACE_VERSIONS variable. The Notes section can be used to record any oddities in the way INTERFACE_VERSIONS is calculated.
The autopackage APIs run this script and match against a given
interface version. If no match is found, the skeletons Retrieval
script is executed. Normally that will simply palm off to another
autopackage provided function, retrieve(), which does
its best to locate a package file for the given unversioned root
name that fulfils the requested interface. In fact this is the default
behaviour if the Retrieval section is missing.
APIs provided
Autopackage provides a large library of functions that make writing install scripts easier. For instance, there are functions to copy files and install common file types, which perform any special actions such as updating databases that are needed.
There are also APIs for performing dependency resolution. These are normally what you'd use in your own scripts and skeleton files, but it's not a hard requirement.
You can read the API reference online.

