Tclish User Guide

1: Introduction

2: Setting up your install

2.1: Customizing the Appearance: The img subdirectory and custom.cfg

2.2: Setting up packages: the packages/ subdirectory

2.2.1: The contents of a .pkg file

2.2.1.1: The package definition
2.2.1.2: The parameters subcommand of the package comand
2.2.1.3: The install command
2.2.1.4: Predefined package combinations

2.2.2: Tarfiles

2.3: Wrapping your install application

2.4: Wrapping the kitchen sink into a single-file install

2.5: Prepare a web install


1: Introduction

Tclish is a simple, customizable installer for virtually any type of application.

A tclish install requires three things:
  1. the install.tcl script
  2. the img/ subdirectory, with img/custom.cfg
  3. the packages/ subdirectory, with your custom package files.
With these three things, you can install your software. However, you may want to take some additional steps to improve your install. Here are some things that may be a good idea, depending on your particular needs:

2: Setting up your install

There are two things that need to be done to set up your install. First, you must configure the appearance of your install. Next, you must set up the packages that will be installed.

2.1: Customizing the Appearance: The img subdirectory and custom.cfg

Example custom.cfg

title "TclBlast! - The Tcl/Tk CD-ROM"
creator "The Tcl/Tk Consortium"
copyright "Copyright \251 1998"
patchString "/tmp/tclbuild"
credits "Thanks to all of the volunteers"
buttonBackground black
buttons "-foreground black \ 
         -tile [create_photo goldbg.gif] \ 
         -activeforeground white \ 
         -activetile [create_photo redbg.gif]"

icon [create_photo blast-lg.gif]
      
startup screen main screen about screen
It's possible (more like "necessary" if you don't want to confuse your users.) to customize the appearance of your installer. This is done by editing the file custom.cfg in the img/ subdirectory. custom.cfg is parsed using a tcl safe interpreter, with the following commands defined:
create_photo imgfile
imgfile is a gif or jpg image in the img/ subdirectory. Returns an image name for use in other commands.
title title
title is the string used in the title bar of the main window
creator creator
creator is given credit on the "about" page
copyright message
message is shown as a copyright message on the "about" page
patchstring string
string is used as the search string to the patch_files command, described later. It should be as long as the longest expected substitution string. Default value is /tmp/build/123456789-123456789-123456789-123456789-123456789-/123456789-123456789-123456789-123456789-123456789-
credits string
string appears on the "about" page
buttonBackground color
color is used as the background for buttons
buttons optionlist
buttons are additionally configured with optionlist. This should be an option list compatible with BLT extended buttons
icon image
image is used in the background of the intro screen. It should be an image name, which can be obtained using the create_photo command.
Any images you use in your custom.cfg file should be put in the img/ subdirectory.

2.2: Setting up packages: the packages/ subdirectory

The first thing needed in the packages/ subdirectory is one or more package files. These should end in the extension .pkg. If there are more than one of them, by convention they should start with a number, like 00all.pkg or 10logmaster.pkg. Tclish will read them in sorted order, and keep the packages in that order on the various screens.



2.2.1: The contents of a .pkg file

The package description files, or .pkg files, are all read in a single tcl interpreter, in sorted order. This means variables or procedures can be shared among package files in the same install.

2.2.1.1: The package definition
Example package definition

package *intro {
    category Overview
    title Introduction
    description {
Tcl/Tk and its extensions are powerful tools 
for software development, and this CD-ROM 
makes it easy to get up and running.
In the list on left, click on the name of a 
package to obtain a description of that package.  
Click on the check box next to the package to 
select it for installation.  Then, click on 
the Next button below, and this program will 
guide you through the installation process.

If you're looking for more information about Tcl/Tk, 
check out the Tcl/Tk Consortium site:
    http://www.tclconsortium.org
    }
    icon [create_photo blast-tiny.gif]
}
      

The primary ingredient in a package file is a package definition. A package definition is defined with the command package name subcommand_list.

name gives a logical name to the package, which is used to refer to it in the .pkg files.

subcommand_list is made of a list of the following subcommands:

category category
Put the package under category category in the browser menu. This will create the category if it doesn't already exist. This will also appear as the main title in the description.
title title
Use the name title in the browser menu. This will appear as the subtitle in the description. Note: It's a good idea to make the package name the same as category plus title, so that users can easily match any errors that occur while installing the package to the package description.
version version_number
This defines a version number for the package.
description text
This text will be displayed as the description when the user clicks the title in the browser.
icon [imagename | imagedata]
This defines an image to use as an icon in the browser display when the user clicks on the title. It can take one of two forms, either an image name returned from the create_photo command, or a base64 encoded string version of the image file. If using the create_photo command, the image will need to be in the img/ subdirectory.
requires packagelist
This defines a list of packages (by package name) that should be installed if this package is installed. If the user attempts an install without the required packages, they will be warned and asked to confirm they know what they're doing.
installcmd tcl_proc
This gives the name of a tcl procedure, which should be defined in the package file, that will be executed when it's time to install the package. The tcl procedure will be described in its own section in this document.

If installcmd is not defined for a package, the package is treated as informational. It will appear as an entry on the browser, but no action will be taken to install it.

