pkg_mkIndex(n) Tcl (8.0) pkg_mkIndex(n)
_________________________________________________________________
NAME
pkg_mkIndex - Build an index for automatic loading of
packages
SYNOPSIS
pkg_mkIndex ?-direct? ?-load pkgPat? ?-verbose? dir ?pattern pattern ...?|
_________________________________________________________________
DESCRIPTION
Pkg_mkIndex is a utility procedure that is part of the
standard Tcl library. It is used to create index files that
allow packages to be loaded automatically when package
require commands are executed. To use pkg_mkIndex, follow
these steps:
[1] Create the package(s). Each package may consist of one
or more Tcl script files or binary files. Binary files
must be suitable for loading with the load command with
a single argument; for example, if the file is test.so
it must be possible to load this file with the command
load test.so. Each script file must contain a package
provide command to declare the package and version
number, and each binary file must contain a call to
Tcl_PkgProvide.
[2] Create the index by invoking pkg_mkIndex. The dir
argument gives the name of a directory and each pattern
argument is a glob-style pattern that selects script or
binary files in dir. The default pattern is *.tcl and |
*.[info sharedlibextension]. The optional switches |
are: |
-direct ||
The generated index will manage to load the |
package immediately upon package require |
instead of delaying loading until actual use |
of one of the commands. |
-load pkgPat ||
The index process will pre-load any packages |
that exist in the current interpreter and |
match pkgPat into the slave interpreter used |
to generate the index. The pattern match |
uses string match rules. See COMPLEX CASES |
below. |
-verbose ||
Generate output during the indexing process. |
Output is via the tclLog procedure, which by |
Page 1 (printed 2/19/99)
pkg_mkIndex(n) Tcl (8.0) pkg_mkIndex(n)
default prints to stderr. |
-- ||
End of the flags, in case dir begins with a |
dash.
Pkg_mkIndex will create a file pkgIndex.tcl in dir with
package information about all the files given by the
pattern arguments. It does this by loading each file
into a slave interpreter and seeing what packages and
new commands appear (this is why it is essential to
have package provide commands or Tcl_PkgProvide calls
in the files, as described above). If you have a
package split among scripts and binary files, or if you
have dependencies among files, you may have to use the
-load option or adjust the order in which pkg_mkIndex
processes the files. See COMPLEX CASES below.
[3] Install the package as a subdirectory of one of the
directories given by the tcl_pkgPath variable. If
$tcl_pkgPath contains more than one directory,
machine-dependent packages (e.g., those that contain
binary shared libraries) should normally be installed
under the first directory and machine-independent
packages (e.g., those that contain only Tcl scripts)
should be installed under the second directory. The
subdirectory should include the package's script and/or
binary files as well as the pkgIndex.tcl file. As long
as the package is installed as a subdirectory of a
directory in $tcl_pkgPath it will automatically be
found during package require commands.
If you install the package anywhere else, then you must
ensure that the directory containing the package is in
the auto_path global variable or an immediate
subdirectory of one of the directories in auto_path.
Auto_path contains a list of directories that are
searched by both the auto-loader and the package
loader; by default it includes $tcl_pkgPath. The
package loader also checks all of the subdirectories of
the directories in auto_path. You can add a directory
to auto_path explicitly in your application, or you can
add the directory to your TCLLIBPATH environment
variable: if this environment variable is present, Tcl
initializes auto_path from it during application
startup.
[4] Once the above steps have been taken, all you need to
do to use a package is to invoke package require. For
example, if versions 2.1, 2.3, and 3.1 of package Test
have been indexed by pkg_mkIndex, the command package
require Test will make version 3.1 available and the
Page 2 (printed 2/19/99)
pkg_mkIndex(n) Tcl (8.0) pkg_mkIndex(n)
command package require -exact Test 2.1 will make
version 2.1 available. There may be many versions of a
package in the various index files in auto_path, but
only one will actually be loaded in a given
interpreter, based on the first call to package
require. Different versions of a package may be loaded
in different interpreters.
PACKAGES AND THE AUTO-LOADER
The package management facilities overlap somewhat with the
auto-loader, in that both arrange for files to be loaded
on-demand. However, package management is a higher-level
mechanism that uses the auto-loader for the last step in the
loading process. It is generally better to index a package
with pkg_mkIndex rather than auto_mkindex because the
package mechanism provides version control: several
versions of a package can be made available in the index
files, with different applications using different versions
based on package require commands. In contrast,
auto_mkindex does not understand versions so it can only
handle a single version of each package. It is probably not
a good idea to index a given package with both pkg_mkIndex
and auto_mkindex. If you use pkg_mkIndex to index a
package, its commands cannot be invoked until package
require has been used to select a version; in contrast,
packages indexed with auto_mkindex can be used immediately
since there is no version control.
HOW IT WORKS
Pkg_mkIndex depends on the package unknown command, the
package ifneeded command, and the auto-loader. The first
time a package require command is invoked, the package
unknown script is invoked. This is set by Tcl
initialization to a script that evaluates all of the
pkgIndex.tcl files in the auto_path. The pkgIndex.tcl files
contain package ifneeded commands for each version of each
available package; these commands invoke package provide
commands to announce the availability of the package, and
they setup auto-loader information to load the files of the
package. Unless the -direct flag was provided when the |
pkgIndex.tcl was generated, a given file of a given version
of a given package isn't actually loaded until the first
time one of its commands is invoked. Thus, after invoking
package require you may not see the package's commands in |
the interpreter, but you will be able to invoke the commands
and they will be auto-loaded.
DIRECT LOADING |
Some packages, for instance packages which use namespaces |
Page 3 (printed 2/19/99)
pkg_mkIndex(n) Tcl (8.0) pkg_mkIndex(n)
and export commands or those which require special |
initialization, might select that their package files be |
loaded immediately upon package require instead of delaying |
the actual loading to the first use of one of the package's |
command. This mode is enabled when generating the package |
index by specifying the -direct argument.
COMPLEX CASES
Most complex cases of dependencies among scripts and binary
files, and packages being split among scripts and binary
files are handled OK. However, you may have to adjust the
order in which files are processed by pkg_mkIndex. These
issues are described in detail below.
If each script or file contains one package, and packages
are only contained in one file, then things are easy. You
simply specify all files to be indexed in any order with
some glob patterns.
In general, it is OK for scripts to have dependencies on
other packages. If scripts contain package require
commands, these are stubbed out in the interpreter used to
process the scripts, so these do not cause problems. If
scripts call into other packages in global code, these calls
are handled by a stub unknown command. However, if scripts
make variable references to other package's variables in
global code, these will cause errors. That is also bad
coding style.
If binary files have dependencies on other packages, things
can become tricky because it is not possible to stub out C-
level API's such as Tcl_PkgRequire API when loading a binary
file. For example, suppose the BLT package requires Tk, and
expresses this with a call to Tcl_PkgRequire in its Blt_Init
routine. To support this, you must run pkg_mkIndex in an
interpreter that has Tk loaded. You can achieve this with
the -load pkgPat option. If you specify this option,
pkg_mkIndex will load any packages listed by info loaded and
that match pkgPat into the interpreter used to process
files. In most cases this will satisfy the Tcl_PkgRequire
calls made by binary files.
If you are indexing two binary files and one depends on the
other, you should specify the one that has dependencies
last. This way the one without dependencies will get loaded
and indexed, and then the package it provides will be
available when the second file is processed. You may also
need to load the first package into the temporary
interpreter used to create the index by using the -load
flag; it won't hurt to specify package patterns that are not
yet loaded.
Page 4 (printed 2/19/99)
pkg_mkIndex(n) Tcl (8.0) pkg_mkIndex(n)
If you have a package that is split across scripts and a
binary file, then you should avoid the -load flag. The
problem is that if you load a package before computing the
index it masks any other files that provide part of the same
package. If you must use -load, then you must specify the
scripts first; otherwise the package loaded from the binary
file may mask the package defined by the scripts.
KEYWORDS
auto-load, index, package, version
Page 5 (printed 2/19/99)