
_Setup PLT_ or _setup-plt_: Collection Setup and Unpacking
==========================================================

The Setup PLT executable (bin/setup-plt for Unix) performs two
services:

 * Compiling and setting up all collections: When Setup PLT is run
   without any arguments, it finds all of the current collections
   (using the PLTHOME and PLTCOLLECTS environment variable)
   and compiles all collections with an info.ss library that
   indicates how the collection is compiled (see the
   --collection-zos flag for mzc).

   The --clean (or -c) flag to Setup PLT causes it to delete
   all existing .zo and extension files, thus ensuring a clean
   build from the source files. (Exactly which files are deleted
   is controlled by the info.ss file. See below for more info.)

   The -l flag takes one or more collection names and restricts 
   Setup PLT's action to those collections.

   In addition to compilation, a collection's info.ss library
   can specify executables to be installed in the plt directory
   (plt/bin under Unix) or other installation actions.

 * Unpacking _.plt_ files: A .plt file is a platform-indepedent
   distribution archive for MzScheme- and MrEd-based software.
   When one or more file names are provided as the command line
   arguments to Setup PLT, the files contained in the .plt
   archive are unpacked (according to specifications embedded in
   the .plt file; see below) and only the collections specified
   by the plt file are compiled and setup.

 Compiling and Setting Up Collections
 ------------------------------------

