Tk Source Code

View Ticket
Bounty program for improvements to Tcl and certain Tcl packages.
Ticket UUID: 1716117
Title: improve genstubs/checkstubs
Type: RFE Version: None
Submitter: dgp Created on: 2007-05-09 20:39:47
Subsystem: 84. Unix Build Assigned To: dgp
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2008-04-16 09:20:35
Resolution: Accepted Closed By: sf-robot
    Closed on: 2008-04-16 02:20:35
With current HEAD of Tcl and Tk:

$ cd tcl/unix
$ ./configure
$ make
$ cd ../../tk/unix
$ ./configure --disable-shared --with-tcl=../../tcl/unix
$ make
gcc -O2  -pipe    -Wl,--export-dynamic  tkAppInit.o -L/home/dgp/cvs/tk/unix -ltk8.5 \
                -L/home/dgp/cvs/tcl/unix -ltcl8.5  -lX11 -lXss -lXext -lXft -lXrender -lfontconfig -lfreetype -lX11   -ldl  -lieee -lm  -Wl,-rpath,/home/dgp/i686/linux/lib -o wish
/home/dgp/cvs/tk/unix/libtk8.5.a(tkStubLib.o): In function `Tk_InitStubs':
tkStubLib.c:(.text+0x1f): undefined reference to `tclStubsPtr'
collect2: ld returned 1 exit status
make: *** [wish] Error 1

If this is supposed to work, well,
it doesn't.

If it's not supposed to work, seems
to me that Tk's configure script
would be better off at least warning
about the incompatible configure options.
User Comments: sf-robot added on 2008-04-16 09:20:35:
Logged In: YES 
Originator: NO

This Tracker item was closed automatically by the system. It was
previously set to a Pending status, and the original submitter
did not respond within 14 days (the time period specified by
the administrator of this Tracker).

dgp added on 2008-04-01 23:37:20:
Logged In: YES 
Originator: YES

I think the commit of 1819422
has resolved this report as well.

das added on 2007-12-10 23:12:33:
Logged In: YES 
Originator: NO

made some progress on this while fixing Tcl bug 1834288:
added a genStubs::export command that is now used to mark symbols that should be exported but are not present in the stubs table (instead of commenting them out).
No changes to the 'checkstubs' target, so the  "(fool checkstubs)" hack for exported variables is still needed.

dkf added on 2007-05-18 19:30:17:
Logged In: YES 
Originator: NO

Converted to a lower-prio FRQ

dkf added on 2007-05-18 19:28:32:
data_type - 362997

das added on 2007-05-18 03:26:30:
Logged In: YES 
Originator: NO

sounds like a good idea.
also, to make checkstubs pass for the exported variables, I had to append dummy text in brackets:
# TclStubs *tclStubsPtr                 (fool checkstubs)
given that currently, checkstubs uses 'grep -c "symbol *("' to look for symbol matches in the *.decls files.
a better solution instead of this hack would be nice as well...
maybe checkstubs should be using tcl to process the *.decls files?

dkf added on 2007-05-17 21:25:45:
Logged In: YES 
Originator: NO

Maybe it would be better to add a "do nothing" command to the genstubs script so that we document that these are things that are explicitly exposed, as opposed to things that have just been commented out?

das added on 2007-05-17 04:22:55:
Logged In: YES 
Originator: NO

probably the wisest decision given the wide impact of this change...

Note that your revert of course made 'make checkstubs' fail again however:
$ make checkstubs  
$ make checkstubs

As mentioned previously, the easiest way to workaround this is to add these symbols as comments to the *.decls files, as was already done with Tcl_Main. I have just committed a change to that effect.

jenglish added on 2007-05-17 01:35:43:
Logged In: YES 
Originator: NO

Per discussion with dgp, the decision was made to leave things as they were in 8.4,
and possibly revisit this issue in the 8.6 timeframe.

Fixed in CVS (generic/tclStubLib.c r1.15).  

Same change made in tk/generic/tkStubLib.c (r1.14).

