diff --git a/doc/asdf.texinfo b/doc/asdf.texinfo index 02bf1661ccf200bb1843aaf0a7d99d0951d3e76f..28c98b0174f118a0d1ef8fbc8f9b9b1099382c34 100644 --- a/doc/asdf.texinfo +++ b/doc/asdf.texinfo @@ -1942,6 +1942,10 @@ of output from ASDF operations. @node The package-inferred-system extension, , Other code in .asd files, Defining systems with defsystem @section The package-inferred-system extension +@codequoteundirected on +@cindex Package inferred systems +@cindex Packages, inferring dependencies from +@findex package-inferred-system Starting with release 3.1.2, ASDF supports a one-package-per-file style of programming, @@ -1969,12 +1973,14 @@ and create a file @file{my-lib.asd} with the @code{:class :package-inferred-system} option in its @code{defsystem}. For instance: @example -#-asdf3.1 (error "my-lib requires ASDF 3.1") +;; This example is based on lil.asd of LISP-INTERFACE-LIBRARY. + +#-asdf3.1 (error "MY-LIB requires ASDF 3.1 or later.") (defsystem "my-lib" :class :package-inferred-system :depends-on ("my-lib/interface/all" - "my-lib/src/all" - "my-lib/extras/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))) @@ -1986,43 +1992,82 @@ For instance: (register-system-packages "closer-mop" - '(:c2mop :closer-common-lisp :c2cl :closer-common-lisp-user :c2cl-user)) + '(:c2mop + :closer-common-lisp + :c2cl + :closer-common-lisp-user + :c2cl-user)) @end example -In the code above, the first line checks that we are using ASDF 3.1, -which provides @code{package-inferred-system}. +In the code above, the first form checks that we are using ASDF 3.1 or +later, which provides @code{package-inferred-system}. The function @code{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 +when the name of the system that provides the package is not the downcase of the package name. -Then, file @file{interface/order.lisp} under the @code{lil} hierarchy, -that defines abstract interfaces for order comparisons, -starts with the following form, -dependencies being trivially computed from the @code{:use} and @code{:mix} clauses: +Then, each file under the @code{my-lib} hierarchy will start with a +package definition, dependencies being computed from the +@code{:use} and @code{:mix} clauses. Take a file +@file{interface/order.lisp} as an example: @example -(uiop:define-package :lil/interface/order +(uiop:define-package :my-lib/interface/order (:use :closer-common-lisp - :lil/interface/definition - :lil/interface/base - :lil/interface/eq :lil/interface/group) + :my-lib/interface/definition + :my-lib/interface/base) (:mix :fare-utils :uiop :alexandria) (:export ...)) @end example ASDF can tell that this file depends on system @code{closer-mop} (registered above), -@code{lil/interface/definition}, @code{lil/interface/base}, -@code{lil/interface/eq}, and @code{lil/interface/group} +@code{my-lib/interface/definition}, @code{my-lib/interface/base} (package and system names match, and they will be looked up hierarchically). +How can ASDF find the file @file{interface/order.lisp} from the +toplevel system @code{my-lib}, however? In the example above, +@file{interface/all.lisp} (and other @code{all.lisp}) will reexport +all the symbols at once from the packages at the same or lower levels +of the hierarchy. This can be easily done with +@code{uiop:define-package}: + +@example +(uiop:define-package :my-lib/interface/all + (:nicknames :my-lib-interface) + (:use :closer-common-lisp) + (:mix :fare-utils :uiop :alexandria) + (:use-reexport + :my-lib/interface/definition + :my-lib/interface/base + :my-lib/interface/order + :my-lib/interface/monad/continuation)) +@end example + +Thus you have only to refer to each @code{my-lib/.../all} system +in the toplevel system because ASDF detects +@file{interface/order.lisp} and all other dependencies from the +@code{:use-reexport} clause. + +@findex define-package +@findex uiop:define-package +The form @code{uiop:define-package} is supported as well as +@code{defpackage}, and has many options that prove useful in this +context, such as @code{:use-reexport} and @code{:mix-reexport} that +allow for ``inheritance'' of symbols being exported. + ASDF also detects dependencies from @code{:import-from} clauses. -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 thus import a well-defined set of symbols from an existing +package, and ASDF will know to load the system that provides that +package. In the following example, ASDF will infer that the current +system depends on +@code{''foo/bar''} from the first @code{:import-from}. +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 -via an @code{:import-from} clause with an empty list of symbols, as in: +via an @code{:import-from} clause with an empty list of symbols. For +example, if we preferred to use the name `foo/quux:bletch`, the second, +empty, @code{:import-from} form would cause ASDF to load +@code{''foo/quux''}. @example (defpackage :foo/bar @@ -2032,19 +2077,42 @@ via an @code{:import-from} clause with an empty list of symbols, as in: (:export ...)) @end example -The form @code{uiop:define-package} is supported as well as @code{defpackage}, -and has many options that prove useful in this context, +In addition to @code{defpackage}, ASDF package-inferred systems support +the macro @code{uiop:define-package}. @code{define-package} +has many options that are useful in system definitions, such as @code{:use-reexport} and @code{:mix-reexport} that allow for ``inheritance'' of symbols being exported. +In @code{my-lib} example above, @file{my-lib/interface/all.lisp} (and +other @code{all.lisp}) will reexport all the symbols from the +packages at the same or lower levels of the hierarchy. This can be +done with @code{:use-reexport}, as follows: + +@example +(uiop:define-package :my-lib/interface/all + (:nicknames :my-lib-interface) + (:use :closer-common-lisp) + (:mix :fare-utils :uiop :alexandria) + (:use-reexport + :my-lib/interface/definition + :my-lib/interface/base + :my-lib/interface/order + :my-lib/interface/monad/continuation)) +@end example + +Not only does this simplify package referencdes, it also means that +you have only to refer to each @code{my-lib/.../all} system in the +toplevel system, and ASDF will find all the implied dependencies. + Note that starting with ASDF 3.1.5.6 only, ASDF will look for source files under -the @code{component-pathname} as specified via the @code{:pathname} option, +the @code{component-pathname} (specified via the @code{:pathname} option), whereas earlier versions ignore this option and use the @code{system-source-directory} where the @file{.asd} file resides. @c See this blog post about it: @c @url{http://davazp.net/2014/11/26/modern-library-with-asdf-and-package-inferred-system.html} +@codequoteundirected off @node The object model of ASDF, Controlling where ASDF searches for systems, Defining systems with defsystem, Top @comment node-name, next, previous, up