Expect and Tclkit

lv writes in comp.lang.tcl the following:

 According to TingChong <[email protected]>:
 :I want to create a standalone expect binary on solaris 8.
 :i.e. without worrying tcl installation.

 Okay - here's what I did.
  1. get a version of tclkit for solaris. This can be downloaded or built from the source. Make certain you put this into a directory of your path and call it "tclkit".
  2. get a copy of the sdx toolkit. Mark it executable. Place it in a directory directory in your path.
  3. get the source code for expect. configure it with the --enable-shared --enable-stubs option. Build and install it.
  4. Create a simple tcl script and mark it executable.
 $ cat tkex.tcl
 #! /usr/tcl84/bin/tclsh

 package require Expect

 puts [package versions Expect]

(where the first line is a path to where _I_ have tclsh installed).

  1. Run it - it should produce a single line - the version of expect that you have installed.
 $ ./tkex.tcl
 5.38.0
  1. execute sdx.kit to create a first starkit:
 $ sdx.kit qwrap tkex.tcl
 5 updates applied
 $ ls -l tkex*
 -rwxr-xr-x   1 lwv26    dept26       824 Aug 18 10:47 tkex.kit
 -rwxr-xr-x   1 lwv26    dept26        80 Aug 18 10:47 tkex.tcl
  1. Now, run the starkit:
 lwv26awu (389) $ ./tkex.kit
 can't find package Expect
     while executing
 "package require Expect"
     (file "/tmp/t/tkex.kit/lib/app-tkex/tkex.tcl" line 4)
     invoked from within
 "source /tmp/t/tkex.kit/lib/app-tkex/tkex.tcl"
     ("package ifneeded" script)
     invoked from within
 "package require app-tkex"
     (file "./tkex.kit/main.tcl" line 3)
     invoked from within
 "source ./tkex.kit/main.tcl"
     ("uplevel" body line 1)
     invoked from within
 "uplevel [list source [file join $self main.tcl]]"

Good - the starkit exists, but shows it cannot currently find Expect.

  1. Unwrap the starkit.
 $ sdx.kit unwrap tkex.kit
 5 updates applied
  1. place expect into a place where tclkit will find it.
 $ cd tkex.vfs/lib
 $ mkdir expect5.38 expect 5.38/SunOS5.8
 $ cp /usr/tcl84/lib/expect5.38/pkgIndex.tcl expect5.38/pkgIndex.tcl
 $ cp /usr/tcl84/lib/expect5.38/libexpect5.38.so expect5.38/SunOS5.8/libexpect5.38.so
    1. Update the pkgIndex.tcl so that it will find it appropriated. After editing pkgIndex.tcl, it now looks like this:
 $ cat tkex.vfs/lib/expect5.38/pkgIndex.tcl
 i# Tcl package index file, version 1.0
 # This file is sourced either when an application starts up or
 # by a "package unknown" script.  It invokes the
 # "package ifneeded" command to set up package-related
 # information so that packages will be loaded automatically
 # in response to "package require" commands.  When this
 # script is sourced, the variable $dir must contain the
 # full path name of this file's directory.

 package ifneeded Expect 5.38.0 [list load [file join $dir [format "%s%s" $::tcl_platform(os) $::tcl_platform(osVersion)] libexpect5.38.so]]
    1. Now test it out.
 $ tclkit tkex.vfs/main.tcl
 5.38.0
    1. That works - so let's wrap up the starkit.
 $ sdx.kit wrap tkex.kit
 9 updates applied
    1. Test out the starkit.
 $ ./tkex.kit
 5.38.0
    1. Now create the single file starpack. First, make a copy of tclkit, so that it can be placed in the final executable.
 $ cp /path/to/tclkit tclkit-runtime
 $ sdx wrap tkex.kit -runtime tclkit-runtime
 8 updates applied
 $ ls -l tkex.kit
 -rwxr-xr-x   1 lwv26    dept26   2329846 Aug 18 10:58 tkex.kit
 $ ksh
 $ unset PATH
 $ ./tkex.kit
 5.38.0
 $ which tclkit
 $

