| Store | Cart

ActiveState Docs

TDK 4.1 Documentation

Loading...

TclApp

An application that you write in Tcl can consist of many components, such as:

  • One or more Tcl scripts
  • Either a standard or a custom Tcl interpreter
  • The standard Tcl libraries and support files (for example, init.tcl)
  • Optionally, the standard Tk libraries and support files
  • Optionally, one or more extensions implemented as libraries of Tcl scripts
  • Optionally, additional data files such as bitmaps

Traditionally, if you wanted to distribute an application that you wrote in Tcl, you would need to make sure that all of the files that your application used were installed on the target system. You would also need to make sure that the system was configured so that your application could find all of the files it needed.

Tcl Dev Kit's TclApp can greatly simplify the process of distributing an application that you write in Tcl. TclApp is a tool that collects all of the files needed to run a Tcl application--such as Tcl scripts, graphics and other data files, Tcl extensions, a Tcl interpreter, and the standard Tcl and Tk libraries--into a single executable file. A user can then install this file anywhere on their system and execute it without installing any other packages or otherwise configuring their system.

TclApp includes both a graphical and a command-line interface. To launch the graphical interface, on Windows, select Tcl Dev Kit TclApp from the Tcl Dev Kit program group on the Windows Start menu. Alternatively, enter tclapp.exe at the command prompt. On Unix, enter tclapp at the shell prompt. To use the command-line version of TclApp, follow the tclapp.exe (or tclapp, on Unix) command with switches.

For example, the command shown below creates an executable named myApp.exe containing the standard Tcl and Tk libraries, the Tcl scripts myApp.tcl and help.tcl, and several GIF images from a subdirectory named images. The following example assumes the command is run on a Windows system. To run the same command on a Unix system, substitute the appropriate command-line syntax (tclapp without the .exe file extension).

C:\> tclapp.exe -prefix base-tk.exe -out myApp.exe myApp.tcl help.tcl images\*.gif

Executing the resulting myApp.exe file is equivalent to entering:

C:\> wish myApp.tcl

To learn about TclApp in a tutorial, see TclApp on the Demos page for more information.

About Starkits and Starpacks

A starkit is a single file that packages a set of Tcl scripts, platform-specific compiled code and application data. It relies on an external run-time interpreter. A starpack is a single executable file that contains both a starkit and an interpreter.

TclApp generates a starpack when a basekit is specified as a build option. Specify a basekit in the Prefix file field on the Basic Tab in the graphical TclApp, or using the -prefix option on the command line. See Specifying the Interpreter: Creating Starpacks and Starkits for more information.

See http://www.equi4.com/191 for an Anatomy of a starkit.

Converting Starkits to Starpacks

The command-line version of TclApp includes a -genpak option used to convert an existing starkit to a starpack. The command syntax is as follows:

  tclapp -genpak \
         basekit \  (Like -prefix in regular use)
         starkit \  (The starkit to convert)
         result  \  (Like -output in regular use)
         ...        (Aditional regular options)
         

For example, tclapp -genpak mybasekit mystarkit myresult will generate a file called "myresult" that uses the prefix file "mybasekit" and contains the contents of "mystarkit".

This command is the equivalent of:

  1. Unpacking the starkit into a temporary directory.
  2. Running the command:
      tclapp -prefix basekit -out result \
    			-anchor / -nospecials -relativeto TempDir \
    			_All_Files_Under_TempDir_
      
  3. Deleting the temporary directory.

Note about Starpacks