Setup PLT attempts to compile and set up any collection that:

 * has an info.ss library;
 
 * is a top-level collection (not a sub-collection; top-level
   collections can specify subcollections to be compiled and
   set up with the `compile-subcollections' info.ss field);
   and

 * has the 'name info.ss field.

Collections meeting this criteria are compiled using the
`compile-collection-zos' procedure described above. If the -e or
--extension flag is specified, then the collections are also compiled
using the `compile-collection-extension' procedure described above.

Additional info.ss fields trigger additional setup actions:

>  'mzscheme-launcher-names - a list of executable names to be
   installed in plt (or plt/bin) to run MzScheme programs implemented
   by the collection. A parallel list of library names must be
   provided by `mzscheme-launcher-libraries'. For each name, a
   launching executable is set up using the launcher collection's
   `install-mzscheme-program-launcher'. If the executable already
   exists, no action is taken.

> 'mzscheme-launcher-libraries - a list of library names in
   parallel to `mzscheme-launcher-names'.

>  'mred-launcher-names - a list of executable names to be installed
   in plt (or plt/bin) to run MrEd programs implemented by the
   collection.  A parallel list of library names must be provided by
   `mred-launcher-libraries'. For each name, a launching executable is
   set up using the launcher collection's
   `install-mred-program-launcher'. If the executable already exists,
   no action is taken.

>  'mred-launcher-libraries - a list of library names in
   parallel to `mred-launcher-names'.

>  'install-collection - a procedure that accepts a directory path
   argument (the path to the collection) and performs
   collection-specific installation work.  This procedure should avoid
   unnecessary work in the case that it is called multiple times for
   the same installation.

> 'clean - a list of pathnames to be deleted when the --clean or
  -c flag is passed to setup-plt. The pathnames must be relative to
  the collection.  If the any path names a directory, each of the
  files in the directory are deleted but none of the subdirectories of that
  directory are checked. If the path names a file,
  the file is deleted.  The default, if this flag is not specified, is
  to delete all files in the compiled subdirectory.
  and all of the files in the architecture-specific subdirectory of
  the compiled directory, for the architecture that setup-plt
  is running under.


 Unpacking .plt Distribution Archives
 ------------------------------------

The extension ".plt" is not required for a distribution archive; this
convention merely helps users identify the purpose of a distribution
file.

The raw format of a distribution file is described below. This format
is uncompressed and sensitive to communication modes (text
vs. binary), so the distribution format is derived from the raw format
by first compressing the file using gzip, then encoding the gzipped
file with the MIME base64 standard (which relies only the characters
A-Z, a-z, 0-9, +, /, and =; all other characters are ignored when
a base64-encoded file is decoded).

The raw format is

 * "PLT" are the first three characters.

 * An info.ss-like procedure that takes a symbol and a failure thunk
   and returns information about archive for recognized symbols. The
   two required info fields are:

     + 'name - a human-readable string describing the archive's
       contents. This name is used only for printing messages to the
       user during unpacking.

     + 'unpacker - a symbol indicating the expected unpacking
       environment. Currently, the only allowed value is 'mzscheme.

   The procedure is extracted from the archive using MzScheme's
   `read' and `eval' procedures.

 * An unsigned unit that drives the unpacking process. The unit accepts two
   imports: a path string for the plt directory and an `unmztar'
   procedure. The remainder of the unpacking process consists of invoking
   ths unit. It is expected that the unit will call `unmztar' procedure to
   unpack directories and files that are defined in the input archive afer
   this unit. The result of invoking the unit must be a list of collection
   paths (where each collection path is a list of strings); once the
   archive is unpacked, Setup PLT will compile and setup the specified
   collections, as if it was invoked with the "-c" option, so the
   "compiled" directories will be deleted.

   The `unmztar' procedure takes one argument: a filter
   procedure. The filter procedure is called for each directory and
   file to be unpacked. It is called with three arguments:

      + 'dir, 'file, 'file-replace - indicates whether the item to be
        unpacked is a directory, a file, or a file to be replaced;

      + a relative path string - the pathname of the directory or file
        to be unpacked, relative to the plt directory; and

      + a path string for the plt directory.

   If the filter procedure returns #f for a directory or file, the
   directory or file is not unpacked. If the filter procedure returns
   #t and the directory or file for 'dir or 'file already exists, it
   is not created. (The file for 'file-replace need not exist
   already.)

   When a directory is unpacked, intermediate directies are created
   as necessary to create the specified directory. When a file is
   unpacked, the directory must already exist.

   The unit is extracted from the archive using MzScheme's `read'
   and `eval' procedures.

Assuming that the unpacking unit calls the `unmztar' procedure, the
archive should continue with unpackables. Unpackables are extracted
until the end-of-file is found (as indicated by an `=' in the
base64-encoded input archive).

An unpackable is one of the following:

 * The symbol 'dir followed by a list. The `build-path' procedure
   will be applied to the list to obtain a relative path for the
   directory (and the relatie path is combined with the plt directory
   path to ge a complete path).

   The 'dir symbol and list are extracted from the archive using
   MzScheme's `read' (and the result is *not* `eval'uated).

 * The symbol 'file, a list, a number, an asterisk, and the file
   data. The list specifies the file's relative path, just as for
   directories. The number indicates the size of the file to be
   unpacked in bytes. The asterisk indicates the start of the file
   data; the next n bytes are written to the file, where n is the
   specified size of the file.

   The symbol, list, and number are all extracted from the archive
   using MzScheme's `read' (and the result is *not* `eval'uated).
   After the number is read, input characters are discarded until
   an asterisk is found. The file data must follow this asterisk
   immediately.

 * The symbol 'file-replace is treated like 'file, but if the file
   exists on disk already, the file in the archive replaces the file
   on disk.

 Making .plt archives
 --------------------

The setup collection's pack.ss library provides functions to help
make .plt archives, especially under Unix:

> (pack dest name paths collections [filter encode? file-mode]) -
  Creates the .plt file specified by the pathname `dest', using the
  string `name' as the name reported to Setup PLT as the archive's
  description, and `collections' as the list of colection paths
  returned by the unpacking unit. The `paths argument must be a list
  of relative paths for directories and files; the contents of these
  files and directories will be packed into the archive.

  The `filter' procedure is called with the relative path of each
  candidate for packing. If it returns #f for some path, then that
  file or directory is omitted from the archive. If it returns 'file
  or 'file-replace for a file, the file is packed with that mode,
  rather than the default mode. The default `filter' is `std-filter'
  (defined below).
  
  If `encode?' is #f, then the output archive is in raw form, and
  still must be gzipped and mime-encoded (in that order). The default
  value is #t.

  The `file-mode' argument must be 'file or 'file-replace, indicating
  the default mode for a file in the archive. The default value is
  'file.

> (std-filter p) - returns #t unless `p' matches one of the following
  regular expressions: "CVS$", "compiled$", "~$", or "^#.*#$".

> (mztar path output filter file-mode) - called by `pack' to write one
   directory/file `path' to the output port `output' using the filter
   procedure `filter' (see `pack' for a description of `filter').  The
   `file-mode' argument specifies the default mode for packing a file,
   either 'file or 'file-replace.

 Unpacking .plt archives
 -----------------------

 The _plt-installer.ss_ library in the setup collection defines two
 procedures:

> (run-installer filename) - run the .plt installer on the .plt file in
  `filename' and show the output in a window.

> (on-installer-run thunk) - sets the on-installer-run thunk to thunk. The
on-installer-run thunk is run after a .plt file is installed.

> (on-installer-run) - returns the on-installer-run thunk to thunk. The
on-installer-run thunk is run after a .plt file is installed.

 The _plt-installerr.ss_ library in the setup collection returns a unit/sig
 that imports mred^ and exports setup:plt-installer^. The signature
 setup:plt-installer^ has two names: run-installer and on-installer-run, as
 above.

 The _plt-installers.ss_ library defines the setup:plt-installer^
 signature, which has two names: run-installer and on-installer-run.

 Setup PLT as a Unit
 -------------------

The _setupr.ss_ library in the setup collection contains a signed
unit that imports

  setup-option^ - described below
  mzlib:file^
  compiler^ - from sig.ss in the compiler collection
  compiler:option^  - from sig.ss in the compiler collection
  launcher-maker^ - from launchers.ss in the `launcher' collection

Invoking this unit starts the setup process. The _setupsig.ss_ library
defines the
>      setup-option^
signature, which is implemented by the unit in _setup-optionr.ss_. It
defines the following parameters that control the setup process:

> verbose - #t => prints message from `make' to stderr [default: #f]
> make-verbose - #t => verbose `make' [default: #f]
> compiler-verbose - #t => verbose `compiler' [default: #f]
> clean - #t => delete .zo and .so/.dll files in the specified collections
         [default: #f]
> make-zo - #t => compile .zo files [default #t]
> make-so - #t => compile .so/.dll files [default: #f]
> make-launchers - #t => make collection info.ss-specified launchers
                   [default: #t]
> call-install - #t => call collection info.ss-specified setup code
                 [default: #t]
> specific-collections - a list of collections to set up; the empty
           list means set-up all collections if  the archives
           list is also empty [default: null]
> archives - a list of .plt archives to unpack; any collections specified
            by the archives are set-up in addition to the collections
            listed in specific-collections  [default: null]

Thus, to unpack a single .plt archive "x.plt", set the `archives'
parameter to (list "x.plt") and leave `specific-collections' as null.

Link the options and setup units so that your option-setting code is
initialized between them, e.g.:

    (compound-unit/sig
      ...
      (link ...
            [OPTIONS : setup-option^ 
                       ((require-library "setup-optionr.ss" "setup"))]
            [MY-CODE : ()
                       ((require-library "init-options.ss") OPTIONS)]
            [SETUP : ()
                     ((require-library "setupr.ss" "setup")
                      OPTIONS ...)])
      ...)


 _Getting fields from info.ss files_
 -----------------------------------

 The file get-info.ss defines 

> (get-info collection-names) -> (union #f (symbol (-> TST) -> TST))

   get-info accepts a list of strings naming a collection or
   sub-collection. It returns #f if there is no info.ss file or if the
   info.ss file has an error during loading. Otherwise, it returns a
   procedure of two arguments. This procedure extracts the value bound to
   the symbol from the info.ss procedure, or returns the result of the
   thunk if the symbol isn't bound in the info.ss file.

   get-info will print an error message if the info.ss has an error during
   loading or when the info.ss procedure is called.
