Starting with release 3.1.2,
ASDF supports a one-package-per-file style of programming,
whereby each file is its own system,
and dependencies are deduced from the
(or its variant
In this style, packages refer to a system with the same name (downcased);
and if a system is defined with
then system names that start with that name
(using the slash
refer to files under the filesystem hierarchy where the system is defined.
For instance, if system
my-lib is defined in
/foo/bar/my-lib/my-lib.asd, then system
will be found in file /foo/bar/my-lib/src/utility.lisp.
This style was made popular by
and at the cost of a stricter package discipline,
seems to make for more maintainable code.
It is used by ASDF itself (starting with ASDF 3) and by
To use this style, choose a toplevel system name, e.g.
and create a file my-lib.asd
:class :package-inferred-system option in its
#-asdf3 (error "my-lib requires ASDF 3") (defsystem my-lib :class :package-inferred-system :defsystem-depends-on (:asdf-package-system) :depends-on (:my-lib/interface/all :my-lib/src/all :my-lib/extras/all) :in-order-to ((test-op (load-op :my-lib/test/all))) :perform (test-op (o c) (symbol-call :my-lib/test/all :test-suite))) (defsystem :my-lib/test :depends-on (:my-lib/test/all)) (register-system-packages :my-lib/interface/all '(:my-lib-interface)) (register-system-packages :my-lib/src/all '(:my-lib-implementation)) (register-system-packages :my-lib/test/all '(:my-lib-test)) (register-system-packages :closer-mop '(:c2mop :closer-common-lisp :c2cl :closer-common-lisp-user :c2cl-user))
In the code above, the
:defsystem-depends-on (:asdf-package-system) is
for compatibility with older versions of ASDF 3 (ASDF 2 is not supported),
and requires the
asdf-package-system library to be present
(it is implicitly provided by ASDF starting with release 3.1.2,
which can be detected with the feature
register-system-packages has to be called to register
packages used or provided by your system and its components
where the name of the system that provides the package
is not the downcase of the package name.
Then, file interface/order.lisp under the
that defines abstract interfaces for order comparisons,
starts with the following form,
dependencies being trivially computed from the
(uiop:define-package :lil/interface/order (:use :closer-common-lisp :lil/interface/definition :lil/interface/base :lil/interface/eq :lil/interface/group) (:mix :fare-utils :uiop :alexandria) (:export ...))
ASDF can tell that this file depends on system
closer-mop (registered above),
(package and system names match, and they will be looked up hierarchically).
ASDF also detects dependencies from
You may thus import a well-defined set of symbols from an existing package
as loaded from suitably named system;
or if you prefer to use any such symbol fully qualified by a package prefix,
you may declare a dependency on such a package and its corresponding system
:import-from clause with an empty list of symbols, as in:
(defpackage :foo/bar (:use :cl) (:import-from :foo/baz #:sym1 #:sym2) (:import-from :foo/quux) (:export ...))
uiop:define-package is supported as well as
and has many options that prove useful in this context,
that allow for “inheritance” of symbols being exported.