Autopackage Packagers Guide

Mike Hearn

Curtis Knight

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

This documentation was built on tor feb 14 17:18:40 CET 2008 for autopackage version: 1.2.5

Autopackage Developers Guide Multiple HTML Pages

Autopackage Developers Guide Single HTML Page

Autopackage API Documents


Table of Contents

1. Introduction to the framework
Basic concepts
Interface versions
Skeleton files
Names and naming
2. Creating a package
Choosing a root name
The specfile format
A quick example
Meta
Description
BuildPrepare
BuildUnprepare
Imports
Prepare
Install
Uninstall
Scripting Variables
Common Variables
Build Variables
Install Variables
Using the makepackage program
Sealed packages
KDE Programs
3. Writing Skeleton Files
What are they and how do they work?
Producing skeleton files
4. Environment Variables
Build Environment Variables
Installation Environment Variables
Environment State Files
5. Prefixing
What is prefixing?
So why isn't this done already
What about the FHS?
The solution
Exception: KDE
6. Autopackage Root Names & Versioning
Dependency checking and resolution
What is a root name?
Versioning
How to integrate this with skeletons
Example
How to interface with require()
requireExact()
requireAtLeast()
More on skeletons
Automatic dependency retrieval
Summary
7. Binary portability
Symbol Versions
Symbolic collisions
Bogus dependencies
Headers
Exception handling internals
C++
8. Alternative solutions
Statifier and Ermine
What are pros and cons of this approach ?
Pros
Cons
Statifier/Ermine and Autopackage
9. Using MimeTypes
Mime Type specs
Writing MIME Type association files
FreeDesktop.org/KDE
Gnome 2.x
Associating Applications with MIME types
.desktop file
Gnome .applications file
Index
Glossary

List of Tables

2.1. Standard Meta Keys
2.2. APIs provided for file types
2.3. Common Variables
2.4. Build Variables
2.5. Install Variables
4.1. Build Environment Variables
4.2. Installation Environment Variables
6.1. Software & Interface Number
6.2. Software & Interface number - Complex
6.3. Software & Interface Number with Skeleton Filename
6.4. Data Definitions between Package Repository File and .apspec File

Chapter 1. Introduction to the framework

Autopackage is a framework for developers that lets them build easy to use installers for their software. It provides an API which allows delegation many things to the framework - for instance, installing menu entries, copying files, uninstalling the software, and providing feedback to the users while it is installing.

As well as providing some useful utility functions for your installers, autopackage acts as a distribution abstraction . Packages built with autopackage are designed to be distribution neutral. The underlying framework and tools take care of the differences between the systems your software is being installed on.

An autopackage is typically a self extracting shell script with a .package extension. It will first check that the autopackage tools are present. If not, then it will automatically fetch them, install them, and then proceed with the installation. It will also download the graphical frontend that best matches the users desktop.

Basic concepts

Autopackage deals with dependencies by checking the system directly for the components needed. Rather than depending on a particular version of a particular piece of software, autopackages depend on an implementation of a particular interface being present. Interfaces are abstract things - a shared library exports an interface (or more commonly, many) but an interface can also be for instance the presence of certain files in certain locations, command line arguments given, protocols between system components and so on.

The first thing to realize then is the need to tell autopackage which interfaces your package needs, and then the system tries to figure out the "best" package that can satisfy that interface, typically the most recent compatible version of that package (but an interface doesn't have to correspond one to one with a particular piece of software).

Interface versions

Autopackage abstracts interfaces behind interface version numbers. These take the form of two integers written as A.B, and they work similar to the libtool versions many of us are used to. The A number is the major number and is incremented when a breaking change is made to an interface (a function is removed, renamed etc). When A is incremented, B is set back to zero. B is the minor number and is incremented when an interface is added. This is in contrast to the software version , which is pretty much freeform and is usually set to the version number chosen by the software authors.

Note that interface versions don't need to bear any resemblance to the version numbers software authors assign their creations (though they can do, if that's convenient). WhizzBang 2003 may well have an interface version of 0.35, or 4.1 or whatever. On the other hand, GTK+ for instance follows the libtool versioning style - every release in the 2.x series is backwards compatible. Because it also uses kernel versioning though, each release increments the minor number by two, not by one. In this case, the interface version can be equal to the software version - the meaning is still close enough that everything will work OK.

Skeleton files

