| [ Team LiB ] |
|
The Sample ExtensionThis section describes the sample extension that is distributed as part of the Tcl Extension Architecture (TEA) standard. The goal of TEA is to create a standard for Tcl extensions that makes it easier to build, install, and share Tcl extensions. The sample Tcl extension is on the CD, and it can be found on the Web at: There is also documentation on the Web at: The extension described here is stored in the network CVS repository under the module name samplextension. If you want direct access to the latest versions of Tcl source code, you can learn about the CVS repository at this web page: The sample extension implements the Secure Hash Algorithm (SHA1). Steve Reid wrote the original SHA1 C code, and Dave Dykstra wrote the original Tcl interface to it. Michael Thomas created the standard configure and Makefile templates, and Jeff Hobbs updated the sample for TEA2. Instead of using the original name, sha1, the example uses a more generic name, sample, in its files, libraries, and package names. When editing the sample templates for your own extension, you can simply replace occurrences of "sample" with the appropriate name for your extension. The sample files are well commented, so it is easy to see where you need to make the changes. configure.inThe configure.in file is the template for the configure script. This file is very well commented. The places you need to change are marked with __CHANGE__. The first macro to change is: AC_INIT(generic/sample.h) The AC_INIT macro lists a file that is part of the distribution. The name is relative to the configure.in file. Other possibilities include ../generic/tcl.h or src/mylib.h, depending on where the configure.in file is relative to your sources. The AC_INIT macro is necessary to support building the package in different directories (e.g., either tcl8.4/unix or tcl8.4/unix/solaris). The next thing in configure.in is a set of variable assignments that define the package's name and version number: PACKAGE = sample MAJOR_VERSION = 0 MINOR_VERSION = 4 PATCH_LEVEL = The package name determines the file names used for the directory and the binary library file created by the Makefile. This name is also used in several configure and Makefile variables. You will need to change all references to "sample" to match the name you choose for your package. The version and patch level support a three-level scheme, but you can leave the patch level empty for two-level versions like 0.4. If you do specify a patch-level, you need to include a leading "." or "p" in it. These values are combined to create the version number like this:
VERSION = ${MAJOR_VERSION}.${MINOR_VERSION}${PATCH_LEVEL}
The configure.in file has a bunch of magic to determine the name of the shared library file (e.g., sample04.dll, libsample.0.4.so, sample.0.2.shlib, etc.). You need to change the macro to match your package name. Define samplestub_LIB_FILE if you want to generate a stub library: AC_SUBST(sample_LIB_FILE) AC_SUBST(samplestub_LIB_FILE) There are several standard TEA macros in configure.in that expand to a set of rules to determine the compiler and other settings. Most of these you can leave alone. Although in some cases you need to change the sample if you are creating a Tk extension, or if you need to use internal Tcl or Tk header files. For example, you may need to add TEA_PATH_TKCONFIG and TEA_LOAD_TKCONFIG, and to choose between TEA_PUBLIC_TCL_HEADERS, TEA_PRIVATE_TCL_HEADERS and between TEA_PUBLIC_TK_HEADERS and TEA_PRIVATE_TK_HEADERS. Using private headers (i.e., tclInt.h) is strongly discouraged. There is also a platform-specific section where you may which to adjust the CLEANFILES and EXTRA_SOURCES macros to match your needs. This section also defines the BUILD_sample macro on Windows. Windows compilers create a special case for shared libraries (i.e., DLLs). When you compile the library itself, you need to declare its functions one way. When you compile code that uses the library, you need to declare its functions another way. This complicates sample.h. Happily, the complexity is hidden inside the BUILD_sample macro. We will show later how this is used in sample.h to control the definition of the Sample_Init procedure. The last macro in configure.in determines which templates are processed by the configure script. The sample generates the Makefile from the Makefile.in template with this directive: AC_OUTPUT([Makefile]) Makefile.inThe Makefile.in template is converted by the configure script into the Makefile. The sample Makefile.in is well commented so that it is easy to see where to make changes. There are a few variables with sample in their name. In particular, sample_LIB_FILE corresponds to a variable name in the configure script. You need to change both files consistently: sample_LIB_FILE = @sample_LIB_FILE@ The @varname@ syntax is used to substitute the configure variable with its platform-specific name (e.g., libsample.dll or libsample.so). You must define the set of source files and the corresponding object files that are part of the library. In the sample, sample.c implements the core of the Secure Hash Algorithm, and the tclsample.c file implements the Tcl command interface: sample_SOURCES = sample.c tclsample.c @EXTRA_SOURCES@ The object file definitions use the OBJEXT variable that is .o for UNIX and .obj for Windows: sample_OBJECTS = $(sample_SOURCES:.c=.@OBJEXT@) The header files that you want to have installed are assigned to the GENERIC_HDRS variable. The srcdir Make variable is defined during configure to be the name of the directory containing the file named in the AC_INIT macro: GENERIC_HDRS = $(srcdir)/generic/sample.h The sample Makefile includes several standard targets. Even if you decide not to use the sample Makefile.in template, you should still define the targets listed in Table 48-4 to ensure your extension is TEA compliant. Plans for automatic build environments depend on every extension implementing the standard make targets. The targets can be empty, but you should define them so that make will not complain if they are used.
Standard Header FilesThis section explains a technique you should use to get symbols defined properly in your binary library. The issue is raised by Windows compilers, which have a notion of explicitly importing and exporting symbols. When you build a library you export symbols. When you link against a library, you import symbols. The BUILD_sample variable is defined on Windows when you are building the library. This variable should be undefined on UNIX, which does not have this issue. Your header file uses this variable like this: #ifdef BUILD_sample #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT #endif /* BUILD_sample */ The TCL_STORAGE_CLASS variable is used in the definition of the EXTERN macro. You must use EXTERN before the prototype for any function you want to export from your library: EXTERN int Sample_Init _ANSI_ARGS_((Tcl_Interp *Interp)); The _ANSI_ARGS_ macro is used to guard against old C compilers that do not tolerate function prototypes. Using the Sample ExtensionYou should be able to configure, compile, and install the sample extension without modification. On my Solaris machine, the binary library is named sample0.4.so, while on my Windows NT machine the library is named sample04.dll. The package name is Tclsha1, and it implements the sha1 Tcl command. Ordinarily these names would be more consistent with the file names and package names in the template files. However, the names in the sample are designed to be easy to edit in the template. Assuming that you use make install to copy the binary library into the standard location for your site, you can use the package from Tcl like this: package require Tclsha1 sha1 -string "some string" The sha1 command returns a 128 bit encoded hash function of the input string. There are a number of options to sha1 you can learn about by reading the manual page that is included with the extension. |
| [ Team LiB ] |
|