A sample dynamically loadable extension for Tcl 8.0

by Scott Stanton w/ help from Ray Johnson
scott.stanton@eng.sun.com
ray.johnson@eng.sun.com

SCCS: @(#) README 1.7 97/08/14 19:01:19

1. Introduction
---------------

Versions 7.5 and later of Tcl have the ability to dynamically load
binary Tcl extensions at run time.  See the load command for
details on how to do this from Tcl.  This distribution provides
a very simple example of how to build a binary Tcl extension
on the various major platforms.

This directory contains a sample dynamically loadable extension for
Tcl.  This extension demonstrates the techniques needed to add a
new command to Tcl in a cross platform manner.  You should be able to
use this example as a template for building your own extensions.

While this example is built to look for Tcl 8.0, it should work with
minor changes on any version of Tcl from 7.5 onward.

2. Contents of this archive
---------------------------
configure.in 	- The template for the UNIX configure script.  Use the GNU 
		  program autoconf to generate the configure from this file.
example.c	- This is the templete for the source code for the 
		  shared library.
example.h	- This .h file contains the public symbols from your
		  shared library.
exampleMacProject.sit.hqx - This archive contains CW Pro 1 project files to
			    build this example on the Mac.  It also contains some 
			    helper files that are described in the Macintosh
			    section below.
makefile.bc     - This is the makefile for Borland C++
Makefile.in     - This is the template UNIX makefile. The configure script
		  generated from configure.in will read this to produce
		  the final Makefile.
makefile.vc	- This is the Visual C++ makefile.
README		- That's this.





3. Compiling the example
------------------------

For Unix systems:

   (a) Make sure that the Tcl 8.0 release is present in the directory
       ../tcl8.0.  Also, be sure that you have built Tcl before you
       configure the example.  You can obtain the Tcl 8.0 release by
       anonymous ftp from ftp.sunlabs.com:/pub/tcl.

   (b) Type "./configure".  This runs a configuration script created
       by GNU autoconf, which configures Tcl for your system and
       creates a Makefile.  The configure script allows you to
       customize the Tcl configuration for your site; for details on
       how you can do this, type "./configure -help" or refer to the
       autoconf documentation (not included here).  Note: the example
       will use the same C compiler (e.g. gcc) as Tcl, as well as
       several other of Tcl's configuration options.  You should not
       usually modify CC in the Makefile generated here (if do you, be
       sure to check all of the definitions related to dynamic loading
       to make sure that they are still correct).  The example
       "configure" supports the following special switches in addition
       to the standard ones:
	   --with-tcl=DIR	Specifies the directory containing the Tcl
				binaries and Tcl's platform-dependent
				configuration information.  By default
				the Tcl directory is assumed to be in
				the location given by (a) above.

   (c) Type "make".  This will create a shared library called
       "example.so" and a package index file called "pkgIndex.tcl".

   (d) Type "make test" to test the example.  This will attempt to
       load the example package from the current directory.  If it
       succeeds, you will see the message "Test passed.", otherwise
       you will see an error.

For Microsoft Windows systems:

   (a) Make sure that you have installed the Tcl 8.0 binary release.
       Because most "make" programs don't support long file names, you
       should install Tcl into a directory that does not contain
       spaces in the name.  This is primarily an issue under Windows
       95, since the default location is under the "Program Files"
       directory.

   (b) If you are using the Borland compilers:

	1. Copy the file "makefile.bc" to the file "makefile".

	2. Edit "makefile" and change the TOOLS and TCL macros to
	   point to the directories where the Borland and Tcl releases
	   are installed.

	3. Type "make".  This will create a DLL called "example.dll"
	   and a package index file called "pkgIndex.tcl".

   (c) If you are using the Visual C++ compilers:

	1. Copy the file "makefile.vc" to the file "makefile".

	2. Edit "makefle" and change the TOOLS32 and TCL variables to point
	   to the directories where the Visual C++ and Tcl releases are
	   installed.

	3. Type "nmake".  This will create a DLL called "example.dll"
	   and a package index file called "pkgIndex.tcl".

   (d) Build the "test" target to test the example.  This will attempt to
       load the example package from the current directory.  If it
       succeeds, you will see the message "Test passed.", otherwise
       you will see an error.

   (e) You can install the example by building the "install"
       target.  This will create an "example" subdirectory under
       $TCL/lib that contains the "example.dll" and the "pkgIndex.tcl"
       files.

For Macintosh systems:

    (a) Before you can compile the example, you must have the Tcl 8.0
        source release.  You can obtain the release by anonymous ftp from
        ftp.sunlabs.com:/pub/tcl/mac.  You should install the directory
        including this example at the same level as the Tcl 8.0 workspace.
        
    (b) Unstuff the exampleMacProjects.sit.hqx using Stuffit Expander.  It
        contains:
        
          Example.r - This is the Rez file that defines the version strings,
                 the pkgIndex resource, and various other things needful
                 in a shared library.
          Example.pi - This is the CWPro 1 Project file.
          MW_ExampleHeaders.pch - This is the precompiled header file for 
                 the shared library.
          MW_rezPrefixCFM68K.h - This is the rez prefix file for CFM68K. It
                 is needed because MetroWerks' rez compiler does not define
                 some needed symbols.
          MW_rezPrefixPPC.h - This is the rez prefix file for PPC.
          Tool Command Language Loc - This is a location file for Stuffit
                 InstallerMaker.

		 If you have "Make Containing Folder" checked in Stuffit
		 Expander, you will need to drag these items out into the
		 top level Example folder.
                 
    (c) Open the project file, and select the Build All target.  Choose 
        Project->Make (or Command-M).  This will produce two results, a
        PowerPC library called Example.shlb, and a CFM68K library called
        ExampleCFM68K.shlb.
        
    (d) To install the project, drag either the PPC or the CFM68K library
        as appropriate (but NOT BOTH) into the Tool Command Language folder 
        in the Extensions folder of your Startup Disk.
        
    (e) If you want to make an installer for your project using Stuffit 
        InstallerMaker, we have provided a Loc file for the Tool Command
        Language folder.  Drag this file into the Locations folder of
        InstallerMaker, and then "Tool Command Language" will appear in 
        the Destinations menu in InstallerMaker.  Just assign this to your 
        library files, and they will be put in the right place.
        
    (f) The pkgIndex file is included in the resource fork of the shared 
        libraries.  If the library is put in the Tool Command Language 
        folder, you will not have to modify the tcl_pkgPath.
        For your own package, remember to modify the "pkgIndex" 
        TEXT resource that is defined in example.r to reflect your package
        name, and the commands it provides.  Read the package & pkg_mkIndex 
        man pages for information about how to construct the pkgIndex.
   

4. Porting Issues
-----------------

Because the binary release of Tcl for Windows is compiled with Borland
C++ 4.52, the malloc() and free() routines it uses are not compatible
with the malloc() and free() supplied by other C run time libraries
(either VC++ or any other compiler).  In order to avoid memory
corruption, you must always use the Tcl_Alloc() and Tcl_Free()
routines to manipulate memory that will be passed to Tcl.