The mapping from the state of the system to an interface version (or set of interface versions) is determined by the skeleton file which encapsulates that dependency. Skeleton files contain a small amount of metadata about a dependency, and they are used by packages to make dependency detection and resolution automatic. Typically for each dependency a package has, there must be a corresponding skeleton file - if one doesn't exist, it should be created and then let the maintainers of the software it represents know of its existence. Don't worry though, creating skeleton files is very easy.

Autopackage comes with a collection of useful skeleton files for common dependencies that can be used immediately in your own packages. If a skeleton is created, please forward the skeleton to us so that it can be in the next release.

Names and naming

Autopackage is designed to be a decentralized system. For this reason, it leverages off of the DNS network to uniquely identify things. The basic unit of currency is called a root name , and looks a bit like this: @foobar.org/frob:2000:3 . Root names have several components:

  • The path, this consists of the @foobar.org/frob part
  • The software version number, which comes after the first colon (2000 in this case)
  • The package release number, which comes after the second colon.

Warning

A root name should not be chosen based on where the package will be hosted, who built it, or anything other than whoever owns the software. Root names are designed to help reduce name conflicts without the need for yet another name "ownership" registry. Typically, if the packager is not the maintainer of the software that is being packaged, the true maintainer should be at the very least emailed to notify them that this root name has been allocated for them. Ideally of course the packager is the enlightened maintainer and wishes to build binary packages so this is not an issue.

Packages (but not skeletons) can optionally have a short name . Short names are more convenient to use than root names, and are more familiar to Linux users. They look like "frozen-bubble", "libxml" or "gnome-panel". Typically, these are the names users will use from the command line. Try and keep them unique if possible, but it's not a disaster if there are conflicts.

Finally, packages and skeletons should be given a display name . This is a human readable string, that can be optionally localized. It will be used in user interfaces where possible, and should take the form of "Product-Name Purpose", for instance "Sound Juicer CD Ripper", "Mozilla Web Browser", or "GNU Emacs Text Editor".

Chapter 2. Creating a package

Constructing an autopackage is fairly straightforward, and uses a system similar to RPM, namely the use of a specfile. This file contains most of the information needed for building the package file. The other pieces of information are pulled from skeleton files as needed.

Note

Use makepackage --mkspec >whatever.apspec.in as a fast way to generate a template specfile that can be customized for your own packages. We also provide a graphical utility that guides you through the process of creating a specfile. See the download tools page

Choosing a root name

Typically, choosing a root name will be one of the first things done while building a package. The path chosen should be controlled by the maintainer of the software , even if they aren't involved in the construction of the package (though really they should be). The path doesn't even have to exist in real life, autopackage will not attempt to resolve the path given in the root name, it's there purely for namespacing reasons.

A root name should consist of an @ symbol, then a valid URI path (without the protocol) part controlled by the maintainer of the software: they should have write access to whatever server it points to, for instance. It should not be related to whoever is packaging it - always notify the maintainer of what root name was selected.

A root name must have at least one path element. The root name can not just be a DNS address on its own, for instance "@myproject.org/myproject" is valid, but "@myproject.org" is not.

Examples are: "@purity.sourceforge.net/purity", "@webspace.myisp.com/~myname/random/software/xfoo", and so on.

The specfile format

Spec files resemble the Windows INI file format of yore, now used also in .desktop files. Typically each section is denoted with a header that looks like this: [Section-Name] . Specfiles usually have a .apspec extension, and are placed in a subdirectory of the projects source tree called autopackage . This directory contains one spec file for each package, in contrast to RPM which allows creation of multiple packages from the same spec. By convention, the primary package has a filename of default.apspec , and the makepackage program will use this if no specfile is specified. Use the autopackage directory to store other useful things, for instance patches.

Warning

Applying patches to the source tree is an indication that something is wrong. Typically the person who should be making an autopackage should be the maintainer of the software themselves, so external patches are not relevant. This is the best arrangement because that way users are guaranteed that source code releases are accompanied by binary releases - there is no need for them to hang around waiting for somebody to rebuild the package for them.

Note

If using GNU autoconf, then call the specfile something.apspec.in and makepackage will automatically run config.status to update the real specfile.

A quick example

