Next: Creating new operations, Previous: Operations, Up: Operations [Contents][Index]
All the operations described in this section are in the asdf
package.
They are invoked via the operate
generic function.
(asdf:operate 'asdf:operation-name :system-name {operation-options ...})
compile-op
This operation compiles the specified component.
A cl-source-file
will be compile-file
’d.
All the children and dependencies of a system or module
will be recursively compiled by compile-op
.
compile-op
depends on prepare-op
which
itself depends on a load-op
of all of a component’s dependencies,
as well as of its parent’s dependencies.
When operate
is called on compile-op
,
all these dependencies will be loaded as well as compiled;
yet, some parts of the system main remain unloaded,
because nothing depends on them.
Use load-op
to load a system.
load-op
This operation loads the compiled code for a specified component.
A cl-source-file
will have its compiled fasl load
ed,
which fasl is the output of compile-op
that load-op
depends on.
All the children and dependencies of a system or module
will be recursively loaded by load-op
.
load-op
depends on prepare-op
which
itself depends on a load-op
of all of a component’s dependencies,
as well as of its parent’s dependencies.
prepare-op
This operation ensures that the dependencies of a component
and its recursive parents are loaded (as per load-op
),
as a prerequisite before compile-op
and load-op
operations
may be performed on a given component.
load-source-op
, prepare-source-op
load-source-op
will load the source for the files in a module
rather than they compiled fasl output.
It has a prepare-source-op
analog to prepare-op
,
that ensures the dependencies are themselves loaded via load-source-op
.
There is no provision in ASDF for ensuring that
some components are always loaded as source, while others are always compiled.
While this idea often comes up in discussions,
it actually doesn’t play well with either the linking model of ECL
or with various bundle operations (see below), and is eventually not workable;
also the dependency model of ASDF would have to be modified incompatibly
to allow for such trick.
If your code doesn’t compile cleanly, fix it.
If compilation makes it slow, use declaim
or eval-when
to adjust your compiler settings,
or eschew compilation by eval
uating a quoted source form at load-time.
test-op
This operation will perform some tests on the module.
The default method will do nothing.
The default dependency is to require
load-op
to be performed on the module first.
The default operation-done-p
is that the operation is never done
—
we assume that if you invoke the test-op
,
you want to test the system, even if you have already done so.
The results of this operation are not defined by ASDF. It has proven difficult to define how the test operation should signal its results to the user in a way that is compatible with all of the various test libraries and test techniques in use in the community.
People typically define test-op
methods like thus:
(defmethod perform ((o asdf:test-op) (s (eql (asdf:find-system :my-system)))) (asdf:load-system :my-system-test) (funcall (read-from-string "my-system-test:test-suite")))
Using load-system
in the perform method
rather than an :in-order-to
dependency,
is sometimes necessary for backward compatibility with ASDF 2 and older,
to avoid circular dependencies that could arise
because of the way these old versions propagate dependencies.
If you don’t care for compatibility with ASDF 2,
you could use the following options in your defsystem
form:
:in-order-to ((test-op (load-op :my-system-test))) :perform (test-op (o c) (symbol-call :my-system-test :test-suite))
fasl-op
, monolithic-fasl-op
, load-fasl-op
, binary-op
, monolithic-binary-op
, lib-op
, monolithic-lib-op
, dll-op
, monolithic-dll-op
, program-op
These are “bundle” operations, that can create a single-file “bundle” for all the contents of each system in an application, or for the entire application.
fasl-op
will create a single fasl file for each of the systems needed,
grouping all its many fasls in one,
so you can deliver each system as a single fasl.
monolithic-fasl-op
will create a single fasl file for target system
and all its dependencies,
so you can deliver your entire application as a single fasl.
load-fasl-op
will load the output of fasl-op
(though if it the output is not up-to-date,
it will load the intermediate fasls indeed as part of building it);
this matters a lot on ECL, where the dynamic linking involved in loading
tens of individual fasls can be noticeably more expensive
than loading a single one.
Once you have created a fasl with fasl-op
,
you can use precompiled-system
to deliver it in a way
that is compatible with clients having dependencies on your system,
whether it is distributed as source or as a single binary;
the .asd file to be delivered with the fasl will look like this:
(defsystem :mysystem :class :precompiled-system :fasl (some expression that will evaluate to a pathname))
Or you can use binary-op
to let ASDF create such a system for you
as well as the fasl-op
output, or monolithic-binary-op
.
This allows you to deliver code for your systems or applications
as a single file.
Of course, if you want to test the result in the current image,
before you try to use any newly created .asd files,
you should not forget to (asdf:clear-configuration)
or at least (asdf:clear-source-registry)
,
so it re-populates the source-registry from the filesystem.
The program-op
operation will create an executable program
from the specified system and its dependencies.
You can use UIOP for its pre-image-dump hooks, its post-image-restore hooks,
and its access to command-line arguments.
And you can specify an entry point my-app:main
by specifying in your defsystem
the option :entry-point "my-app:main"
.
Depending on your implementation,
running (asdf:operate 'asdf:program-op :my-app)
may quit the current Lisp image upon completion.
See the example in
test/hello-world-example.asd and test/hello.lisp,
as built and tested by
test/test-program.script and test/make-hello-world.lisp.
There is also lib-op
for building a linkable .a file (Windows: .lib)
from all linkable object dependencies (FFI files, and on ECL, Lisp files too),
and its monolithic equivalent monolithic-lib-op
.
And there is also dll-op
(respectively its monolithic equivalent monolithic-lib-op
)
for building a linkable .so file
(Windows: .dll, MacOS X: .dynlib)
to create a single dynamic library
for all the extra FFI code to be linked into each of your systems
(respectively your entire application).
All these “bundle” operations are available since ASDF 3
on all actively supported Lisp implementations,
but may be unavailable on unmaintained legacy implementations.
This functionality was previously available for select implementations,
as part of a separate system asdf-bundle
,
itself descended from the ECL-only asdf-ecl
.
The pathname of the output of bundle operations
is subject to output-translation as usual,
unless the operation is equal to
the :build-operation
argument to defsystem
.
This behavior is not very satisfactory and may change in the future.
Maybe you have suggestions on how to better configure it?
concatenate-source-op
, monolithic-concatenate-source-op
, load-concatenated-source-op
, compile-concatenated-source-op
, load-compiled-concatenated-source-op
, monolithic-load-concatenated-source-op
, monolithic-compile-concatenated-source-op
, monolithic-load-compiled-concatenated-source-op
These operation, as their respective names indicate,
consist in concatenating all cl-source-file
source files in a system
(or in a system and all its dependencies, if monolithic),
in the order defined by dependencies,
then loading the result, or compiling then loading the result.
These operations are useful to deliver a system or application as a single source file, and for testing that said file loads properly, or compiles then loads properly.
ASDF itself is notably delivered as a single source file this way
using monolithic-concatenate-source-op
,
transcluding a prelude and the uiop
library
before the asdf/defsystem
system itself.
Next: Creating new operations, Previous: Operations, Up: Operations [Contents][Index]