Reviewing bundle.lisp

Faré fahree at
Thu Sep 22 13:44:05 UTC 2016

On Wed, Sep 21, 2016 at 10:08 AM, Robert Goldman <rpgoldman at> wrote:
> I have been making my first experiments with the bundle operations, to
> try to get a better understanding of this corner of ASDF.
> One thing I see in the new documentation is the following:
>    (defclass bundle-op (basic-compile-op)
> +    ;; NB: use of instance-allocated slots for operations is DEPRECATED
> +    ;; and only supported in a temporary fashion for backward
> compatibility.
> +    ;; Supported replacement: Define slots on program-system instead.
>      ((build-args :initarg :args :initform nil :accessor extra-build-args)
>       (name-suffix :initarg :name-suffix :initform nil)
>       (bundle-type :initform :no-output-file :reader bundle-type)
> -     #+(or clasp ecl) (lisp-files :initform nil :accessor
> extra-object-files)))
> +     #+(or clasp ecl) (lisp-files :initform nil :accessor
> extra-object-files))
> +    (:documentation "base class for operations that bundle outputs from
> multiple components"))
> I think this is worth a discussion, before we get it set in stone.  I
> can see two reasons why putting this in the system definition  ("slots
> on program-system)" instead of in the operation might not be desirable:
> 1. It violates "the Faré principle" of the person who knows getting to
> specify.  The programmer of the system doesn't know where the user wants
> the bundle delivered, but by putting this information in the system
> definition, it's the programmer, not the user, who gets to choose.
> Compare this with the way output translations work, where it's the user
> who chooses, not the developer.  Another analogy: it's like "make
> install" without PREFIX.
The "Faré principle" says that he who knows should be able and/or
required to specify, and he who doesn't know shouldn't be either able
or required to specify.

In the case of build flags for extra libraries, certainly the author
of one program cannot possibly know the flags required for another
program that his transitively depends on, and shouldn't have to
specify a list of libraries valid for all such transitive dependencies
(assuming a single list can make do without mutual incompatibilities
between libraries), and shouldn't even be able to specify libraries
that would interfere with how transitive dependencies are built. Yet,
this is how the broken design of putting flags in operations works.

NB: Once again, the design used to make sense as a kluge on top of
ASDF 1 in which there couldn't be transitive dependencies linked into
a different program, anyway, and modifying the ASDF system class
hierarchy was not feasible or not desirable while adding operations
was a given. I'm not blaming the author of asdf-ecl, Michael Goffioul,
or its original maintainer Juan Jose Garcia Ripoll. I'm just saying
the design was a heroic kluge in its time, and is completely broken in
a modern context. And I am blaming whoever is defending this design
today. (And I hope Daniel Kochmanski has stopped defending it.)

The analogy with Make would be that flags you pass to Make do not
transmit transitively to all libraries that you build outside the
current program. Because Make is a small build tool that isn't
designed to build more than the current program. i.e. Make isn't
geared to handle more than what ASDF considers is a single system (or
primary system). In the C world, they need lots and lots of build
systems, and complex "distributions" to coordinate the build of more
than one system. Lisp, for all its kluges and legacy, is radically

> 2. This makes things cumbersome when you have a system that has the same
> codebase, but multiple different entry points.  Consider a compression
> program that uses the same codebase, but wants to deliver 2 different
> executables, "squish" (compress) and "unsquish" (decompress).  If we
> have the build destination hard-coded into the system definition, this
> is impossible.  I was just experimenting with such a case myself, and
> ended up with a main system and 4 "slashy" systems, one for each entry
> point.  Not a disaster, but not obviously a Good Thing, either.
Putting extra build flags in the operation forces every system to be
built with the same entry point, that the user must specify. Putting
the flags in the system allows each system to have its own entry
point, that the user doesn't have to worry about.

For squish and unsquish, just have two different secondary systems.
You found the solution yourself! That's the *correct* solution, and
yes, a Good Thing, reproducible by any user without having to know
magic different operate invocations for each subsystem.

There is no correct solution putting the flags in the operation.

> OTOH, putting slots on operations is a nuisance, because then we need to
> propagate those slot-values from operations to derived operations.
> I think it would be good to ponder this issue a bit.
See my other response about MAKE-OPERATION.

—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics•
Atheism is a non-prophet organization.

More information about the asdf-devel mailing list