Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SWIG1.3.9 and Stubs

0 views
Skip to first unread message

Jackson McCann

unread,
Dec 13, 2001, 4:55:24 AM12/13/01
to
Hi,

I use the new version of SWIG from time to time to build extensions
for TCL and at present find myself adding (by hand) the following to
all of them:

#ifdef USE_TCL_STUBS
if ( Tcl_InitStubs(interp, "8.1", 0) == NULL ) {
return TCL_ERROR ;
}
#endif

Before I email Mr Beazley asking him to add this to swig I thought a
sanity check in the TCL group would be a 'good thing'.

For a start - is this the right code to initialise for stubs? I think
8.1 was the first release they came in at but can someine confirm
this.

Should the code always be generated or should their be an option to
swig to make it include the code? eg 'swig -tcl -tclstubs' or some
such.

Anything else?

Regards Jackson McCann

Bob Techentin

unread,
Dec 21, 2001, 9:02:58 AM12/21/01
to
SWIG should include a call to Tcl_InitStubs() in the generated C code.
but I would suggest replacing "8.1" with TCL_VERSION, so the code looks
like:

#ifdef USE_TCL_STUBS
if ( Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL ) {
return TCL_ERROR ;
}
#endif

Yes, Tcl 8.1 is the first to support stubs, but this is a forward
compatibility feature, not a backward compatibility feature.If you
compile your extension against Tcl 8.3, then you are guaranteed that it
will work with future Tcl versions (i.e., Tcl 8.4) but you are not
guaranteed that your extension will work with the stub tables in Tcl
8.1.

You could, of course, keep a copy of Tcl 8.1 around just for compiling
your extension.

SWIG should always generate this code. The #ifdef/#endif will prevent
it from being compiled if stubs are not available.

Bob
--
Bob Techentin techenti...@mayo.edu
Mayo Foundation (507) 538-5495
200 First St. SW FAX (507) 284-9171
Rochester MN, 55901 USA http://www.mayo.edu/sppdg/


"Jackson McCann" <mcc...@britannic.co.uk> wrote in message
news:a827c380.01121...@posting.google.com...

Don Porter

unread,
Dec 21, 2001, 10:05:39 AM12/21/01
to
Bob Techentin wrote:
> SWIG should include a call to Tcl_InitStubs() in the generated C code.
> but I would suggest replacing "8.1" with TCL_VERSION, so the code looks
> like:
>
> #ifdef USE_TCL_STUBS
> if ( Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL ) {
> return TCL_ERROR ;
> }
> #endif
>
> Yes, Tcl 8.1 is the first to support stubs, but this is a forward
> compatibility feature, not a backward compatibility feature.If you
> compile your extension against Tcl 8.3, then you are guaranteed that it
> will work with future Tcl versions (i.e., Tcl 8.4) but you are not
> guaranteed that your extension will work with the stub tables in Tcl
> 8.1.

For an automatic code generator like SWIG, I agree.

When writing code "by hand" though, I prefer for the developer to
know what version of the Tcl interface their code needs, and put
that explicit value in the Tcl_InitStubs call as a way of documenting
what that need is. That way, source distributions work even when
distributed to a builder/packager using a different release of Tcl.

That requires developer knowledge about the requirements of his
package, though. For SWIG, the best proxy for that knowledge is
the version of the header used in the compiler.



> SWIG should always generate this code. The #ifdef/#endif will prevent
> it from being compiled if stubs are not available.

True, but the #ifdef/#endif is not necessary. When USE_TCL_STUBS
is not defined, Tcl_InitStubs gets converted into Tcl_PkgRequire.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

Bob Techentin

unread,
Dec 21, 2001, 12:25:18 PM12/21/01
to
"Don Porter" <d...@email.nist.gov> wrote

>
> When writing code "by hand" though, I prefer for the developer to
> know what version of the Tcl interface their code needs, and put
> that explicit value in the Tcl_InitStubs call as a way of documenting
> what that need is. That way, source distributions work even when
> distributed to a builder/packager using a different release of Tcl.
>
> That requires developer knowledge about the requirements of his
> package, though. For SWIG, the best proxy for that knowledge is
> the version of the header used in the compiler.
>
> ... When USE_TCL_STUBS

> is not defined, Tcl_InitStubs gets converted into Tcl_PkgRequire.

I disagree, Don. I think of Tcl_PackageRequire() and Tcl_InitStubs() as
serving two different purposes.

Tcl_PackageRequire() should be used by the programmer to specify the
minimum Tcl version that supports the features required by her code. If
her code uses [lsort -unique], then she'd better require Tcl 8.3 (if I
read the ChangeLog correctly). If she purposefully wrote her code to be
backwards compatible with older Tcl versions, she might only need to
require Tcl 7.6. Then anybody can compile the source for this extension
against older versions of Tcl.