That part with the unset of PATH is just to prove that the file is self-contained - no tclkit (or anything else!) is in the path, so the only thing executing is the starpack.


Or, we could point out in the http://expect.sf.net/ release ChangeLog something like:

 2003-02-14  Andreas Kupries  <[email protected]>
  • configure.in: Made expect aware of tcl stubs. Derived from the
  • exp_command.h: patches to expect done by Steve Landers
  • exp_command.c: <[email protected]>. Modifications:
  • exp_main_sub.c No global cmdinfo structures for 'close' and
  • exp_main_exp.c: 'return'. Made this per-interpreter information
  • exp_main_tk.c: as it should be. Using interp assoc data for this.
        NOTE: stubs is not default, but has to be activated via '--enable-stubs'

.

  • configure: Regenerated.

ActiveState's Tcl Dev Kit has full support for including Expect in starkits and starpacks. You can even do it on Windows [L1 ].


The following is an old comment.


[Explain how Expect has not been generally available for Tclkit applications (significance of stubs and so on), but there have always been several other ways (some proprietary) to create, for example, single-file executables. In any case, Guido Ostkamp has demonstrated "clean" co-operation between the two [L2 ]. His patch--Steve Landers' "modified files" [L3 ] converted into 'patch' format--is publicly available [L4 ].]


TingChong writes in comp.lang.tcl the following:

 Subject: create a single self-contained standalone expect binary on solaris 8
 Date: 5 Jan 2004 11:44:07 -0800

These are the steps to create a single self-contained standalone expect binary on solaris 8. i.e. a expectkit similar to tclkit. Thanks for all those who help me to discover this.

1. Download expect source files from

http://expect.nist.gov

Then gunzip the downloaded file expect.tar.gz.

gzcat expect.tar.gz | tar xfp -

2. Configure the compilation environment:

If the line too long, use "\" to continue the long line.

./configure --with-tcl=$HOME/<tcl directory>/build/<hostname>/tcl --with-tclinclude=$HOME/<tcl directory>/src/tcl/generic --with-tk=$HOME/<tcl directory>/build/<hostname>/tkdyn --with-tkinclude=$HOME/<tcl directory>/src/tk/generic --enable-shared --enable-stubs

3. Compile by the command:

make

4. Create the standalone expect by the starpack method.

Create this directory structure:

mkdir -p expect.vfs/lib

5. Copy the newly compiled expect.so to the expect.vfs/lib directory.

cp <expectbindir>/expect.so expect.vfs/lib

6. Create the tcl script pkgIndex.tcl in the expect.vfs/lib directory to load expect.so:

package ifneeded Expect 5.38.0 [list load [file join $dir expect[info sharedlibextension] Expect]

where 5.38.0 is the current expect version.

7. Check the result:

ls -R expect.vfs

expect.vfs:

lib

expect.vfs/lib:

expect.so pkgIndex.tcl

8. Create a copy of the tclkit used by sdx.kit.

cp tclkit tclkit.copy

9. Use sdx to combine expect.so and tclkit.copy to create the standalone expect.

sdx.kit wrap expect -runtime tclkit.copy

Please note that every expect script using this standalone expect must have the "package require Expect" immediately after the first line.

e.g.

#!/bsmbootstrap/sbin/expect

package require Expect


Brian Theado 20Sep2005 - I downloaded version 5.43 from http://expect.nist.gov and I didn't find the --enable-stubs option. I guess the http://expect.sf.net CVS repository is the place to go to find the code for which stubs can be easily enabled.

See also Stubsification of Expect


DGSB - 2009-07-22 03:18:43

The --enable-stubs does not work (or is not even present) on the 5.43 release of expect. It does work on the 5.44 release and the described procedure above does work to add the expect extension to a starpack with this expect version. The 5.44 release can be found here http://expect.nist.gov/src/ .


LVwikignoming - 2009-07-22 07:35:54

I typically get my version of expect from either ActiveState's teapot repository or http://expect.sf.net/ . I don't know how synchronized the source at the .gov site and the .net site are.