Starkit and SDX

As you could see in the previous example, Tclkit can be used as a replacement for tclsh, because it is able to run .tcl scripts. This feature, although useful, is nothing new. What is really innovative is that Tclkit is also capable of executing Starkits.

What is Starkit? It is a technology that allows you to pack (or wrap) the entire directory structure containing your scripts and other files crucial for your application into a single file with a virtual system inside of it. Having read the previous sections of this chapter, it won't be a surprise for you that Metakit, along with the appropriate VFS driver, is used to achieve this goal.

The structure and naming convention of directories and files to pack is precisely defined, so Tclkit will be able to locate appropriate scripts inside it and start your application.

The word 'Starkit' also refers to any file created with this technology. Such a file contains your application, is very portable, installation-free, and has no external dependencies. As a convention, these files are named using the .kit extension.

Creating a Starkit file

To create a Starkit file (we will also refer to it simply as 'starkit'), you may use the utility called SDX available at http://www.equi4.com/starkit/sdx.html. What is interesting is that SDX is nothing more than another application delivered in the form of Starkit, and the file is simply called sdx.kit.

SDX accepts a number of command-line options, where the most important ones are:

  • qwrap—a convenient way for the quick creation of the .kit file, when your application comes in the form of a single-file Tcl script
  • lsk—lists the content of a .kit file
  • unwrap—unpacks a .kit file, so you can easily inspect its contents with the file manager of your choice
  • wrap—allows the creation of .kit files based on a strictly defined directory structure that reflects VFS contents

Let's focus on the quick creation of the starkit first. Surely, you still remember our "Hello World" example, constituted from one single file named main.tcl. It is a perfect candidate to be wrapped into a .kit file. For better readability, we will rename main.tcl as hello.tcl, in order to more clearly reflect what the script does. To wrap up our example, put Tclkit and SDX in the same directory, and use the following command:

c:workspaceTclHelloWorld>tclkitsh-win32.upx.exe sdx.kit qwrap hello.tcl
5 updates applied

Once finished, you will notice that a new file called hello.kit is created. Now you can verify if it is working according to your expectations:

c:workspaceTclHelloWorld>tclkitsh-win32.upx.exe hello.kit
Hello World one more time!

At first glance, there is no logical reason to wrap this script, because you simply replace one file with another—but you will see what the differences are in a later section.

To unpack the file you have just created, use the unwrap command:

c:workspaceTclHelloWorld>tclkitsh-win32.upx.exe sdx.kit unwrap hello.kit
5 updates applied

As a result of this command, the hello.vfs directory is created. This directory reflects the contents of the virtual file system stored inside hello.kit. What you will obviously notice first is that this directory contains more files than just hello.tcl. As mentioned before, the structure of starkit's VFS is strictly defined, so SDX's qwrap command works like a wizard and adds all the necessary files and directories. The structure will be explained in more detail later.

Although the qwrap command is handy, it does not cover more complex variants. Imagine the opposite situation: instead of retrieving the full VFS structure from the .kit file, you would actually wrap your already prepared directory tree along with sources of your valuable application. This is where the wrap command becomes handy:

c:workspaceTclHelloWorld>tclkitsh-win32.upx.exe sdx.kit wrap hello2.kit hello.vfs
5 updates applied

The wrap command runs with two parameters—the name of the file to create and the name of the directory to wrap. Therefore, in this case, we simply wrapped the hello.vfs directory into the hello2.kit starkit file. Note that we describe the latest available version of SDX at the time of writing; the earlier releases had a slightly different syntax for this command.

The second parameter can be skipped. In this case, if first parameter is in the form of<app-name>.kit. The wrapper will search for the<app-name>.vfs directory to wrap, so the command line will be:

c:workspaceTclHelloWorld>tclkitsh-win32.upx.exe sdx.kit wrap hello.kit
5 updates applied

It is important to notice that, by default, the starkits produced by SDX are read-only. If you would like your application to have the ability to modify or write files inside a wrapped VFS, you will have to specify the -writable flag:

c:workspaceTclHelloWorld>tclkitsh-win32.upx.exe sdx.kit wrap hello.kit -writable
5 updates applied

Internal structure of starkits

If you are thinking seriously about using Starkit technology, the structure of VFS inside it can not be any mystery to you. Let's first inspect the hello.vfs directory from the previous example, and then discuss how to improve it with additional files crucial for your application.

Internal structure of starkits

The top-level directory contains:

  • The main.tcl file—this script is interpreted once the VFS has been mounted at start time.
  • The lib directory—this holds additional packages required for your application. Every package is kept in a separate subdirectory. The most important thing is that, by default, your application is also automatically converted to a package. The naming convention for such a package is app-your_application_name, so in this case, the name is app-hello.

Let's focus on main.tcl first. In our case, this file was generated automatically by SDX's qwrap command, and its contents are:

package require starkit
starkit::startup
package require app-hello