jenglish added on 2007-05-13 02:04:13:
Logged In: YES 
Originator: NO

Tcl_InitStubs() should also have public visibility, for the same reason.  Also, contrary to the comment near the top of the file, the other stub symbols must _not_ be built non-exported (with the exception of HasStubSupport(), which is static).

Ideally, the copy of tclStubLib.o in libtclstub.a _should_ mark everything as MODULE_SCOPE (so that extension shared libraries each have their own copy), but the copy in libtcl.a / _must not_ if this mode of linking is to remain supported.

Another alternative is to leave tclStubLib.o out of libtcl.{a,so} altogether, and make a note that extended tclshs must now be linked with -ltclstub in addition to -ltcl if any component extensions are stub-enabled.

The same issues apply to tk/generic/tkStubLib.c.

jenglish added on 2007-05-13 00:27:30:
Logged In: YES 
Originator: NO

This affects more than just Tk: building an extended tclsh / Big Wish with statically-compiled, stubs-enabled extensions and linking against no longer works either.  (Reported by Rolf Ade on the chat).

Option (1), export tclStubsPtr from again, is the right solution.

das added on 2007-05-10 07:41:15:
Logged In: YES 
Originator: NO

I see three solutions to this problem:

1) make tclStubsPtr an exported symbol from the tcl shared library.

2) modify tkStubLib.c to not reference tcl symbols through the tcl stubs table when it is used as part of a tk library built without USE_TCL_STUBS. This would require two separate compilations of tkStubLib.c, as the tkStubLib object file used for libtkstub will continue to need to go through the tcl stubs table in all cases.

3) modify tkWindow.c Initialize() as below (to ensure the tcl stubs table is setup) and link wish with libtclstub even when the static tk is used, or preferably, include tclStubLib.o in the static tk library (by extracting tclStubLib.o from libtclstub via 'ar x').

Index: generic/tkWindow.c
RCS file: /cvsroot/tktoolkit/tk/generic/tkWindow.c,v
retrieving revision 1.80
diff -u -p -r1.80 tkWindow.c
--- generic/tkWindow.c13 Feb 2007 00:16:39 -00001.80
+++ generic/tkWindow.c10 May 2007 00:22:10 -0000
@@ -2949,6 +2949,10 @@ Initialize(
      * only an issue when Tk is loaded dynamically.
+#ifdef Tcl_InitStubs
+#undef Tcl_InitStubs
     if (Tcl_InitStubs(interp, TCL_PATCH_LEVEL, 1) == NULL) {
 return TCL_ERROR;

das added on 2007-05-10 05:11:56:
Logged In: YES 
Originator: NO

the reference to tclStubsPtr is caused by the following in tkStubLib.c:
 * We need to ensure that we use the stub macros so that this file contains no
 * references to any of the stub functions. This will make it possible to
 * build an extension that references Tk_InitStubs but doesn't end up
 * including the rest of the stub functions.


this causes Tcl_PkgRequireEx and Tcl_SetResult to be calls through the tcl stubs table.
in the present case this would seem to be unnecessary as these routines could be called directly in the shared tcl library.

indeed tclStubLib.c explicitly says:
 * Ensure that Tcl_InitStubs is built as an exported symbol. The other stub
 * symbols should be built as non-exported symbols.
so it appears clients of the tcl shared library are not intended to be able to use tclStubsPtr directly?

das added on 2007-05-10 04:54:41:
Logged In: YES 
Originator: NO

this is quite likely MODULE_SCOPE related, as tclStubsPtr was indeed made MODULE_SCOPE to get 'checkstubs' to pass.
Don't understand yet where Tk_InitStubs() uses it though, there is some deep stubs magic going on in tkStubLib.c...

dgp added on 2007-05-10 03:53:07:
Logged In: YES 
Originator: YES

The core-8-4-branch does *not*
suffer from this problem.  This
is a regression.

Priority raised, passing to das to
opine on whether this is another
MODULE_SCOPE-related matter?