Tclkits and basekits (files matching base-* in ActiveTcl's bin directory) limit ::auto_path by default to only look in the wrapped application's lib directory upon startup. This means the application in the starpack is unable to find packages outside of itself. To circumvent this restriction, the application can extend ::auto_path to include the location the unwrapped additional packages that it needs.

This solution has compatibility and security implications. This default behavior exists to ensure that starpacks are seen as completely self-contained. By allowing them to search externally for packages, it becomes possible to substitute the packages it uses with incompatible versions or arbitrary code by incrementing the minor version number. This is independent of the order of paths in ::auto_path. Use package require -exact in the application and its dependencies to prevent this from happening if you extend ::auto_path.

Preparing an Application for Wrapping

There are minor differences in the way an application runs when it is wrapped versus when it runs unwrapped. However, it is relatively easy to modify your application so that you can test it in unwrapped form, and then wrap the same files for distribution. This section shows you how to change your application to ensure that it works properly both unwrapped and wrapped. This section also covers wrapping custom packages.

Detecting when an Application Is Wrapped

Because TclApp supports the Virtual Filesystem, the tcl_platform(isWrapped) variable is no longer required. Conditional code that relies on this variable should generally be rewritten to make use of standard filesystem operations.

If you have a special case where you need to check the status of an application (wrapped or unwrapped), use the following code in the application:

  set iswrapped [expr {[lindex [file system [info script]] 0] ne "native"}] 

The status variable iswrapped will be true or false depending on the result of the test.

Modifying Custom Shells

TclApp can use specially written Tcl interpreters to work with wrapped applications in Starpacks. When using the command-line TclApp, specify interpreters using the -prefix switch.

Creating a Statically Linked Wrapped Application with a Standard Interpreter and Custom Initialization Files

When creating a statically linked wrapped application with a standard interpreter and custom Tcl initialization files, your tclapp command line must include the following:

  • All of your custom Tcl initialization files
  • Any -code options that are required to initialize other Tcl configuration variables such as tk_library.

For example, the following wraps an application with the a basekit and a set of initialization files contained in the directory /usr/local/siteTcl/lib:

% tclapp -prefix base-tcl-win32-ix86.exe -out myApp myApp.tcl img/*.gif \
/usr/local/siteTcl/lib/tcl8.2/*.tcl \
/usr/local/siteTcl/lib/tcl8.2/tclIndex \
/usr/local/siteTcl/lib/tcl8.2/encoding/*.enc \
/usr/local/siteTcl/lib/tk8.2/*.tcl \
/usr/local/siteTcl/lib/tk8.2/tclIndex \
-code "set tk_library usr/local/siteTcl/lib/tk8.2"

Accessing Files from a Shared Directory

Files shared by multiple applications or projects are typically put in a shared directory, often on a file server. An application myscript.tcl might then access those files as follows:

set shared {Z:\tcl\common}
source [file join $shared help.tcl]
source [file join $shared display.tcl]

Unfortunately, because of the absolute pathname, the code above no longer works if you wrap the files in the shared directory with the application.

However, you can easily modify this code to work either unwrapped or wrapped by testing to see whether the application is wrapped and modifying the value of shared appropriately. For example:

if {[info exist starkit::startup]} {
set shared [file join starkit::topdir ... common]
} else {
set shared {Z:\tcl\common}
}
source [file join $shared help.tcl]
source [file join $shared display.tcl]

You would then need to wrap the shared files using the -relativeto, -anchor and -alias flags (if using the command-line TclApp) or by specifying relative paths (if using the graphical TclApp wrapper), as in the following example:

C:> tclapp myscript.tcl -relativeto Z:\tcl Z:\tcl\common\*.tcl

Accessing Wrapped Files Relative to a Script's Directory

A common trick to avoid hard-wiring pathnames into scripts is to figure out where the script is located with the info script command and then accessing files relative to the script's directory. For example:

set home [file dirname [info script]]
source [file join $home help.tcl]
source [file join $home display.tcl]

Wrapping Custom Packages and Definition Files

When wrapping an application containing custom packages, you must create a custom TclApp Package definition (.tap) file for each package. The .tap file specifies the files contained within each custom package. Use the TDK Package Editor to create a new package or to save a package definition (.tap) file.

Locating Custom Packages and Definition Files with TclApp

To ensure TclApp finds all custom packages and .tap files when wrapping an application, choose from the following options below. Note that TclApp finds custom .tap files for packages not included with the Tcl Dev Kit using either option.

  • Set the TclApp Preferences: Open the preference dialog and enter a list of paths to search for packages. TclApp will find all .tap files placed in these directories and all their subdirectories one level deep.

    and/or

  • Set the Environment Variable to the Directories: Set the environment variable TCLAPP_PKGPATH to a list of paths to search for package definition files. TclApp will find all .tap files placed in these directories and all their subdirectories one level deep.

    Put all your custom .tap files into these custom directories.

For information on moving packages and .tap files, see Using Placeholders for Portability in the Package Editor guide.

Using Tcl_InitStubs in Compiled Packages

Custom binary packages must be built with the Tcl stubs mechanism initialized (i.e. using Tcl_InitStubs(interp, version, exact)) to work with TclApp. For more information, see How to Use the Tcl Stubs Library and the Tcl_InitStubs man page.

Top

Using the Graphical TclApp

Tcl Dev Kit TclApp is a graphical interface for the TclApp wrapper. To launch the graphical wrapper, select Tcl Dev Kit TclApp from the Tcl Dev Kit program group on the Windows Start menu, or enter tclapp on the command-line. (To launch the command-line wrapper, you must specify arguments with the tclapp command.)

When running the graphical wrapper on Unix systems, the DISPLAY environment variable must be configured in order to launch the program.

Field and Color Conventions

  • Case Sensitivity: Path and file name specifications are not case-sensitive on the Windows platform, but are case-sensitive on Unix platforms.
  • Directory Slashes: Either frontslashes or backslashes can be used to indicate directories on the Windows platform. On Unix platforms, directories can only be specified with frontslashes.
  • Field Colors: When a non-existent path or file is specified or an invalid value is given, the text is highlighted (yellow background on Windows and OS X, red text on Linux).
  • Tooltips: Context-sensitive tooltips are displayed when the mouse pointer hovers over the graphical wrapper fields. These are especially useful on highlighted errors. The tooltip will provide explanatory information about the error.
  • Changing Font Size: Use Ctrl-plus to increase and Ctrl-minus to decrease the displayed font size. On Windows, you can also use Ctrl with the mouse wheel.

TclApp Projects

TclApp project definitions are stored in text files with .tpj extensions. When the graphical version of TclApp is first invoked, no project is loaded.

To load an existing project: select Load Project from the File menu.

To save a project: select Save Project from the File menu, and specify a directory location and project name for the project file.

To create a new project: select New Project from the File menu. This will reset the fields in TclApp to their default state.

Basic Tab

The Basic tab is for specifying general characteristics of the wrapped executable.

Prefix file: Use this field to include an interpreter in the output file (thus creating a starpack).

The specified file must exist, must to be readable, and must contain a Metakit Filesystem (MFS). The presence of additional data before the MFS is allowed, and makes starkits and starpacks possible.

If no prefix is specified, the output will include the starkit header by default, and will require an external interpreter to run.

To create a starpack, use a basekit as prefix file. ActiveTcl includes basekits located in the bin directory: base-tcl* and base-tk* (which is base-tcl plus tk) are included for each platform; base-tclsvc* is included with Tcl Dev Kit on Windows, and is used to create portable Services. You may also specify a custom basekit (most newer starkits are compatible), or a basekit for a different platform (available from the ActiveState TEApot repository via teacup get). The basekit could also be generated by TclApp.

If an icon file is associated with the prefix file, it will be displayed to the left of the Prefix file field. The text "no icon" will be displayed if no prefix file has been specified or if no icon is associated with the specified file.

  • Select Encodings: Select encodings to add to those already supported by the basekit specified above (normally standard European encodings). You may specify multiple encodings using 'Ctrl-click' (add a single encoding) or 'Shift-click' (select block). Although the encodings are always added to the wrapped application, they will have an effect at runtime only if a basekit was specified. Selection of additional encodings is relevant only when generating a starpack.
  • Show Prefix Packages: Brings up a dialog box showing all packages provided by the specified basekit.

Custom icon: Custom icons can be assigned to wrapped applications using the Custom icon field. Icon files are specified with an ".ico" (Windows and Unix) or ".icns" (OS X) extension. The selected prefix file must support the icon file type you are using. Selecting a custom icon will override any icon associated with the prefix file. TclApp will check geometry and color depth (bits per pixel, bpp) of the specified icon file against the icon specified in the prefix file. (Results of the comparison will be displayed in a tooltip generated when the mouse hovers over the Custom icon field.) It will replace only the parts which match, and leave the remainder untouched.

Note: ".icns" images cannot be previewed in the Custom icon panel.

For an exact description of the comparison between the custom icon and the prefix file icon, see Assigning a Custom Icon to the Output File in the command-line section.

Interpreter: If no Prefix file is specified, use the Interpreter field to specify the interpreter that should be used to run the starkit.

If a Prefix file is specified, that file will be used to run the application. However, within the Prefix file, it may be possible to specify an interpreter. If the prefix file contains the string @__interpreter__@ in the first 200 characters of the file, then the value specified in the Interpreter field will replace the @__interpreter__@ string during wrapping.

Note that on Windows, the file extension is used to determine the interpreter; information in the header is ignored. However, the interpreter specification would be relevant when building applications that will be deployed on platforms other than windows.

Modifiers:

  • Compile .tcl files: If this option is selected, all files with the extension .tcl (except for files named 'pkgIndex.tcl') are compiled to tcl bytecodes before they are stored in the output metakit filesystem. Tcl files specified in packages are not compiled. To wrap a package in compiled format, use the Tcl Dev Kit Compiler to compile the files specified in the package, then create a package that includes the compiled files.

    For the execution of such a starkit, the package tbcload has to be present. To ensure this, tclapp wraps that package automatically (unless the no tbcload option is enabled).

  • no tbcload: By default, if Compile .tcl files: is specified, the 'tbcload' package is automatically included. To prevent the 'tbcload' package from being wrapped, check (no tbcload). If the 'tbcload' package has been added on the Files Tab, it will be included regardless of this setting.

  • Suppress special files: TclApp normally stores a './main.tcl' file. This file contains code telling the tclkit running the wrapped application which package or file to load to invoke the application. Specifying this option suppresses the generation of the file. Specifying this option effectively cancels out the effects of the Set Main button on the Files tab.

    Use this option to wrap a code base that already provides main.tcl.

  • Suppress list of packages wrapped in the prefix: Useful for most wrapped applications where the list of provided packages is not used. If you are creating a basekit, leave this option de-selected.

Output File Options:

  • Merge selected files: This option will merge the specified files and packages into the file specified by the Output File option. It cannot be used in conjunction with the Prefix field.

  • Output file: The default name of the output file generated by TclApp is tclapp-out. To specify an alternative name, enter the desired path and name in this field. The file does not need to exist, but if you specify a directory, the directory must exist and must be writable. (If the Merge option is specified, the file must exist and must be writable.)

    If no file extension is specified, TclApp will use the same file extension as the Prefix file. (If the prefix file has no extension, the output file will have no extension.) If no prefix file is specified, on Windows, TclApp will automatically add the extension '.tcl'. On all other platforms, no extension will be added.

  • Make an OS X Application Bundle: Creates an OS X '.app' directory structure for the wrapped application. This is recommended for user interface applications on OS X, but not neccessary for command line applications.

  • Target Architecture: The Target Architecture button brings up a dialog box which allows you to manually configure the target architecture(s) for Starkits. When a basekit is specified (i.e. for building a Starpack) the target architecture is automatically set to that of the basekit. The following values can be used.

    TDK distributions:

    • aix-powerpc
    • hpux-parisc
    • linux-glibc2.2-ix86
    • macosx-universal
    • solaris2.10-ix86
    • solaris2.6-sparc

    ActiveTcl, ActiveTcl Enterprise and OEM:

    • hpux-ia64
    • linux-glibc2.3-ia64
    • linux-glibc2.3-x86_64
    • macosx-ix86
    • macosx-powerpc
    • solaris2.8-sparc

  • Metadata and String Resources: The three buttons at the bottom-center of the Output file panel are for specifying:

    • TEApot metadata
    • OS X Info.plist metadata (OS X applications only)
    • Win32 String Resources (Windows applications only)

Files Tab

Use the Files tab to specify the packages, files and directories you wish to include in the output. Files and directories may be specified as either absolute (by specifying the entire drive and path) or relative (by specifying only the relative directories or filename).

To add individual files: Click the File button to the right of the files field. Navigate to the desired file, and then double-click to add the file to the list. (Select multiple files by using the Ctrl or Shift keys.) Files added by this method will have absolute paths. Alternatively, specify the file name of the desired file (and, optionally, the full or relative path) and click the Add button or press the Enter key. Files added by this method will have absolute or relative paths depending on how they were specified.

To add individual files using wildcards: Enter the file specification in the field at the top of the Files tab. For example, to add all files with the extension ".tcl", enter "*.tcl" in the file field.

To add a directory: Click the Folder button to the right of the files field. Navigate to the desired directory, then double-click to add the directory to the list. Alternatively, specify the directory (and, optionally, the complete path) in the field at the top and click the Add button or press the Enter key. Adding a directory will not add any files; to do this, select the directory in the file list, then use the field at the top of the dialog to specify one or more files in that directory for inclusion. File specifications may include wild cards (see above).

To add all files and directories beneath a directory: Click the folder/file button on the far right. All files and directories located beneath the specified directory will be added to the archive.

To remove a file or directory: Select the file or directory in the list, then click the Remove button or press the Delete key.

To specify the startup file: In the list field, click the file you wish to run when the output file is executed, then click the Set Main button.

To edit an entry in the file list: Select the desired item, and click the Edit button.

Packages Tab

The Packages tab is used to specify packages to include in the wrapped executable.

The main window shows a list of packages and their version requirements (if any). Packages are added to and removed from the list using the following controls:

  • Edit repository list: TclApp searches for packages in the following order:
    1. the prefix file (if specified)
    2. files specified explicitly in the Files tab
    3. TEApot repositories configured for the project
    4. TEApot repositories configured globally in the Preferences Dialog
    5. a virtual repository containing only Tcl and Tk (if no prefix file is specified)
    6. globally configured TAP search paths
    To add, remove, or change the search order of project repositories click the Edit Repositories buton. This brings up a dialog for specifying or browsing for TEApot and .tap repositories. ActiveState's TEApot repository can be easily added from the drop list.
  • Scan for required packages: Scans for packages required by the specified application files.
  • Add required dependent packages: Adds package dependencies of the required packages using configured TEApot repositories.
  • Add required and recommended dependent packages: As above, but also adds packages listed as recommended (in the TEApot metadata).
  • Add packages from list of all packages: Brings up a dialog box with a complete list of packages available from the sources mentioned above. Packages can be selected individually and added to the main list.
  • Remove selected package: Removes the currently selected package from the list below.

Note: Scanning for required packages and adding dependent packages does not verify that the packages are actually available locally or in the repositories. This verification happens during wrapping, and missing packages will appear as errors in the command output on the Run tab

Advanced Tab

The Advanced tab is used to specify command line arguments for the script, initialization actions, etc.

Verbose log: By default, TclApp suppresses output while processing options and wrapping files. The Verbose flag activates additional logging of current activity while TclApp is running.

Temporary build directory: This field is used to specify a directory that TclApp uses to temporarily hold files created during the wrapping process. By default, TclApp uses the directory specified in the TEMP, TMP, or TMPDIR environment variables (which are checked in that order).

Initialization: Used to run specified code before the starkit support is loaded and initialized, and before the application package or main (startup) file is loaded/invoked.

Arguments: Used to specify additional arguments to pass to the wrapped application. These are treated as if they were submitted to an unwrapped application on the command line. The arguments are stored in the Tcl argv variable. Arguments specified here are inserted before any command-line arguments entered by the end user when they execute the wrapped application.

Nonstandard package directories: Use this field to specify additional non-standard package directories. All listed paths are seen as relative to the root of the generated archive. During startup of the wrapped application, they are added to the auto_path variable of the tcl interpreter, causing the interpreter to look in these directories for packages. These paths must be specified if a wrapped package is placed into a nonstandard location (i.e. outside of '/lib').

Run Tab

Use the Run tab to generate the output file and display the corresponding command line string. If the activity field is blank and the Wrap button is enabled, the project configuration contains no errors and is ready to run. If the project configuration contains errors, an interpretive message with a red background will be displayed in the activity field, and the Wrap button will be disabled. You must fix the errors on the other tabs before you can wrap the project.



Preferences Dialog

Use the Preference Dialog to manage the list of paths used by TclApp when searching for package definition files.



Top

Using TclApp on the Command-Line

This section explains how to wrap applications from the command line. First we provide examples for the most common tasks and switches, this is then followed by a more detailed review of all the command line switches of TclApp. If a only a reference sheet is required see the TclApp Command Line Reference.

Basic Wrapping

Wrap a file 'app.tcl', generate a starkit, use the default name 'tclapp-out' for the result.

C:> tclapp app.tcl

As before, but generate a starpack. This requires the specification of a basekit to be used as the runtime of the result.

C:> tclapp -prefix basekit.exe app.tcl

As before, but also specify the name of the result as 'myapp.exe'.

C:> tclapp -prefix basekit.exe -out myapp.exe app.tcl

As the first example, and additionally put the 'snit' package into the wrap result. As no version number is specified for 'snit' TclApp will wrap the highest version it finds.

C:> tclapp -pkgref snit app.tcl

As before, but a specific version of 'snit' is requested. More complex specifications are possible, like ranges of allowed versions, restriction to specific entity types, platforms, etc. For this see the section about Entity references in the TEApot Meta Data Specification, and the acompanying examples.

C:> tclapp -pkgref 'snit 1.3' app.tcl

By default TclApp will wrap exactly the packages which have been specified, but none of their dependencies. Now ask TclApp to include not only the specified packages, but all of their required dependencies, recursively.

C:> tclapp -pkgref 'snit 1.3' -follow app.tcl

When packages are not found specify more repositories to search. Here we ask TclApp to look in ActiveState's public TEApot repository first.

C:> tclapp -pkgref 'Tkhtml 3-' -archive http://teapot.activestate.com app.tcl

Note: Instead of specifying the archives to search every time TclApp is invoked it is possible to put them into the global configuration. This is currently only acessible through the Preferences Dialog in the GUI, but has to be done only once.

As before, now creates a starpack. The invisible magic here is that TclApp looks into the specified basekit to see what architecture it is for and retrieves matching packages from the repository (if they are binary, like Tkhtml). This makes cross-wrapping easy, i.e. the wrapping of an application for platform FOO on a machine with a different architecture.

C:> tclapp -prefix basekit -pkgref 'Tkhtml 3-' -archive http://teapot.activestate.com app.tcl

With the examples above we have now covered the most common command line switches and their meaning, i.e.

-prefix
Basekit to use as runtime for a starpack.
-out
Name of the wrap result.
-pkgref
Packages to wrap.
-follow
Follow package dependencies.
-archive
Search packages in more repositories.

Wrapping Files

To wrap one or more Tcl scripts and any associated data files (for example, bitmaps), simply list all the files as arguments to the tclapp command. For example, suppose you have an application consisting of a single script file, app.tcl. To wrap it, enter:

C:> tclapp app.tcl

This creates a wrapped application called tclapp-out. When you run the wrapped application, it will look in the Tcl Dev Kit installation for the appropriate interpreter to run the application.

If your application has several script files, just include them on the tclapp command line. For example, if app.tcl sources the files utils.tcl and help.tcl from the aux subdirectory, you can wrap them with the following command:

C:> tclapp app.tcl aux\utils.tcl aux\help.tcl

Important: By default, your wrapped application sources the first file you list in the tclapp command. So, in this example, when you execute your wrapped application, it sources app.tcl. You can change this behavior with the -startup option (on the command line, or by using the Set Main button in the graphical TclApp.

You can use wildcard characters in your file names to specify multiple files. On Windows systems, tclapp uses Tcl's glob command to handle wildcard expansion. (See the Tcl glob reference page for details of its operation.) Therefore, in the above example, if utils.tcl and help.tcl were the only .tcl files in the aux subdirectory, you could accomplish the same effect as above with the following command:

C:> tclapp app.tcl aux\*.tcl

The files that you wrap are stored in the wrapped application's internal file archive. See How the Internal File Archive Works in a Wrapped Application for more information.

Wrapping Packages

Rather than specifying individual files, it is often easier to construct a package which lists a group of files. Packages can be fetched from the ActiveState TEApot repository or constructed using the Package Editor.

When these packages are included in a wrap specification, the files listed in the package will be included in the resulting output file.

Use the -pkgref NAME switch to specify packages to be included in the wrapped application.

TclApp searches for packages in the following order:

  1. the prefix file (if specified)
  2. files specified explicitly with -pkgfile
  3. TEApot repositories configured for the project with -archive
  4. TEApot repositories configured globally in the TclApp Preferences Dialog.
  5. a virtual repository containing only Tcl and Tk (if no prefix file is specified)
  6. globally configured TAP search paths (from the TclApp Preferences and the TCLAPP_PKGPATH environment variable)

Legacy TAP package definition files created using the Package Editor are located in the /lib/tap directory beneath the root Tcl installation. To search for package definition files in other directories, specify the desired directories using the TCLAPP_PKGPATH environment variable.

The -pkgref option is not required. However, at least one -pkgref NAME must be specified if no individual files are explicitly wrapped.

Files listed in the package are placed into the directory lib/NAME of the output Metakit filesystem. The package NAME has exclusive use of the directory lib/NAME. Placing other files into this directory via file specification options is not allowed.

The NAME argument of -pkgref can be a plain package name, or of the form PKGNAME VERSION. The latter allows the user to request a specific version of the package PKGNAME. More complex forms are possible too, and discussed (with examples) in the section Entity references of the TEApot Meta Data Specification. If the specified version does not exist, a message will be display and the wrap will be aborted. Use the -upgrade option to force the wrap; the highest available version of the specified package will be used.

Three more switches can be used to influence the wrapping of packages:

The -follow switch causes TclApp to inspect the required dependencies of the chosen packages and wrap them as well, inclusive their dependencies, etc.

The -follow-recommend switch is like -follow except that not only required, but recommended dependencies are added as well.

These two options should be used with care. If only a part of a package A requires a package B then B will a declared dependency and drawn in. Even if the functionality of A requiring it is not used by the application to be wrapped. In the case of version-less dependencies it may also find and use packages which are later in conflict with each, or the underlying version of the Tcl core. An example of that would be the selection of snit v2 through a dependency, requiring Tcl 8.5, for Tcl 8.4 based basekit.

Use the -force switch to force TclApp to perform the wrapping even if it was not able find all dependent packages in the archives it had available.

Specifying the Startup Application

Use the -app NAME switch to instruct TclApp that the specified package is the "application" package, that is, the package that will start the wrapped application. TclApp will insert code into the wrap framework to [package require] this package.

If -app NAME is used explicitly, the specified files cannot define the application package anymore. Because of this, the initial destination base path for files (specified using the -anchor switch) reverts from 'lib/application' to '/' (the root of the output metakit filesystem).

If -app NAME is used, usage of the option -startup is illegal, as the package already knows which file(s) to load to run the application.

Wrapping Individual Files

To wrap specific files, enter the file name(s) after the tclapp command. The specified file is read and stored in the output metakit filesystem. If the file is a glob pattern (specified using wildcards), it is expanded into a list of files. Each file in the list is processed as if specified explicitly on the command line. The path of the file in the output MFS is determined by the name of the input file and the current settings for the source base directory (-relativeto), destination base directory (-anchor), and file rename modifier (-alias).

Specifying Source and Destination Base Directories

Use the -relativeto PATH switch to specify the source base directory for the files that follow. This affects the translation of source paths to destination paths. The initial value is '' (i.e. the empty string).

The -anchor PATH switch specifies the destination base directory for the files that follow. This affects the translation of source paths to destination paths. The initial value is 'lib/application', which places explicitly specified files into a default application package, or '/', if -app was specified.

The -alias PATH switch modifies the translation to the destination path of the filename that follows. If that is a glob pattern, it modifies the translation of the first file in the expanded pattern. Note that any intervening argument which is not a file name invalidates this option.

Specifying the Startup File

By default, the wrapped application sources the first file listed after the tclapp command. Use the -startup PATH switch to specify the file in the output metakit filesystem that invokes the application (package). TclApp will insert code into the wrap framework to [source] this file. It will also set 'argv0' to this file (in case the application changes behavior if its file name is not the name of the application). An example of such an application is 'tkcon'.

The -startup flag cannot be used if -app NAME was specified.

-startup can be helpful if you use wildcard characters to specify files to wrap. For example, consider the case of wrapping three Tcl scripts, display.tcl, help.tcl, and main.tcl, all in the same directory, and wanting to source main.tcl when you start your application. You could accomplish this with:

C:> tclapp -startup main.tcl *.tcl

Specify the startup file using a relative path. Files specified with an absolute path will not be found in the wrapped application at execution time.

Specifying Build Options

Verbose versus Quiet Logging

By default, TclApp suppresses output while processing options and wrapping files. The -verbose switch activates additional logging of current activity while TclApp is running.

Storing Log Output

Use the -log option to write output to a log file. The -log FILENAME option must be specified before any other arguments in the command string. For example, -log mylogfile will write the output to the file "mylogfile".

Specifying an External Configuration File

The -config CONFIG_FILE switch is used to specify a file that contains additional configuration options. The contents of the file are processed as if they were specified on the command line as option modifiers, with the following exceptions:

  • Changes to the destination base path (-anchor) inside of the configuration file are canceled after the file is processed, and the state before the processing of the file is restored.
  • If the file is a TDK Prowrap configuration, -anchor '' will be set before processing its contents to ensure compatibility with Prowrap.

A configuration file may contain additional -config specifications. However, the recursive inclusion of a file is not permitted.

This option also accepts a TclApp Project File ('.tpj') as configuration file.

Specifying Output Options

Specifying the Interpreter: Creating Starpacks and Starkits

Use the -prefix PATH switch to include an interpreter in the output file (thus creating a starpack). (Prowrap's -executable option is still supported, but has been deprecated.)

The specified -prefix must exist, must be readable, and must contain a Metakit Filesystem (MFS). The presence of additional data before the MFS is allowed, and makes starkits and starpacks possible.

To create a starpack, use a tclkit as prefix file. The Tcl Dev Kit includes basekits located in the bin directory beneath the Tcl installation: base-tcl* and base-tk* (which is base-tcl plus tk) are included for each platform; base-tclsvc* is included only on Windows, and is used to create portable Services. You may also specify a custom basekit; most newer starkits are compatible. See How do I create a custom base kit? in the Tcl Dev Kit FAQ for more information. Additionally, the base kit could be a kit generated by TclApp.

Basekits for different platforms are available from the ActiveState TEApot repository via teacup get. This makes it possible to "cross wrap" applications for target architectures other than the one TclApp is running on.

It is not possible to directly use the application (tclsh, wish, tclkit) currently used to run TclApp itself as -prefix. A copy of that file has to be used. This is because the file of the application is mounted to get access to the Tcl runtime library stored in the metakit VFS at the end of the file. Because of this, the application itself sees the file as directory, and directories cannot be used for -prefix. This also means that we are unable to copy the contents of that file from within tcl / tclapp.

If no -prefix (or -executable) option is specified, the output will include by default the starkit header, and will require an external interpreter to run. Use the -interpreter PATH switch to specify an external interpreter.

If -prefix PATH is specified, that file will be used to run the application. However, within the Prefix file, it is possible to specify an interpreter. If the prefix file contains the string @__interpreter__@ in the first 200 characters of the file, then the value specified by the -interpreter setting will replace the @__interpreter__@ string during wrapping.

Note that on the Windows platform, the file extension is used to determine the interpreter; information in the header is ignored. However, the interpreter specification would be relevant when building applications that will be deployed on platforms other than windows.

Specifying the Output File Name

The default name of the output file generated by TclApp is tclapp-out. To specify an alternative name, use the -out PATH switch. The file does not need to exist, but if you specify a directory, the directory must exist and must be writable. (If the -merge switch is specified, the file must exist and must be writable.)

If no file extension is specified, TclApp will use the same file extension as the -prefix file. (If the prefix file has no extension, the output file will have no extension.) If no -prefix file is specified, on Windows systems TclApp will automatically add the extension '.tcl'. On all other platforms, no extension will be added.

When using a -prefix file, the prefix file's extension will be used as the default extension for the generated application (if no explicit output file name is specified). If the prefix has no extension, the name of the generated application will have no extension.

Creating a '.app' Bundle (Mac OS X only)

The -osxapp creates an OS X '.app' directory structure for the wrapped application. This is recommended for user interface applications on OS X, but not neccessary for command line applications. The wrapped executable itself is put in 'application.app/Contents/MacOS/'.

Merging the Output

The -merge option will merge the specified files and packages into the file specified by the -out switch. It cannot be used in conjunction with the -prefix (or -executable) switch.

Assigning a Custom Icon to the Output File

To assign a custom icon to the output application, use the -icon PATH option. Icon files have an ".ico" extension (Windows and Unix) or an ".icns" extension (OS X). This function can only be used in conjunction with the -prefix option, and the specified prefix file must support the icon file type you are using. Selecting a custom icon will override any icon associated with the -prefix file.

For ".ico" files TclApp will check geometry and color depth (bits per pixel, bpp) of the specified icon file against the icon specified in the prefix file. The icon dimensions must match the dimensions of the icon associated with the prefix file. It will replace only the parts which match, and leave the remainder untouched.

For example, if the -prefix file contains an icon with two variants of 32x32/4bpp and 32x32/8bpp, and the custom -icon file contains the variants 16x16/4 and 32x32/4, the following would result:

  • The 16x16/4 variant is ignored as there is no match in the specified -prefix file.
  • The 32x32/4 variant in the prefix is replaced with the one in the -icon file.
  • The 32x32/8 variant in the -prefix file is left untouched as there is no match in the -icon file.

Failures resulting from an incorrect -icon specification, (such as mis-matched icon dimensions) will generate warnings but will not cause the build to fail.

Setting Custom Metadata into the Output File (Cross-platform)

To set custom TEApot metadata in the output application, use the -metadata DICT option. The argument DICT is interpreted as a Tcl dictionary (i.e. a Tcl list where keys and associated values are listed in alternation). For example:

    -metadata {name myapp version 0.1 platform macosx-universal}

If this option is used, 'name' and 'version' keys are required. If 'platform' is not specified, the platform TclApp is running on is assumed.

Setting Custom String Information into the Output File (Windows specific)

To set custom string information into the output application, use the -stringinfo DICT option. This function can only be used in conjunction with the -prefix option, and the specified prefix file must support string information. Using custom string information will override any existing string information associated with the -prefix file. The argument DICT is interpreted as a Tcl dictionary, i.e. a Tcl list where keys and associated values are listed in alternation. For example:

    -stringinfo 'Language 0409 CodePage 04b0 FileDescription {Coins Animation} ...'

TclApp will check the specified keys against the keys specified in the prefix file, and will generate warnings if keys are dropped from or added to the file.

Failures resulting from an incorrect -stringinfo specification, (such as a too large replacement string) will generate an error and cause the build to fail.

Setting Custom Info.plist Information into the Output File (Mac OS X specific)

To set custom info.plist information into the output application, use the -infoplist DICT option. This function can only be used in conjunction with the -osxapp option. The argument DICT is interpreted as a Tcl dictionary, i.e. a Tcl list where keys and associated values are listed in alternation. For example:

    -infoplist 'CFBundleName myapp CFBundleShortVersionString {} CFBundleVersion ...'

Suppressing Special Files

TclApp normally stores a './main.tcl' file that contains code that instructs instructing the tclkit running the wrapped application which package to load to invoke the application.

Use the -nospecials option to suppress the generation of this file. This can be used to wrap a code base that already includes the file. This option effectively negates the effects of the -startup and -app flags. For the latter, it still behaves as -pkg, but without the marking of an application package.

Suppressing Compression

TclApp normally uses zlib's deflate to compress the stored files. This can lead to long wrap times when the wrap includes large, difficult to non-compressible files.

Use the -nocompress option to disable the compression step. For the situation above this will bring wrap times back to sensible values, but can also lead to a much larger wrapped application as nothing is compressed any longer.

Compiling .tcl Files

If the -compile switch is specified, files with the extension .tcl (except for files named 'pkgIndex.tcl') are compiled to tcl bytecodes before they are stored in the output metakit filesystem. Tcl files specified in packages are not compiled. To wrap a package in compiled format, use the Tcl Dev Kit Compiler to compile the files specified in the package, then create a package that includes the compiled files.

For the execution of such a starkit, the package 'tbcload' has to be present. To ensure this, tclapp wraps that package automatically. In other words, compiling implies -pkg tbcload. To prevent the 'tbcload' package from being wrapped, specify -notbcload. If the 'tbcload' package is being specifically added using the -pkg switch, it will be included regardless of the -notbcload setting.

There may be situations where the unconditional compilation of all .tcl files is not wanted. If only some of the specified files must not be compiled use the switch-nocompilefile to exclude them from the compilation. This is done by putting the switch in front of just the excluded files. And in the complementary situation, i.e. to force the compilation of only a few files, use the switch -compilefile, again by putting it in front of the files to be compiled.

If a -prefix file is specified the compiler will generate bytecodes for the Tcl version found in the prefix.

If however either no prefix was specified, or it was not possible to determine which version of Tcl is used by the prefix TclApp will generate bytecodes for Tcl 8.4, as they can be loaded into Tcl 8.5 as well, i.e. are more compatible.

To override TclApp's choice in these cases use -compilefor to specify explicitly the version of Tcl for which to generate bytecodes for.

Advanced Options

Specifying Run-Time Arguments

Use the -arguments ARGUMENT_LIST option to specify additional arguments to the wrapped application. These are treated as if they were submitted to an unwrapped application on the command line. The arguments are stored in the Tcl argv variable. Arguments specified using this switch are inserted before any command-line arguments entered by the end user when they execute the wrapped application.

If this switch is specified multiple times, only the last specification takes effect.

Provide the arguments as a single argument on the TclApp command line; use proper quoting conventions of your command shell to accomplish this. For example, the following example passes the arguments -height 50 -width 20 to the main.tcl script:

c:> tclapp main.tcl img\*.gif -arguments "-height 50 -width 20"

Specifying Code to Execute at Application Startup

The -code TCL_SCRIPT_TEXT option is used to run specified code before the starkit support is loaded and initialized, and before the application package is loaded/invoked. If this option is specified multiple times, the code fragments are concatenated.

The -postcode TCL_SCRIPT_TEXT option is used to run specified code after the application package has been loaded/invoked. If this option is specified multiple times, the code fragments are concatenated.

Specifying Encodings

The standard basekits include encodings for all European languages. Use the -encoding ENCODING_NAME option to specify additional encodings to include in the output, such as encodings for Asian languages. The option can be specified multiple times. Although the encodings are always added to the wrapped application, they will have an effect at runtime only if a basekit was specified. In other words, selection of additional encodings is worthwhile only when generating a starpack.

Specifying a Non-Standard Package Directory

Use the -pkgdir PATH switch to specify additional non-standard package directories. All listed paths are seen as relative to the root of the generated archive. During startup of the wrapped application, they are added to the auto_path variable of the tcl interpreter, causing the interpreter to look in these directories for packages. This switch must be used if a wrapped package is placed into a nonstandard location (i.e. outside of '/lib').

Specifying a Temporary Directory

The -temp PATH argument is used to specify a directory that TclApp uses to temporarily hold files created during the wrapping process. By default, TclApp uses the directory specified in the TEMP, TMP, or TMPDIR environment variables (which are checked in that order).

Top

How the Internal File Archive Works in a Wrapped Application

The internal file archive of a wrapped application contains all the Tcl scripts and data files that you specify when you generate an application using TclApp. TclApp incorporates special support into the wrapped application that allows Tcl scripts in the wrapped application to access files in the internal file archive just as if they were stored individually on disk. In other words, your Tcl scripts in a wrapped application can execute standard Tcl commands such as source and open to access files in the internal file archive.

Note: The files in the internal file archive are read-only.

The source path of each file to wrap is translated into the destination path according to the rules described below. "Source" means the path of the file in the original filesystem, and "destination" is the path of the file in the output Metakit FileSystem (MFS).

The context for the translation is determined by the occurrence of the -relativeto (source base path), -anchor (destination base path), and -alias (file modifier) switches. These values are used in the translation of a PATH in the same order as given above.

-relativeto

If there is no -relativeto setting before PATH (equivalent to -relativeto '') a relative PATH is left unchanged. An absolute path is made relative by stripping of the /, or the drive specification (x:\).

With -relativeto RPATH, it is illegal to specify a PATH which does not have RPATH as prefix. The PATH is modified by removing the RPATH prefix from it.

-anchor ANCHOR

The result from the translation above is taken, and the current ANCHOR is inserted as a prefix. The destination is placed under ANCHOR in the output MFS.

-alias PATH

If this value is set the file name in the result of the translation above (i.e. the last component of that path) is replaced with PATH. As a path is allowed, this not only allows renaming of the file, but also moving it further down the hierarchy.

Examples


(1)	tclapp
		-relativeto /foo/bar		\
		-anchor	    greeze		\
		-alias	    command		\
		/foo/bar/this/is/here/file

	(a)	=>	this/is/here/file
	(b)	=>	greeze/this/is/here/file
	(c)	=>	greeze/this/is/here/command

(2)	tclapp
		-relativeto /foo/bar	\
		-anchor	    lib/app	\
		-alias	    bin/file	\
		/foo/bar/file

	(a)	=>	file
	(b)	=>	lib/app/file
	(c)	=>	lib/app/bin/file

Another way of looking at the steps (a) to (c) above is this:

(a) Strip the irrelevant portion of the location in the source tree from PATH.

(b) Move the path to its proper spot in the destination tree.

(c) Perform fine-tuning of actual filename and location in the destination tree.

Path Handling

The Prowrap wrapper had a number of special rules regarding file paths, especially regarding the distinction between files included in the wrapped application and files on the target system.

For example, if a relative path was specified, the application first looked for the file in the archive. If the file was not found, the application would then look on the native filesystem on the system where the application was running. If an absolute path was specified, the application would always bypass the archive and look for the file in the native filesystem.

Because TclApp makes use of the Virtual Filesystem (VFS), these considerations no longer apply. The VFS makes the archive look like an ordinary directory. Files in the virtual directory are accessed simply by specifying the path; if the path does not exist in the virtual filesystem, the application will look on the native filesystem. There is no special distinction between absolute and relative paths.

For example, if an application is located as follows:

/path/to/app

...this path will become the virtual directory used to access the contents of the archive. So, if a file was wrapped as:

lib/application/foo.tcl

...the virtual directory path would be:

/path/to/app/lib/application/foo.tcl

Alternatively, you could specify:

cd /path/to/app/lib
open application/foo.tcl

The base path can be queried from within the application using the statements:

package require starkit
set base $starkit::topdir

The -relativeto, -alias and -anchor switches can be used to modify the default behavior.

Top

Converting Prowrap Projects to TclApp Projects

TclApp replaces the Prowrap Wrapper component included with previous Tcl Dev Kit distributions. TclApp is a significant enhancement over the Prowrap Wrapper, as it makes use of the Virtual File System (VFS) support included in Tcl version 8.4. VFS vastly simplifies the wrapping process, and allows developers to specify packages as well as individual files.

Changes to Build Options

-uses ("Wrap specification")

The command-line -uses option (and the corresponding Wrap specification field in the Graphical Wrapper) is no longer supported. It has been superseded by:

  • -pkg (Package Picker): used to specify the packages to include.
  • -config: used to specify the inclusion of entire projects, including Prowrap projects, TclApp projects, or collections of command line options recognized by TclApp. (This option has no corresponding function in the Graphical TclApp.)

-tcllibrary ("Tcl script library directory")

This option is no longer relevant, as the Virtual Filesystem (VFS) does not require the specification of the library directory that will be used by the wrapped Tcl core.

-executable ("Base executable")

This option was required by the Prowrap Wrapper. In TclApp, it is optional, and is deprecated in favor of the -prefix option.

The Wrapper required the specification of a tclwrapper-enabled application. Now any file containing a metakit-based virtual filesystem on the target system is allowed. However, only two uses seem relevant:

  • A file containing a standard tcl script as header invoking the application stored in the virtual filesystem. This can be easily invoked by not specifying the option. Tclapp then uses a standard file (it has stored in itself) as the base.
  • A platform-specific executable file set up so that it is able to invoke the application stored in the virtual filesystem at its end. The original application for this is Jean-Claude Wippler's tclkit. In the bin directory of the Tcl Dev Kit installation, two such files are provided. These are called base-*-ARCH.exe, where "ARCH" is a string denoting the platform.

The first instance generates a 'starkit'; the second instance generates a 'starpack'.

The -prefix switch should be used instead of the -executable switch. Support for the -executable switch will be dropped in future releases.

Individual File Locations

The Prowrap Wrapper computed a relative path for all files, and placed them in the archive relative to the root of the archive.

TclApp also computes a relative path, but places this path by default into the /lib/application subdirectory of the archive.

When you are specifying a collection of individual files (rather than specifying a package defined in a .tap specification file), keep in mind that, by default, the subdirectories of lib/application are not searched for package indices.

To make such 'loose' packages visible, use the -pkgdir switch (on the command line), or specify Nonstandard package directories in the Graphical TclApp.

Custom Package Locations

TclApp can locate and wrap custom packages in varying locations when you set the environment variable TCLAPP_PKGPATH to the directory or set a placeholder in your .tap file(s). See Locating Custom Packages and Definition Files with TclApp for more information. To move packages and .tap files, see Using Placeholders for Portability in the Package Editor Guide for more information.

Statically Linked versus Dynamically Loaded Libraries

Users were discouraged from using dynamically loaded libraries with the Prowrap Wrapper. Instead, they were advised to use static libraries, by creating specialized tclwrapper-enabled executables.

Because TclApp makes use of the Virtual FileSystem (VFS) included in Tcl 8.4, using shared libraries in a wrapped application is as easy as using shared libraries in an unwrapped application. Therefore, shared libraries are now preferred over custom tclkits.

When dynamically loaded libraries (loadable by Tcl) are included in a TclApp, the Virtual FileSystem will automatically load the DLL if it has to be moved to the disk first (as most operating systems cannot load DLLs from memory).

However, when working with dependent libraries, i.e. DLLs which are not loadable by Tcl, but that are required by other DLLs that are loaded, you must specially handle moving the dependent DLLs out to the file system in a known system library path location before loading the main DLL.

Rather than specifying individual DLLs in the TclApp specification, the Package Manager can be used to construct sets of files to include, including DLLs. Using a package to specify the inclusion of a DLL ensures that the auto_path variable correctly specifies the DLL's location.

Changes to the Source Application

Obsolete Variable: tcl_platform(isWrapped)

When using the Prowrap Wrapper, the presence of the tcl_platform(isWrapped) variable indicated that the application was wrapped. Therefore, the same script could be run in both wrapped and unwrapped mode, as the application would know whether to use the special file access rules for wrapped files.

Because TclApp supports the Virtual Filesystem, the tcl_platform(isWrapped) variable is no longer required. Conditional code that relies on this variable should generally be rewritten to make use of standard filesystem operations.

If you have a special case where you need to check the status of an application (wrapped or unwrapped), test the result of the command [starkit::startup]. The results are interpreted as follows:

  • starkit: launched from a starkit
  • starpack: launched from a starpack
  • unwrapped: called from an unwrapped tcl script
  • sourced: [source]'ed by another starkit

Path Handling

The Prowrap Wrapper had a number of special rules regarding file paths, especially regarding the distinction between files included in the wrapped application and files on the target system.

For example, if a relative path was specified, the application first looked for the file in the archive. If the file was not found, the application would look on the native filesystem on the system where the application was running. If an absolute path was specified, the application would always bypass the archive and look for the file in the native filesystem.

Because TclApp makes use of the Virtual Filesystem (VFS), these considerations no longer apply. The VFS makes the archive look like an ordinary directory. Files in the virtual directory are accessed simply by specifying the path. There is no special distinction between absolute and relative paths.

For example, if an application is located as follows:

/path/to/app

...this path will become the virtual directory used to access the contents of the archive. So, if a file was wrapped as:

lib/application/foo.tcl

...the virtual directory path would be:

/path/to/app/lib/application/foo.tcl

Alternatively, you could specify:

cd /path/to/app/lib
open application/foo.tcl

The base path can be queried from within the application using the statements:

package require starkit
set base $starkit::topdir

Another example of path handling is illustrated by the following scenario. The /tmp/tcl directory contains the following scripts:

    $ cat main.tcl
      #!/bin/sh
      # \
      exec /usr/tcl84/bin/tclsh "$0" "$@"
    
      source sourced.tcl
    $ cat sourced.tcl
      puts "in sourced"

These scripts are wrapped using TclApp:

    $ tclapp \
      -prefix /TclDevKit/bin/base-tk-solaris-sparc \
      -out testapp main.tcl sourced.tcl

When the application is run from another directory:

    $ cd ..
    $ tcl/testapp

...the source sourced.tcl command within the application fails, because sourced.tcl does not exist within the current working directory.

A wrapped application inherits the current working directory from the location in the shell where the script was run. The runtime support does not change the current working directory to a location within the wrapped application. Therefore, you must explicitly specify file locations, for example by using the following method:

    source [file join [file dirname [info script]] sourced.tcl
    info script
    file dirname

"info script" returns the absolute path of the executing script. "file dirname" returns the directory of the executing script.

Alternatively, use the $starkit::topdir method described above to determine the base path within the application.

Globbing

The Prowrap file system did not support use of the [glob] command to specify virtual directories. Therefore, applications looking for lists of files relied on the presence of the tcl_platform(isWrapped) variable; if the application was wrapped, the list of files had to be hard-coded.

TclApp supports the [glob] command, which now works for virtual directories in the same manner as native directories. There is no need to hard-code such lists anymore, and the special-case code can be eliminated.

Top