_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 (see the MzScheme manual for information on collections) and compiles module libraries in each collection with an "info.ss" library. The "info.ss" can indicate specifically how the collection's modules are compiled (see below). In this mode, Setup PLT also compiles any module that is referenced by a compiled module. The --clean (or -c) flag to Setup PLT causes it to delete existing .zo and extension files, thus ensuring a clean build from the source files. The exact set of deleted files can be controlled by "info.ss" libraries; see below for more info. The -l flag takes one or more collection names and restricts Setup PLT's action to those collections. The --mode flag causes Setup PLT to use a .zo compiler other than the default, and to put the resulting .zo files in a subdirectory (of the usual place) names . The compiler is obtained by using as a collection name, finding a _zo-compile.ss_ module in that collection, and extracting its `zo-compile' export. The `zo-compile' export should be a function like MzScheme's `compile'. 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-independent 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) and only 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 (see the mzc manual for a description of info.ss); * has the 'name' field in "info.ss"; * is either a top-level collection or a sub-collection of a compilable collection. Collections meeting this criteria are compiled using the `compile-collection-zos' procedure described in the "compiler" collection (which means that even if a collection has no "info.ss" file, its modules will get compiled if they are used by other compiled modules). If the -e or --extension flag is specified, then the collections are also compiled using the `compile-collection-extension' procedure from "compiler" (which does not compile a module merely because it is used by another). 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' or `mzscheme-launcher-flags' (see below). For each name, a launching executable is set up using the launcher collection's `make-mzscheme-launcher'. The arguments are "-qmvL-" and "" "/..." where lib is the file named by `mzscheme-launcher-libraries' and "/..." are the collections (and subcollections) of the info.ss file. In addition, (build-aux-from-path (build-path (collection-path ...) )) is provided for the optional "aux" argument (for icons, etc.), where is without its suffix (see launcher/doc.txt). If `mzscheme-launcher-flags' is provided, it is used as a list of command-line argument lists to pass to mzscheme instead of the above default, allowing arbitrary command-line arguments. If `mzscheme-launcher-flags' is specified together with `mzscheme-launcher-libraries', then the flags will override the libraries, but the libraries can still be used to specify a name for `build-aux-from-path' (to find related information like icon files etc). If compile-subcollections mentions a subcollection with this field, the executable is also set up for that subcollection. If the executable already exists, no action is taken. > mzscheme-launcher-libraries - a list of library names in parallel to `mzscheme-launcher-names' (see above). > mzscheme-launcher-flags - a list of command-line flag lists, in parallel to `mzscheme-launcher-names' (see above). > mred-launcher-names - a list of executable names to be installed in "plt" (or "plt/bin") to run MrEd programs implemented by the collection. This is treated in parallel to `mred-launcher-libraries' and `mred-launcher-flags' similarly to `mzscheme-launcher-names' above. > mred-launcher-libraries - a list of library names in parallel to `mred-launcher-names' (see above). > mred-launcher-flags - a list of command-line flag lists, in parallel to `mred-launcher-names' (see above). > install-collection - a string or a path for a library module relative to the collection. The module must provide `installer' as a procedure that accepts either one or two arguments. The first argument is a directory path to the parent of the PLT installation's "collects" directory; the second argument, if accepted, is a path to the collection's own directory. The procedure should perform collection-specific installation work, and it should avoid unnecessary work in the case that it is called multiple times for the same installation. > pre-install-collection - like `install-collection', except that the corresponding installer is called *before* the normal .zo build, instead of after. The provided procedure should be named `pre-installer' in this case so it can be provided by the same file that provides an installer. > post-install-collection - like `install-collection'. It is called right after the `install-collection' procedure is executed. The only difference between these is that the `--no-install' flag can be used to disable the previous two installers, but not this one. It is therefore expected to perform operations that are always needed, even after an installation that contains pre-compiled files. The provided procedure should be named `post-installer' in this case so it can be provided by the same file that provides the previous two. > 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 any path names a directory, each of the files in the directory are deleted, but none of the subdirectories of the 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 platform-specific subdirectory of the compiled directory for the current platform. Just as compiling .zo files will compile each module used by a compiled module, deleting a module's compiled image will delete the .zo of each module that is used by the module. More specifically, used modules are determined when deleting a ".dep" file, which would have been created to accompany a .zo file when the .zo was built by Setup PLT. If the .dep file indicates another module, that module's .zo is deleted only if it also has an accompanying .dep file. In that case, the .dep file is deleted, and additional used modules are deleted based on the used module's .dep file, etc. Supplying a specific list of collections to Setup PLT disables this dependency-based deletion of compiled files. Running Setup PLT from Scheme on a Single .plt file --------------------------------------------------- The _plt-single-installer.ss_ module provides a function for installing a single .plt file: > (run-single-installer file get-dir-proc) file : path string get-dir-proc: (-> (union string #f)) Creates a separate thread and namespace, runs the installer in that thread with the new namespace, and returns when the thread completes or dies. It also creates a custodian to manage the created thread, sets the exit handler for the thread to shut down the custodian, and explicitly shuts down the custodian when the created thread terminates or dies. The `get-dir-proc' procedure is called if the installer needs a target directory for installation, and a #f result means that the user canceled the installation. Typically, `get-dir-proc' is `current-directory'. Setup PLT as a Unit ------------------- The _setup-unit.ss_ library in the setup collection exports a _setup@_ signed unit that imports setup-option^ - described below compiler^ - from "sig.ss" in the "compiler" collection compiler:option^ - from "sig.ss" in the "compiler" collection launcher-maker^ - from "launcher-sig.ss" in the "launcher" collection Invoking this unit starts the setup process. The _option-sig.ss_ library in "setup" defines the > setup-option^ signature, which is implemented by the _setup:option@_ unit in _option-unit.ss_. It imports nothing and exports 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] > compile-mode - path => use a .zo compiler other than plain `compile', and build to (build-path "compiled" (compile-mode)) [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] > make-info-domain - #t => update info-domain/compiled/cache.ss for each collection path [default: #t] > call-install - #t => call collection "info.ss"-specified setup code [default: #t] > force-unpack - #t => ignore version and already-installed errors when unpacking a .plt archive [default: #f] > pause-on-errors - #t => in the event of an error, prints a summary error and waits for stdin input before terminating [default: #f] > 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] > current-target-directory-getter - a thunk that returns the target directory for unpacking a relative .plt archive; when unpacking an archive, either this or the procedure in `current-target-plt-directory-getter' will be called [default: current-directory] > current-target-plt-directory-getter - a procedure that takes a preferred path, a path to the parent of the main "collects" directory, and a list of path choices; it returns a path for a "plt-relative" install; when unpacking an archive, either this or the procedure in `current-target-directory-getter' will be called, and in the former case, this procedure one may be called multiple times [default: (lambda (preferred main-parent-dir choices) preferred)] Thus, to unpack a single .plt archive "x.plt", set the `archives' parameter to (list "x.plt") and leave `specific-collections' as null. Beware that the current namespace might interfere with setup actions. For example, if setup is supposed to compile a module `(lib "foo.ss")' that imports `(lib "bar.ss")', but `(lib "bar.ss")' is already loaded in the current namespace, then compilation will use the loaded module rather than re-loading it. If `(lib "bar.ss")' has changed, re-using the loaded module is unlikely to be the desired behavior. Avoid this problem by invoking the setup process in a fresh namespace. 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^ (setup:option@)] [MY-CODE : () (my-init-options@ OPTIONS)] [SETUP : () (setup@ OPTIONS ...)]) ...) _Finding installation directories_ ================================== The _dirs.ss_ modules defines several procedures for locating installation directories: > (find-collects-dir) Returns a path to the installation's main "collects" directory, or #f if none can be found. (A #f result is likely only in a stand-alone executable that is distributed without libraries.) > (find-user-collects-dir) Returns a path to the user-specific "collects" directory; the directory indicated by the returned path may or may not exist. > (get-collects-search-dirs) Returns the same result as `(current-library-collection-paths)' (which means that this result is not sensitive to the value of the `use-user-specific-search-paths' parameter). > (find-doc-dir) Returns a path to the installation's "doc" directory. The result is #f if no such directory is available. > (find-user-doc-dir) Returns a path to a user-specific "doc" directory; the directory indicated by the returned path may or may not exist. > (get-doc-search-dirs) Returns a list of paths to search for documentation, not including documentation stored in individual collections. Unless it is configured otherwise, the result includes any non-#f result of `(find-doc-dir)' and `(find-user-doc-dir)' --- but the latter is included only if the value of the `use-user-specific-search-paths' parameter is true. > (find-lib-dir) Returns a path to the installation's "lib" directory, which contains libraries and other build information. The result is #f if no such directory is available. > (find-dll-dir) Returns a path to the directory that contains DLLs for use with the current executable (e.g., "libmzsch.dll" under Windows). The result is #f if no such directory is available, or if no specific directory is available (i.e., other than the platform's normal search path). > (find-user-lib-dir) Returns a path to a user-specific "lib" directory; the directory indicated by the returned path may or may not exist. > (get-lib-search-dirs) Returns a list of paths to search for libraries. Unless it is configured otherwise, the result includes any non-#f result of `(find-lib-dir)', `(find-dll-dir)', and `(find-user-lib-dir)' --- but the last is included only if the value of the `use-user-specific-search-paths' parameter is true. > (find-include-dir) Returns a path to the installation's "include" directory, which contains .h files for building MzScheme extensions and embedding programs. The result is #f if no such directory is available. > (find-user-include-dir) Returns a path to a user-specific "include" directory; the directory indicated by the returned path may or may not exist. > (get-include-search-dirs) Returns a list of paths to search for .h files. Unless it is configured otherwise, the result includes any non-#f result of `(find-include-dir)' and `(find-user-include-dir)' --- but the latter is included only if the value of the `use-user-specific-search-paths' parameter is true. > (find-console-bin-dir) Returns a path to the installation's executable directory, where the stand-alone MzScheme executable resides. The result is #f if no such directory is available. > (find-gui-bin-dir) Returns a path to the installation's executable directory, where the stand-alone MrEd executable resides. The result is #f if no such directory is available. > absolute-installation? A binary boolean flag that is true if this installation is using absolute path names. _Getting info.ss fields_ ======================== The _getinfo.ss_ module defines the following procedures: > (get-info collection-names) -> (union #f (symbol (-> TST) -> TST)) Accepts a list of strings naming a collection or sub-collection, and calls `get-info/full' with the full path corresponding to the named collection. > (get-info/full path) -> (union #f (symbol (-> TST) -> TST)) Accepts a path to a directory. It returns #f if there is no "info.ss" file in the directory. If the "info.ss" file has the wrong shape (i.e., not a module using (lib "infotab.ss" "setup")), or if the "info.ss" file fails to load, then an exception is raised. Otherwise, `get-info' returns an info procedure of one or two arguments. The first argument to the info procedure is always a symbolic name, and the result is the value of the name in the "info.ss" file, if the name is defined. The optional second argument to the info procedure is a thunk that is called when the name is not defined, and the result of the info procedure is the result of the thunk in that case. If the name is not defined and no thunk is provided, then an exception is raised. > (find-relevant-directories list-of-sym [mode]) -> list-of-path Returns a list paths identifying installed directories (i.e., collections and installed PLaneT packages) whose "info.ss" file defines one or more of the given symbols. The result is based on a cache that is computed by Setup PLT and stored in the "info-domain" sub-directory of each collection directory (as determined by the PLT_COLLECTION_PATHS environment variable, etc.) and the file "cache.ss" in the user addon dir. The result is in a canonical order (sorted lexicographically by directory name), and the paths it returns are suitable for providing to get-info/full. If mode is specified, it must be either 'preferred (the default) or 'all-available. If mode is 'all-available, find-relevant-collections will return all installed directories whose info files contain the specified symbols -- for instance, all installed PLaneT packages will be searched if 'all-available is specified. If mode is 'preferred, then only a subset of "preferred" packages will be searched, and in particular only the directory containing the most recent version of any PLaneT package will be returned. No matter what mode is specified, if more than one collection has the same name, find-relevant-directories will only search the one that occurs first in the PLT_COLLECTION_PATHS environment variable. _.plt_ Archive Internals ========================================================== NOTE: mzc can be used to create .plt files; see the mzc manual for details. The internals of .plt archive files should be of little interest to most users. 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. * A procedure that takes a symbol and a failure thunk and returns information about archive for recognized symbols and calls the failure thunk for unrecognized symbols. The information symbols 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. + 'requires - collections required to be installed before unpacking the archive, which associated versions; see the documentation of `pack' for details. + 'conflicts - collections required *not* to be installed before unpacking the archive + 'plt-relative? - a boolean; if true, then the archive's content should be unpacked relative to the plt add-ons directory. + 'plt-home-relative? - a boolean; if true and if `plt-relative?' is true, then the archive's content should be unpacked relative to the PLT installation. + 'test-plt-dirs - #f or a list of path strings; in the latter case, a true value of 'plt-home-relative? is cancelled if any of the directories in the list (relative to the PLT installation) is unwritable by the user. The procedure is extracted from the archive using MzScheme's `read' and `eval' procedures (in a fresh namespace). * An unsigned unit that drives the unpacking process. The unit accepts two imports: a path string for the parent of the main "collects" directory and an `unmztar' procedure. The remainder of the unpacking process consists of invoking this unit. It is expected that the unit will call `unmztar' procedure to unpack directories and files that are defined in the input archive after 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. 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 unpack directory; and + a path string for the unpack directory (which can vary for a PLT-relative install when elements of the archive start with "collects", "lib", etc.). 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 directories 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 relative path is combined with the target directory path to get 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 -------------------- mzc supports the creation of simple .plt files (see the mzc manual for details) but the setup collection's _pack.ss_ library provides more general functions to help make .plt archives: > (pack-collections-plt dest name collections [#:replace? replace?] [#:at-plt-home? at-home?] [#:test-plt-collects? test?] [#:extra-setup-collections collection-list] [#:file-filter filter-proc]) 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. The archive contains the collections listed in `collections', which should be a list of collection paths; each collection path is, in turn, a list of relative-path strings. If the #:replace? argument is #f, then attempting to unpack the archive will report an error when any of the collections exist already, otherwise unpacking the archive will overwrite an existing collection. If the #:at-plt-home? argument is true, then the archived collections will be installed into the PLT installation directory instead of the user's directory if the main "collects" directory is writable by the user. If the #:test-plt-collects? argument is #f (the default is #t) and the #:at-plt-home? argument is true, then installation fails if the main "collects" directory is not writable. The optional #:extra-setup-collections argument is a list of collection paths that are not included in the archive, but are set-up when the archive is unpacked. The optional #:file-filter argument is the same as for `pack-plt' (see below). > (pack-collections dest name collections replace? extra-setup-collections [filter] [at-plt-home?]) Old, keywordless variant of `pack-collections-plt' for backward compatibility. > (pack-plt dest name paths [#:file-filter filter-proc] [#:encode? encode?] [#:file-mode file-mode-sym] [#:unpack-unit unit-expr-or-#f] [#:collections collection-list] [#:plt-relative? plt-relative?] [#:at-plt-home? at-plt-home?] [#:test-plt-dirs dir-list-or-#f] [#:requires mod-and-version-list] [#:conflicts mod-list]) 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. 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 #:file-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 is `std-filter' (defined below). If the #:encode? argument 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 is 'file. The `unpack-unit' argument is usually #f. Otherwise, it must be an S-expression for a unsigned unit that performs the work of unpacking; see the above section on .plt internals for more information about the unit. If `unpack-unit' is #f, an appropriate unpacking unit is generated. The #:collections argument is a list of collection paths to be compiled after the archive is unpacked. The default is the empty list. If the #:plt-relative? argument is true (the default is #f), the archive's files and directories are to be unpacked relative to the user's add-ons directory or the PLT installation directories, depending on whether the #:at-plt-home? argument is true and whether directories specified by #:test-plt-dirs are writable by the user. If the #:at-plt-home? argument is true (the default is #f), then #:plt-relative? must be true, and the archive is unpacked relative to the PLT installation directory. In that case, a relative path that starts with "collects" is mapped to the installation's main "collects" directory, and so on, for the following the initial directory names: - "collects" - "doc" - "lib" - "include" If #:test-plt-dirs is a list, then #:at-plt-home? must be true. In that case, when the archive is unpacked, if any of the relative directories in the #:test-plt-dirs list is unwritable by the current user, then the archive is unpacked in the user's add-ons directory after all. The #:requires argument should have the shape (list (list ) ...) where each is a non-empty list of relative-path strings, and each is a (possibly empty) list of exact integers. The indicated collections must be installed at unpacking time, with version sequences that match as much of the version sequence specified in the corresponding . A collection's version is indicated by the `version' field of it's info.ss file. The #:conflicts argument should have the shape (list ...) where each is a non-empty list of relative-path strings. The indicated collections must *not* be installed at unpacking time. > (pack dest name paths collections [filter encode? file-mode unpack-unit plt-relative? requires conflicts at-plt-home?]) Old, keywordless variant of `pack-plt' for backward compatibility. > (std-filter p) - returns #t unless `p', after stripping its directory path and converting to a byte string, matches one of the following regular expressions: "^CVS$", "^[.]svn$", "^[.]cvsignore", "^compiled$", "~$", "^#.*#$", "^[.]#", or "[.]plt$". > (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 these procedures: > (run-installer filename) - run the .plt installer on the .plt file in `filename' and show the output in a window. This is a composition of `with-installer-window' and `run-single-installer' with a `get-dir-proc' that prompts the user for a directory (turning off the busy cursor while the dialog is active). > (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. The on-installer-run thunk is run after a .plt file is installed. > (with-installer-window do-install cleanup-thunk) do-install : ((union (instanceof dialog%) (instanceof frame%)) -> void) creates a frame, sets up the current error and output ports, and turns on the busy cursor before calling `do-install' in a separate thread. Returns before the installation process is complete; cleanup-thunk is called on a queued callback to the eventspace active when `with-installer-window' is invoked. (run-single-installer file get-dir-proc) - the same as the sole export of _plt-single-installer.ss_; see above for documentation. The _plt-installer-unit.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-installer-sig.ss_ library defines the setup:plt-installer^ signature, which has two names: run-installer and on-installer-run.