Tcl_InitStubs(), on the other hand, uses a version specific stub table
which is defined when the extension is compiled against a specific Tcl
version. If you compile the code against Tcl 8.3, then you won't have
to recompile the extension for 8.4, 8.5... etc. Stubs allows you to
distribute binary extension packages that should "drop in" for many
users for a long time to come. But you have no guarantee that the
binary extension will work with Tcl 8.1. Even though 8.1 supports
stubs, your compiled extension is _not_ compatible with 8.1, because the
core stub table in an 8.1 interpreter is different from the version 8.3
stub table linked to your application.

I know that I'm being a little strict with my language here. As I
understand stubs, compiled extensions *might* be backward compatible.
But it isn't guaranteed. The only way to guarantee that your extension
is binary compatible with Tcl 8.1+ is to actually compile and link it
against libtclstub8.1.a. If I am wrong, please correct me, but this is
my understanding of stubs.

I didn't realize that Tcl_InitStubs() degenerates into
Tcl_PackageRequire(), but that makes a lot of sense. If you're not
linking against the stub table, then the binary extension will work with
*only* the exact version of Tcl against which it was compiled. In that
case, it might not be a bad idea to have Tcl_InitStubs() degenerate into
Tcl_PackageRequire(interp,"Tcl",TCL_VERSION,1);.

Jeff Hobbs

unread,
Dec 21, 2001, 2:56:11 PM12/21/01
to
Bob Techentin wrote:
...

> Tcl_InitStubs(), on the other hand, uses a version specific stub table
> which is defined when the extension is compiled against a specific Tcl
> version. If you compile the code against Tcl 8.3, then you won't have
> to recompile the extension for 8.4, 8.5... etc. Stubs allows you to
> distribute binary extension packages that should "drop in" for many
> users for a long time to come. But you have no guarantee that the
> binary extension will work with Tcl 8.1. Even though 8.1 supports
> stubs, your compiled extension is _not_ compatible with 8.1, because the
> core stub table in an 8.1 interpreter is different from the version 8.3
> stub table linked to your application.
>
> I know that I'm being a little strict with my language here. As I
> understand stubs, compiled extensions *might* be backward compatible.
> But it isn't guaranteed. The only way to guarantee that your extension
> is binary compatible with Tcl 8.1+ is to actually compile and link it
> against libtclstub8.1.a. If I am wrong, please correct me, but this is
> my understanding of stubs.

That's a bit of a strict overstatement. While that is the intention
and the "safe" way to view stubs, it is largely incorrect in practice.
If you always restrict yourself to an 8.1 subset of the table, you
will be OK compiling against tclstubs8.3 but running in 8.1. The
issues come in that new C APIs are always being added onto the stubs
table. So, for example, Tcl_ChannelName() and a bunch of related
C APIs for the I/O rewrite in 8.3.2 were added in 8.3.2. If you use
those, you not only have to use an 8.3.2+ stubs lib to compile
against, but you must of course run on an 8.3.2+ Tcl as well. Using
just the old hash table and string functions though would cause no
problems.

The real magic of the stubs table is that I could actually make an
8.2.4 or even an 8.0.6 that added the C functions, or some
emulation thereof (like ignoring Unicode in 8.0.6) that would
actually allow you to run an app compiled against 8.4 stubs table
that is using 8.4 defined functions.

--
Jeff Hobbs The Tcl Guy
Senior Developer http://www.ActiveState.com/
Tcl Support and Productivity Solutions
http://www.ActiveState.com/Products/ASPN_Tcl/

Joe English

unread,
Dec 21, 2001, 8:09:13 PM12/21/01
to
Jeff Hobbs <Je...@ActiveState.com> wrote:

>Bob Techentin wrote:
>> The only way to guarantee that your extension
>> is binary compatible with Tcl 8.1+ is to actually compile and link it
>> against libtclstub8.1.a. If I am wrong, please correct me, but this is
>> my understanding of stubs.
>
>That's a bit of a strict overstatement. While that is the intention
>and the "safe" way to view stubs, it is largely incorrect in practice.
>If you always restrict yourself to an 8.1 subset of the table, you
>will be OK compiling against tclstubs8.3 but running in 8.1. The
>issues come in that new C APIs are always being added onto the stubs
>table. So, for example, Tcl_ChannelName() and a bunch of related
>C APIs for the I/O rewrite in 8.3.2 were added in 8.3.2. If you use
>those, you not only have to use an 8.3.2+ stubs lib to compile
>against, but you must of course run on an 8.3.2+ Tcl as well.

The stub library implementation (tclStubLib.c) hasn't changed
since 8.1 though; the stub table itself is initialized by the
Tcl interpreter. You need to compile against the 8.3.2+ *include
files* if you use 8.3.2+ features, and get loaded into an 8.3.2+
interpreter, but you should be able to statically link against
any old copy of libtclstub8.X.a.

Conversely, successfully linking against libtclstub8.X.a gives
no guarantee at all that the extension will work with an 8.X
interpreter.

That's why I like to use

Tcl_InitStubs(interp, TCL_VERSION, 0);

since this will guarantee that the run-time interpreter
is compatible with the compile-time #include files.
(That the extension is compatible with the compile-time
#include files is enforced at compile-time.)


--Joe English

jeng...@flightlab.com

0 new messages