How to create a new package

The simplest way to create a new package is to use the pakman utility (currently under development). By default, pakman creates a very small package structure -- to make it create a package in the Tycho format, give it the -style tycho option.

The rest of this page describes the structure of a package, so you can roll your own.

What a package contains

Each package contains a file called pkgIndex.tcl that looks like this:
  package ifneeded tycho.metapkg.package 2.0 \
      [list source [file join $dir package.tcl]]
where package means the name of the package, and metapkg is the directory containing this package. For example, the package tycho.kernel.gui has the meta-package kernel, and the package name gui. What this says is that when a startup script or another package says something like:
  package require tycho.metapkg.package
then the package load file named package.tcl will be sourced. When a package is required, the package load script is responsible for doing everything that is needed so that it can operate. Here is the minimum necessary in the package load file:
  package provide tycho.metapkg.package 2.0
  global env
  set env(PACKAGE_LIBRARY) [file dirname [info script]]
  lappend auto_path $env(PACKAGE_LIBRARY)
What this does is:
  1. Tell Tcl which package it has just loaded
  2. Make env global in case this script is sourced from a procedure.
  3. Set an environment variable that points to the source directory of the package. This is a Tcl convention.
  4. Append the package directory to the auto_path variable so that Tcl can load files automatically. (For this to work, the directory must contain a valid tclIndex file.)

The package load file can perform other actions. Typical actions include performing a package require for any packages that it depends upon and sourcing Tcl or [incr Tcl] files then and there to avoid the overhead of auto-loading. We recommend that in general, the package load file not contain Tcl procedure definitions -- these should be in separate files, not in the package load file.

Making a meta-package

"Meta-package" is our term for a directory that does nothing but contain a collection of real packages. In the standard Tycho installation, the directories kernel/, edit/, and util/ are meta-packages.

The purpose of a meta-package is simply to provide a way to group packages in order to manage growth. In Tycho, because we have quite a number of packages and developers that come and go developing their own packages, this is important.

The only trick about meta-packages is that Tcl has to be told about the packages contained inside it. Provided that Tcl can find the meta-package (its directory or parent directory is in the auto_path -- see Installing packages), the first package require will cause Tcl to source the meta-package's pkgIndex.tcl file. In order to tell Tcl about the packages contained therein, just make the file contain this:

catch {
    foreach file [glob -nocomplain [file join $dir * pkgIndex.tcl]] {
	set dir [file dirname $file]
	if [catch {source $file} msg] {
	    tclLog "error reading package index file $file: $msg"
	}
    }
}
Bingo! Your packages will be found and the one given as the argument to the package require will be loaded. (By the way, this is also the reason we recommend that stand-alone command-line-driven packages not be in the Tycho meta-package: doing all that globbing and sourcing does increase start-up time.)


Copyright © 1998, The Regents of the University of California. All rights reserved.
Last updated: 06/11/98, comments to: johnr@eecs.berkeley.edu