platformnamecmd tcl_proc
This gives the name of a tcl procedure, which should be defined in the package file, that will be executed when it's time to figure out which platform is needed. The tcl procedure should return an appropriate string for the platform.

If installcmd is not defined for a package, a default platform is used. This matches the platforms that tclish is distributed under.

files file ...
This command accepts a list of files that are required to install the package. The files listed here should be in the packages/ subdirectory. This list is used to retrieve those files during a web install. The character * in the filename will be replaced with the platform name of the install - sunos, sol, sol26, hp10, aix4, or linux.
parameters parameterlist
This sets up parameters that will be obtained from the user before installing the package, such as install location. The parameter subcommand will be described in detail in its own section in this document.


2.2.1.2: The parameters subcommand of the package comand
Example parameters specification

parameters {
sourcedir {Log Master Server 2.5.1} \ 
  {Please select a directory for 
  the LogMaster server} \ 
  lm_rootdir lm_rootdir_default
directory {License Manager} \ 
  { Please select a directory for 
  the license server } \ 
  lm_licdir lm_licdir_default
form {License File} \ 
  {Please select the file containing 
  the license sent by BMC.}
  {{-file License File}} ""
}
      
A package may define any number of parameters whose value must be obtained from the user before installing the package. Any number of parameter specifications may be listed as part of the parameters subcommand. Each parameter specification is a list with these 5 elements:
type
This gives the type for the parameter. There are three types - sourcedir, directory, and form. sourcedir prompts for a read-only directory, which must already exists. directory prompts for a directory which must be writable, and will be created if it doesn't exist. form allows a configurable number of fill-in-the-blank parameters which appear together on a form.
title
This title will be used on the screen asking the user for the value of the parameter.
description
This description will be given on the screen asking the user for the value of the parameter.
name
This gives a name to the parameter. If two packages each define a parameter with the same name, tclish will assume that the parameter's value need only be obtained one time during the install, so the two packages will share that parameter - so be careful with naming to prevent unintended collisions.

For form parameters, name is actually a list of names, one per entry on the form. For each name in that list which has a first element of "-file", the entry in the form will have a "browse..." button. (-file will be dropped from the name of the parameter.) Also, the parameter name will appear on the form as a description for that blank in the form.

default
This specifies a default value for the parameter. It may optionally take the form "-force default" in which case the user is never prompted, the default is always taken.

default may also be the name of a tcl procedure defined in the package files. In that case, before prompting the user, the tcl procedure is run, and its return value is taken as the default. (The return value may specify "-force" also.)

In the case of a form parameter, default (or the return from the tcl procedure) is taken as a list of values, one per blank in the form.



2.2.1.3: The install command
Example installcmd

proc lm_datadir_install {pkg} {
  global parameter

  untar $parameter(lm_datadir) dd-v2.5.1-Oracle-*.tar.Z
  catch {
    eval exec chmod -R u+w $parameter(lm_datadir)
    eval exec chmod -R g+w $parameter(lm_datadir)
    eval exec chmod -R o-w $parameter(lm_datadir)
    eval exec chown -R $parameter(Userid) $parameter(lm_datadir)
    eval exec chgrp -R $parameter(Group) $parameter(lm_datadir)
  }

  return
}
      
The installcmd defined for the packages get executed, one by one, after all parameter values have been obtained. The parameters are accessible from the global variable parameter. parameter is an array, indexed by parameter name.

There are a set of commands defined in the interpreter that are useful in for a typical package install.

packagefile filename
packagefile returns a fully-qualified path to filename based on the location of the packages directory, whether on the CD, or in the case of a web-based install, in a temporary location. In addition, occurrences of the character * in the filename will be replaced with the architecture string sunos, sol, sol26, aix4, hp10, or linux depending on the operating system and its version.
untar directory tarfile extra_steps
This will pipe the file tarfile through uncompress and then an untar command, in the directory directory. During the uncompress, a progress widget will be updated for the user. tarfile should be a full path, normally a path returned from the packagefile command.

It returns the current step number, which can then be incremented and passed to progress in further steps. Extra_steps specifies the number of steps that will follow the untar.

progress num ?max? ?task? ?message?
This updates the progress bar for the package. The bar will show num out of max completed, expressed as a percentage. If max isn't specified (or is ""), it will remain the same as the last time it was specified. task and message are displayed as detailed information on the window. They remain unchanged if not specified.
patch_files filelist patchstring
This will substitute the string patchstring into each of the files specified in filelist, replacing the string patchString which was defined in custom.cfg.

Where this comes in handy is updating the search path for shared libraries, etc. When building the package, specify patchString as a location to be searched for files used your program, or in the compile as a directory where the run-time linker should look for shared libraries. Then after the install, that string can be replaced with the correct value. The replacement will overlay the existing string without changing the length of the file, so the program will run normally - except it will magically know the right place to look for the files based on the user's install. Just be sure to reserve enough room (by using a long patchString.)



2.2.1.4: Predefined package combinations
Example install options

installoption normal {Normal installation.
Install the packages most users need.}
installoption_add normal {Log Master} \ 
    {Log Master Server 2.5.1 for Oracle}
