Building Tclkit

(For full details about Tclkit, see https://www.equi4.com/tclkit.html)

If you are lucky, it will take 7 commands to go from nothing to a ready-to-run tclkit executable on Unix:

    $ wget https://www.equi4.com/pub/tk/tars/genkit
    $ tclsh genkit A
    $ tclsh genkit B tcl
    $ sh genkit B
    $ sh genkit C
    $ sh genkit D
    $ sh genkit E

The result will be called "tclkit-$HOSTNAME". You can rename it to "tclkit" and put it anywhere you like.

If you don't have wget, try this instead from tclsh, courtesy of Jeff Hobbs:

    package require http
    set url  "https://www.equi4.com/pub/tk/tars/genkit"
    set file [file tail $url]
    set fid  [open $file w]
    set tok  [http::geturl $url -binary 1 -channel $fid]
    http::wait $tok
    close $fid

(see Tcl's "http::config" for ways to go through a proxy, i.e. "man n http")

If seven steps sounds like hard manual labor to you, try the following wrapper, courtesy of Ulrich Schöbel:

    $ wget https://www.equi4.com/pub/tk/tars/Makefile
    $ make

If none of the above worked out of the box, the following pages will describe it all step by step (yes, there is a way around just about everything):

If you want to have some more background information about the way tclkit works, read on...


THE GENERAL PLAN

On Unix, the "genkit" script takes you through the necessary steps to create the Tclkit standalone executable.

On Windows, builds are done through one large MSVC6 project file, with subprojects for each of the components. This setup also supports debug builds, making it an effective way to debug issues at the C/C++ level.

On Macintosh, MacOS X builds with X11 (XonX) are done as for Unix. The "Classic" builds (MacOS 8/9, both PPC and 68K) are done through a set of Codewarrior projects (optionally ending up as one "fat" binary). The most modern version - MacOS X with Aqua - is work in progress, and requires the ProjectBuilder environment.

TCLKIT'S ANATOMY

Tclkit combines a compiled executable with a basic set of runtime files, which are packaged as "starkit", placed at the end of the application. The result is a single file, which runs without unpacking due to "VFS", the Virtual File System which is part of Tcl as of version 8.4.

Tclkit uses the Metakit embedded database as basis for VFS storage. So, as with any regular starkit, Tclkit is simply a header plus a Metakit datafile appended to it. In the case of Tclkit itself, the header is a platform-specific binary application - whereas is other cases the header is a minute Tcl script. The Metakit VFS implementation zip-compresses the data as the default.

The datafile at the end of Tclkit is identical for all Unix platforms (apart from the Tck and Incrtcl extensions, which are loaded from VFS). It contains all the usual Tcl, Tk, and other runtime files. It also contains a few Unicode encoding files (not the full set, see below).

HOW TCLKIT GETS BUILT

The original builds of Tclkit used a trick to avoid the chicken-and-egg problem of constructing a starkit without yet having a working Tclkit. The idea being that the constructed executable was *just* enough to be able to run a script and create a copy of itself and then construct a starkit at the end. This is still the way in which the current Win32 build works - it builds a "kit.exe", which when run starts to execute a fixed script named "setup.tcl" next to it, which in turn contains the logic to construct a "tclkit.exe". For convenience, this is also still the way in which Tclkit gets built under Linux.

Other builds no longer rely on this mechanism. Instead they need to be "finalized" with a working tclkit. In the simplest case this is just a matter of doing "cat compiledapp runtimedata >tclkit; chmod +x tclkit". In more involved cases such as to embed Tk in VFS as dynamic extension, the process involves mounting the resulting starkit to tweak it.

In the new approach changes to the runtime side of things can easily be carried through in all releases, because the finalization of Tclkit can be done anywhere, without access to the target platform. As long as a recompile is not needed, changes and additions to Tclkit can be quick.

HOW TCLKIT STARTS UP

The startup process for Tclkit is somewhat tricky. It needs to extract a script to initialize Tcl with, *before* Tcl's VFS code can be used to "mount" the embedded datafile as a more or less normal filesystem. It also has to get the Unicode encoding logic right. And lastly, it has to deal with "custom tclkits", i.e. modified versions which not only include the standard runtime files, but an entire custom application.

The C side of the startup logic is fully contained in the source file "kitInit.c". The Tcl side of the special startup logic is stored in a file "boot.tcl" at the root of the embedded VFS data. Existing hooks in Tcl were used so "boot.tcl" runs first in each new Tcl interpreter.

In the most basic case, Tclkit gets launched with no args (i.e. as an interactive system), or with a script as first command line argument. In those cases it will behave just like a classical tclsh or wish.

One step up, but almost identical, is when the first arg is a scripted document - that too runs as a script (but the header sets Metakit up so it mounts the remainder as datafile, and launches a script from it).

But if a "main.tcl" script is detected inside Tclkit, then it assumes that it was altered and is to act as a single-file custom application. In this case the args are passed unchanged, and "main.tcl" gets control. The "main.tcl" script must be stored *next* to "boot.tcl" to be found.

For some diagrams illustrating how starkits start up and use Tclkit, see Anatomy of a starkit.