Commit 04ee8ddb authored by Peter Van Eynde's avatar Peter Van Eynde
Browse files

Merge branch 'upstream'

parents 3f0004ab c17d8fbb
......@@ -12,7 +12,6 @@ test/conf.d/
test/dir1/
test/dir2/
# We build these at various stages in the make process
LICENSE
website/output/
......@@ -21,9 +20,9 @@ tmp/
lift-local.config
*.dribble
*.fasl
*.dfsl
*.cfsl
*.fas
*.dfsl
*.cfsl
*.fas
*.lib
*.o
*.*fsl
......
system := "asdf"
#user := $(shell basename `echo "$home"`)
user := "gking"
user := "frideau"
webhome_private := $(user)@common-lisp.net:/project/asdf/public_html/
webhome_public := "http://common-lisp.net/project/asdf/"
clnet_home := "/project/asdf/public_html/"
......@@ -38,7 +38,7 @@ website-copy: FORCE
bin/rsync-cp.sh tmp/asdf.lisp $(webhome_private)
clean_dirs = $(sourceDirectory)
clean_extensions = fasl dfsl cfsl fasl fas lib dx32fsl lx64fsl lx32fsl
clean_extensions = fasl dfsl cfsl fasl fas lib dx32fsl lx64fsl lx32fsl o
clean: FORCE
@for dir in $(clean_dirs); do \
......@@ -63,4 +63,4 @@ test-all: FORCE
sbcl --userinit /dev/null --sysinit /dev/null --load bin/make-helper.lisp \
--eval "(write-test-web-pages)" --eval "(quit)"
FORCE:
\ No newline at end of file
FORCE:
========================
ASDF Output Translations
========================
This file specifies how ASDF stores "binary" outputs for its operations,
typically Lisp FASL files, but also any other files
that may be generated, e.g. C files and executables from CFFI-GROVEL.
Configurations
==============
Configurations specify mappings from source locations to binary locations.
1- An application may explicitly initialize the output-translations
configuration using the `Configuration API`_ below,
in which case this takes precedence.
It may itself compute this configuration from the command-line,
from a script, from its own configuration file, etc.
2- The source registry will be configured from
the environment variable ``ASDF_OUTPUT_TRANSLATIONS`` if it exists.
3- The source registry will be configured from
user configuration file
``~/.config/common-lisp/asdf-output-translations.conf``
if it exists.
4- The source registry will be configured from
user configuration directory
``~/.config/common-lisp/asdf-output-translations.conf.d/``
if it exists.
5- The source registry will be configured from
system configuration file
``/etc/common-lisp/asdf-output-translations.conf``
if it exists.
6- The source registry will be configured from
system configuration directory
``/etc/common-lisp/asdf-output-translations.conf.d/``
if it exists.
Each of these configurations is specified as a SEXP
in a trival domain-specific language (defined below).
Additionally, a more shell-friendly syntax is available
for the environment variable (defined yet below).
Each of these configurations is only used if the previous
configuration explicitly or implicitly specifies that it
includes its inherited configuration.
Additionally, some implementation-specific directories
may be automatically added to whatever mappings are specified
in configuration files, no matter if the last one inherits or not.
Backward Compatibility
======================
We purposefully do NOT provide backward compatibility with earlier versions of
asdf-binary-locations (8 Sept 2009),
common-lisp-controller (7.00) or
cl-launch (2.35),
each of which had similar general capabilities.
Future versions of same packages (if any)
will hopefully use the new ASDF API as defined below.
These previous programs' API was not designed
for easy configuration by the end-user
in an easy way with configuration files,
and their previous API didn't fit the new paradigm.
But this incompatibility won't inconvenience many people.
Indeed, few people use and customize these packages;
these people are experts who can trivially adapt to the new configuration.
Most people are not experts, could not properly configure these features
(except inasmuch as the default configuration of
common-lisp-controller and/or cl-launch
might have been doing the right thing for some users),
and yet will experience software that "just works",
as configured by the system distributor, or by default.
Nevertheless, if you want to use the old ASDF-Binary-Locations
(the one available as an extension to load of top of ASDF,
not the one built into a few old versions of ASDF),
it may still work if you just make sure you do not configure the new
builtin ASDF-Output-Translations.
But if you configure both ASDF's new builtin and ASDF-Binary-Locations
(or an old common-lisp-controller or cl-launch),
you may experience "interesting" issues, so don't do it.
Configuration DSL
=================
Here is the grammar of the SEXP DSL for asdf-output-translations configuration:
;; A configuration is single SEXP starting with keyword :source-registry
;; followed by a list of directives.
CONFIGURATION := (:output-translations DIRECTIVE ...)
;; A directive is one of the following:
DIRECTIVE :=
;; include a configuration file or directory
(:include PATHNAME-DESIGNATOR) |
;; Your configuration expression MUST contain
;; exactly one of either of these:
:inherit-configuration | ; splices contents of inherited configuration
:ignore-inherited-configuration | ; drop contents of inherited configuration
;; enable global cache in ~/.common-lisp/cache/sbcl-1.0.35-x86-64/ or something.
:enable-user-cache |
;; Disable global cache. Map / to /
:disable-cache |
;; add a single directory to be scanned (no recursion)
(DIRECTORY-DESIGNATOR DIRECTORY-DESIGNATOR)
DIRECTORY-DESIGNATOR :=
ABSOLUTE-COMPONENT-DESIGNATOR |
(ABSOLUTE-COMPONENT-DESIGNATOR RELATIVE-COMPONENT-DESIGNATOR ...)
ABSOLUTE-COMPONENT-DESIGNATOR :=
STRING | ;; namestring (directory is assumed, better be absolute or bust, ``/**/*.*`` added)
PATHNAME | ;; pathname (better be an absolute directory or bust)
:HOME | ;; designates the user-homedir-pathname ~/
:USER-CACHE | ;; designates the default location for the user cache
:SYSTEM-CACHE | ;; designates the default location for the system cache
:ROOT | ;; the root of the filesystem hierarchy
:CURRENT-DIRECTORY ;; the current directory
RELATIVE-COMPONENT-DESIGNATOR :=
STRING | ;; namestring, directory is assumed. If the last component, ``/**/*.*`` is added
PATHNAME | ;; pathname unless last component, directory is assumed.
:IMPLEMENTATION | ;; a directory based on implementation, e.g. sbcl-1.0.32.30-linux-x86-64
:IMPLEMENTATION-TYPE | ;; a directory based on lisp-implementation-type only, e.g. sbcl
:CURRENT-DIRECTORY | ;; all components of the current directory, without the :absolute
:UID | ;; current UID -- not available on Windows
:USER ;; current USER name -- NOT IMPLEMENTED(!)
Relative components better be either relative
or subdirectories of the path before them, or bust.
The last component, if not a pathname, is notionally completed by ``/**/*.*``.
You can specify more fine-grained patterns by using a pathname object,
e.g. ``#p"some/path/**/foo*/bar-*.fasl"``
You may use ``#+features`` to customize the configuration file.
The second designator of a mapping may be ``NIL``, indicating that files are not mapped
to anything but themselves (same as if the second designator was the same as the first).
``:include`` statements cause the search to recurse with the path specifications
from the file specified.
An ``:inherit-configuration`` statement cause the search to recurse with the path
specifications from the next configuration
(see section Configurations_ above).
:enable-user-cache is the same as ``(:root :user-cache)``.
:disable-cache is the same as ``(:root :root)``.
:user-cache uses the contents of variable ``asdf::*user-cache*``
which by default is the same as using
``(:home ".cache" "common-lisp" :implementation)``.
:system-cache uses the contents of variable ``asdf::*system-cache*``
which by default is the same as using
``(:root "var" "cache" "common-lisp" :uid :implementation-type)``
Configuration Directories
=========================
Configuration directories consist in files each contains
a list of directives without any enclosing ``(:asdf-output-translations ...)`` form.
The files will be sorted by namestring as if by ``#'string<`` and
the lists of directives of these files with be concatenated in order.
An implicit ``:inherit-configuration`` will be included
at the end of the list.
This allows for packaging software that has file granularity
(e.g. Debian's ``dpkg`` or some future version of ``clbuild``)
to easily include configuration information about distributed software.
Directories may be included by specifying a directory pathname
or namestring in an ``:include`` directive, e.g.::
(:include "/foo/bar/")
Shell-friendly syntax for configuration
=======================================
When considering environment variable ``ASDF_OUTPUT_TRANSLATIONS``
ASDF will skip to next configuration if it's an empty string.
It will ``READ`` the string as a SEXP in the DSL
if it begins with a paren ``(``
and it will be interpreted as a colon-separated list of directories.
Directories should come in pairs, each pair indicating a :map directive.
The magic empty entry indicates the splicing of inherited configuration
rather than one of entry in a mapping pair.
Semantics of Output Translations
================================
From the specified configuration, a list of mappings is extracted
in a straightforward way:
mappings are collected in order, recursing through
included or inherited configuration as specified.
To this list is prepended some implementation-specific mappings,
and is appended a global default.
The list is then compiled to a mapping table as follows:
for each entry, in order, resolve the first designated directory
into an actual directory pathname for source locations.
If no mapping was specified yet for that location,
resolve the second designated directory to an output location directory
add a mapping to the table mapping the source location to the output location,
and add another mapping from the output location to itself
(unless a mapping already exists for the output location).
Based on the table, a mapping function is defined,
mapping source pathnames to output pathnames:
given a source pathname, locate the longest matching prefix
in the source column of the mapping table.
Replace that prefix by the corresponding output column
in the same row of the table, and return the result.
If no match is found, return the source pathname.
(A global default mapping the filesystem root to itself
may ensure that there will always be a match,
with same fall-through semantics).
Caching Results
===============
The implementation is allowed to either eagerly compute the information
from the configurations and file system, or to lazily re-compute it
every time, or to cache any part of it as it goes.
To explicitly flush any information cached by the system, use the API below.
Output location API
===================
The specified functions are exported from package ASDF.
(initialize-output-translations)
will read the configuration and initialize all internal variables.
(clear-output-translations)
undoes any output location configuration
and clears any cache for the mapping algorithm.
You might want to call that before you
dump an image that would be resumed with a different configuration,
and return an empty configuration.
Note that this does not include clearing information about
systems defined in the current image, only about
where to look for systems not yet defined.
(ensure-output-translations)
checks whether output translations have been initialized.
If not, initialize them.
This function will be called before any attempt to operate on a system.
If your application wants to override the provided defaults,
it will have to use the below function process-output-translations.
(apply-output-translations PATHNAME)
Applies the configured output location translations to PATHNAME
(calls ensure-output-translations for the translations).
Credits
=======
Thanks a lot to Bjorn Lindberg and Gary King for ASDF-Binary-Locations,
and to Peter van Eynde for Common Lisp Controller.
All bad design ideas and implementation bugs are to mine, not theirs.
But so are good design ideas and elegant implementation tricks.
-- Francois-Rene Rideau <fare@tunes.org>
..
;;; Local Variables:
;;; mode: rst
;;; End:
......@@ -49,6 +49,15 @@ in a trival domain-specific language (defined below).
Additionally, a more shell-friendly syntax is available
for the environment variable (defined yet below).
Each of these configurations is only used if the previous
configuration explicitly or implicitly specifies that it
includes its inherited configuration.
Additionally, some implementation-specific directories
may be automatically prepended to whatever directories are specified
in configuration files, no matter if the last one inherits or not.
Backward Compatibility
======================
......@@ -92,11 +101,11 @@ DIRECTIVE :=
;; Your configuration expression MUST contain
;; exactly one of either of these:
(:inherit-configuration) | ; splices contents of inherited configuration
(:ignore-inherited-configuration) ; drop contents of inherited configuration
:inherit-configuration | ; splices contents of inherited configuration
:ignore-inherited-configuration | ; drop contents of inherited configuration
;; This directive specifies that some default must be spliced.
(:default-registry)
:default-registry
PATTERN := a string without wildcards, that will be matched exactly
against the name of a any subdirectory in the directory component
......@@ -113,7 +122,7 @@ the lists of directives of these files with be concatenated in order.
An implicit ``:inherit-configuration`` will be included
at the end of the list.
This allows for packaging software with has file granularity
This allows for packaging software that has file granularity
(e.g. Debian's ``dpkg`` or some future version of ``clbuild``)
to easily include configuration information about distributed software.
......@@ -283,6 +292,15 @@ for the sake of keeping ASDF no more complex than strictly necessary.
down a filesystem tree in the environment variable.
It isn't that Lisp friendly either.
TODO
====
* Integrate into the rest of the documentation.
* Add examples
* Add proper defaults.
* Get inspired by the XDG base directory specification?
http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
Credits
=======
......@@ -294,4 +312,4 @@ Thanks to Rommel Martinez for the initial implementation attempt.
All bad design ideas and implementation bugs are to mine, not theirs.
But so are good design ideas and elegant implementation tricks.
-- Francois-Rene Rideau <fare@tunes.org>, Sun, 24 Jan 2010 20:54:19 -0500
-- Francois-Rene Rideau <fare@tunes.org>, Mon, 22 Feb 2010 00:07:33 -0500
......@@ -16,32 +16,12 @@
;;;
;;; COMPILE-OP / LOAD-OP
;;;
;;; We change these operations to produce both FASL files and the
;;; In ECL, these operations produce both FASL files and the
;;; object files that they are built from. Having both of them allows
;;; us to later on reuse the object files for bundles, libraries,
;;; standalone executables, etc.
;;;
(defmethod initialize-instance :after ((instance compile-op) &key &allow-other-keys)
(setf (slot-value instance 'flags) '(:system-p t)))
(defmethod output-files ((o compile-op) (c cl-source-file))
(list (compile-file-pathname (component-pathname c) :type :object)
(compile-file-pathname (component-pathname c) :type :fasl)))
(defmethod perform :after ((o compile-op) (c cl-source-file))
;; Note how we use OUTPUT-FILES to find the binary locations
;; This allows the user to override the names.
(let* ((input (output-files o c))
(output (compile-file-pathname (first input) :type :fasl)))
(c:build-fasl output :lisp-files (remove "fas" input :key #'pathname-type :test #'string=))))
(defmethod perform ((o load-op) (c cl-source-file))
(loop for i in (input-files o c)
unless (string= (pathname-type i) "fas")
collect (let ((output (compile-file-pathname i)))
(load output))))
;;;
;;; BUNDLE-OP
;;;
......
This diff is collapsed.
......@@ -14,7 +14,7 @@
This manual describes asdf, a system definition facility for Common
Lisp programs and libraries.
asdf Copyright @copyright{} 2001-2007 Daniel Barlow and contributors
asdf Copyright @copyright{} 2001-2010 Daniel Barlow and contributors
This manual Copyright @copyright{} 2001-2007 Daniel Barlow and
contributors
......@@ -65,6 +65,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@insertcopying
@menu
* Introduction::
* Using asdf to load systems::
* Defining systems with defsystem::
......@@ -96,6 +97,7 @@ Defining systems with defsystem
* The defsystem grammar::
* Other code in .asd files::
The object model of asdf
* Operations::
......@@ -453,7 +455,7 @@ option := :components component-list
| :default-component-class
| :perform method-form
| :explain method-form
| :output-files method-form
| :output-files method-form
| :operation-done-p method-form
| :depends-on ( {dependency-def}* )
| :serial [ t | nil ]
......@@ -461,8 +463,7 @@ option := :components component-list
component-list := ( {component-def}* )
component-def := simple-component-name
| ( component-type name {option}* )
component-def := ( component-type name {option}* )
component-type := :module | :file | :system | other-component-type
......@@ -1282,8 +1283,6 @@ location of the system's source file and the relative pathname. For example
@comment node-name, next, previous, up
@chapter Getting the latest version
@emph{FIXME: Need to revise this to give information about the git repository.}
Decide which version you want. HEAD is the newest version and
usually OK, whereas RELEASE is for cautious people (e.g. who already
have systems using asdf that they don't want broken), a slightly older
......@@ -1396,6 +1395,68 @@ interfere.
ASDF bugs are tracked on launchpad: @url{https://launchpad.net/asdf}.
@item ``I want to put my module's files at the top level. How do I do this?''
By default, the files contained in an asdf module go
in a subdirectory with the same name as the module.
However, this can be overridden by adding a @code{:pathname} argument
to the module description.
For example, here is how it is done
in the spatial-trees ASDF system definition:
@example
(asdf:defsystem :spatial-trees
:components
((:module base
:pathname ""
:components
((:file "package")
(:file "basedefs" :depends-on ("package"))
(:file "rectangles" :depends-on ("package"))))
(:module tree-impls
:depends-on (base)
:pathname ""
:components
((:file "r-trees")
(:file "greene-trees" :depends-on ("r-trees"))
(:file "rstar-trees" :depends-on ("r-trees"))
(:file "rplus-trees" :depends-on ("r-trees"))
(:file "x-trees" :depends-on ("r-trees" "rstar-trees"))))
(:module viz
:depends-on (base)
:pathname ""
:components
((:static-file "spatial-tree-viz.lisp")))
(:module tests
:depends-on (base)
:pathname ""
:components
((:static-file "spatial-tree-test.lisp")))
(:static-file "LICENCE")
(:static-file "TODO")))
@end example
All of the files in the @code{tree-impls} module are at the top level,
instead of in a @code{tree-impls/} subdirectory.
Note that the argument to @code{:pathname} can be either a pathname object or a string.
A pathname object can be constructed with the @code{#p"foo/bar/"} syntax,
but this is discouraged because the results of parsing a namestring are not portable.
A pathname can only be portably constructed with such syntax as
@code{#.(make-pathname :directory '(:relative "foo" "bar"))},
and similarly the current directory can only be portably specified as
@code{#.(make-pathname :directory '(:relative))}.
However, as of ASDF 1.624, you can portably use a string to denote a pathname.
The string will be parsed as a @code{/}-separated path from the current directory,
such that the empty string @code{""} denotes the current directory, and
@code{"foo/bar"} (no trailing @code{/} required in the case of modules)
portably denotes the same subdirectory as above.
When files are specified, the last @code{/}-separated component is interpreted
either as the name component of a pathname
(if the component class specifies a pathname type),
or as a name component plus optional dot-separated type component
(if the component class doesn't specifies a pathname type).
@end itemize
@node TODO list, missing bits in implementation, FAQ, Top
......@@ -1612,4 +1673,3 @@ probably will be again soon ]
@bye
#+xcvb
(module
(:fullname "asdf"
(:fullname "/asdf"
:author ("Daniel Barlow and contributors")
:licence "MIT" ;; MIT-style license. See asdf.lisp
:description "ASDF"
:long-description "Another System Definition Facility."
:depends-on ("asdf")
:depends-on ("asdf" (:when (:featurep :ecl) "asdf-ecl"))
:build-image nil))
(in-package #:common-lisp-user)
(load "test/script-support.lisp")
(load (merge-pathnames "script-support" *load-pathname*))
(cond ((probe-file "asdf.lisp")
(cond ((probe-file *asdf-lisp*)
(ensure-directories-exist *asdf-fasl*)
(multiple-value-bind (result warnings-p errors-p)
(compile-file "asdf.lisp")
;; style warnings shouldn't abort the compilation [2010/02/03:rpg]
(handler-bind ((style-warning
#'(lambda (w)
(princ w *error-output*)
(muffle-warning w))))
(compile-file *asdf-lisp*
:output-file *asdf-fasl*))
(declare (ignore result))
(cond (warnings-p
(leave-lisp "Testuite failed: ASDF compiled with warnings" 1))
(errors-p
(leave-lisp "Testuite failed: ASDF compiled with ERRORS" 2))
(cond (warnings-p
;;; ECL gives warnings that it shouldn't!
#+ecl (leave-lisp "ASDF compiled with warnings. Please fix ECL." 0)
#-ecl
(leave-lisp "Testsuite failed: ASDF compiled with warnings" 1))
(errors-p
(leave-lisp "Testsuite failed: ASDF compiled with ERRORS" 2))
(t
(leave-lisp "ASDF compiled cleanly" 0)))))
(t
(leave-lisp "Testsuite failed: unable to find ASDF source" 3)))
\ No newline at end of file
......@@ -15,7 +15,7 @@ http://ilc2009.scheming.org/
(already-compiled :initarg :already-compiled :reader test-already-compiled)
(expected :initarg :expected :reader test-expected)))
(defmacro define-test (test-name system-name
(defmacro define-test (test-name system-name
&key operation-name already-compiled expected)
`(progn
(push ',test-name *all-tests*)
......@@ -34,7 +34,7 @@ http://ilc2009.scheming.org/
(defmethod asdf:operation-done-p ((o asdf:compile-op) (c test-file))
(declare (ignorable o))
(member (asdf:component-name c) (test-already-compiled *test*)
(member (asdf:component-name c) (test-already-compiled *test*)
:test #'string=))
(defmethod asdf:operation-done-p ((o asdf:operation) (c test-file))
......@@ -70,7 +70,7 @@ http://ilc2009.scheming.org/
(first steps) *steps*)))
;(format t "~2%STEPS: ~S~3%" *steps*)
(dolist (expectation (test-expected *test*))
(destructuring-bind (op file &rest at)
(destructuring-bind (op file &rest at)
expectation
;(format t "~2%Expectation: ~S~3%" expectation)
(check-type file string)
......@@ -81,8 +81,8 @@ http://ilc2009.scheming.org/
(fail "~S was not ~A" file op)
(loop for (relationship file2) on at by #'cddr do
(check-type file2 string)
(let* ((op2 (ecase relationship
(:after-loading :loaded)
(let* ((op2 (ecase relationship
(:after-loading :loaded)
(:after-compiling :compiled)))
(pos2 (position (cons op2 file2) *steps*
:test #'equal)))
......@@ -92,7 +92,7 @@ http://ilc2009.scheming.org/
((<