This is a specfile for the GnuTLS library. It's fairly typical. Examine it for a while, it is straight forward to understand.

                    
[Meta]
RootName: @gnutls.org/gnutls:$SOFTWAREVERSION
ShortName: gnutls
SoftwareVersion: @VERSION@
DisplayName: GNU Transport Layer Security
Summary: Provides support for the TLS/SSL protocols
Maintainer: Nikos Mavroyanopoulos <nmav@hellug.gr>
Packager: Mike Hearn <mike@theoretic.com>
InterfaceVersion: 10.3
Language: de es fr
DisplayName[de]: Gnu Transport-Schicht-Sicherheit
Summary[de]: Gibt Unterstützung für die TLS/SSL Protokolle.
DisplayName[es]: Seguridad De la Capa De Transporte del Gnu
Summary[es]: Proporciona la ayuda para los protocolos de TLS/SSL.
DisplayName[fr]: Gnu Transport-Schicht-Sicherheit
Summary[fr]: Fournit l'appui pour les protocoles de TLS/SSL.

[Description]
This is a TLS (Transport Layer Security) 1.0 and SSL (Secure Sockets Layer) 3.0
implementation for the GNU project.

[BuildPrepare]
prepareBuild --with-included-libtasn1 --disable-openpgp-authentication

[BuildUnprepare]
unprepareBuild

[Globals]
export sover="10.3.8"

[Imports]
import <<EOF
lib/libgnutls.so.$sover
lib/libgnutls-extra.so.$sover
EOF

[Prepare]
require @gnupg.org/libgcrypt 7.1
require @gnupg.org/libgpg-error 0.0

[Install]
installLib libgnutls.so.$sover libgnutls-extra.so.$sover

[Uninstall]
uninstallFromLog

Meta

This section consists of a number of keys, of the form "Key: Value". Most of these should be obvious from the discussion of basic concepts - this is where short name , software version , interface version (optional), display name and so on are defined. Translated versions can be provided of DisplayName and Summary by appending [langcode] to the key names. The 'Scripting Key' variables are in addition to the common variables listed in the scripting variables section.

Some variables can be used as values of these keys. The $SOFTWAREVERSION is embedded into the root name - recall that root names can have the software version as a component.

Table 2.1. Standard Meta Keys

Meta Key Scripting Key Description Value Type REQ? Example
AutopackageTarget $AUTOPACKAGETARGET

Minimum targetted API version of autopackage for which the generated package requires.

numeric Yes 1.0
Compression $COMPRESSION

Sets compression encoding of payload. Defaults to bzip2 .

string No

lzma

bzip2

CPUArchitectures $CPUARCHITECTURES

The CPU architectures to be generated from the source.

string Yes x86
DisplayName[xx] $DISPLAYNAME

"Product-Name Purpose" of the package, for instance "Sound Juicer CD Ripper", "Mozilla Web Browser", or "GNU Emacs Text Editor".

Substitute a particular language code for [xx] like "DisplayName[fr]" or "DisplayName[de]". English text should not have any language declaration.

string Yes

DisplayName: Autopackage GTK+ Graphical User Interface

DisplayName[fr]: Autopackage GTK+ Frontend Graphique

InterfaceVersion $INTERFACEVERSION

Abstraction of the interface the package exposes represented as "A.B". Not useful for, say, applications or themes that do not expose an interface.

numeric No 1.0
License $LICENSE

License of the package.

string No

GNU General Public License, Version 2

GNU Lesser General Public License, Version 2.1

Apache License, Version 2.0

Public Domain

Maintainer $MAINTAINER

The name and email of the software's author or a group.

string Yes

Joe Developer <joe@developer.net>

The FooBar Development Team <development@foobar.org>

PackageDesktop $PACKAGEDESKTOP

List of languages and DisplayName/Summary strings will be pulled from this .desktop file if declared. Default is to pull strings from specfile. File location should be relative to import (payload) location.

string No share/applications/foobar.desktop
Packager $PACKAGER

Name of the person who created this package. Usually equal to the value of the Maintainer key.

string Yes Joe Packager <joe@packager.net>
PackageFileName $PACKAGEFILENAME

The name of the package generated by makepackage . Before autopackage 1.2, this was set by default to $SHORTNAME-$SOFTWAREVERSION-$PACKAGEVERSION.x86.package ; now it defaults to $DISPLAYNAME $SOFTWAREVERSION-$PACKAGEVERSION.package but using this key you can specify any arbitrary output file name.

string No $SHORTNAME-$SOFTWAREVERSION-$PACKAGEVERSION.x86.package
PackageReporting $PACKAGEREPORTING

Packages can anonymously report statistics. If the user is allowing statistics to be gathered, the packager can remove the package from being reported. Defaults to Yes .

string No

Yes

No

PackageVersion $PACKAGEVERSION

Version of the package.

numeric No 1
Repository $REPOSITORY

URL location of luau xml repository file. Data is required for application update function.

