Tcl Source Code

View Ticket
Login
Ticket UUID: 695441
Title: tcl_findLibrary does not look in $::auto_path
Type: RFE Version: None
Submitter: jenglish Created on: 2003-03-01 04:09:33
Subsystem: 38. Init - Library - Autoload Assigned To: dgp
Priority: 9 Immediate Severity:
Status: Closed Last Modified: 2004-11-17 00:19:59
Resolution: Accepted Closed By: dgp
    Closed on: 2004-11-16 17:19:59
Description:
The tcl_findLibrary procedure does not check the
directories listed in $::auto_path when looking for the
specified initialization script.

This means that a combined script/binary package which
calls tcl_findLibrary in its _Init() routine might not
be able to find its own library, even though Tcl's
package mechanism was able to find the binary library.
User Comments: dgp added on 2004-11-17 00:19:59:
Logged In: YES 
user_id=80530


modified version backported for
Tcl 8.4.8.

dgp added on 2004-10-27 00:02:52:
Logged In: YES 
user_id=80530


what portion of this, if any,
should be backported, should
be sorted out before 8.4.8 release.

dgp added on 2004-08-24 00:40:08:
Logged In: YES 
user_id=80530

patch committed to HEAD.

Assigning to tclguy to judge
whether an 8.4 backport is
also appropriate.

dgp added on 2004-08-19 23:56:54:

File Deleted - 98323: 



File Added - 98426: 695441.patch

Logged In: YES 
user_id=80530

updated patch should
correct the safe interp glitch.

dgp added on 2004-08-19 23:18:55:
Logged In: YES 
user_id=80530

Patch is incompatible with
Safe Base, which apparently
does not allow [file normalize]
in a safe interp.

dgp added on 2004-08-19 03:37:17:

File Added - 98323: 695441.patch

dgp added on 2004-08-19 03:37:16:
Logged In: YES 
user_id=80530


Attached patch changes the
search path to include directories
in the $::auto_path and the
scriptdir,runtime in the package's
configuration, if any.

Some obsolete directories that
should be included in auto_path
when relevant were also dropped.

Testing invited.

dgp added on 2003-07-04 06:21:28:
Logged In: YES 
user_id=80530

Economy of search algorithms is
attractive, I agree.

I don't think the two package answer
really works though, because we really
don't have two packages.  Presumably
package FOO (in this case, Tk) needs
package FOO-tcl to work correctly, while
at the same time FOO-tcl makes use of
commands provided by FOO.

Circular dependency is immediate evidence
that there's really only one package here
(one unit of loading).

andreas_kupries added on 2003-07-04 06:02:02:
Logged In: YES 
user_id=75003

IMHO. From my POV the script part of a package FOO should 
simply be another package, maybe named 'FOO-tcl' or some 
such. Then the binary part can simply 'package require' the 
thing and it does not matter there the script part is located. 
The package search mechanism will be enough and obviates 
the need for 'another' search algorithm to locate stuff.

dgp added on 2003-07-04 05:55:18:
Logged In: YES 
user_id=80530

see also Tk Bug 765642

dgp added on 2003-04-17 04:03:07:
Logged In: YES 
user_id=80530


FWIW...

I notice that on Max OS X only, the ::tcl_pkgPath
is also searched.  This seems like a half-fulfillment
of this feature request on a single platform.

jenglish added on 2003-03-04 06:56:48:
Logged In: YES 
user_id=68433

Calling tcl_findLibrary from the package _Init() routine is
useful since it works for statically loaded as well as
dynamically loaded packages.  Plus, it provides useful hooks
for overriding the library path from the environment (for
e.g., debugging) and from the application (for e.g.,
tclkits).

BTW, I agree that the script and binary parts should always
be installed in the same place.  However, for
statically-linked, statically-loaded packages there might
not be a separate binary part (or even a pkgIndex.tcl).

Basically: if the binary part loads the script part, the
package can work as a Tcl_StaticPackage() or be dynamically
loaded with no code changes.  The other way around, it
can't.

dgp added on 2003-03-03 09:01:01:
Logged In: YES 
user_id=80530

my strong preference is that no new package 
uses [tcl_findLibrary], and packages that
currently use [tcl_findLibrary] should try to
move away from it.

[tcl_findLibrary] exists to solve a problem that
packages are much better off just not
creating for themselves in the first place.

For your example, just be sure to install 
all files of Foo 1.0 [*] -- libFoo.so, fooInit.tcl,
and pkgIndex.tcl  -- all in the same installation
directory.  Then, pkgIndex.tcl should contain:

package ifneeded Foo 1.0 [list source [file join $dir
fooInit.tcl]]

And fooInit.tcl should contain:

load [file join [file dirname [info script]] libFoo[info
sharedlibextension]] Foo

Since your package includes binary files, it should
be installed only on an appropriate platform, either
under TCL_EXEC_PREFIX, or somewhere else
that will be placed on auto_path only on appropriate
platforms.

I believe this approach is what TEA2 recommends.

The older style of installing binary parts under
TCL_EXEC_PREFIX and cross-platform parts
under TCL_PREFIX is what led to the need
for [tcl_findLibrary] to allow the package to find
its missing half.  The only benefit of that scheme
was to save disk space on file servers serving
multi-platform clients, and that's largely an
optimization of a bygone era.  Much better for
runtime sanity and for uninstall capability to
put all parts of an installed package in just
one place.  

[*] FWIW, I'd rather you named the package
"foo" rather than "Foo".

jenglish added on 2003-03-01 11:20:57:
Logged In: YES 
user_id=68433

An example is probably in order:

Suppose Foo 1.0 contains libFoo.so, fooInit.tcl, and
pkgIndex.tcl, where pkgIndex.tcl says:

package ifneeded Foo 1.0 [list load [file join $dir
libFoo[info sharedlibextension]]]

and Foo_Init() Tcl_Eval()s a startup script containing

tcl_findLibrary Foo 1.0 1.0 fooInit.tcl FOO_LIBRARY 
Foo_Library

If Foo1.0 is installed in one of the standard places
(according to tcl_findLibrary), this will work.  If it's
stored in a nondefault location, [tclPkgUnknown] can find
out about the package if $::auto_path is extended, but the
package will still fail to load since tcl_findLibrary
doesn't look in the same place(s) as [tclPkgUnknown].

Or is this an improper use of tcl_findLibrary?

Attachments: