Tcl extension: check Tcl version?

Tcl extension: check Tcl version?

Post by odt » Fri, 04 Apr 2008 22:43:28


Is there a recommended way to check if a (binary) Tcl extension
is loaded to the same Tcl version that was used for linking
the extension?

Currently I'm encountering a problem with an extension that
I have built (and linked) with libtk8.3.so and that can be
loaded under wish8.5 as well (without re-bulding, using
package require). A number of newly provided commands work
well in spite of the version mixture, but others don't, and
wish8.5 crashes when these commands are used.

Is this behavior normal, i.e. should I check that compile-time
version and run-time version are identical? Or does this
indicate some subtle coding problem?

Thanks for any suggestions
Olaf
 
 
 

Tcl extension: check Tcl version?

Post by schlen » Fri, 04 Apr 2008 23:37:23


Not subtle. Major problem. DO NOT DO THAT.

If you want to be loadable across multiple versions do NOT link with
libtk directly, use the stubs table to do it, it was made for that
usecase. (read about it on the wiki http://www.yqcomputer.com/
http://www.yqcomputer.com/ )

Michael

 
 
 

Tcl extension: check Tcl version?

Post by Donald G P » Sat, 05 Apr 2008 00:01:41


The recommended way is to use Tcl's stubs interfaces to produce
an extension that can be [load]ed into more than one minor release
of Tcl.


Since you're extending Tk as well, use Tk's stubs interfaces too.

and that can be

From one minor release to the next, stubs-compatibility and
source compatibility (possibly with help of some #define's) are
what the Tcl/Tk developers aim to achieve.

There's no aim to maintain binary compatibility between the
shared libraries of different minor releases. That's why those
shared libraries are labeled with their version numbers (libtcl8.4.so
vs libtcl8.5.so, etc.). Lack of binary compatibility is likely to
show up as crashes, so yes your troubles are to be expected.

I strongly recommend you convert to using the stubs interfaces.

If for some reason you truly can't make that conversion, use the
"exact" flag of your Tcl_PkgRequire() calls in your extension to
force a match to the minor version(s) you compiled against:

int
Extension_Init(Tcl_Interp *interp) {
...
if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) {
return TCL_ERROR;
}
...
if (Tcl_PkgRequire(interp, "Tk", TK_VERSION, 1) == NULL) {
return TCL_ERROR;
}
...
}

--
| Don Porter Mathematical and Computational Sciences Division |
| XXXX@XXXXX.COM Information Technology Laboratory |
| http://www.yqcomputer.com/ ~DPorter/ NIST |
|______________________________________________________________________|
 
 
 

Tcl extension: check Tcl version?

Post by Donald G P » Sat, 05 Apr 2008 06:15:33


It's been politely pointed out to me that in my effort to simplify the
example for posting, I converted it into something that won't work with
Tcl/Tk 8.5 and later. Please use this example instead:

int
Extension_Init(Tcl_Interp *interp) {
...
if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
return TCL_ERROR;
}
...
if (Tk_InitStubs(interp, TK_VERSION, 1) == NULL) {
return TCL_ERROR;
}
...
}

This revised example is source compatible with Tcl/Tk header files from
version 8.5. And for programs still choosing to lock themselves to a
single minor release of Tcl and Tk, source compatibility is the kind
you want. Sorry about any confusion or grief.

The other benefit is that written this way, you are only a
-DUSE_TCL_STUBS -DUSE_TK_STUBS away from starting to use stubs, and
then only a s/1/0/g away from using stubs to produce [load]ability
into multiple minor releases of Tcl/Tk.

--
| Don Porter Mathematical and Computational Sciences Division |
| XXXX@XXXXX.COM Information Technology Laboratory |
| http://www.yqcomputer.com/ ~DPorter/ NIST |
|______________________________________________________________________|
 
 
 

Tcl extension: check Tcl version?

Post by odt » Sat, 05 Apr 2008 22:58:06

Donald G Porter < XXXX@XXXXX.COM >:

As you (and Michael) pointed out, using the stubs mechanism
is certainly the right thing to do and I'm currently trying
to modify the Init function and the makefile appropriately.

However, I do have a problem with pkg_mkIndex now. As soon as
I compile with Tk_InitStubs() (either with the conventional or
with the libtclstub/libtkstub libraries), pkg_mkIndex complains:

~$ wish8.3
pkg_mkIndex -verbose . my_ext.so
warning: error while loading my_ext.so: can't find package Tk 8.3

while directly loading the extension:

load ./my_ext.so

works.

The same behavior is seen under wish8.4 or wish8.5 if the
exact_flag is set to 0 (if it is set to 1, then pkg_mkIndex
correctly complains about non-matching versions).

Any more suggestions?

Thanks,
Olaf
 
 
 

Tcl extension: check Tcl version?

Post by schlen » Sat, 05 Apr 2008 23:51:08


Basically: Don't use pkg_mkIndex..., its not worth the trouble, it was
fine when lazy loading was still en vogue, but that time has passed...

The nearly generic line for your pkgIndex.tcl is trivial, so use that,
just add in the right version number.

package ifneeded YourPackage 1.0 [list load [file join $dir
my_ext[info sharedlibextension]]]

Michael
 
 
 

Tcl extension: check Tcl version?

Post by Donald G P » Sun, 06 Apr 2008 00:37:46


[pkg_mkIndex] is at best fragile when trying to index extensions
that depend on other extensions. Simplest advice is don't use it
and construct your pkgIndex.tcl file without it.

But, just to see how close to working you are, try this:

$ wish8.3
% pkg_mkIndex -load Tk -verbose . my_ext.so

--
| Don Porter Mathematical and Computational Sciences Division |
| XXXX@XXXXX.COM Information Technology Laboratory |
| http://www.yqcomputer.com/ ~DPorter/ NIST |
|______________________________________________________________________|
 
 
 

Tcl extension: check Tcl version?

Post by Donald G P » Sun, 06 Apr 2008 00:44:02


Oh, yeah, since you're working with such an outdated version of Tcl,
you will probably want to explicitly use either the -direct or -lazy
options, depending what sort of indexing you want. This will avoid any
confusion due to changes over time which of those options is the default.

--
| Don Porter Mathematical and Computational Sciences Division |
| XXXX@XXXXX.COM Information Technology Laboratory |
| http://www.yqcomputer.com/ ~DPorter/ NIST |
|______________________________________________________________________|
 
 
 

Tcl extension: check Tcl version?

Post by odt » Sun, 06 Apr 2008 01:04:23

Donald G Porter < XXXX@XXXXX.COM >:


I'm slightly surprised by this advise since I had the impression
(from the Tcl 8.5 manpages) that pkg_mkIndex is still the recommended
way to create index files (and it worked fine before I tried to use
the stubs mechanism). But it's no problem to avoid pkg_mkIndex
and to construct pkgIndex.tcl without pkg_mkIndex.



Perfect! Works as expected!

Wouldn't it be reasonable to either update the documentation and
to mention these limitations of pkg_mkIndex in combination with
tcl-stubs, or to improve pkg_mkIndex such that it isn't confused
by Tk_InitStubs()?


Thanks for your help
Olaf