installoption_add normal {Log Master} \ 
    {Log Master Data Directory}
installoption_add normal {Log Master} \ 
    {Log Master Client Integration}
installoption_add normal {Log Master} \ 
    {Log Master Bourne Shell Environment Config}
installoption_add normal {Log Master} \ 
    {Log Master C Shell Environment Config}
installoption_add normal {Log Master} \ 
    {Log Master Media Key}

installoption license {License Only.
Install or update a Log Master license key.}
installoption_add license {Log Master} \ 
    {Log Master Permanent License}

installoption datadir {Data Directory.
Create an additional Log Master Data Directory.}
installoption_add datadir {Log Master} \ 
    {Log Master Data Directory}
      
Often there are a few different combinations of packages, any one of which might be useful to the user. You can define these combinations so the user can easily pick one, rather than choosing packages individually. "Custom installation" always appears as an option, and if you don't specify any other options, "Full installation" will appear by default. (Or if you define an option "full", it will automatically have all packages added to it.)

The first step is to define an installoption using the command

installoption name description
where name gives a name you can refer to when adding packages to the installoption, and description appears next to the option in the window.

Next you must add packages to the option, using the command

installoption_add name category packagename
category specifies the category defined in the package, and packagename is the name of the package.

2.2.2: Tarfiles

Tarfiles used in the unstall should be compressed using "compress". The untar command will automatically uncompress and untar the files.

In addition, it's necessary for performance reasons to include a "manifest" file. It should have the same name as the tarfile (including extensions) with .manifest added on the end. This can be created using a command like:

cat tarfile | uncompress | tar tf - > tarfile.manifest

If a manifest file is not available, one will be created when the install is run - which will fail on a CDROM since it's not writable. But this can be used to create the files before burning a CD.


2.3: Wrapping your install application

The recommended tool for wrapping your install application into an executable that doesn't require Tcl to be installed is freewrapBLT, from the freewrap distribution. The install program makes use of BLT extensions, so whatever wrapping application you use, be sure to include BLT. Also, the install makes use of the http package from the standard tcl distribution, so be sure to include that in the wrapped application.

These are the steps in wrapping the install program:

  1. Create the file http.fwp in the directory where install.tcl is located. This should contain a list of the files in the tcl standard http package, one per line (with full path.)

    Here's an example of how you might create the file:

    httpdir=`find /usr -type d -name http2.3 2> /dev/null | head -1`
    find $httpdir -type f > http.fwp

    Note that the filename is important - the install program looks for this file to know when to load the http package from freewrap instead of the normal way.

  2. Run freewrapBLT, telling it to include install.tcl, the contents of http.fwp, and the http.fwp file itself. Example:
    freewrapBLT install.tcl http.fwp -f http.fwp
    Note that freewrap will name the executable install. If you need to make installs for multiple architectures, you might consider renaming that to something architecture specific, like install-solaris for example.



2.4: Wrapping the kitchen sink into a single-file install

To go a step beyond wrapping the install program into an executable, you can add the files in the img/ and packages/ subdirectories into the executable as well. This is great for small installs, but could become unweildy quickly for larger installs, so be careful.

To do this, do step one, above, to wrap the install application. Then:

  1. Put a listing of the binary files in your install package into a file called binpackages.fwp, also in the same directory as install.tcl. Here's an example of how to do that:

    find img packages -name '*.gif' > binpackages.fwp
    find img packages -name '*.Z' >> binpackages.fwp
    freewrap will automatically detect some binary files, based on extension, but misses some (for example, .Z files) so it's best to be explicit by separating them into this file.

  2. Put a listing of the rest of the files into the file packages.fwp in the same directory as install.tcl. Example:
    find img packages -name '*.cfg' > packages.fwp
    find img packages -name '*.manifest' >> packages.fwp
    find img packages -name '*.pkg' >> packages.fwp
  3. Wrap all of that into the executable (including the .fwp files.) Be sure to force freewrap to interpret the contents of binpackages.fwp as binary. Example:
    freewrapBLT install.tcl http.fwp packages.fwp binpackages.fwp \
        -f http.fwp -f packages.fwp -b binpackages.fwp
    Note that freewrap will name the executable install. If you need to make installs for multiple architectures, you might consider renaming that to something architecture specific, like install-solaris for example.



2.5: Prepare a web install

Suppose your package is too big to be rolled into the executable, but you want to enable easy web installs. Tclish is smart enough to handle it - it will automatically download files it needs, as it needs them. Big files like tarfiles will be downloaded as part of the installation steps, after all parameter values have been obtained.

There's only one trick to the web install, and that's configuring tclish to know where the web site is. To do that, simply create the file install.url in the same directory as install.tcl, and include it when you wrap the executable. The file should contain only the URL where you will put the install. Example:

echo http://tclish.sourceforge.net/latest > install.url
freewrapBLT install.tcl install.url http.fwp -f http.fwp
Having done that, copy your install package (the install binary, and the img/ and packages/ subdirectories) to that location on your web server. Tclish will use that URL, and append "img/whatever" or "packages/whatever" to it to get the other files.