1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" RCS: @(#) $Id: pkgMkIndex.n,v 1.4 1998/10/30 23:02:02 welch Exp $
'\"
.so man.macros
.TH pkg_mkIndex n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
pkg_mkIndex \- Build an index for automatic loading of packages
.SH SYNOPSIS
.nf
.VS 8.0.3
\fBpkg_mkIndex ?\fI-direct\fR? ?\fI-verbose\fR? \fIdir\fR ?\fIpattern pattern ...\fR?
.VE
.fi
.BE
.SH DESCRIPTION
.PP
\fBPkg_mkIndex\fR 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 \fBpackage require\fR commands are executed.
To use \fBpkg_mkIndex\fR, follow these steps:
.IP [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 \fBload\fR command
with a single argument; for example, if the file is \fBtest.so\fR it must
be possible to load this file with the command \fBload test.so\fR.
Each script file must contain a \fBpackage provide\fR command to declare
the package and version number, and each binary file must contain
a call to \fBTcl_PkgProvide\fR.
.IP [2]
Create the index by invoking \fBpkg_mkIndex\fR.
The \fIdir\fR argument gives the name of a directory and each
\fIpattern\fR argument is a \fBglob\fR-style pattern that selects
script or binary files in \fIdir\fR.
.VS 8.0.3
The default pattern is \fB*.tcl\fR and \fB*.[info sharedlibextension]\fR.
If the optional \fI-direct\fR argument is given, the generated index
will manage to load the package immediately upon \fBpackage require\fR
instead of delaying loading until actual use of one of the commands.
.VE
.RS
.LP
\fBPkg_mkIndex\fR will create a file \fBpkgIndex.tcl\fR in \fIdir\fR
with package information about all the files given by the \fIpattern\fR
arguments.
It does this by loading each file and seeing what packages
and new commands appear (this is why it is essential to have
\fBpackage provide\fR commands or \fBTcl_PkgProvide\fR 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 adjust the order in which \fBpkg_mkIndex\fR processes
the files. See COMPLEX CASES below.
.RE
.IP [3]
Install the package as a subdirectory of one of the directories given by
the \fBtcl_pkgPath\fR variable. If \fB$tcl_pkgPath\fR 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 \fBpkgIndex.tcl\fR
file. As long as the package is installed as a subdirectory of a
directory in \fB$tcl_pkgPath\fR it will automatically be found during
\fBpackage require\fR commands.
.RS
.LP
If you install the package anywhere else, then you must ensure that
the directory containing the package is in the \fBauto_path\fR global variable
or an immediate subdirectory of one of the directories in \fBauto_path\fR.
\fBAuto_path\fR contains a list of directories that are searched
by both the auto-loader and the package loader; by default it
includes \fB$tcl_pkgPath\fR.
The package loader also checks all of the subdirectories of the
directories in \fBauto_path\fR.
You can add a directory to \fBauto_path\fR explicitly in your
application, or you can add the directory to your \fBTCLLIBPATH\fR
environment variable: if this environment variable is present,
Tcl initializes \fBauto_path\fR from it during application startup.
.RE
.IP [4]
Once the above steps have been taken, all you need to do to use a
package is to invoke \fBpackage require\fR.
For example, if versions 2.1, 2.3, and 3.1 of package \fBTest\fR
have been indexed by \fBpkg_mkIndex\fR, the command
\fBpackage require Test\fR will make version 3.1 available
and the command \fBpackage require \-exact Test 2.1\fR will
make version 2.1 available.
There may be many versions of a package in the various index files
in \fBauto_path\fR, but only one will actually be loaded in a given
interpreter, based on the first call to \fBpackage require\fR.
Different versions of a package may be loaded in different
interpreters.
.SH "PACKAGES AND THE AUTO-LOADER"
.PP
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 \fBpkg_mkIndex\fR
rather than \fBauto_mkindex\fR 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 \fBpackage require\fR commands.
In contrast, \fBauto_mkindex\fR 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
\fBpkg_mkIndex\fR and \fBauto_mkindex\fR.
If you use \fBpkg_mkIndex\fR to index a package, its commands cannot
be invoked until \fBpackage require\fR has been used to select a
version; in contrast, packages indexed with \fBauto_mkindex\fR
can be used immediately since there is no version control.
.SH "HOW IT WORKS"
.PP
\fBPkg_mkIndex\fR depends on the \fBpackage unknown\fR command,
the \fBpackage ifneeded\fR command, and the auto-loader.
The first time a \fBpackage require\fR command is invoked,
the \fBpackage unknown\fR script is invoked.
This is set by Tcl initialization to a script that
evaluates all of the \fBpkgIndex.tcl\fR files in the
\fBauto_path\fR.
The \fBpkgIndex.tcl\fR files contain \fBpackage ifneeded\fR
commands for each version of each available package; these commands
invoke \fBpackage provide\fR commands to announce the
availability of the package, and they setup auto-loader
information to load the files of the package.
.VS 8.0.3
Unless the \fI-direct\fR flag was provided when the \fBpkgIndex.tcl\fR
was generated,
.VE
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 \fBpackage require\fR you
.VS 8.0.3
may
.VE
not see
the package's commands in the interpreter, but you will be able
to invoke the commands and they will be auto-loaded.
.VS 8.0.3
.SH "DIRECT LOADING"
.PP
Some packages, for instance packages which use namespaces and export
commands or those which require special initialization, might select
that their package files be loaded immediately upon \fBpackage require\fR
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 \fI-direct\fR argument.
.VE
.SH "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 \fBpkg_mkIndex\fR.
The only case that is not supported is a package that is
provided by more than one binary file.
These issues are described in detail below.
.PP
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.
.PP
In general, it is OK for scripts to have dependencies on other
packages.
If scripts contain \fBpackage require\fP 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 \fBunknown\fP 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.
.PP
If binary files have dependencies on other packages, things
can become tricky because it is not possible to stub out
the C-level \fBTcl_PkgRequire\fP API.
For example, suppose the BLT package requires Tk, and expresses
this with a call to \fBTcl_PkgRequire\fP in its \fBBlt_Init\fP routine.
To support this, you must run \fBpkg_mkIndex\fR in a shell that
has Tk loaded. \fBpkg_mkIndex\fR will load any packages listed by
\fBinfo loaded\fP into the interpreter used to process files.
In most cases this will satisfy the \fBTcl_PkgRequire\fP calls
made by binary files.
.PP
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.
.PP
You cannot have the same package provided by two different binary
files. Well, you can, but they cannot be indexed by \fBpkg_mkIndex\fR
and it seems like a poor design choice anyway. The problem is that
once the package is provided by the first binary file, then that
masks the provide made by the other binary file. If you
absolutely must do this, you'll have to run \fBpkg_mkIndex\fR on
each different file, save the resulting pkgIndex.tcl files,
and merge the results.
.PP
If you have a package that is split across scripts and a binary file,
then you must specify the scripts first; otherwise the package loaded from
the binary file may mask the package defined by the scripts.
.SH KEYWORDS
auto-load, index, package, version
|