Our first task was to reduce the overall size of a statically build interpreter executable (tclsh) and/or interpreter library (libtcl.a). This was realized by making a number of features provided by the standard interpreter optional, i.e removable at will during compile time. With this an end-user of the modularized core is free to remove any features which are not needed by his application and thus to shrink the space required for the executable or library.
The overall set of features which were initially made removable were determined by the requirements of our customer. In other words, we did not spent any time on features possibly giving us a high gain for the effort, but only on features our customer deemed irrelevant for his environment. The details however, i.e. the division of the features named by our customer into the actual removable features, were guided by the results of the discussions the community had had on the newsgroup comp.lang.tcl about this topic [5].
The chosen features are listed in Table 1, together with the C preprocessor macros whose existence will activate the removal of a particular feature. By default none of these macros are defined. Setting the macro MODULAR_TCL will activate all of these macros and thus remove the whole set of features.
Macro | Removed feature |
TCL_NO_SOCKETS | Channel driver "tcp" |
TCL_NO_TTY | Channel driver "tty" |
TCL_NO_PIPES | Channel driver "pipe" |
TCL_NO_PIDCMD | Command pid |
TCL_NO_NONSTDCHAN | Creation of channels beyond stdin, stdout and stderr |
TCL_NO_CHANNELCOPY | Channel copying, C/Tcl, fcopy |
TCL_NO_CHANNEL_READ | Command read and ``Tcl_ReadChars'' |
TCL_NO_CHANNEL_EOF | Command eof |
TCL_NO_CHANNEL_CONFIG | Command fconfigure and Tcl_GetChannelOption |
TCL_NO_CHANNEL_BLOCKED | fblocked |
TCL_NO_FILEEVENTS | fileevent and underlying APIs |
TCL_NO_FILESYSTEM | Everything related to the file system |
TCL_NO_LOADCMD | load and machinery below |
TCL_NO_SLAVEINTERP | Slave interpreters |
TCL_NO_CMDALIASES | Command aliases |
As Source Navigator crashed when processing the Tcl C sources at that time we decided to conditionalize the code by hand with support by the C compiler. This means that it is possible that we missed code which could have been made optional but currently is not. This may happen especially for a function F which is shared by removable features, and only such. In that case removing all features requiring F will not remove F. This deficiency has to be addressed in the future.
Starting at the topmost function for a feature, usually the function implementing the command to remove we followed the sources and determined the public and non-public non-static functions reachable from this point. After excluding them from the sources through ifdef's a complete build was performed and the compiler log analyzed to find all functions which are actually required by other parts of the core. These functions were made unconditional again. Additional runs of the compiler then allowed us to find all static functions required only by the excluded functionality. These were excluded as well.