From: Douglas S. Rand
Subject: portable defsystem
Date: 
Message-ID: <DSR.91Feb22135652@mir.mitre.org>
Some long time ago (glancing at the header tells me about 1987) I posted
a public domain defsystem which a number of folks have picked up to
use.  I thought I'd post the latest and anyone who'd like to can
stick in in a public directory.  In particular I hope someone will
replace the existing copy on ucbarpa as the old email address is incorrect.

Documentation follows.  Code in a separate posting
----- defsys.doc -------
Intro:

     Common  LISP  lacks  a  method for tying a group of files together under a
convenient name.  The common method for doing this in  ZetaLISP  is  defsystem.
This  is  a public domain implementation of defsystem.  Where possible the same
keywords are used as  in  ZetaLISP  but  this  implementation  has  a  slightly
different flavor from the ZetaLISP defsystem.

Changes (2.2):

     Compile-load-system   combines   compile-system   and   load-system  as  a
convenience.

     The package name is now  defsys  to  eliminate  name  conflicts  with  the
defsystem macro.

     All   the  system  oriented  functions  (load-system,  compile-system  and
show-system, compile-load-system) now  have  the  system-name  argument  as  an
optional argument.  If the argument is given then the variable *current-system*
is set to  that  value.    If  the  argument  is  ommited  then  the  value  of
*current-system* is used.  If *current-system* is NIL then an error is raised.

     A variable defsys::*downcase-path-from-module-name* is set to T under UNIX
and NIL otherwise.  Since module names are  normally  entered  as  symbols  the
mapping  is  normally  into uppercase.  Since UNIX is case sensitive this means
that one would then need to name the files in uppercase.

Defsystem macro:

(defsystem system-name
   (system-options*)
   module-descriptions*
   )
     Load order is implied by the order of the modules.    System  options  are
(defaults in {}s):

:default-pathname {#P""}
                The default place to find files in.

:default-package {nil, i.e. current}
                The default package to load/compile modules in.

:needed-systems {nil}
                A list of subsystems

:load-before-compile {nil}
                A list of subsystems needed for compilation

     A  module  is  a single name representing a file.  A module description is
either a module name or a list whose car is the module name and the  cdr  is  a
set of keywords and values.  The module options are:

:recompile-on (mod, mod, ...)
                This will cause the module list to be checked for dtm if one of
                the  listed  modules  is  newer then the current module will be
                recompiled.  If the current module is recompiled  the  list  of
                recompile dependencies will be loaded first.

                This  is  also a recursive recompilation.  If foo dependends on
                bar and bar is out of date then bar will be recompiled.  

:load-before-compile (mod, mod, ..)
                These  are  modules  that  are  loaded  before  recompiling the
                current module.

:load-after (mod, mod, ...)
                This  is  really  a  useful  option  only  for  modules  during
                compilation since the load order  will  normally  be  satisfied
                during  a load-system. These are followed until a loaded module
                is found.

:pathname path  If specified it gives a pathname to find this module.  Normally
                this  defaults to the concatenation of the default pathname for
                the system and the module name.

:package package-name
                What  package  to load/compile this module in.  Defaults to the
                system default package.

:compile-satisfies-load {nil}
                If   T  then  compiling  this  module  will  set  it's  loading
                information to T. This is usually  true  for  files  with  just
                macros.

UnDefSystem (macro)

(undefsystem system-name)
     Removes the system description from *all-systems*.

Load-system (function)

(load-system {system-name} {keys})
     Loads  modules  of  a  system.   Load-system is called recursively for all
required systems.  Keyword options are:
:reload {nil} - if T force a full reload of everything.
:included-components {T} - if T call load-system on subcomponents

Compile-system (function)

(compile-system {system-name} {keys})
     Compiles all modules requiring recompilation.  The recompile keyword  will
cause  all recompilations to occur regardless of 'need'.  Need is determined by
the date-time of the respective binary and source files.
:recompile {nil} - recompile everything if T
:included-components {T} - call compile-system on subcomponents
:reload {nil} - always reload needed modules

Show-System (function)

(show-system {system-name
     ) } Pretty output of system description.

Simple Sample Defsystems

 (defsystem life
   (:needed-systems (curses)
    :default-pathname #P"doug.x>lisp>life>")
   life
   )

 (defsystem curses
   (:default-pathname #P"doug.x>lisp>curses>"
    :default-package curses)
   curses
   (curses-internals :package curses-internals)
   )

 (defsystem profile
   ()
   profile timer
   )
--
Douglas S. Rand 
Internet:   <······@mitre.org>
Snail:	    MITRE, Burlington Road, Bedford, MA 
Disclaimer: MITRE might agree with me - then again...
Amateur Radio: KC1KJ