ASDF System
An ASDF System is a collection of source files and a .asd file which tells asdf how to compile and load them. This document describes the standard used by cirCLe which asdf systems should comply with for a more consistent end-user experience, and outlines a preferred way in which a package management technology such as RPM or dpkg could be layered onto it

System contents

An asdf system is a collection of files. Distribution and packaging technologies such as tar, cpio, RPM, etc may be used to bundle up complete asdf systems for ease of transportation, but the choice of package format is not specified here and should be made by the packager.

The contents of an asdf system called 'my-package' are


  • Starts with DEFPACKAGE and IN-PACKAGE forms for "MY-PACKAGE-SYSTEM", which should use the ASDF and COMMON-LISP packages.
  • Contains the DEFSYSTEM form(s) necessary to build this system. This should
    • specify a version number in dotted-decimal format (x, x.y, x.y.z, etc) using a change in the major number to indicate a release that is not backward-compatible at source level with its predecessor
    • not specify a toplevel :pathname option
Trivial example:
;;; -*- Lisp -*- mode
(defpackage #:split-sequence-system (:use #:cl #:asdf))
(in-package :split-sequence-system)
(defsystem :split-sequence
    :version "20011114.1"
    :components ((:file "split-sequence")))

source files

Everything we need to build. Lisp source files should have the type "lisp"


Undecided currently, but see hyperdoc for ideas towards one important component.


to do. there will be a standard test harness: it will probably be RT

Interaction with other Lisp implementation module systems

The rest of this document does not apply to cirCLe

asdf packages do not use the provide/require mechanism, nor touch *modules*, because ANSI CL reserves the specification of these to the Lisp implementor. If implementations want to adopt asdf systems to implement provide/require, we welcome that, but they will need to do their own manipulation of *modules* and so on.

I haven't decided if we should meddle with *features* or not. We can test the presence/absense of packages - and their versions - directly in system definitions anyway.

How it's used - personal lisp installations

When a pathname is not supplied to an asdf system definition, the TRUENAME of the .asd file is used. So, all that is required to use a asdf package is to create a symlink to its .asd file from the place that your Lisp installation is configured to look for system files

Suppose your asdf package was supplied to you in a b2zipped tar file, and your local asdf installation is configured to look in $HOME/src/defsystems, you might follow a process like this to install a new asdf system:

$ cd ~/src/lisp
$ tar jxf /tmp/downloads/my-package-1.0.tar.bz2
$ cd ~/src/defsystems
$ ln -s ~/src/lisp/my-package-1.0/package.asd .
CL-USER> (asdf:operate 'asdf:load-op 'package)

If the .asd file defines more than one system, create as many symlinks to the .asd file as the defined systems, with names matching those of the systems.

Interaction with vendor packaging systems

Where the packaging technology allows for arbitrary actions to be specified at package installation and removal file (e.g. "postinst scripts"), certain such actions are required of an asdf system

Where the packaging technology tracks installed files so that the local system administrator may use it to install and remove packages cleanly or to query the `owning package' of a particular file, there should be a simple, and ideally mechanically derivable, relationship between the package name and the asdf system name. For example, a policy of prefixing all asdf package names with "asdf-" or "cl-" would satisfy this.

How it's used - platform packages

Platform package systems often take it upon themselves to `manage' certain areas of the filesystem. For example, in most Linux systems the content of /usr (other than /usr/local) is expected to be reserved to packages that use the vendor package format.

When we refer to the "managed area" here, we mean the part of the filesystem that the platform package system has allocated to Lisp files: for example, /usr/share/common-lisp/source/ and /usr/lib/common-lisp/$implementation/

Requirement on managed Lisp implementations

Each managed Lisp implementation should ensure when it starts that it defines an appropriate asdf:output-files :around method that tests whether the output file is in the managed source area and relocates it to the appropriate binary area if so

Requirements on package

The packagename, version, and dependencies on other lisp packages should all be extracted from the asdf system definition.

Dependencies on non-Lisp packages need to be listed somewhere, but the problem is that different platforms will have different package names for the same functionality. Perhaps we could spec dependencies on filenames and have the package maker look up the package(s) that provide that file

The package should arrange that the contents of the upstream archive are installed into /usr/share/common-lisp/source/my-package/

Post-installation, the package system should arrange that

  • a symlink is made from /usr/share/common-lisp/systems/my-package.asd to the source dir
  • "(asdf:oos 'load-op 'package)" is run using each managed lisp implementation that the package is expected to be used with

At package removal time, the source files, symlink and all created binary files must be removed