string No http://ftp.sunsite.dk/projects/autopackage/1.2/foobar.xml
RepositoryFilename $REPOSITORYFILENAME Filename for luau xml repository file. Defaults to $SHORTNAME.xml string No  
RootInstallOnly $ROOTINSTALLONLY

Forces package installation to the global database which makes it available system-wide. Requires user to have super user (root) password.

boolean No Yes
RootName $ROOTNAME

Identifier for the package which is composed of package owner, software version and package release version.

string Yes @foobar.org/frob:2000:3
ShortName $SHORTNAME

Short names are more convenient to use than root names, and are more familiar to Linux users. They look like "frozen-bubble", "libxml" or "gnome-panel". Typically, these are the names users will use from the command line.

string Yes autopackage-gtk
SoftwareVersion $SOFTWAREVERSION

Version of the software usually set by the software authors.

numeric Yes 2.6
Summary[xx] $SUMMARY

A short, one-line description of the package.

Substitute a particular language code for [xx] like "Summary[fr]" or "Summary[de]". English text should not have any language declaration.

string Yes

Summary: A graphical (GTK+) frontend for installing Autopackage packages.

Summary[fr]: Un frontend (GTK+) graphique pour installer des paquets d'Autopackage.

URL $URL

Home location that relates to the package.

string No http://organization.org/application-page.html

Description

This section should contain an English description of the package (in non technical terms please if at all possible). Non-English versions should go into the Description:xx sections, where xx is the language code. A good description will provide a brief overview of the purpose of the software and it's capabilities.

BuildPrepare

This section contains a bash script that will be used to prepare (build/compile) the sources for import. Import is the process whereby the files are selected and placed into the package archive. Preparation gives the chance to do things like run configure scripts, Makefiles and other such things if the project requires them.

If your project is using GNU autoconf/automake, calling prepareBuild() function will usually do the trick nicely. It simply reconfigures the tree to a temporary prefix, then does the make, make install cycle. Please note that your software must be relocatable; refer to paragraph 3 for more information.

This section is optional but recommended. A warning will be displayed if it is missed.

BuildUnprepare

This section is run after Imports and allows for any tidying up. This section is optional. Use the unprepareBuild() function to reset the source tree back to its original configuration, assuming prepareBuild() was used.

Imports

This script is used to select files that you want to put inside the package. You use the import command to import files in your package.

The import command is invoked like this:

echo (filenames...) | import

import reads filenames from STDIN. Each file must be seperated by a newline. The command also accepts wildcards, so you can also type:

echo '*' | import

The current working directory is the build root directory ( $build_root ). If you used prepareBuild , then all built files are automatically installed to this build root (by using 'make install'), so the only thing you have to do is to call echo '*' | import .

If you're not using prepareBuild , then there are two things you can do:

  1. Invoke a build system command similar to 'make install'. Make sure the files are installed to $build_root . After that, you can simple call echo '*' | import .
  2. The files that are built during the build process are probably in the source directory. You can manually import files from that directory. The location of the source directory is specified in $source_dir .

    For example, your project is based on a simple make-based build system. Make compiles superpig.c to the binary superpig . Your source directory also has wai.png , a data file used by superpig . You write this in your specfile:

                            
    import <<EOF
    $source_dir/superpig
    $source_dir/wai.png
    EOF
    

Prepare

The prep script is the first part of any package. It is responsible for "preparing" the package, which basically means ensuring all the dependencies are present, making any decisions about what to install or not install, and so on. No installation of any files occur here.

Dependencies are best handled with the require function, although they don't have to be if your needs are quite specialist:

require @gnome.org/libxml 2.0

In this case, that's all we have to do. The correct skeleton file will automatically be selected and copied into the package by the makepackage script. Later, when this line of script is run, the require function will run the script associated with the skeleton file and handle the error if the dependency fails. If the check passes, the script will continue.

There are several different ways of expressing dependencies. Require is the most common but there is also recommend . Recommending a dependency means autopackage will check for it, and try to install it if it's missing, but if it can't this will not cause the function to fail. Instead, the dependency will be listed in the summary screen to inform the users that if they had this library, new functionality would be available. An easy way to make something recommended rather than required is to use dlopen, and an easy way to use dlopen is to use relaytool.

You can also use the requireAtLeast and requireExact functions if you rely on implementation details of a dependency (for instance, maybe you need a bugfix). These only work if SOFTWARE_VERSIONS is set though, and not all skeletons set this. So check before using them. Both of these functions have recommend equivalents.

Note

