racket/pkgs/racket-doc/scribblings/raco/setup.scrbl

2065 lines
88 KiB
Racket

#lang scribble/doc
@(require scribble/manual
scribble/bnf
"common.rkt"
(for-label racket
racket/future
setup/setup-unit
setup/option-unit
setup/option-sig
setup/dirs
setup/getinfo
setup/main-collects
setup/collection-name
setup/collection-search
setup/matching-platform
setup/cross-system
setup/path-to-relative
setup/xref scribble/xref
;; info -- no bindings from this are used
(only-in info)
setup/pack
setup/unpack
setup/link
compiler/compiler
compiler/module-suffix
launcher/launcher
compiler/sig
launcher/launcher-sig
dynext/file-sig
racket/gui/base
racket/future
mrlib/terminal
(only-in ffi/unsafe ffi-lib)
racket/path
setup/collects
syntax/modcollapse
racket/runtime-path
pkg/path))
@(define-syntax-rule (local-module mod . body)
(begin
(define-syntax-rule (go)
(begin
(require (for-label mod))
. body))
(go)))
@(define ref-src
'(lib "scribblings/reference/reference.scrbl"))
@(define (defaults v)
@elem{The default is @|v|.})
@(define pkg-doc '(lib "pkg/scribblings/pkg.scrbl"))
@title[#:tag "setup" #:style 'toc]{@exec{raco setup}: Installation Management}
The @exec{raco setup} command builds bytecode, documentation,
executables, and metadata indexes for all installed collections.
The collections that are built by @exec{raco setup} can be part of the
original Racket distribution, installed via the package manager (see
@other-manual[pkg-doc]), installed via
@|PLaneT| (see @other-manual['(lib "planet/planet.scrbl")]), linked
via @exec{raco link}, in a directory that is listed in the
@envvar{PLTCOLLECTS} environment variable, or placed into one of the
default collection directories.
The @exec{raco setup} tool itself does not directly support the
installation of collections, except through the now-discouraged
@Flag{A} flag (see @secref["raco-setup-A"]). The @exec{raco setup} command is
used by installation tools such as the package manager or @|PLaneT|.
Programmers who modify installed collections may find it useful to run
@exec{raco setup} as an alternative to un-installing and re-installing
a set of collections.
@local-table-of-contents[]
@; ------------------------------------------------------------------------
@section[#:tag "running"]{Running @exec{raco setup}}
With no command-line arguments, @exec{raco setup} finds all of the
current collections---see @secref[#:doc ref-src]{collects}---and
compiles libraries in each collection. (Directories that are named
@filepath{.git} or @filepath{.svn} are not treated as collections.)
To restrict @exec{raco setup} to a set of collections, provide the
collection names as arguments. For example, @exec{raco setup
scribblings/raco} would only compile and render the documentation for
@exec{raco}, which is implemented in a @filepath{scribblings/raco}
collection.
An optional @filepath{info.rkt} within the collection can indicate
specifically how the collection's files are to be compiled and other
actions to take in setting up a collection, such as creating
executables or building documentation. See @secref["setup-info"] for
more information.
The @exec{raco setup} command accepts the following command-line
flags:
@itemize[
@item{Constraining to specified collections or @|PLaneT| packages:
@itemize[
@item{@DFlag{only} --- restrict setup to specified collections and
@|PLaneT| packages, even if none are specified. This mode is the
default if any collection is specified as a command-line argument
or through the @Flag{l}, @DFlag{pkgs}, or @Flag{P} flag.}
@item{@Flag{l} @nonterm{collection} @racket[...] --- constrain setup
actions to the specified @nonterm{collection}s (i.e., the same as
providing @nonterm{collections}s without a flag, but with no
possibility that a @nonterm{collection} is interpreted as a flag).}
@item{@DFlag{pkgs} @nonterm{pkg} @racket[...] --- constrain setup
actions to collections that are within (or partially within) the
named @nonterm{pkg}s.}
@item{@Flag{P} @nonterm{owner} @nonterm{package-name} @nonterm{maj}
@nonterm{min} --- constrain setup actions to the specified @|PLaneT|
package, in addition to any other specified @|PLaneT| packages or
collections.}
@item{@DFlag{doc-index} --- build collections that implement
documentation indexes (when documentation building is enabled), in
addition to specified collections.}
@item{@DFlag{tidy} --- remove metadata cache information and
documentation for non-existent collections or documentation (to
clean up after removal), even when setup actions are otherwise
confined to specified collections.}
]}
@item{Constraining to specific tasks:
@itemize[
@item{@DFlag{clean} or @Flag{c} --- delete existing @filepath{.zo}
files, thus ensuring a clean build from the source files. The exact
set of deleted files can be controlled by @filepath{info.rkt}; see
@elemref["clean"]{@racket[clean]} for more information.}
@item{@DFlag{fast-clean} or @Flag{c} --- like @DFlag{clean}, but
without forcing a bootstrap of @exec{raco setup} from source (which
means that @DFlag{fast-clean} cannot clean corruption that affects
@exec{raco setup} itself).}
@item{@DFlag{no-zo} or @Flag{n} --- refrain from compiling source
files to @filepath{.zo} files.}
@item{@DFlag{trust-zos} --- fix timestamps on @filepath{.zo} files on
the assumption that they are already up-to-date (unless the
@envvar{PLT_COMPILED_FILE_CHECK} environment variable is set to
@litchar{exists}, in which case timestamps are ignored).}
@item{@DFlag{no-launcher} or @Flag{x} --- refrain from creating
executables or installing @tt{man} pages (as specified in
@filepath{info.rkt}; see @secref["setup-info"]).}
@item{@DFlag{no-foreign-libs} or @Flag{F} --- refrain from installing foreign
libraries (as specified in @filepath{info.rkt}; see
@secref["setup-info"]).}
@item{@DFlag{only-foreign-libs} --- disable actions other than
installing foreign libraries; equivalent to @Flag{nxiIdD}, except
that @DFlag{only-foreign-libs} doesn't reject (redundant)
specification of those individual flags.}
@item{@DFlag{no-install} or @Flag{i} --- refrain from running
pre-install actions (as specified in @filepath{info.rkt} files; see
@secref["setup-info"]).}
@item{@DFlag{no-post-install} or @Flag{I} --- refrain from running
post-install actions (as specified in @filepath{info.rkt} files; see
@secref["setup-info"]).}
@item{@DFlag{no-info-domain} or @Flag{d} --- refrain from building
a cache of metadata information from @filepath{info.rkt}
files. This cache is needed by other tools. For example,
@exec{raco} itself uses the cache to locate plug-in tools.}
@item{@DFlag{no-docs} or @Flag{D} --- refrain from building
documentation.}
@item{@DFlag{doc-pdf} @nonterm{dir} --- in addition to building HTML
documentation, render documentation to PDF and place files in
@nonterm{dir}.}
@item{@DFlag{no-pkg-deps} or @Flag{K} --- refrain from checking
whether dependencies among libraries are properly reflected by
package-level dependency declarations, whether modules are declared
by multiple packages, and whether package version dependencies are
satisfied. See @secref["setup-check-deps"] for more information.}
@item{@DFlag{check-pkg-deps} --- checks package dependencies (unless
explicitly disabled) even when specific collections are provided to
@exec{raco setup}, and even for packages that have no dependency
declarations. See @secref["setup-check-deps"] for more information.}
@item{@DFlag{fix-pkg-deps} --- attempt to correct dependency
mismatches by adjusting package @filepath{info.rkt} files (which
makes sense only for packages that are installed as links). See
@secref["setup-check-deps"] for more information.}
@item{@DFlag{unused-pkg-deps} --- attempt to report dependencies that
are declared but are unused. Beware that some package dependencies
may be intentionally unused (e.g., declared to force installation of
other packages as a convenience), and beware that package
dependencies may be reported as unused only because compilation of
relevant modules has been suppressed. See
@secref["setup-check-deps"] for more information.}
]}
@item{Constraining user versus installation setup:
@itemize[
@item{@DFlag{no-user} or @Flag{U} --- refrain from any user-specific
(as opposed to installation-specific) setup actions.}
@item{@DFlag{no-planet} --- refrain from any setup actions for
@|PLaneT| actions; this flag is implied by @DFlag{no-user}.}
@item{@DFlag{avoid-main} --- refrain from any setup actions that
affect the installation, as opposed to user-specific actions.}
@item{@DFlag{force-user-docs} --- when building documentation, create
a user-specific documentation entry point even if it has the same
content as the main installation.}
]}
@item{Selecting parallelism and other build modes:
@itemize[
@item{@DFlag{jobs} @nonterm{n}, @DFlag{workers} @nonterm{n},
or @Flag{j} @nonterm{n} --- use up
to @nonterm{n} parallel processes. By default, @exec{raco setup}
uses @racket[(processor-count)] jobs, which typically uses
all of the machine's processing cores.}
@item{@DFlag{verbose} or @Flag{v} --- more verbose output about
@exec{raco setup} actions.}
@item{@DFlag{make-verbose} or @Flag{m} --- more verbose output about
dependency checks.}
@item{@DFlag{compiler-verbose} or @Flag{r} --- even more verbose
output about dependency checks and compilation.}
@item{@DFlag{mode} @nonterm{mode} --- use a @filepath{.zo} compiler
other than the default compiler, and put the resulting
@filepath{.zo} files in a subdirectory (of the usual place) named
by @nonterm{mode}. The compiler is obtained by using @nonterm{mode}
as a collection name, finding a @filepath{zo-compile.rkt} module in
that collection, and extracting its @racket[zo-compile] export. The
@racket[zo-compile] export should be a function like
@racket[compile]; see the @filepath{errortrace} collection for an
example.}
@item{@DFlag{fail-fast} --- attempt to break as soon as any error is
discovered.}
@item{@DFlag{pause} or @Flag{p} --- pause for user input if any
errors are reported (so that a user has time to inspect output that
might otherwise disappear when the @exec{raco setup} process ends).}
]}
@item{Unpacking @filepath{.plt} archives:
@itemize[
@item{@Flag{A} @nonterm{archive} @racket[...] --- Install each
@nonterm{archive}; see @secref["raco-setup-A"].}
@item{@DFlag{force} --- for use with @Flag{A}, treat version
mismatches for archives as mere warnings.}
@item{@DFlag{all-users} or @Flag{a} --- for use with @Flag{A},
install archive into the installation instead of a user-specific
location.}
]}
]
When building @exec{racket}, flags can be provided to @exec{raco
setup} as run by @exec{make install} by setting the
@as-index{@envvar{PLT_SETUP_OPTIONS}} environment variable. For
example, the following command line uses a single process to build
collections during an install:
@commandline{env PLT_SETUP_OPTIONS="-j 1" make install}
Running @exec{raco setup} is sensitive to the
@envvar{PLT_COMPILED_FILE_CHECK} environment variable in the same way
as @exec{raco make}. Specifically, if @envvar{PLT_COMPILED_FILE_CHECK}
is set to @litchar{exists}, then @exec{raco make} does not attempt to
update a compiled file's timestamp if the file is not recompiled.
@history[#:changed "6.1" @elem{Added the @DFlag{pkgs},
@DFlag{check-pkg-deps}, and
@DFlag{fail-fast} flags.}
#:changed "6.1.1" @elem{Added the @DFlag{force-user-docs} flag.}
#:changed "6.1.1.6" @elem{Added the @DFlag{only-foreign-libs} flag.}
#:changed "6.6.0.3" @elem{Added support for @envvar{PLT_COMPILED_FILE_CHECK}.}]
@; ------------------------------------------------------------------------
@section[#:tag "raco-setup-A"]{Installing @filepath{.plt} Archives}
A @filepath{.plt} file is a platform-independent distribution archive
for software based on Racket. A typical @filepath{.plt} file can be
installed as a package using @exec{raco pkg} (see @other-manual['(lib
"pkg/scribblings/pkg.scrbl")]), in which case @exec{raco pkg} supplies
facilities for uninstalling the package and managing dependencies.
An older approach is to supply a @filepath{.plt} file to @exec{raco
setup} with the @Flag{A} flag; the files contained in the
@filepath{.plt} archive are unpacked (according to specifications
embedded in the @filepath{.plt} file) and only collections specified
by the @filepath{.plt} file are compiled and setup. Archives processed
in this way can include arbitrary code that is executed at install
time, in addition to any actions triggered by the normal
collection-setup part of @exec{raco setup}.
Finally, the @exec{raco unpack} (see @secref["unpack"]) command can
list the content of a @filepath{.plt} archive or unpack the archive
without installing it as a package or collection.
@; ------------------------------------------------------------------------
@section[#:tag "setup-info"]{Controlling @exec{raco setup} with @filepath{info.rkt} Files}
To compile a collection's files to bytecode, @exec{raco setup} uses the
@racket[compile-collection-zos] procedure. That procedure, in turn,
consults the collection's @filepath{info.rkt} file, if it exists, for
specific instructions on compiling the collection. See
@racket[compile-collection-zos] for more information on the fields of
@filepath{info.rkt} that it uses, and see @secref["info.rkt"] for
information on the format of an @filepath{info.rkt} file.
Additional fields are used by the
@seclink["top" #:doc '(lib "pkg/scribblings/pkg.scrbl") "Racket package manager"]
and are documented in @secref["metadata" #:doc '(lib "pkg/scribblings/pkg.scrbl")].
The @exec{raco test} command also recognizes additional fields, which are
documented in @secref["test-config-info" #:doc '(lib "scribblings/raco/raco.scrbl")].
Optional @filepath{info.rkt} fields trigger additional actions by
@exec{raco setup}:
@itemize[
@item{@as-index{@racketidfont{scribblings}} : @racket[(listof (cons/c string? list?))] ---
A list of documents to build. Each document in the list is itself
represented as a list, where each document's list starts with a
string that is a collection-relative path to the document's source
file. A document name (which is derived from the source module's
name by default) is intended to be globally unique in the same way
as a package or module name.
More precisely a @racketidfont{scribblings} entry must be a value
that can be generated from an expression matching the following
@racket[_entry] grammar:
@racketgrammar*[
#:literals (list)
[entry (list doc ...)]
[doc (list src-string)
(list src-string flags)
(list src-string flags category)
(list src-string flags category name)
(list src-string flags category name out-k)
(list src-string flags category name out-k order-n)]
[flags (list mode-symbol ...)]
[category (list category-string-or-symbol)
(list category-string-or-symbol sort-number)]
[name string
#f]
]
A document's list optionally continues with information on how to
build the document. If a document's list contains a second item,
@racket[_flags], it must be a list of mode symbols (described
below). If a document's list contains a third item,
@racket[_category], it must be a list that categorizes the document
(described further below). If a document's list contains a fourth
item, @racket[_name], it is a name to use for the generated
documentation, instead of defaulting to the source file's name
(sans extension), where @racket[#f] means to use the default; a
non-@racket[#f] value for @racket[_name] must fit the grammar
of a collection-name element as checked by
@racket[collection-name-element?]. If a
document's list contains a fifth item, @racket[_out-k], it is used
a hint for the number of files to use for the document's
cross-reference information; see below. If a document's list
contains a fourth item, @racket[_order-n], it is used a hint for
the order of rendering; see below.
Each mode symbol in @racket[_flags] can be one of the following,
where only @racket['multi-page] is commonly used:
@itemize[
@item{@racket['multi-page] : Generates multi-page HTML output,
instead of the default single-page format.}
@item{@racket['main-doc] : Indicates that the generated
documentation should be written into the main installation
directory, instead of to a user-specific directory. This
mode is the default for a collection that is itself located
in the main installation.}
@item{@racket['user-doc] : Indicates that the generated
documentation should be written a user-specific
directory. This mode is the default for a collection that
is not itself located in the main installation.}
@item{@racket['depends-all] : Indicates that the document should
be rebuilt if any other document is rebuilt---except for
documents that have the @racket['no-depend-on] flag.}
@item{@racket['depends-all-main] : Indicates that the document
should be rebuilt if any other document is rebuilt that is
installed into the main installation---except for documents
that have the @racket['no-depend-on] flag.}
@item{@racket['depends-all-user] : Indicates that the document
should be rebuilt if any other document is rebuilt that is
installed into the user's space---except for documents
that have the @racket['no-depend-on] flag.}
@item{@racket['always-run] : Build the document every time that
@exec{raco setup} is run, even if none of its dependencies
change.}
@item{@racket['no-depend-on] : Removes the document for
consideration for other dependencies. Furthermore,
references from the document to other documents are always
direct, instead of potentially indirect (i.e., resolved at
document-viewing time and potentially redirected to a
remote site).}
@item{@racket['main-doc-root] : Designates the root document for
the main installation. The document that currently has this
mode should be the only one with the mode.}
@item{@racket['user-doc-root] : Designates the root document for
the user-specific documentation directory. The document
that currently has this mode should be the only one with
the mode.}
@item{@racket['keep-style] : Leave the document's style as-is,
instead of imposing the document style for manuals.}
@item{@racket['no-search] : Build the document without a search
box.}
]
The @racket[_category] list specifies how to show the document in
the root table of contents. The list must start with a category,
which determines where the manual appears in the root
documentation page. A category is either a string or a symbol. If
it is a string, then the string is the category label on the root
page. If it is a symbol, then a default category label is
used. The available symbols and the order of categories on the
root documentation page is as below:
@itemize[
@item{@racket['getting-started] : High-level, introductory
documentation, typeset at the same level as other
category titles.}
@item{@racket['language] : Documentation for a prominent
programming language.}
@item{@racket['tool] : Documentation for an executable.}
@item{@racket['gui-library] : Documentation for GUI and graphics
libraries.}
@item{@racket['net-library] : Documentation for networking
libraries.}
@item{@racket['parsing-library] : Documentation for parsing
libraries.}
@item{@racket['tool-library] : Documentation for programming-tool
libraries (i.e., not important enough for the more
prominent @racket['tool] category).}
@item{@racket['interop] : Documentation for interoperability
tools and libraries.}
@item{All string categories as ordered by @racket[string<=?].}
@item{@racket['library] : Documentation for libraries; this
category is the default and used for unrecognized category
symbols.}
@item{@racket['legacy] : Documentation for deprecated libraries,
languages, and tools.}
@item{@racket['experimental] : Documentation for an experimental
language or library.}
@item{@racket['other] : Other documentation.}
@item{@racket['omit] : Documentation that should not be listed on
the root page or indexed for searching.}
@item{@racket['omit-start] : Documentation that should not be
listed on the root page but should be indexed for
searching.}
]
If the category list has a second element, it must be a real number
that designates the manual's sorting position with the category;
manuals with the same sorting position are ordered
alphabetically. For a pair of manuals with sorting numbers
@racket[_n] and @racket[_m], the groups for the manuals are
separated by space if @racket[(truncate (/ _n 10))]and
@racket[(truncate (/ _m 10))] are different.
The @racket[_out-k] specification is a hint on whether to break the
document's cross-reference information into multiple parts, which
can reduce the time and memory use for resolving a cross-reference
into the document. It must be a positive, exact integer, and the
default is @racket[1].
The @racket[_order-n] specification is a hint for ordering document
builds, since documentation references can be mutually recursive.
The order hint can be any real number. A value of @racket[-10] or
less disables running the document in parallel to other documents.
The main Racket reference is given a value of @racket[-11], the
search page is given a value of @racket[10], and the default is
@racket[0].
A directory for pre-rendered documentation is computed from the
source file name by starting with the directory of the
@filepath{info.rkt} file, adding @filepath{doc}, and then using the
document name (which is usually the source file's name without a
suffix); if such a directory exists and does not have a
@filepath{synced.rktd} file, then it is treated as pre-rendered
documentation and moved into place, in which case the documentation
source file need not be present. Moving documentation into place
may require no movement at all, depending on the way that the
enclosing collection is installed, but movement includes adding a
@filepath{synced.rktd} file to represent the installation.
@history[#:changed "6.4" @elem{Allow a category to be a string
instead of a symbol.}]}
@item{@as-index{@racketidfont{release-note-files}} : @racket[(listof (cons/c string? (cons/c string? list?)))] ---
A list of release-notes text files to link from the main documentation pages.
Each note is itself represented as a list, and the list can specify auxiliary
notes that are grouped with the main note.
A @racketidfont{release-note-files} entry must be a value
that can be generated from an expression matching the following
@racket[_entry] grammar:
@racketgrammar*[
#:literals (list)
[entry (list note ...)]
[doc (list label-string note-path)
(list label-string note-path order-integer)
(list label-string note-path order-integer
(list sub-note ...))]
[sub-note (list label-string note-path)]
]
The @racket[_order-integer] is used to order notes and defaults to @racket[0].}
@item{@indexed-racket[racket-launcher-names] : @racket[(listof string?)]
--- @elemtag["racket-launcher-names"] A list of executable names
to be generated in the installation's executable directory to run
Racket-based programs implemented by the collection. A parallel
list of library names must be provided by
@racket[racket-launcher-libraries] or
@racket[racket-launcher-flags].
For each name, a launching executable is set up using
@racket[make-racket-launcher]. The arguments are @Flag{l-} and
@tt{@nonterm{colls}/.../@nonterm{file}}, where @nonterm{file} is
the file named by @racket[racket-launcher-libraries] and
@tt{@nonterm{colls}/...} are the collections (and subcollections)
of the @filepath{info.rkt} file.
In addition,
@racketblock[
(build-aux-from-path
(build-path (collection-path #,(nonterm "colls") _...) #,(nonterm "suffixless-file")))
]
is provided for the optional @racket[_aux] argument (for icons,
etc.) to @racket[make-racket-launcher], where
@nonterm{suffixless-file} is @nonterm{file} without its suffix.
If @racket[racket-launcher-flags] is provided, it is used as a
list of command-line arguments passed to @exec{racket} instead of
the above default, allowing arbitrary command-line arguments. If
@racket[racket-launcher-flags] is specified together with
@racket[racket-launcher-libraries], then the flags will override
the libraries, but the libraries can still be used to specify a
name for @racket[build-aux-from-path] (to find related information
like icon files etc).}
@item{@indexed-racket[racket-launcher-libraries] : @racket[(listof
path-string?)] --- A list of library names in parallel to
@elemref["racket-launcher-names"]{@racket[racket-launcher-names]}.}
@item{@indexed-racket[racket-launcher-flags] : @racket[(listof string?)]
--- A list of command-line flag lists, in parallel to
@elemref["racket-launcher-names"]{@racket[racket-launcher-names]}.}
@item{@indexed-racket[mzscheme-launcher-names],
@racket[mzscheme-launcher-libraries], and
@racket[mzscheme-launcher-flags] --- Backward-compatible variant of
@racket[racket-launcher-names], etc.}
@item{@indexed-racket[gracket-launcher-names] : @racket[(listof string?)] ---
@elemtag["gracket-launcher-names"] Like
@elemref["racket-launcher-names"]{@racket[racket-launcher-names]},
but for GRacket-based executables. The launcher-name list is treated
in parallel to @racket[gracket-launcher-libraries] and
@racket[gracket-launcher-flags].}
@item{@indexed-racket[gracket-launcher-libraries] : @racket[(listof path-string?)]
--- A list of library names in parallel to
@elemref["gracket-launcher-names"]{@racket[gracket-launcher-names]}.}
@item{@indexed-racket[gracket-launcher-flags] : @racket[(listof string?)] --- A
list of command-line flag lists, in parallel to
@elemref["gracket-launcher-names"]{@racket[gracket-launcher-names]}.}
@item{@indexed-racket[mred-launcher-names],
@racket[mred-launcher-libraries], and
@racket[mred-launcher-flags] --- Backward-compatible variant of
@racket[gracket-launcher-names], etc.}
@item{@indexed-racket[copy-foreign-libs] : @racket[(listof (and/c
path-string? relative-path?))] --- Files to copy into a
directory where foreign libraries are found by @racket[ffi-lib].
If @racket[install-platform] is defined, then the files are copied
only if the current platform matches the definition.
On Mac OS, when a Mach-O file is copied, if the copied file
includes a library reference that starts @litchar{@"@"loader_path/},
and if the referenced library exists in a different location among
the paths listed by @racket[(get-lib-search-dirs)], then the
library reference is updated to an absolute path.
On Unix, when an ELF file is copied, if the copied file includes an
RPATH setting of @litchar{$ORIGIN} and the file is being installed
to a user-specific location, then the file's RPATH is adjusted to
@litchar{$ORIGIN:} followed by the path to the main installation's
library directory as reported by @racket[(find-lib-dir)].
On Windows, deleting a previously installed foreign library may be
complicated by a lock on the file, if it is in use. To compensate,
@exec{raco setup} deletes a foreign-library file by first renaming
the file to have the prefix @filepath{raco-setup-delete-}; it then
attempts to delete the renamed file and merely issues a warning on
a failure to delete the renamed file. Meanwhile, in modes where
@exec{raco setup} removes uninstalled libraries, it attempts to
delete any file in the foreign-library directory whose name starts
with @filepath{raco-setup-delete-} (in an attempt to clean up after
previous failures).}
@item{@indexed-racket[move-foreign-libs] : @racket[(listof (and/c
path-string? relative-path?))] --- Like @racket[copy-foreign-libs],
but the original file is removed after it is copied (which makes sense
for precompiled packages).}
@item{@indexed-racket[copy-shared-files] : @racket[(listof (and/c
path-string? relative-path?))] --- Files to copy into a
directory where shared files are found.
If @racket[install-platform] is defined, then the files are copied
only if the current platform matches the definition.
On Windows, uninstalled files are deleted in the same way as for
@racket[copy-foreign-libs], and the name prefix
@filepath{raco-setup-delete-} is similarly special.}
@item{@indexed-racket[move-shared-files] : @racket[(listof (and/c
path-string? relative-path?))] --- Like @racket[copy-shared-files],
but the original file is removed after it is copied (which makes sense
for precompiled packages).}
@item{@indexed-racket[copy-man-pages] : @racket[(listof (and/c
path-string? relative-path? filename-extension))] --- Files to copy
into a @tt{man} directory. The file suffix determines its category;
for example, @litchar{.1} should be used for a @tt{man} page
describing an executable.
On Windows, uninstalled files are deleted in the same way as for
@racket[copy-foreign-libs], and the name prefix
@filepath{raco-setup-delete-} is similarly special.}
@item{@indexed-racket[move-man-pages] : @racket[(listof (and/c
path-string? relative-path? filename-extension))] --- Like
@racket[copy-man-pages], but the original file is removed after it
is copied (which makes sense for precompiled packages).}
@item{@indexed-racket[install-platform] : @racket[platform-spec?]
--- Determines whether files are copied or moved
for @racket[copy-foreign-libs], @racket[move-foreign-libs],
@racket[copy-shared-files], or @racket[move-shared-files].
See @racket[matching-platform?] for information on the way that the
specification is compared to @racket[(system-type)]
and @racket[(system-library-subpath #f)].}
@item{@indexed-racket[install-collection] : @racket[path-string?] ---
A library module relative to the collection that provides
@racket[installer]. The @racket[installer] procedure must accept
one, two, three, or four arguments:
@itemlist[
@item{The first argument is a directory path to the parent of the
Racket installation's @filepath{collects} directory.}
@item{The second argument, if accepted, is a path to the
collection's own directory.}
@item{The third argument, if accepted, is a boolean indicating
whether the collection is installed as user-specific (@racket[#t])
or installation-wide (@racket[#f]).}
@item{The fourth argument, if accepted, is a boolean indicating
whether the collection is installed as installation-wide and should
nevertheless avoid modifying the installation; an
@racket[installer] procedure that does not accept this argument is
never called when the argument would be @racket[#t]. An installer
that does accept this argument is called with @racket[#t] to that
it can perform user-specific work, even though the collection is
installed installation-wide.}
]}
@item{@indexed-racket[pre-install-collection] : @racket[path-string?] ---
Like @racket[install-collection], except that the corresponding
installer procedures are called @emph{before} the normal @filepath{.zo} build,
instead of after. The provided procedure is
@racket[pre-installer], so it can be provided by the
same file that provides an @racket[installer] procedure.}
@item{@indexed-racket[post-install-collection] : @racket[path-string?] ---
Like @racket[install-collection] for a procedure that is called right after the
@racket[install-collection] procedure is executed. The
@DFlag{no-install} flag can be provided to @exec{raco setup}
to disable @racket[install-collection] and @racket[pre-install-collection],
but not @racket[post-install-collection]. The @racket[post-install-collection]
function is therefore expected to perform operations that are always needed,
even after an installation that contains pre-compiled files. The
provided procedure is @racket[post-installer], so it
can be provided by the same file that provides an
@racket[installer] procedure.}
@item{@indexed-racket[assume-virtual-sources] : @racket[any/c] ---
A true value indicates that bytecode files without a corresponding
source file should not be removed from @filepath{compiled} directories,
and no files should not be removed when the
@DFlag{clean} or @Flag{c} flag is passed to @exec{raco setup}.}
@item{@indexed-racket[clean] : @racket[(listof path-string?)] ---
@elemtag["clean"] A list of pathnames to be deleted when the
@DFlag{clean} or @Flag{c} flag is passed to @exec{raco setup}. 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 @filepath{compiled}
subdirectory, and all of the files in the platform-specific
subdirectory of the compiled directory for the current platform.
Just as compiling @filepath{.zo} files will compile each module
used by a compiled module, deleting a module's compiled image will
delete the @filepath{.zo} of each module that is used by the
module. More specifically, used modules are determined when
deleting a @filepath{.dep} file, which would have been created to
accompany a @filepath{.zo} file when the @filepath{.zo} was built
by @exec{raco setup} or @exec{raco make} (see
@secref["Dependency\x20Files"]). If the @filepath{.dep} file
indicates another module, that module's @filepath{.zo} is deleted
only if it also has an accompanying @filepath{.dep} file. In that
case, the @filepath{.dep} file is deleted, and additional used
modules are deleted based on the used module's @filepath{.dep}
file, etc. Supplying a specific list of collections to @exec{raco
setup} disables this dependency-based deletion of compiled files.}
@item{@racket[compile-omit-paths], @racket[compile-omit-files], and
@racket[compile-include-files] --- Used indirectly via
@racket[compile-collection-zos].}
@item{@racket[module-suffixes] and @racket[doc-module-suffixes] ---
Used indirectly via @racket[get-module-suffixes].}
]
@; ------------------------------------------------------------------------
@include-section["info.scrbl"]
@; ------------------------------------------------------------------------
@section[#:tag "setup-check-deps"]{Package Dependency Checking}
When @exec{raco setup} is run with no arguments,@margin-note*{Unless
@DFlag{check-pkg-deps} is specified, dependency checking is disabled
if any collection is specified for @exec{raco setup}.} after building
all collections and documentation, @exec{raco setup} checks package
dependencies. Specifically, it inspects compiled files and
documentation to check that references across package boundaries are
reflected by dependency declarations in each package-level
@filepath{info.rkt} file (see @secref[#:doc pkg-doc "metadata"]).
Dependency checking in @exec{raco setup} is intended as an aid to
package developers to help them declare dependencies correctly. The
@exec{raco setup} process itself does not depend on package dependency
declarations. Similarly, a package with a missing dependency
declaration may install successfully for other users, as long as they
happen to have the dependencies installed already. A missing
dependency creates trouble for others who install a package without
having the dependency installed already.
Practically every package depends on the @filepath{base} package,
which includes the collections that are in a minimal variant of
Racket. Declaring a dependency on @filepath{base} may seem
unnecessary, since its collections are always installed. In a future
version of Racket, however, the minimal collections may change, and
the new set of minimal collections will then have a package name, such
as @filepath{base2}. Declaring a dependency on @filepath{base} ensures
forward compatibility, and @exec{raco setup} complains if the
declaration is missing.
To accommodate the early stages of package development, missing
dependencies are not treated as an error for a package that has no
dependency declarations.
@subsection{Declaring Build-Time Dependencies}
A build-time dependency is one that is not present in a package if it
is converted to a @tech[#:doc pkg-doc]{binary package} (see
@secref[#:doc pkg-doc "strip"]). For example, @filepath{tests} and
@filepath{scribblings} directories are stripped away in a binary
package by default, so cross-package references from directories with
those names are treated as build dependencies. Similarly,
@racketidfont{test} and @racketidfont{doc} submodules are stripped
away, so references within those submodules create build dependencies.
Build-time-only dependencies can be listed as @racket[build-deps]
instead of @racket[deps] in a package's @filepath{info.rkt} file.
Dependencies listed in @racket[deps], meanwhile, are treated as both
run-time and build-time dependencies. The advantage of using
@racket[build-deps], instead of listing all dependencies in
@racket[deps], is that a binary version of the package can install
with fewer dependencies.
@subsection{How Dependency Checking Works}
Dependency checking uses @filepath{.zo} files, associated
@filepath{.dep} files (see @secref["Dependency Files"]), and the
documentation index. Dynamic references, such as through
@racket[dynamic-require], are not visible to the dependency checker;
only dependencies via @racket[require],
@racket[define-runtime-module-path-index], and other forms that
cooperate with @racket[raco make] are visible for dependency checking.
Dependency checking is sensitive to whether a dependency is needed
only as a build-time dependency. If @exec{raco setup} detects that a
missing dependency could be added as a build-time dependency, it will
suggest the addition, but @exec{raco setup} will not suggest
converting a normal dependency to a build-time dependency (since every
normal dependency counts as a build-time dependency, too).
@; ------------------------------------------------------------------------
@section[#:tag "setup-plt-plt"]{API for Setup}
@defmodule[setup/setup]
@defproc[(setup [#:file file (or/c #f path-string?) #f]
[#:collections collections (or/c #f (listof (listof path-string?))) #f]
[#:planet-specs planet-specs (or/c #f
(listof (list/c string?
string?
exact-nonnegative-integer?
exact-nonnegative-integer?)))
#f]
[#:make-user? make-user? any/c #t]
[#:avoid-main? avoid-main? any/c #f]
[#:make-docs? make-docs? any/c #t]
[#:make-doc-index? make-doc-index? any/c #f]
[#:force-user-docs? force-user-docs? any/c #f]
[#:clean? clean? any/c #f]
[#:tidy? tidy? any/c #f]
[#:jobs jobs exact-nonnegative-integer? #f]
[#:fail-fast? fail-fast? any/c #f]
[#:get-target-dir get-target-dir (or/c #f (-> path-string?)) #f])
boolean?]{
Runs @exec{raco setup} with various options:
@itemlist[
@item{@racket[file] --- if not @racket[#f], installs @racket[file] as
a @filepath{.plt} archive.}
@item{@racket[collections] --- if not @racket[#f], constrains setup to
the named collections, along with @racket[planet-specs], if any}
@item{@racket[planet-spec] --- if not @racket[#f], constrains setup to
the named @|PLaneT| packages, along with @racket[collections], if any}
@item{@racket[make-user?] --- if @racket[#f], disables any
user-specific setup actions}
@item{@racket[avoid-main?] --- if true, avoids setup actions that affect
the main installation, as opposed to user directories}
@item{@racket[make-docs?] --- if @racket[#f], disables any
documentation-specific setup actions}
@item{@racket[make-doc-index?] --- if true, builds
documentation index collections in addition to @racket[collections],
assuming that documentation is built}
@item{@racket[force-user-docs?] --- if true, then when building
documentation, creates a user-specific documentation entry point
even if it has the same content as the installation}
@item{@racket[clean?] --- if true, enables cleaning mode instead of setup mode}
@item{@racket[tidy?] --- if true, enables global tidying of
documentation and metadata indexes even when @racket[collections]
or @racket[planet-specs] is non-@racket[#f]}
@item{@racket[jobs] --- if not @racket[#f], determines the maximum number of parallel
tasks used for setup}
@item{@racket[fail-fast?] --- if true, breaks the current thread as soon as an
error is discovered}
@item{@racket[get-target-dir] --- if not @racket[#f], treated as a
value for @sigelem[setup-option^ current-target-directory-getter]}
]
The result is @racket[#t] if @exec{raco setup} completes without error,
@racket[#f] otherwise.
Instead of using @envvar{PLT_COMPILED_FILE_CHECK}, @racket[setup] is
sensitive to the @racket[use-compiled-file-check] parameter.
@history[#:changed "6.1" @elem{Added the @racket[fail-fast?] argument.}
#:changed "6.1.1" @elem{Added the @racket[force-user-docs?] argument.}]}
@subsection{@exec{raco setup} Unit}
@defmodule[setup/setup-unit]
The @racketmodname[setup/setup-unit] library provides @exec{raco setup} in unit
form. The associated @racket[setup/option-sig] and
@racket[setup/option-unit] libraries provides the interface for
setting options for the run of @exec{raco setup}.
For example, to unpack a single @filepath{.plt} archive
@filepath{x.plt}, set the @sigelem[setup-option^ archives] parameter
to @racket[(list "x.plt")] and leave @sigelem[setup-option^
specific-collections] as @racket[null].
Link the options and setup units so that your option-setting code is
initialized between them, e.g.:
@racketblock[
(compound-unit
_...
(link _...
[((OPTIONS : setup-option^)) setup:option@]
[() my-init-options@ OPTIONS]
[() setup@ OPTIONS _...])
_...)
]
@defthing[setup@ unit?]{
Imports
@itemize[#:style "compact"]{
@item{@racket[setup-option^]}
@item{@racket[compiler^]}
@item{@racket[compiler:option^]}
@item{@racket[launcher^]}
@item{@racket[dynext:file^]}
}
and exports nothing. Invoking @racket[setup@] starts the setup process.}
@; ----------------------------------------
@subsection[#:tag "setup-plt-options"]{Options Unit}
@defmodule[setup/option-unit]
@defthing[setup:option@ unit?]{
Imports nothing and exports @racket[setup-option^].}
@; ----------------------------------------
@subsection{Options Signature}
@defmodule[setup/option-sig]
@defsignature[setup-option^ ()]{
@signature-desc{Provides parameters used to control @exec{raco setup} in unit
form.}
@defparam[setup-program-name name string?]{
The prefix used when printing status messages.
@defaults[@racket["raco setup"]]
}
@defboolparam[verbose on?]{
If on, prints messages from @exec{make} to @envvar{stderr}.
@defaults[@racket[#f]]}
@defboolparam[make-verbose on?]{
If on, verbose @exec{make}. @defaults[@racket[#f]]}
@defboolparam[compiler-verbose on?]{
If on, verbose @exec{compiler}. @defaults[@racket[#f]]}
@defboolparam[clean on?]{
If on, delete @filepath{.zo} and
@filepath{.so}/@filepath{.dll}/@filepath{.dylib} files in the
specified collections. @defaults[@racket[#f]]}
@defparam[compile-mode path (or/c path? #f)]{
If a @racket[path] is given, use a @filepath{.zo} compiler other than plain
@exec{compile}, and build to @racket[(build-path "compiled" (compile-mode))].
@defaults[@racket[#f]]}
@defboolparam[make-zo on?]{
If on, compile @filepath{.zo}. @defaults[@racket[#t]]}
@defboolparam[make-info-domain on?]{
If on, update @filepath{info-domain/compiled/cache.rkt} for each
collection path. @defaults[@racket[#t]]}
@defboolparam[make-launchers on?]{
If on, make collection @filepath{info.rkt}-specified launchers and @tt{man} pages. @defaults[@racket[#t]]}
@defboolparam[make-foreign-lib on?]{
If on, install collection @filepath{info.rkt}-specified libraries. @defaults[@racket[#t]]}
@defboolparam[make-docs on?]{
If on, build documentation.
@defaults[@racket[#t]]
}
@defboolparam[make-user on?]{
If on, build the user-specific collection tree.
@defaults[@racket[#t]]
}
@defboolparam[make-planet on?]{
If on, build the planet cache.
@defaults[@racket[#t]]
}
@defboolparam[avoid-main-installation on?]{
If on, avoid building bytecode in the main installation tree when building
other bytecode (e.g., in a user-specific collection). @defaults[@racket[#f]]}
@defboolparam[make-tidy on?]{
If on, remove metadata cache information and
documentation for non-existent collections (to clean up after removal)
even when @racket[specific-collections] or @racket[specific-planet-dirs]
is non-@racket['()] or @racket[make-only] is true. @defaults[@racket[#f]]}
@defboolparam[call-install on?]{
If on, call collection @filepath{info.rkt}-specified setup code.
@defaults[@racket[#t]]}
@defboolparam[call-post-install on?]{
If on, call collection @filepath{info.rkt}-specified post-install code.
@defaults[@racket[#t]]}
@defboolparam[pause-on-errors on?]{
If on, in the event of an error, prints a summary error and waits for
@envvar{stdin} input before terminating. @defaults[@racket[#f]]}
@defparam[parallel-workers num exact-nonnegative-integer?]{
Determines the number of places to use for compiling bytecode
and for building the documentation.
@defaults[@racket[(min (processor-count) 8)]]
}
@defboolparam[fail-fast on?]{
If on, breaks the original thread as soon as an error is discovered.
@defaults[@racket[#f]]
@history[#:added "1.2"]}
@defboolparam[force-unpacks on?]{
If on, ignore version and already-installed errors when unpacking a
@filepath{.plt} archive. @defaults[@racket[#f]]}
@defparam[specific-collections colls (listof (listof path-string?))]{
A list of collections to set up; the empty list means set-up all
collections if the archives list and @racket[specific-planet-dirs]
is also @racket['()]. @defaults[@racket['()]]}
@defparam[specific-planet-dirs dir (listof (list/c string?
string?
exact-nonnegative-integer?
exact-nonnegative-integer?))]{
A list of planet package version specs to set up; the empty list means to
set-up all planet collections if the archives list and @racket[specific-collections]
is also @racket['()]. @defaults[@racket['()]]
}
@defboolparam[make-only on?]{
If true, set up no collections if @racket[specific-collections]
and @racket[specific-planet-dirs] are both @racket['()].}
@defparam[archives arch (listof path-string?)]{
A list of @filepath{.plt} archives to unpack; any collections specified
by the archives are set-up in addition to the collections listed in
specific-collections. @defaults[@racket[null]]}
@defboolparam[archive-implies-reindex on?]{
If on, when @racket[archives] has a non-empty list of packages, if any
documentation is built, then suitable documentation start pages, search pages,
and master index pages are rebuilt. @defaults[@racket[#t]]}
@defparam[current-target-directory-getter thunk (-> path-string?)]{
A thunk that returns the target directory for unpacking a relative
@filepath{.plt} archive; when unpacking an archive, either this or
the procedure in @racket[current-target-plt-directory-getter] will
be called. @defaults[@racket[current-directory]]}
@defparam[current-target-plt-directory-getter
proc (path-string?
path-string?
(listof path-string?) . -> . path-string?)]{
A procedure that takes a preferred path, a path to the parent of the main
@filepath{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 @racket[current-target-directory-getter] will
be called, and in the former case, this procedure may be called
multiple times. @defaults[@racket[(lambda (preferred main-parent-dir choices) preferred)]]}
}
@; ------------------------------------------------------------------------
@section[#:tag ".plt-archives"]{API for Installing @filepath{.plt} Archives}
The @racketmodname[setup/plt-single-installer] module provides a
function for installing a single @filepath{.plt} file.
@subsection{Non-GUI Installer}
@local-module[setup/plt-single-installer]{
@defmodule[setup/plt-single-installer]
@defproc[(run-single-installer
(file path-string?)
(get-dir-proc (-> (or/c path-string? #f)))
[#:show-beginning-of-file? show-beginning-of-file? any/c #f])
void?]{
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
(see @secref[#:doc ref-src]{custodians}) 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 @racket[get-dir-proc] procedure is called if the installer needs a
target directory for installation, and a @racket[#f] result means that
the user canceled the installation. Typically, @racket[get-dir-proc] is
@racket[current-directory].
If @racket[show-beginning-of-file?] is a true value and the installation
fails, then @racket[run-single-installer] prints the first 1,000 characters
of the file (in an attempt to help debug the cause of failures).
}
@defproc[(install-planet-package [file path-string?]
[directory path-string?]
[spec (list/c string? string?
(listof string?)
exact-nonnegative-integer?
exact-nonnegative-integer?)])
void?]{
Similar to @racket[run-single-installer], but runs the setup process
to install the archive @racket[file] into @racket[directory] as the
@|PLaneT| package described by @racket[spec]. The user-specific
documentation index is not rebuilt, so @racket[reindex-user-documentation]
should be run after a set of @|PLaneT| packages are installed.}
@defproc[(reindex-user-documentation) void?]{
Similar to @racket[run-single-installer], but runs only the part of
the setup process that rebuilds the user-specific documentation
start page, search page, and master index.}
@defproc[(clean-planet-package [directory path-string?]
[spec (list/c string? string?
(listof string?)
exact-nonnegative-integer?
exact-nonnegative-integer?)])
void?]{
Undoes the work of @racket[install-planet-package]. The user-specific
documentation index is not rebuilt, so @racket[reindex-user-documentation]
should be run after a set of @|PLaneT| packages are removed.}}
@; ----------------------------------------------------------
@section[#:tag "dirs"]{API for Finding Installation Directories}
@defmodule[setup/dirs]{
The @racketmodname[setup/dirs] library provides several procedures for locating
installation directories:}
@defproc[(find-collects-dir) (or/c path? #f)]{
Returns a path to the installation's main @filepath{collects} directory, or
@racket[#f] if none can be found. A @racket[#f] result is likely only
in a stand-alone executable that is distributed without libraries.}
@defproc[(find-user-collects-dir) path?]{
Returns a path to the user-specific @filepath{collects} directory; the
directory indicated by the returned path may or may not exist.}
@defproc[(get-collects-search-dirs) (listof path?)]{
Returns the same result as @racket[(current-library-collection-paths)],
which means that this result is not sensitive to the value of the
@racket[use-user-specific-search-paths] parameter.}
@defproc[(get-main-collects-search-dirs) (listof path?)]{
Returns a list of paths to installation @filepath{collects}
directories, including the result of @racket[find-collects-dir].
These directories are normally included in the result of
@racket[(current-library-collection-paths)], but a
@envvar{PLTCOLLECTS} setting or change to the parameter may cause
them to be omitted. Any other path in
@racket[(current-library-collection-paths)] is treated as
user-specific. The directories indicated by the returned paths may
or may not exist.}
@defproc[(find-config-dir) (or/c path? #f)]{
Returns a path to the installation's @filepath{etc} directory, which
contains configuration and package information---including
configuration of some of the other directories (see @secref["config-file"]).
A @racket[#f] result indicates that no configuration directory
is available.}
@defproc[(find-links-file) path?]{
Returns a path to the installation's @tech[#:doc
reference-doc]{collection links file}. The file indicated by the
returned path may or may not exist.}
@defproc[(find-user-links-file [vers string? (get-installation-name)]) path?]{
Returns a path to the user's @tech[#:doc reference-doc]{collection
links file}. The file indicated by the returned path may or may not
exist.}
@defproc[(get-links-search-files) path?]{
Returns a list of paths to installation @tech[#:doc
reference-doc]{collection links files} to search in
order. (Normally, the result includes the result of
@racket[(find-links-file)], which is where new installation-wide
links are installed by @exec{raco link} or @racket[links].) The
files indicated by the returned paths may or may not exist.}
@defproc[(find-pkgs-dir) path?]{
Returns a path to the directory containing packages with
installation scope; the directory indicated by the returned path may
or may not exist.}
@defproc[(find-user-pkgs-dir [vers string? (get-installation-name)]) path?]{
Returns a path to the directory containing packages with
user-specific scope for installation name @racket[vers]; the directory indicated by
the returned path may or may not exist.}
@defproc[(get-pkgs-search-dirs) (listof path?)]{
Returns a list of paths to the directories containing packages in
installation scope. (Normally, the result includes the result of
@racket[(find-pkgs-dir)], which is where new packages are installed
by @exec{raco pkg install}.) The directories indicated by the returned
paths may or may not exist.}
@defproc[(find-doc-dir) (or/c path? #f)]{
Returns a path to the installation's @filepath{doc} directory.
The result is @racket[#f] if no such directory is available.}
@defproc[(find-user-doc-dir) path?]{
Returns a path to a user-specific @filepath{doc} directory. The directory
indicated by the returned path may or may not exist.}
@defproc[(get-doc-search-dirs) (listof path?)]{
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-@racket[#f] result of
@racket[(find-doc-dir)] and @racket[(find-user-doc-dir)]---but the latter is
included only if the value of the @racket[use-user-specific-search-paths]
parameter is @racket[#t].}
@defproc[(find-lib-dir) (or/c path? #f)]{
Returns a path to the installation's @filepath{lib} directory, which contains
libraries and other build information. The result is @racket[#f] if no such
directory is available.}
@defproc[(find-user-lib-dir) path?]{
Returns a path to a user-specific @filepath{lib} directory; the directory
indicated by the returned path may or may not exist.}
@defproc[(get-lib-search-dirs) (listof path?)]{
Returns a list of paths to search for foreign libraries. Unless it is
configured otherwise, the result includes any non-@racket[#f] result of
@racket[(find-lib-dir)]
and @racket[(find-user-lib-dir)]---but the latter is included only if the
value of the @racket[use-user-specific-search-paths] parameter
is @racket[#t].
@history[#:changed "6.1.1.4" @elem{Dropped @racket[(find-dll-dir)]
from the set of paths to
explicitly include in the
default.}]}
@defproc[(find-dll-dir) (or/c path? #f)]{
Returns a path to the directory that contains DLLs for use with the
current executable (e.g., @filepath{libracket.dll} on Windows).
The result is @racket[#f] if no such directory is available, or if no
specific directory is available (i.e., other than the platform's normal
search path).}
@defproc[(find-share-dir) (or/c path? #f)]{ Returns a path to the
installation's @filepath{share} directory, which contains installed
packages and other platform-independent files. The result is
@racket[#f] if no such directory is available.}
@defproc[(find-user-share-dir) path?]{
Returns a path to a user-specific @filepath{share} directory; the directory
indicated by the returned path may or may not exist.}
@defproc[(find-include-dir) (or/c path? #f)]{
Returns a path to the installation's @filepath{include} directory, which
contains @filepath{.h} files for building Racket extensions and embedding
programs. The result is @racket[#f] if no such directory is available.}
@defproc[(find-user-include-dir) path?]{
Returns a path to a user-specific @filepath{include} directory; the
directory indicated by the returned path may or may not exist.}
@defproc[(get-include-search-dirs) (listof path?)]{
Returns a list of paths to search for @filepath{.h} files. Unless it is
configured otherwise, the result includes any non-@racket[#f] result of
@racket[(find-include-dir)] and @racket[(find-user-include-dir)]---but the
latter is included only if the value of the
@racket[use-user-specific-search-paths] parameter is @racket[#t].}
@defproc[(find-console-bin-dir) (or/c path? #f)]{
Returns a path to the installation's executable directory, where the
stand-alone Racket executable resides. The result is @racket[#f] if no
such directory is available.}
@defproc[(find-gui-bin-dir) (or/c path? #f)]{
Returns a path to the installation's executable directory, where the
stand-alone GRacket executable resides. The result is @racket[#f] if no such
directory is available.}
@defproc[(find-user-console-bin-dir) path?]{
Returns a path to the user's executable directory; the directory
indicated by the returned path may or may not exist.}
@defproc[(find-user-gui-bin-dir) path?]{
Returns a path to the user's executable directory for graphical
programs; the directory indicated by the returned path may or may
not exist.}
@defproc[(find-apps-dir) (or/c path? #f)]{
Returns a path to the installation's directory @filepath{.desktop}
files (for Unix). The result is @racket[#f] if no such directory
exists.}
@defproc[(find-user-apps-dir) path?]{
Returns a path to the user's directory for @filepath{.desktop} files
(for Unix); the directory indicated by the returned path may or may
not exist.}
@defproc[(find-man-dir) (or/c path? #f)]{
Returns a path to the installation's man-page directory. The result is
@racket[#f] if no such directory exists.}
@defproc[(find-user-man-dir) path?]{
Returns a path to the user's man-page directory; the directory
indicated by the returned path may or may not exist.}
@defproc[(get-doc-search-url) string?]{
Returns a string that is used by the documentation system, augmented
with a version and search-key query, for remote documentation links.}
@defproc[(get-doc-open-url) (or/c string? #f)]{
Returns @racket[#f] or a string for a root URL to be used as an
alternative to opening a local file for documentation. A
non-@racket[#f] configuration means that DrRacket, for example,
performs keyword searches for documentation via the specified URL
instead of from locally installed documentation.
@history[#:added "6.0.1.6"]}
@defproc[(get-installation-name) string?]{ Returns the current
installation's name, which is often @racket[(version)] but can be
configured via @racket['installation-name] in @filepath{config.rktd}
(see @secref["config-file"]).}
@defproc[(get-build-stamp) (or/c #f string?)]{ Returns a string
that identifies an installation build, which can be used to augment
the Racket version number to more specifically identify the
build. An empty string is normally produced for a release build.
The result is @racket[#f] if no build stamp is available.}
@defproc[(get-absolute-installation?) boolean?]{
Returns @racket[#t] if this installation uses
absolute path names for executable and library references,
@racket[#f] otherwise.}
@deftogether[(
@defproc[(find-addon-tethered-console-bin-dir) (or/c #f path?)]
@defproc[(find-addon-tethered-gui-bin-dir) (or/c #f path?)]
)]{
Returns a path to a user-specific directory to hold an extra copy of
each installed executable, where the extra copy is created by
@exec{raco setup} and tethered to a particular result for
@racket[(find-system-path 'addon-dir)] and
@racket[(find-config-dir)].
Unlike other directories, which are configured via
@filepath{config.rktd} in the @racket[(find-config-dir)] directory
(see @secref["config-file"]), these paths are configured via
@racket['addon-tethered-console-bin-dir] and
@racket['addon-tethered-gui-bin-dir] entries in
@filepath{config.rktd} in @racket[(build-path (find-system-path
'addon-dir) "etc")]. If no configuration is present, the result from
the corresponding function,
@racket[find-addon-tethered-console-bin-dir] or
@racket[find-addon-tethered-gui-bin-dir], is @racket[#f] instead of
a path.
The intent of this protocol is to support a kind of sandbox: an
installation that is more specific than user-specific, and where
copies of executables such as @exec{racket} serve as entry points
into the sandbox. Assuming that the addon directory is set to a
directory other than the user's default addon directory when
@exec{raco setup} creates the executable copies, then further
package build and setup operations through the entry points will be
confined to the sandbox and not affect a user's default environment.
@history[#:added "6.5.0.2"]}
@deftogether[(
@defproc[(find-config-tethered-console-bin-dir) (or/c #f path?)]
@defproc[(find-config-tethered-gui-bin-dir) (or/c #f path?)]
)]{
Similar to @racket[find-addon-tethered-console-bin-dir] and
@racket[find-addon-tethered-gui-bin-dir], but configured via
@filepath{config.rktd} in the @racket[(find-config-dir)] directory
(see @secref["config-file"]) and triggers executables that are
tethered only to a particular value of @racket[(find-config-dir)].
@history[#:added "6.5.0.2"]}
@; ------------------------------------------------------------------------
@section[#:tag "getinfo"]{API for Reading @filepath{info.rkt} Files}
@defmodule[setup/getinfo]{ The @racketmodname[setup/getinfo] library
provides functions for accessing fields in @filepath{info.rkt}
files. The file format for @filepath{info.rkt} files is documented
in @secref["info.rkt" #:doc '(lib "scribblings/raco/raco.scrbl")].
}
@defproc[(get-info [collection-names (listof string?)]
[#:namespace namespace (or/c namespace? #f) #f]
[#:bootstrap? bootstrap? any/c #f])
(or/c
(symbol? [(-> any)] . -> . any)
#f)]{
Accepts a list of strings naming a collection or sub-collection,
and calls @racket[get-info/full] with the full path corresponding to the
named collection and the @racket[namespace] argument.}
@defproc[(get-info/full [path path-string?]
[#:namespace namespace (or/c namespace? #f) #f]
[#:bootstrap? bootstrap? any/c #f])
(or/c (->* (symbol?) ((-> any)) any)
#f)]{
Accepts a path to a directory. If it finds either a well-formed
@filepath{info.rkt} file or an @filepath{info.ss} file (with
preference for the @filepath{info.rkt} file),
it returns an info procedure that accepts either 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 @filepath{info.rkt} file, if the name is defined. The optional
second argument, @racket[_thunk], is a procedure that takes no
arguments to be called when the name is not defined; the result of
the info procedure is the result of the @racket[_thunk] in that
case. If the name is not defined and no @racket[_thunk] is
provided, then an exception is raised.
The @racket[get-info/full] function returns @racket[#f] if there is
no @filepath{info.rkt} (or @filepath{info.ss}) file in the directory. If there is a
@filepath{info.rkt} (or @filepath{info.ss}) file that has the wrong shape (i.e., not a module
using @racketmodname[info] or @racketmodname[setup/infotab]),
or if the @filepath{info.rkt} file fails to load, then an exception
is raised. If the @filepath{info.rkt} file loaded, @racket[get-info/full]
returns the @racket[get-info] file. If the @filepath{info.rkt} file does not exist,
then @racket[get-info/full] does
the same checks for the @filepath{info.ss} file, either raising an exception
or returning the @racket[get-info] function from the @filepath{info.ss} file.
The @filepath{info.rkt} (or @filepath{info.ss}) module is loaded
into @racket[namespace] if it is not @racket[#f], or a private,
weakly-held namespace otherwise.
If @racket[bootstrap?] is true, then
@racket[use-compiled-file-paths] is set to @racket['()] while
reading @filepath{info.rkt} (or @filepath{info.ss}), in case an
existing compiled file is broken. Furthermore, the
@racketmodname[info] and @racketmodname[setup/infotab] modules are
attached to @racket[namespace] from the namespace of
@racket[get-info/full] before attempting to load
@filepath{info.rkt} (or @filepath{info.ss}).
As the module is loaded, the @tech[#:doc reference-doc]{environment variable set}
is pruned to contain only environment variables that are listed in the
@envvar{PLT_INFO_ALLOW_VARS} environment variable, which contains a
@litchar{;}-separated list of names. By default, the list of allowed
variable names is empty.
@history[#:changed "6.5.0.2" @elem{Added environment-variable
pruning and @envvar{PLT_INFO_ALLOW_VARS} support.}]}
@defproc[(find-relevant-directories
(syms (listof symbol?))
(mode (or/c 'preferred 'all-available 'no-planet 'no-user) 'preferred))
(listof path?)]{
Returns a list of paths identifying
collections and installed @|PLaneT| packages whose
@filepath{info.rkt} file defines one or more of the given
symbols. The result is based on a cache that is computed by
@exec{raco setup}.
Note that the cache may be out of date by the time you call
@racket[get-info/full], so do not assume that every returned
directory's @filepath{info.rkt} file will supply one of the
requested symbols.
The result is in a canonical order (sorted lexicographically by
directory name), and the paths it returns are suitable for
providing to @racket[get-info/full].
If @racket[mode] is specified, it must be either
@racket['preferred] (the default), @racket['all-available],
@racket['no-planet], or @racket['no-user]. If @racket[mode] is
@racket['all-available], @racket[find-relevant-directories] returns
all installed directories whose info files contain the specified
symbols---for instance, all versions of all installed PLaneT
packages will be searched if @racket['all-available] is
specified. If @racket[mode] is @racket['preferred], then only a
subset of ``preferred'' packages will be searched: only the
directory containing the most recent version of any PLaneT package
will be returned. If @racket[mode] is @racket['no-planet], then
PLaneT packages are not included in the search. If @racket[mode] is
@racket['no-user], then only installation-wide directories are
searched, which means omitting @|PLaneT| package directories.
Collection links from the installation-wide @tech[#:doc
reference-doc]{collection links file} or packages with installation
scope are cached with the installation's main @filepath{lib}
directory, and links from the user-specific @tech[#:doc
reference-doc]{collection links file} and packages are cached with
the user-specific directory @racket[(build-path (find-system-path
'addon-dir) "collects")] for all-version cases, and in @racket[(build-path
(find-system-path 'addon-dir) (version) "collects")] for
version-specific cases.}
@defproc[(find-relevant-directory-records
[syms (listof symbol?)]
[key (or/c 'preferred 'all-available 'no-planet 'no-user)])
(listof directory-record?)]{
Like @racket[find-relevant-directories], but returns @racket[directory-record] structs
instead of @racket[path?]s.
}
@defstruct[directory-record ([maj integer?]
[min integer?]
[spec any/c]
[path path?]
[syms (listof symbol?)])]{
A struct that records information about a collection or a @PLaneT package that has been installed.
Collections will have the major version being @racket[1] and the minor version being @racket[0].
The @racket[spec] field is a quoted module spec; the @racket[path] field is where the @tt{info.rkt}
file for this collection or @PLaneT package exists on the filesystem; the @racket[syms] field holds the
identifiers defined in that file.
}
@defproc[(reset-relevant-directories-state!) void?]{
Resets the cache used by @racket[find-relevant-directories].}
@; ------------------------------------------------------------------------
@section[#:tag "relative-paths"]{API for Relative Paths}
The Racket installation tree can usually be moved around the filesystem.
To support this, care must be taken to avoid absolute paths. The
following two APIs cover two aspects of this: a way to convert a path to
a value that is relative to the @filepath{collects} tree, and a way to
display such paths (e.g., in error messages).
@subsection{Representing Collection-Based Paths}
@defmodule[setup/collects]
@defproc[(path->collects-relative [path path-string?]
[#:cache cache (or/c #f (and/c hash? (not/c immutable?)))])
(or/c path-string?
(cons/c 'collects
(cons/c bytes? (non-empty-listof bytes?))))]{
Checks whether @racket[path] (normalized by
@racket[path->complete-path] and @racket[simplify-path] with
@racket[#f] as its second argument) matches the result of
@racket[collection-file-path]. If so, the result is a list starting
with @racket['collects] and containing the relevant path elements as
byte strings. If not, the path is returned as-is.
The @racket[cache] argument is used with @racket[path->pkg], if needed.}
@defproc[(collects-relative->path
[rel (or/c path-string?
(cons/c 'collects
(cons/c bytes? (non-empty-listof bytes?))))])
path-string?]{
The inverse of @racket[path->collects-relative]: if @racket[rel]
is a pair that starts with @racket['collects], then it is converted
back to a path using @racket[collection-file-path].}
@defproc[(path->module-path [path path-string?]
[#:cache cache (or/c #f (and/c hash? (not/c immutable?)))])
(or/c path-string? module-path?)]{
Like @racket[path->collects-relative], but the result is either
@racket[path] or a normalized (in the sense of
@racket[collapse-module-path]) module path.}
@subsection{Representing Paths Relative to @filepath{collects}}
@defmodule[setup/main-collects]
@defproc[(path->main-collects-relative [path (or/c bytes? path-string?)])
(or/c path? (cons/c 'collects (non-empty-listof bytes?)))]{
Checks whether @racket[path] has a prefix that matches the prefix to
the main @filepath{collects} directory as determined by
@racket[(find-collects-dir)]. If so, the result is a list starting
with @racket['collects] and containing the remaining path elements as
byte strings. If not, the path is returned as-is.
The @racket[path] argument should be a complete path. Applying
@racket[simplify-path] before @racket[path->main-collects-relative] is
usually a good idea.
For historical reasons, @racket[path] can be a byte string, which is
converted to a path using @racket[bytes->path].
See also @racket[collects-relative->path].}
@defproc[(main-collects-relative->path
[rel (or/c bytes?
path-string?
(cons/c 'collects (non-empty-listof bytes?)))])
path>]{
The inverse of @racket[path->main-collects-relative]: if @racket[rel]
is a pair that starts with @racket['collects], then it is converted
back to a path relative to @racket[(find-collects-dir)].}
@subsection{Representing Paths Relative to the Documentation}
@defmodule[setup/main-doc]
@defproc[(path->main-doc-relative [path (or/c bytes? path-string?)])
(or/c path? (cons/c 'doc (non-empty-listof bytes?)))]{
Like @racket[path->main-collects-relative], except that it checks
for a prefix relative to @racket[(find-doc-dir)] and returns a list
starting with @racket['doc] if so.
}
@defproc[(main-doc-relative->path
[rel (or/c bytes?
path-string?
(cons/c 'doc (non-empty-listof bytes?)))])
path>]{
Like @racket[path->main-collects-relative], except it is the inverse
of @racket[path->main-doc-relative].
}
@subsection{Displaying Paths Relative to a Common Root}
@defmodule[setup/path-to-relative]
@defproc[(path->relative-string/library
[path path-string?]
[default (or/c (-> path-string? any/c) any/c)
(lambda (x) (if (path? x) (path->string x) x))]
[#:cache cache (or/c #f (and/c hash? (not/c immutable?))) #f])
any/c]{
Produces a string suitable for display in error messages. If the path
is an absolute one that is inside a package, the
result is a string that begins with @racket["<pkgs>/"]. If the path
is an absolute one that is inside the @filepath{collects} tree, the
result is a string that begins with @racket["<collects>/"].
Similarly, a path in the user-specific collects results in a prefix of
@racket["<user-collects>/"], a @PLaneT path results in
@racket["<planet>/"], and a path into documentation results in
@racket["<doc>/"] or @racket["<user-doc>/"].
If @racket[cache] is not @racket[#f], it is used as a cache argument
for @racket[pkg->path] to speed up detection and conversion of
package paths.
If the path is not absolute, or if it is not in any of these, it is
returned as-is (converted to a string if needed). If @racket[default]
is given, it specifies the return value instead: it can be a procedure
that is applied onto the path to get the result, or the result
itself.
Note that this function can return a non-string only if
@racket[default] is given and it does not return a string.
}
@defproc[(path->relative-string/setup
[path path-string?]
[default (or/c (-> path-string? any/c) any/c)
(lambda (x) (if (path? x) (path->string x) x))]
[#:cache cache (or/c #f (and/c hash? (not/c immutable?))) #f])
any/c]{
The same as @racket[path->relative-string/library], for backward
compatibility.}
@defproc[(make-path->relative-string
[dirs (listof (cons (-> path?) string?))]
[default (or/c (-> path-string? any/c) any/c)
(lambda (x) (if (path? x) (path->string x) x))])
(path-string? any/c . -> . any)]{
This function produces functions like
@racket[path->relative-string/library] and
@racket[path->relative-string/setup].
The @racket[dirs] argument determines the prefix substitutions. It must be an
association list mapping a path-producing thunk to a prefix string for
paths in the specified path.
@racket[default] determines the default for the resulting function
(which can always be overridden by an additional argument to this
function).
}
@; ------------------------------------------------------------------------
@section[#:tag "collection-names"]{API for Collection Names}
@defmodule[setup/collection-name]
@defproc[(collection-name? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a string that is syntactically
valid as a collection name, which means that it is one or more
@litchar{/}-separated strings for which
@racket[collection-name-element?] returns true.}
@defproc[(collection-name-element? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a string that is syntactically
valid as a top-level collection name or as a part of a collection
name, which means that it is non-empty and contains only ASCII
letters, ASCII digits, @litchar{-}, @litchar{+}, @litchar{_}, and
@litchar{%}, where a @litchar{%} is allowed only when followed by two
lowercase hexadecimal digits, and the digits must form a number that
is not the ASCII value of a letter, digit, @litchar{-}, @litchar{+},
or @litchar{_}.}
@; ------------------------------------------------------------------------
@section[#:tag "collection-search"]{API for Collection Searches}
@defmodule[setup/collection-search]
@history[#:added "6.3"]
@defproc[(collection-search [mod-path normalized-lib-module-path?]
[#:init result any/c #f]
[#:combine combine (any/c (and/c path? complete-path?) . -> . any/c) (lambda (r v) v)]
[#:break? break? (any/c . -> . any/c) (lambda (r) #f)]
[#:all-possible-roots? all-possible-roots? any/c #f])
any/c]{
Generalizes @racket[collection-file-path] to support folding over all
possible locations of a collection-based file in the current
configuration. Unlike @racket[collection-file-path],
@racket[collection-search] takes the file to location in module-path
form, but always as a @racket['lib] path.
Each possible path for the file (not counting a @filepath{.ss} to/from
@filepath{.rkt} conversion) is provided as a second argument to the
@racket[combine] function, where the first argument is the current
result, and the value produced by @racket[combine] becomes the new
result. The @racket[#:init] argument provides the initial result.
The @racket[break?] function short-circuits a search based on the
current value. For example, it could be used to short-circuit a search
after a suitable path is found.
If @racket[all-possible-roots?] is @racket[#f], then @racket[combine]
is called only on paths within @filepath{collects}-like directories
(for the current configuration) where at least a matching collection
directory exists.}
@defproc[(normalized-lib-module-path? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a module path (in the sense of
@racket[module-path?]) of the form @racket['(lib _str)] where
@racket[_str] contains at least one slash. The
@racket[collapse-module-path] function produces such module paths for
collection-based module references.}
@; ------------------------------------------------------------------------
@section[#:tag "matching-platform"]{API for Platform Specifications}
@defmodule[setup/matching-platform]
@history[#:added "6.0.1.13"]
@defproc[(platform-spec? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a symbol, string, or regexp value
(in the sense of @racket[regexp?]), @racket[#f] otherwise.}
@defproc[(matching-platform? [spec platform-spec?]
[#:cross? cross? any/c #f]
[#:system-type sys-type (or/c #f symbol?) (if cross?
(cross-system-type)
(system-type))]
[#:system-library-subpath sys-lib-subpath (or/c #f path-for-some-system?)
(if cross?
(cross-system-library-subpath #f)
(system-library-subpath #f))])
boolean?]{
Reports whether @racket[spec] matches @racket[sys-type] or
@racket[sys-lib-subpath], where @racket[#f] values for the latter are
replaced with the default values.
If @racket[spec] is a symbol, then the result is @racket[#t] if
@racket[sys-type] is the same symbol, @racket[#f] otherwise.
If @racket[spec] is a string, then the result is @racket[#t] if
@racket[(path->string sys-lib-subpath)] is the same string,
@racket[#f] otherwise.
If @racket[spec] is a regexp value, then the result is @racket[#t] if
the regexp matches @racket[(path->string sys-lib-subpath)],
@racket[#f] otherwise.
@history[#:changed "6.3" @elem{Added @racket[#:cross?] argument and
changed the contract on @racket[sys-lib-subpath]
to accept @racket[path-for-some-system?]
instead of just @racket[path?].}]}
@; ------------------------------------------------------------------------
@section[#:tag "cross-system"]{API for Cross-Platform Configuration}
@defmodule[setup/cross-system]{The @racketmodname[setup/cross-system]
library provides functions for querying the system properties of a
destination platform, which can be different than the current platform
in cross-installation modes.}
A Racket installation includes a @filepath{system.rktd} file in the
directory reported by @racket[(find-lib-dir)]. When the information in that file
does not match the running Racket's information, then the
@racketmodname[setup/cross-system] module infers that Racket is being
run in cross-installation mode.
For example, if an in-place Racket installation for a different
platform resides at @nonterm{cross-dir}, then
@commandline{racket -G @nonterm{cross-dir}/etc -X @nonterm{cross-dir}/collects -l- raco pkg}
runs @exec{raco pkg} using the current platform's @exec{racket}
executable, but using the collections and other configuration
information of @nonterm{cross-dir}, as well as modifying the packages
of @nonterm{cross-dir}. That can work as long as no platform-specific
libraries need to run to perform the requested @exec{raco pkg} action
(e.g., when installing built packages).
@history[#:added "6.3"]
@defproc[(cross-system-type [mode (or/c 'os 'word 'gc 'link 'machine
'so-suffix 'so-mode 'fs-change)
'os])
(or/c symbol? string? bytes? exact-positive-integer? vector?)]{
Like @racket[system-type], but for the target platform instead of the
current platform in cross-installation mode. When not in
cross-installation mode, the results are the same as for
@racket[system-type].}
@defproc[(cross-system-library-subpath [mode (or/c 'cgc '3m #f)
(system-type 'gc)])
path-for-some-system?]{
Like @racket[system-library-subpath], but for the target platform
instead of the current platform in cross-installation mode. When not
in cross-installation mode, the results are the same as for
@racket[system-library-subpath].
In cross-installation mode, the target platform may have a different
path convention than the current platform, so the result is
@racket[path-for-some-system?] instead of @racket[path?].}
@defproc[(cross-installation?) boolean?]{
Returns @racket[#t] if cross-installation mode has been detected,
@racket[#f] otherwise.}
@; ------------------------------------------------------------------------
@section[#:tag "xref"]{API for Cross-References for Installed Manuals}
@defmodule[setup/xref]
@defproc[(load-collections-xref [on-load (-> any/c) (lambda () (void))])
xref?]{
Like @racket[load-xref], but automatically find all cross-reference files for
manuals that have been installed with @exec{raco setup}.
A cached copy of cross-reference information can be used, in which
case @racket[on-load] is @emph{not} called.}
@defproc[(make-collections-xref [#:no-user? no-user? any/c #f]
[#:no-main? no-main? any/c #f]
[#:doc-db db-path (or/c #f path?) #f]
[#:quiet-fail? quiet-fail? any/c #f]
[#:register-shutdown! register-shutdown! ((-> any) . -> . any) void])
xref?]{
Like @racket[load-collections-xref], but takes advantage of a
cross-reference database @racket[db-path], when support is available,
to delay the loading of cross-reference details until needed.
Cross-reference information is skipped when it is installed in the
main installation or in a user-specific location, respectively, if
@racket[no-main?] or @racket[no-user?] is @racket[#t].
If @racket[quiet-fail?] is true, then errors are suppressed while
loading cross-reference information.
The @racket[register-shutdown!] callback may be called to register a
function that closes database connections when the result of
@racket[make-collections-xref] is no longer needed. If
@racket[register-shutdown!] is not supplied or if a function sent to
@racket[register-shutdown!] is never called, database connections will
be closed only though a @tech[#:doc reference-doc]{custodian}.}
@defproc[(get-rendered-doc-directories [no-user? any/c]
[no-main? any/c])
(listof path?)]{
Returns a list of directories for all documentation for all installed
collections, omitting documentation that is installed in the main
installation or in a user-specific location, respectively, if
@racket[no-main?] or @racket[no-user?] is @racket[#t].}
@defproc[(get-current-doc-state) doc-state?]{
Records the time stamps of files that are touched whenever the
documentation is changed.
@history[#:added "1.2"]
}
@defproc[(doc-state-changed? [doc-state doc-state?]) boolean?]{
Returns @racket[#t] when the time stamps of the files in
@racket[doc-state] changed (or new files appeared) and @racket[#f] otherwise.
If the result is @racket[#t], then the documentation in this installation of
Racket has changed and otherwise it hasn't.
@history[#:added "1.2"]
}
@defproc[(doc-state? [v any/c]) boolean?]{
A predicate to recognize the result of @racket[get-current-doc-state].
@history[#:added "1.2"]
}
@; ------------------------------------------------------------------------
@section[#:tag "materialize-user-docs"]{API for Materializing User-Specific Documentation}
@defmodule[setup/materialize-user-docs]
@history[#:added "1.1"]
@defproc[(materialize-user-docs [on-setup ((-> boolean?) -> any) (lambda (setup) (setup))])
void?]{
Checks whether a user-specific documentation entry point already
exists in @racket[(find-user-doc-dir)], and if not, runs @exec{raco
setup} in a mode that will create the entry point (to have the same
content as the installation's documentation entry point.)
The run of @exec{raco setup} is packaged in a thunk that is provided to
@racket[on-setup], which can adjust the current output and error ports
as appropriate and check the thunk's result for success.
The @racket[on-setup] argument is not called if the documentation entry
point already exists in @racket[(find-user-doc-dir)].
}