TL; DR
When compiling a program with main you should not use stubs. Instead, building without USE_TCL_STUBS and USE_TK_STUBS defines and associates with libtcl.so and libtk.so (well, with any version number that was attached to them). Due to the nature of the Unix linker, you must place the Tk library in front of the Tcl library (and you may also need to manually link to other libraries as well, such as the X library, sometimes this is due to black art).
Justification
The stubs mechanism is designed so that the Tcl extension library can use the Ccl (and Tk) C API without binding itself to the Tcl library itself. This means that the library does not depend on what exact version of Tcl is present during its loading, but simply depends on the specific version of the Tcl API (Tcl is pretty good at managing long-term APIs and ABI compatibility). However, all this depends on the initialization function of the library, called using a special kind of pointer, which allows you to view all other API functions. (Once Tcl has been loaded this way, itโs much easier to find all the other APIs.) When you create the application, as you do, the problem is that there is no existing boot instance of the Tcl library for your code to link to; it must be connected directly (and in fact, both Tcl_Main and Tk_Main are disjoint functions for this exact reason).
Those of you who read at home might think that this Tcl repeats a lot of what the dynamic linker does. You would be right. However, the system dynamic linker has a number of ways that it may not do quite correctly (for example, it can become very confused if there are several versions of the library), and it subtly changes in its capabilities between platforms. Tcl uses its own mechanism because it does the job exactly (for Tcl) everywhere, giving us much better control over long-term ABI compatibility.
There is an exception to the stub rule above, and this is tclkit , which is the full runtime of Tcl and Tk (plus a small NoSQL database) in a single file. The bootstrap code for tclkit is terribly complicated; you donโt want to deal with things that you donโt need! If you want to use the single-page Tcl environment, you use tclkit (or one of the few other systems that do almost equivalent things).
Donal fellows
source share