Newer
Older
the second for the error-output, and the third for the return value.
(Beware that before ASDF 3.0.2.11, it didn't handle input or error-output,
and returned only one value,
the one for the output if any handler was specified, or else the exit code;
please upgrade ASDF, or at least UIOP, to rely on the new enhanced behavior.)
@var{output} is its most important argument;
it specifies how the output is captured and processed.
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
If it is @code{nil}, then the output is redirected to the null device,
that will discard it.
If it is @code{:interactive}, then it is inherited from the current process
(beware: this may be different from your @var{*standard-output*},
and under SLIME will be on your @code{*inferior-lisp*} buffer).
If it is @code{t}, output goes to your current @var{*standard-output*} stream.
Otherwise, @var{output} should be a value that is a suitable first argument to
@code{slurp-input-stream} (see below), or
a list of such a value and keyword arguments.
In this case, @code{run-program} will
create a temporary stream for the program output;
the program output, in that stream,
will be processed by a call to @code{slurp-input-stream},
using @var{output} as the first argument
(or if it's a list the first element of @var{output} and the rest as keywords).
The primary value resulting from that call
(or @code{nil} if no call was needed)
will be the first value returned by @code{run-program}.
E.g., using @code{:output :string}
will have it return the entire output stream as a string.
And using @code{:output '(:string :stripped t)}
will have it return the same string stripped of any ending newline.
@var{error-output} is similar to @var{output}, except that
the resulting value is returned as the second value of @code{run-program}.
@code{t} designates the @var{*error-output*}.
Also @code{:output} means redirecting the error output to the output stream,
in which case @code{nil} is returned.
@var{input} is similar to @var{output}, except that
@code{vomit-output-stream} is used, no value is returned,
and @code{t} designates the @var{*standard-input*}.
@code{element-type} and @code{external-format} are passed on
to your Lisp implementation, when applicable, for creation of the output stream.
One and only one of the stream slurping or vomiting may or may not happen
in parallel in parallel with the subprocess,
depending on options and implementation,
and with priority being given to output processing.
Other streams are completely produced or consumed
before or after the subprocess is spawned, using temporary files.
@code{force-shell} forces evaluation of the command through a shell,
even if it was passed as a list rather than a string.
If a shell is used, it is @file{/bin/sh} on Unix or @file{CMD.EXE} on Windows,
except on implementations that (erroneously, IMNSHO)
insist on consulting @code{$SHELL} like clisp.
@code{ignore-error-status} causes @code{run-program}
to not raise an error if the spawned program exits in error.
Following POSIX convention, an error is anything but
a normal exit with status code zero.
By default, an error of type @code{subprocess-error} is raised in this case.
@code{run-program} works on all platforms supported by ASDF, except Genera.
See the source code for more documentation.
@end defun
@defun slurp-input-stream processor input-stream @Akey
It's a generic function of two arguments, a target object and an input stream,
and accepting keyword arguments.
Predefined methods based on the target object are as follow:
If the object is a function, the function is called with the stream as argument.
If the object is a cons, its first element is applied to its rest appended by
a list of the input stream.
If the object is an output stream, the contents of the input stream are copied to it.
If the @var{linewise} keyword argument is provided, copying happens line by line,
and an optional @var{prefix} is printed before each line.
Otherwise, copying happen based on a buffer of size @var{buffer-size},
using the specified @var{element-type}.
If the object is @code{'string} or @code{:string}, the content is captured into a string.
Accepted keywords include the @var{element-type} and a flag @var{stripped},
which when true causes any single line ending to be removed as per @code{uiop:stripln}.
If the object is @code{:lines}, the content is captured as a list of strings,
one per line, without line ending. If the @var{count} keyword argument is provided,
it is a maximum count of lines to be read.
If the object is @code{:line}, the content is capture as with @code{:lines} above,
and then its sub-object is extracted with the @var{at} argument,
which defaults to @code{0}, extracting the first line.
A number will extract the corresponding line.
See the documentation for @code{uiop:access-at}.
If the object is @code{:forms}, the content is captured as a list of S-expressions,
as read by the Lisp reader.
If the @var{count} argument is provided,
it is a maximum count of lines to be read.
We recommend you control the syntax with such macro as
@code{uiop:with-safe-io-syntax}.
If the object is @code{:form}, the content is capture as with @code{:forms} above,
and then its sub-object is extracted with the @var{at} argument,
which defaults to @code{0}, extracting the first form.
A number will extract the corresponding form.
See the documentation for @code{uiop:access-at}.
We recommend you control the syntax with such macro as
@code{uiop:with-safe-io-syntax}.
@end defun
@node Getting the latest version, FAQ, Miscellaneous additional functionality, Top
@comment node-name, next, previous, up
@chapter Getting the latest version
Decide which version you want.
The @code{master} branch is where development happens;
its @code{HEAD} is usually OK, including the latest fixes and portability tweaks,
but an occasional regression may happen despite our (limited) test suite.
The @code{release} branch is what cautious people should be using;
it has usually been tested more, and releases are cut at a point
where there isn't any known unresolved issue.
You may get the ASDF source repository using git:
@kbd{git clone git://common-lisp.net/projects/asdf/asdf.git}
You will find the above referenced tags in this repository.
You can also browse the repository on
@url{http://common-lisp.net/gitweb?p=projects/asdf/asdf.git}.
Discussion of ASDF development is conducted on the
mailing list
@kbd{asdf-devel@@common-lisp.net}.
@url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel}
@node FAQ, TODO list, Getting the latest version, Top
@comment node-name, next, previous, up
ASDF bugs are tracked on launchpad: @url{https://launchpad.net/asdf}.
If you're unsure about whether something is a bug, or for general discussion,
use the @url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
@section ``What has changed between ASDF 1 and ASDF 2?''
@subsection What are ASDF 1 and ASDF 2?
On May 31st 2010, we have released ASDF 2.
ASDF 2 refers to release 2.000 and later.
(Releases between 1.656 and 1.728 were development releases for ASDF 2.)
ASDF 1 to any release earlier than 1.369 or so.
If your ASDF doesn't sport a version, it's an old ASDF 1.
ASDF 2 and its release candidates push
@code{:asdf2} onto @code{*features*} so that if you are writing
ASDF-dependent code you may check for this feature
to see if the new API is present.
@emph{All} versions of ASDF should have the @code{:asdf} feature.
Additionally, all versions of ASDF 2
define a function @code{(asdf:asdf-version)} you may use to query the version;
and the source code of recent versions of ASDF 2 features the version number
prominently on the second line of its source code.
If you are experiencing problems or limitations of any sort with ASDF 1,
we recommend that you should upgrade to ASDF 2,
or whatever is the latest release.
@subsection ASDF can portably name files in subdirectories
Common Lisp namestrings are not portable,
except maybe for logical pathnamestrings,
that themselves have various limitations and require a lot of setup
that is itself ultimately non-portable.
In ASDF 1, the only portable ways to refer to pathnames inside systems and components
were very awkward, using @code{#.(make-pathname ...)} and
@code{#.(merge-pathnames ...)}.
Even the above were themselves were inadequate in the general case
due to host and device issues, unless horribly complex patterns were used.
Plenty of simple cases that looked portable actually weren't,
leading to much confusion and greavance.
ASDF 2 implements its own portable syntax for strings as pathname specifiers.
Naming files within a system definition becomes easy and portable again.
@xref{Miscellaneous additional functionality,system-relative-pathname},
@code{merge-pathnames*},
@code{coerce-pathname}.
Francois-Rene Rideau
committed
On the other hand, there are places where systems used to accept namestrings
where you must now use an explicit pathname object:
@code{(defsystem ... :pathname "LOGICAL-HOST:PATH;TO;SYSTEM;" ...)}
must now be written with the @code{#p} syntax:
@code{(defsystem ... :pathname #p"LOGICAL-HOST:PATH;TO;SYSTEM;" ...)}
@xref{The defsystem grammar,,Pathname specifiers}.
A popular feature added to ASDF was output pathname translation:
@code{asdf-binary-locations}, @code{common-lisp-controller},
@code{cl-launch} and other hacks were all implementing it in ways
both mutually incompatible and difficult to configure.
Output pathname translation is essential to share
source directories of portable systems across multiple implementations
or variants thereof,
or source directories of shared installations of systems across multiple users,
or combinations of the above.
In ASDF 2, a standard mechanism is provided for that,
@code{asdf-output-translations},
with sensible defaults, adequate configuration languages,
a coherent set of configuration files and hooks,
and support for non-Unix platforms.
@xref{Controlling where ASDF saves compiled files}.
@subsection Source Registry Configuration
Configuring ASDF used to require special magic
to be applied just at the right moment,
between the moment ASDF is loaded and the moment it is used,
in a way that is specific to the user,
the implementation he is using and the application he is building.
This made for awkward configuration files and startup scripts
that could not be shared between users, managed by administrators
or packaged by distributions.
ASDF 2 provides a well-documented way to configure ASDF,
with sensible defaults, adequate configuration languages,
and a coherent set of configuration files and hooks.
We believe it's a vast improvement because it decouples
application distribution from library distribution.
The application writer can avoid thinking where the libraries are,
and the library distributor (dpkg, clbuild, advanced user, etc.)
can configure them once and for every application.
Yet settings can be easily overridden where needed,
so whoever needs control has exactly as much as required.
At the same time, ASDF 2 remains compatible
with the old magic you may have in your build scripts
(using @code{*central-registry*} and
@code{*system-definition-search-functions*})
to tailor the ASDF configuration to your build automation needs,
and also allows for new magic, simpler and more powerful magic.
@xref{Controlling where ASDF searches for systems}.
@subsection Usual operations are made easier to the user
In ASDF 1, you had to use the awkward syntax
@code{(asdf:oos 'asdf:load-op :foo)}
to load a system,
and similarly for @code{compile-op}, @code{test-op}.
In ASDF 2, you can use shortcuts for the usual operations:
@code{(asdf:load-system :foo)}, and
similarly for @code{compile-system}, @code{test-system}.
@subsection Many bugs have been fixed
The following issues and many others have been fixed:
The infamous TRAVERSE function has been revamped completely
between ASDF 1 and ASDF 2, with many bugs squashed.
In particular, dependencies were not correctly propagated
across modules but now are.
It has been completely rewritten many times over
Francois-Rene Rideau
committed
between ASDF 2.000 and ASDF 3,
with fundamental issues in the original model being fixed.
Timestamps were not propagated at all, and now are.
The internal model of how actions depend on each other
is now both consistent and complete.
The :version and
the :force (system1 .. systemN) feature have been fixed.
Francois-Rene Rideau
committed
Performance has been notably improved for large systems
(say with thousands of components) by using
hash-tables instead of linear search,
and linear-time list accumulation
instead of quadratic-time recursive appends.
@item
Many features used to not be portable,
especially where pathnames were involved.
Windows support was notably quirky because of such non-portability.
@item
The internal test suite used to massively fail on many implementations.
While still incomplete, it now fully passes
on all implementations supported by the test suite,
except for GCL (due to GCL bugs).
@item
Support was lacking for some implementations.
ABCL and GCL were notably wholly broken.
ECL extensions were not integrated with ASDF release.
The documentation was grossly out of date.
@subsection ASDF itself is versioned
Between new features, old bugs fixed, and new bugs introduced,
there were various releases of ASDF in the wild,
and no simple way to check which release had which feature set.
People using or writing systems had to either make worst-case assumptions
as to what features were available and worked,
or take great pains to have the correct version of ASDF installed.
With ASDF 2, we provide a new stable set of working features
that everyone can rely on from now on.
Use @code{#+asdf2} to detect presence of ASDF 2,
@code{(asdf:version-satisfies (asdf:asdf-version) "2.345.67")}
to check the availability of a version no earlier than required.
@subsection ASDF can be upgraded
When an old version of ASDF was loaded,
it was very hard to upgrade ASDF in your current image
without breaking everything.
Instead you had to exit the Lisp process and
somehow arrange to start a new one from a simpler image.
Something that can't be done from within Lisp,
making automation of it difficult,
which compounded with difficulty in configuration,
made the task quite hard.
Yet as we saw before, the task would have been required
to not have to live with the worst case or non-portable
subset of ASDF features.
With ASDF 2, it is easy to upgrade
from ASDF 2 to later versions from within Lisp,
and not too hard to upgrade from ASDF 1 to ASDF 2 from within Lisp.
We support hot upgrade of ASDF and any breakage is a bug
that we will do our best to fix.
There are still limitations on upgrade, though,
most notably the fact that after you upgrade ASDF,
you must also reload or upgrade all ASDF extensions.
@subsection Decoupled release cycle
When vendors were releasing their Lisp implementations with ASDF,
they had to basically never change version
because neither upgrade nor downgrade was possible
without breaking something for someone,
and no obvious upgrade path was visible and recommendable.
With ASDF 2, upgrade is possible, easy and can be recommended.
This means that vendors can safely ship a recent version of ASDF,
confident that if a user isn't fully satisfied,
he can easily upgrade ASDF and deal
with a supported recent version of it.
This means that release cycles will be causally decoupled,
the practical consequence of which will mean faster convergence
towards the latest version for everyone.
Francois-Rene Rideau
committed
@subsection Pitfalls of the transition to ASDF 2
The main pitfalls in upgrading to ASDF 2 seem to be related
to the output translation mechanism.
@itemize
@item
Output translations is enabled by default. This may surprise some users,
most of them in pleasant way (we hope), a few of them in an unpleasant way.
It is trivial to disable output translations.
@xref{FAQ,,``How can I wholly disable the compiler output cache?''}.
@item
Some systems in the large have been known
not to play well with output translations.
They were relatively easy to fix.
Once again, it is also easy to disable output translations,
or to override its configuration.
@item
The new ASDF output translations are incompatible with ASDF-Binary-Locations.
They replace A-B-L, and there is compatibility mode to emulate
your previous A-B-L configuration.
Francois-Rene Rideau
committed
See @code{enable-asdf-binary-locations-compatibility} in
@pxref{Controlling where ASDF saves compiled files,,Backward Compatibility}.
But thou shalt not load ABL on top of ASDF 2.
Francois-Rene Rideau
committed
@end itemize
Other issues include the following:
@itemize
Francois-Rene Rideau
committed
@item
ASDF pathname designators are now specified
in places where they were unspecified,
Francois-Rene Rideau
committed
and a few small adjustments have to be made to some non-portable defsystems.
Notably, in the @code{:pathname} argument
to a @code{defsystem} and its components,
Francois-Rene Rideau
committed
a logical pathname (or implementation-dependent hierarchical pathname)
must now be specified with @code{#p} syntax
where the namestring might have previously sufficed;
moreover when evaluation is desired @code{#.} must be used,
where it wasn't necessary in the toplevel @code{:pathname} argument
(but necessary in other @code{:pathname} arguments).
Francois-Rene Rideau
committed
@item
There is a slight performance bug, notably on SBCL,
when initially searching for @file{asd} files,
the implicit @code{(directory "/configured/path/**/*.asd")}
for every configured path @code{(:tree "/configured/path/")}
in your @code{source-registry} configuration can cause a slight pause.
Try to @code{(time (asdf:initialize-source-registry))}
to see how bad it is or isn't on your system.
If you insist on not having this pause,
you can avoid the pause by overriding the default source-registry configuration
and not use any deep @code{:tree} entry but only @code{:directory} entries
or shallow @code{:tree} entries.
Or you can fix your implementation to not be quite that slow
when recursing through directories.
@emph{Update}: This performance bug fixed the hard way in 2.010.
@item
On Windows, only LispWorks supports proper default configuration pathnames
based on the Windows registry.
Other implementations make do with environment variables,
that you may have to define yourself
if you're using an older version of Windows.
Francois-Rene Rideau
committed
Windows support is somewhat less tested than Unix support.
Please help report and fix bugs.
@emph{Update}: As of ASDF 2.21, all implementations
should now use the same proper default configuration pathnames
and they should actually work, though they haven't all been tested.
Francois-Rene Rideau
committed
@item
The mechanism by which one customizes a system so that Lisp files
may use a different extension from the default @file{.lisp} has changed.
Previously, the pathname for a component
was lazily computed when operating on a system,
Francois-Rene Rideau
committed
and you would
@code{(defmethod source-file-type ((component cl-source-file) (system (eql (find-system 'foo))))
(declare (ignorable component system)) "lis")}.
Francois-Rene Rideau
committed
Now, the pathname for a component is eagerly computed when defining the system,
Francois-Rene Rideau
committed
and instead you will @code{(defclass cl-source-file.lis (cl-source-file) ((type :initform "lis")))}
and use @code{:default-component-class cl-source-file.lis}
as argument to @code{defsystem},
Francois-Rene Rideau
committed
as detailed in a @pxref{FAQ,How do I create a system definition where all the source files have a .cl extension?} below.
@findex source-file-type
@section Issues with installing the proper version of ASDF
@subsection ``My Common Lisp implementation comes with an outdated version of ASDF. What to do?''
We recommend you upgrade ASDF.
@xref{Loading ASDF,,Upgrading ASDF}.
If this does not work, it is a bug, and you should report it.
@xref{FAQ, report-bugs, Where do I report a bug}.
In the meantime, you can load @file{asdf.lisp} directly.
@xref{Loading ASDF,Loading an otherwise installed ASDF}.
@subsection ``I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?''
Francois-Rene Rideau
committed
Since ASDF 2,
it should always be a good time to upgrade to a recent version of ASDF.
You may consult with the maintainer for which specific version they recommend,
but the latest @code{release} should be correct.
Though we do try to test ASDF releases against all implementations that we can,
we may not be testing against all variants of your implementation,
and we may not be running enough tetst;
we trust you to thoroughly test it with your own implementation
before you release it.
If there are any issues with the current release,
it's a bug that you should report upstream and that we will fix ASAP.
Francois-Rene Rideau
committed
As to how to include ASDF, we recommend the following:
Francois-Rene Rideau
committed
@itemize
@item
If ASDF isn't loaded yet, then @code{(require "asdf")}
Francois-Rene Rideau
committed
should load the version of ASDF that is bundled with your system.
If possible so should @code{(require "ASDF")}.
Francois-Rene Rideau
committed
You may have it load some other version configured by the user,
if you allow such configuration.
@item
If your system provides a mechanism to hook into @code{CL:REQUIRE},
then it would be nice to add ASDF to this hook the same way that
ABCL, CCL, CLISP, CMUCL, ECL, SBCL and SCL do it.
Please send us appropriate code to this end.
Francois-Rene Rideau
committed
@item
You may, like SBCL, have ASDF be implicitly used to require systems
that are bundled with your Lisp distribution.
If you do have a few magic systems that come with your implementation
in a precompiled way such that one should only use the binary version
that goes with your distribution, like SBCL does,
then you should add them in the beginning of @code{wrapping-source-registry}.
@item
If you have magic systems as above, like SBCL does,
then we explicitly ask you to @emph{NOT} distribute
@file{asdf.asd} as part of those magic systems.
You should still include the file @file{asdf.lisp} in your source distribution
and precompile it in your binary distribution,
but @file{asdf.asd} if included at all,
should be secluded from the magic systems,
in a separate file hierarchy.
Alternatively, you may provide the system
after renaming it and its @file{.asd} file to e.g.
Francois-Rene Rideau
committed
@code{asdf-ecl} and @file{asdf-ecl.asd}, or
@code{sb-asdf} and @file{sb-asdf.asd}.
Indeed, if you made @file{asdf.asd} a magic system,
then users would no longer be able to upgrade ASDF using ASDF itself
to some version of their preference that
they maintain independently from your Lisp distribution.
@item
If you do not have any such magic systems, or have other non-magic systems
that you want to bundle with your implementation,
then you may add them to the @code{wrapping-source-registry},
and you are welcome to include @file{asdf.asd} amongst them.
Non-magic systems should be at the back of the @code{wrapping-source-registry}
while magic systems are at the front.
@item
Since ASDF 3, the library UIOP comes transcluded in ASDF.
But for extra brownies, you may package UIOP separately,
so that one may @code{(require "uiop")} and not pull ASDF,
or one may @code{(require "asdf")}
and that would implicitly require the former.
Francois-Rene Rideau
committed
@item
Please send us upstream any patches you make to ASDF itself,
so we can merge them back in for the benefit of your users
when they upgrade to the upstream version.
Francois-Rene Rideau
committed
@end itemize
@section Issues with configuring ASDF
@subsection ``How can I customize where fasl files are stored?''
@xref{Controlling where ASDF saves compiled files}.
Note that in the past there was an add-on to ASDF called
@code{ASDF-binary-locations}, developed by Gary King.
That add-on has been merged into ASDF proper,
Francois-Rene Rideau
committed
then superseded by the @code{asdf-output-translations} facility.
Note that use of @code{asdf-output-translations}
can interfere with one aspect of your systems
--- if your system uses @code{*load-truename*} to find files
(e.g., if you have some data files stored with your program),
then the relocation that this ASDF customization performs
is likely to interfere.
Use @code{asdf:system-relative-pathname} to locate a file
in the source directory of some system, and
use @code{asdf:apply-output-translations} to locate a file
whose pathname has been translated by the facility.
@subsection ``How can I wholly disable the compiler output cache?''
To permanently disable the compiler output cache
for all future runs of ASDF, you can:
@example
mkdir -p ~/.config/common-lisp/asdf-output-translations.conf.d/
echo ':disable-cache' > ~/.config/common-lisp/asdf-output-translations.conf.d/99-disable-cache.conf
@end example
This assumes that you didn't otherwise configure the ASDF files
(if you did, edit them again),
and don't somehow override the configuration at runtime
with a shell variable (see below) or some other runtime command
(e.g. some call to @code{asdf:initialize-output-translations}).
To disable the compiler output cache in Lisp processes
Francois-Rene Rideau
committed
run by your current shell, try (assuming @code{bash} or @code{zsh})
(on Unix and cygwin only):
@example
export ASDF_OUTPUT_TRANSLATIONS=/:
@end example
To disable the compiler output cache just in the current Lisp process,
use (after loading ASDF but before using it):
@example
Francois-Rene Rideau
committed
(asdf:disable-output-translations)
@section Issues with using and extending ASDF to define systems
@subsection ``How can I cater for unit-testing in my system?''
ASDF provides a predefined test operation, @code{test-op}.
@xref{Predefined operations of ASDF, test-op}.
The test operation, however, is largely left to the system definer to specify.
@code{test-op} has been
a topic of considerable discussion on the
@url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list},
@url{https://launchpad.net/asdf,launchpad bug-tracker}.
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
Here are some guidelines:
@itemize
@item
For a given system, @var{foo}, you will want to define a corresponding
test system, such as @var{foo-test}. The reason that you will want this
separate system is that ASDF does not out of the box supply components
that are conditionally loaded. So if you want to have source files
(with the test definitions) that will not be loaded except when testing,
they should be put elsewhere.
@item
The @var{foo-test} system can be defined in an asd file of its own or
together with @var{foo}. An aesthetic preference against cluttering up
the filesystem with extra asd files should be balanced against the
question of whether one might want to directly load @var{foo-test}.
Typically one would not want to do this except in early stages of
debugging.
@item
Record that testing is implemented by @var{foo-test}. For example:
@example
(defsystem @var{foo}
:in-order-to ((test-op (test-op @var{foo-test})))
....)
(defsystem @var{foo-test}
:depends-on (@var{foo} @var{my-test-library} ...)
....)
@end example
@end itemize
This procedure will allow you to support users who do not wish to
install your test framework.
One oddity of ASDF is that @code{operate} (@pxref{Operations,operate})
does not return a value. So in current versions of ASDF there is no
reliable programmatic means of determining whether or not a set of tests
has passed, or which tests have failed. The user must simply read the
console output. This limitation has been the subject of much
discussion.
@subsection ``How can I cater for documentation generation in my system?''
The ASDF developers are currently working to add a @code{doc-op}
to the set of predefined ASDF operations.
@xref{Predefined operations of ASDF}.
See also @url{https://bugs.launchpad.net/asdf/+bug/479470}.
@subsection ``How can I maintain non-Lisp (e.g. C) source files?''
@subsection ``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 could be done
in the spatial-trees ASDF system definition for ASDF 2:
@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 ""
((:static-file "spatial-tree-viz.lisp")))
:pathname ""
((:static-file "spatial-tree-test.lisp")))
(:static-file "LICENCE")
(:static-file "TODO")))
@end example
Francois-Rene Rideau
committed
All of the files in the @code{tree-impls} module are at the top level,
instead of in a @file{tree-impls/} subdirectory.
Francois-Rene Rideau
committed
Note that the argument to @code{:pathname} can be either a pathname object or a string.
A pathname object can be constructed with the @file{#p"foo/bar/"} syntax,
Francois-Rene Rideau
committed
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
Francois-Rene Rideau
committed
@code{#.(make-pathname :directory '(:relative))}.
However, as of ASDF 2, you can portably use a string to denote a pathname.
Francois-Rene Rideau
committed
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.
Francois-Rene Rideau
committed
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).
Francois-Rene Rideau
committed
@subsection How do I create a system definition where all the source files have a .cl extension?
Francois-Rene Rideau
committed
Starting with ASDF 2.014.14, you may just pass
the builtin class @code{cl-source-file.cl} as
the @code{:default-component-class} argument to @code{defsystem}:
Francois-Rene Rideau
committed
(defsystem my-cl-system
:default-component-class cl-source-file.cl
...)
Francois-Rene Rideau
committed
Another builtin class @code{cl-source-file.lsp} is offered
for files ending in @file{.lsp}.
If you want to use a different extension
for which ASDF doesn't provide builtin support,
or want to support versions of ASDF
earlier than 2.014.14 (but later than 2.000),
you can define a class as follows:
Francois-Rene Rideau
committed
;; Prologue: make sure we're using a sane package.
(defpackage :my-asdf-extension
(:use :asdf :common-lisp)
(:export #:cl-source-file.lis))
(in-package :my-asdf-extension)
(defclass cl-source-file.lis (cl-source-file)
Francois-Rene Rideau
committed
((type :initform "lis")))
Francois-Rene Rideau
committed
@end lisp
Then you can use it as follows:
@lisp
(defsystem my-cl-system
:default-component-class my-asdf-extension:cl-source-file.lis
...)
Francois-Rene Rideau
committed
Of course, if you're in the same package, e.g. in the same file,
you won't need to use the package qualifier before @code{cl-source-file.lis}.
Actually, if all you're doing is defining this class
and using it in the same file without other fancy definitions,
you might skip package complications:
Francois-Rene Rideau
committed
(in-package :asdf)
(defclass cl-source-file.lis (cl-source-file)
((type :initform "lis")))
(defsystem my-cl-system
Francois-Rene Rideau
committed
:default-component-class cl-source-file.lis
...)
Francois-Rene Rideau
committed
It is possible to achieve the same effect
in a way that supports both ASDF 1 and ASDF 2,
but really, friends don't let friends use ASDF 1.
Francois-Rene Rideau
committed
Please upgrade to ASDF 3.
Francois-Rene Rideau
committed
In short, though: do same as above, but
@emph{before} you use the class in a @code{defsystem},
you also define the following method:
@lisp
Francois-Rene Rideau
committed
(defmethod source-file-type ((f cl-source-file.lis) (s system))
(declare (ignorable f s))
Francois-Rene Rideau
committed
"lis")
@end lisp
@section ASDF development FAQs
@subsection How do run the tests interactively in a REPL?
This not-so-frequently asked question is primarily for ASDF developers,
but those who encounter an unexpected error in some test may be
interested, too.
Here's the procedure for experimenting with tests in a REPL:
@example
(load "script-support.lisp")
(in-package :asdf-test)
(compile-load-asdf) ; there are a number of other functions to load ASDF
;; experiment with test code from a .script file...
@end example
@comment FIXME: Add a FAQ about how to use a new system class...
@node TODO list, Inspiration, FAQ, Top
Here is an old list of things to do,
in addition to the bugs that are now tracked on launchpad:
@url{https://launchpad.net/asdf}.
@section Outstanding spec questions, things to add
** packaging systems
*** manual page component?
** style guide for .asd files
You should either use keywords or be careful
with the package that you evaluate defsystem forms in.
Otherwise @code{(defsystem partition ...)}
being read in the @code{cl-user} package
will intern a @code{cl-user:partition} symbol,
which will then collide with the @code{partition:partition} symbol.
Actually there's a hairier packages problem to think about too.
@code{in-order-to} is not a keyword:
if you read @code{defsystem} forms in a package that doesn't use ASDF,
odd things might happen.
** extending defsystem with new options
You might not want to write a whole parser,
but just to add options to the existing syntax.
Reinstate @code{parse-option} or something akin.
** Diagnostics
A ``dry run'' of an operation can be made with the following form:
@lisp
(let ((asdf::*verbose-out* *standard-output*))
(loop :for (op . comp) :in
(asdf::traverse (make-instance '<operation-name> :force t)
(asdf:find-system <system-name>))
:do (asdf:explain op comp)))
This uses unexported symbols.
What would be a nice interface for this functionality?
@section Missing bits in implementation
** reuse the same scratch package whenever a system is reloaded from disk
Have a package ASDF-USER instead of all these temporary packages?
** proclamations probably aren't
** A revert function
Other possible interface: have a ``revert'' function akin to @code{make clean}.
(asdf:revert 'asdf:compile-op 'araneida)
would delete any files produced by @code{(compile-system :araneida)}.
Of course, it wouldn't be able to do much about stuff in the image itself.
How would this work?
There's a difference between a module's dependencies (peers)
and its components (children).
Perhaps there's a similar difference in operations?
For example, @code{(load "use") depends-on (load "macros")} is a peer,
whereas @code{(load "use") depends-on (compile "use")}
is more of a ``subservient'' relationship.
@node Inspiration, Concept Index, TODO list, Top
@comment node-name, next, previous, up
@chapter Inspiration
@section mk-defsystem (defsystem-3.x)
We aim to solve basically the same problems as @code{mk-defsystem} does.
However, our architecture for extensibility
better exploits CL language features (and is documented),
and we intend to be portable rather than just widely-ported.
No slight on the @code{mk-defsystem} authors and maintainers is intended here;
that implementation has the unenviable task
of supporting pre-ANSI implementations, which is no longer necessary.
The surface defsystem syntax of asdf is more-or-less compatible with
@code{mk-defsystem}, except that we do not support
the @code{source-foo} and @code{binary-foo} prefixes
for separating source and binary files, and
we advise the removal of all options to specify pathnames.
The @code{mk-defsystem} code for topologically sorting
a module's dependency list was very useful.
@section defsystem-4 proposal
Marco and Peter's proposal for defsystem 4 served as the driver for
many of the features in here. Notable differences are:
@itemize
@item
We don't specify output files or output file extensions
as part of the system.
If you want to find out what files an operation would create,
ask the operation.
@item
We don't deal with CL packages
If you want to compile in a particular package, use an @code{in-package} form
in that file (ilisp / SLIME will like you more if you do this anyway)
@item
There is no proposal here that @code{defsystem} does version control.
A system has a given version which can be used to check dependencies,
but that's all.
@end itemize
The defsystem 4 proposal tends to look more at the external features,
whereas this one centres on a protocol for system introspection.
Francois-Rene Rideau
committed
@section kmp's ``The Description of Large Systems'', MIT AI Memo 801
Available in updated-for-CL form on the web at
@url{http://nhplace.com/kent/Papers/Large-Systems.html}
In our implementation we borrow kmp's overall @code{PROCESS-OPTIONS}
and concept to deal with creating component trees
from @code{defsystem} surface syntax.
[ this is not true right now, though it used to be and
probably will be again soon ]
@c -------------------
@node Concept Index, Function and Class Index, Inspiration, Top
@unnumbered Concept Index
@printindex cp
@node Function and Class Index, Variable Index, Concept Index, Top