The first line is obvious and causes the starkit package to be loaded. This package is an integral part of Tclkit, responsible for proper handling of the entire Starkit technology. Once this package is loaded, the starkit::startup command is available to be called. The command performs two important actions:

  • It modifies the auto_path variable, so it includes the lib subdirectory, effectively causing all packages stored there to be available for your application.
  • It sets starkit::topdir variable. The value of this variable is a (virtual) path that points to the directory where main.tcl is located.

After the starkit::startup command is run, we can assume that the packages from the lib subdirectory can easily be loaded—regardless of whether we run main.tcl from hello.vfs, a starkit, or a Starpack (which is described later). This feature provides great flexibility for code development—you don't have to generate a starkit after each change, because you will still be able to run the script in the normal way.

The starkit::startup command also returns a value that may be used to distinguish how the script was invoked. It returns the following values:

  • unwrapped—the script was executed in a normal way, using the command tclkit hello.vfs/main.tcl
  • starkit—the script is executed as a part of starkit, using the command tclkit hello.kit
  • starpack—the script is executed as a part of Starpack (discussed in the next section), for example, hello.exe
  • sourced—the script was sourced from the another script using the command source hello.vfs/main.tcl

This value can be used for altering the operations of the script depending on the way it was executed.

At this point, package require app-hello can be called successfully, causing your wrapped application code to be executed. What really happens is that the pkgIndex.tcl file is sourced. Its content is:

package ifneeded app-hello 1.0 [list source [file join $dir hello.tcl]]

Therefore, effectively, it sources the hello.tcl file. If you look inside it, you will find that this is basically the original file you wrapped in, with a slight modification to the first line:

package provide app-hello 1.0
puts "Hello World one more time!"

The line with the package information was automatically added by qwrap.

It is important to mention at this point, that this structure is not obligatory. The mandatory items are only the main.tcl file and, in case you want to use some packages that are not built into Tclkit, the lib directory. You can put your entire application code into main.tcl, or some other files inside the VFS structure of your choice. You could even sacrifice the starkit::topdir variable (while handling the lib directory) and not use the starkit package at all. However, we do not recommend such a daring move—coding standards were not invented only to be, but also to facilitate understanding and development for other people. Just imagine what would happen if you wanted to maintain some weird code written by a bold programmer who believes standards are not his concern!

Using resource files in starkits

Often, your application will consist not only of script files, but also other items as well—for example, graphical images or sound files. There is no problem in putting additional files and directories inside the contents of the VFS, and the wrap command will put them all inside the starkit file. Assuming you placed a file, say image.jpg in a VFS subdirectory called images (images/image.jpg), you can refer to it in your scripts as follows:

$starkit::topdir/images/image.jpg

Putting additional packages into a starkit

As mentioned earlier, the starkit::startup command extends the $auto_path variable so it includes the lib directory. Therefore, adding additional packages is nothing more than putting them into this directory. Then the extension is available and you can use it in your code in the standard Tcl way:

package require <name_of_extension>

Format of the starkit file

If you display hello.kit (or any other .kit file) with any text viewer/editor, you will notice that it starts like a normal script file:

#!/bin/sh
# 
exec tclkit "$0" ${1+"$@"}
package require starkit
starkit::header mk4 readonly

After this header comes the binary data (that forms the content of the Metakit database lying below the VFS). Such a header allows you to run .kit files directly on any Unix-like system by simply adding executable permissions and putting tclkit in your system path. On a Windows system, you will have to associate the .kit extension with a Tclkit program in order to achieve this functionality.

When the header is interpreted by Tcl, the starkit package is loaded. This package is included in all Tclkit versions. The last line causes the starkit package to mount the VFS and start processing the files stored inside it.

Interactions between different starkit files

Your application does not have to be limited to only one starkit file. It is possible to use the Tcl command source with .kit files, for example:

source hello.kit

It may seem a little magical at first, but as we already mentioned, a .kit file starts with normal Tcl script commands, and after interpreting the data, it effectively executes main.tcl inside that starkit. If that script includes a call to the starkit::startup command, it will expand the auto_path variable including libraries (extensions) from the new .kit file, and also replace the starkit::topdir variable's value (so it is important to store its value before sourcing):

set topdir $starkit::topdir
source hello.kit
set starkit::topdir $topdir

The main disadvantage is that the entire main.tcl file will be executed, and if you just want to make packages from another .kit file available, this is undesired behavior. In such a situation, instead of sourcing the .kit file, it is better to:

vfs::mk4::Mount /path/to/file.kit /path/to/file.kit -readonly
append ::auto_path /path/to/file.kit /path/to/file.kit/lib

The first line mounts the hypothetical file.kit file (located at /path/to) at the mountpoint named /path/to/file.kit (that's right, a good standard in case of VFS is to mount it under the same name as the original file containing it). On the other hand, the second line extends the auto_path variable.

Starkit files are perfect candidates for delivering ready-to-use pieces of code like extensions/packages. This idea is implemented in terms of sdarchive (found at the website http://tcl.tk/starkits), which is nothing more than a collection of ready-to-download and ready-to-use starkits. If your application uses a lot of packages, it is up to you to decide whether to put all of them into one main .kit file or use some starkits from sdarchive.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.201.217