The prep and install scripts run in +e mode, which means that any line which returns a non-zero exit code will terminate the script . If running a command might fail but the script should carry on regardless, stick || true on the end of it.

Install

The install section is the meat of your package. It consists of a series of calls to the autopackage API, in order to affect the users system in some fashion.

In theory you can do anything you like in these scripts, including using regular shell commands like "cp" or "mv". In practice, where autopackage provides a replacement command, you should use that. For instance, use copyFiles instead of cp. The builtin versions have advantages over the raw shell commands, for instance using copyFiles will register the files in the log so they will be automatically uninstalled, and they will appear in the file list. Whilst copyFiles and copyFile are very generic, for some types of file there are more specific functions available. Here is a short list:

Table 2.2. APIs provided for file types

File type API used
Executable programs (ELF/scripts) installExe
Public ELF shared libraries installLib
Architecture-neutral data (share) installData
Man pages installMan
.desktop files for menu entries installMenuItem
.desktop files for MIME type associations but not menus installMimeDesktop
Translations installLocale
MIME type sniffing/matching templates installMime
Icons installIcon
TeXInfo files installInfo
App specific config files installConfig
GConf schemas installGConfSchema

In the install section, like in the Prepare section, any command that fails will abort the install. That doesn't apply inside if statements of course.

Uninstall

This is usually easy - just a call to uninstallFromLog will suffice, as this runs the uninstall script that was generated automatically by the installer functions, and will automatically remove any files copied/any directories created etc. If any actions was done without using the autopackage APIs, now is a good time to undo them. Remember - forgive the user . They may well have screwed around with the install, so if custom actions are included, check that they make sense (IE the file exists before trying to delete it).

Scripting Variables

The following is an alphabetical list of variables that are available for scripting use.

Common Variables

The following is an alphabetical list of variables that are available for all scripting use. The variables are in addition to the 'Scripting Key' variables listed with the Standard Meta keys.

Table 2.3. Common Variables

Name Description Value Type Example
BUILDHOST

The host machine from which the package was generated.

string build-machine.organization.org
CPUARCHITECTURE

The CPU architecture of the installing or installed package.

string x86
DATASIZE

Size in bytes of the package's compressed payload.

numeric 654321
DESCRIPTION

Deprecated in version 1.2 .

Text that describes the package contents. Typically formatted to be a fixed column width.

string The GIMP (GNU Image Manipulation Program) is a powerful image composition and editing program, which can be extremely useful for creating logos and other graphics for Web pages. The GIMP has many of the tools and filters...

Formatted to a fixed width like 69.

DISTRIBUTIONCODENAME

Deprecated in version 1.2 . Use environment variable AUTOPACKAGE_DISTRIBUTION_CODENAME.

The distribution code name of the target machine.

string Community
DISTRIBUTIONDESCRIPTION

Deprecated in version 1.2 . Use environment variable AUTOPACKAGE_DISTRIBUTION_DESCRIPTION.

The distribution description of the target machine.

string Mandrakelinux
DISTRIBUTIONID

Deprecated in version 1.2 . Use environment variable AUTOPACKAGE_DISTRIBUTION_ID.

The distribution id of the target machine.

string mandrakelinux
DISTRIBUTIONMANAGER

Deprecated in version 1.2 . Use environment variable AUTOPACKAGE_DISTRIBUTION_MANAGER.

The distribution manager of the target machine.

string urpmi
DISTRIBUTIONMANAGERGRAPHICAL

Deprecated in version 1.2 . Use environment variable AUTOPACKAGE_DISTRIBUTION_FRONTEND.

The graphic distribution manager of the target machine.

string urpmi
DISTRIBUTIONRELEASE

Deprecated in version 1.2 . Use environment variable AUTOPACKAGE_DISTRIBUTION_RELEASE.

The distribution release of the target machine.

string 10.1
EXPANDSIZE

The size in bytes of the expanded (uncompressed) full package.

numeric 7654321
FILETOTAL

The total file count within the package.

numeric 87
LSBVERSION

Deprecated in version 1.2, use environment variable AUTOPACKAGE_LSB_VERSION.

The lsb version of the target machine.

numeric 2.0
METASIZE

The size in bytes of the package's compressed meta data.

numeric 4321
PACKAGELANGUAGES

The generated list of languages that are specifically supported within the package.

string de en fr nl
PREFIX

The installation prefix where the package was installed.

string /home/user/.local
TIMESTAMPBUILD

The universal coordinated time ISO-8601 date from when the package was generated.

string 2004-10-09T01:12:59Z


Build Variables