Tcl Extension Architecture (TEA) Sample Extension

Check-in [ee070e089e]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to tclconference@googlegroups.com
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Rename configure.in -> configure.ac in more places. Add .project file (which makes it easier to use this as Eclipse project)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ee070e089eb392de4f905a8a7e1816dea182992a
User & Date: jan.nijtmans 2015-04-21 10:14:53
Context
2015-04-21
10:55
Fix execute permission on a lot of files (caused by using older cygwin dll when checking out ...) check-in: f370bff0fe user: jan.nijtmans tags: trunk
10:14
Rename configure.in -> configure.ac in more places. Add .project file (which makes it easier to use this as Eclipse project) check-in: ee070e089e user: jan.nijtmans tags: trunk
2015-01-22
10:53
Rename configure.in to configure.ac, and update to latest TEA. check-in: 1c6d81fc6f user: jan.nijtmans tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

.fossil-settings/binary-glob became executable.

.fossil-settings/crnl-glob became executable.

.fossil-settings/ignore-glob became executable.

Added .project.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>sampleextension</name>
	<comment></comment>
	<projects>
	</projects>
	<buildSpec>
	</buildSpec>
	<natures>
	</natures>
</projectDescription>

ChangeLog became executable.

Changes to Makefile.in.

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@

PKG_CFLAGS	= @PKG_CFLAGS@

# TCL_DEFS is not strictly need here, but if you remove it, then you
# must make sure that configure.in checks for the necessary components
# that your library may use.  TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS		= @DEFS@ $(PKG_CFLAGS)

# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
................................................................................

dist: dist-clean
	$(INSTALL_DATA_DIR) $(DIST_DIR)
	cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
		$(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
		$(DIST_DIR)/
	chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
	chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in

	for i in $(srcdir)/*.[ch]; do \
	    if [ -f $$i ]; then \
		cp -p $$i $(DIST_DIR)/ ; \
	    fi; \
	done;

................................................................................

#========================================================================
# End of user-definable section
#========================================================================

#========================================================================
# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
# variable in configure.in
#========================================================================

clean:
	-test -z "$(BINARIES)" || rm -f $(BINARIES)
	-rm -f *.$(OBJEXT) core *.core
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)








|







 







|







 







|







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@

PKG_CFLAGS	= @PKG_CFLAGS@

# TCL_DEFS is not strictly need here, but if you remove it, then you
# must make sure that configure.ac checks for the necessary components
# that your library may use.  TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS		= @DEFS@ $(PKG_CFLAGS)

# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
................................................................................

dist: dist-clean
	$(INSTALL_DATA_DIR) $(DIST_DIR)
	cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
		$(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
		$(DIST_DIR)/
	chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
	chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.ac

	for i in $(srcdir)/*.[ch]; do \
	    if [ -f $$i ]; then \
		cp -p $$i $(DIST_DIR)/ ; \
	    fi; \
	done;

................................................................................

#========================================================================
# End of user-definable section
#========================================================================

#========================================================================
# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
# variable in configure.ac
#========================================================================

clean:
	-test -z "$(BINARIES)" || rm -f $(BINARIES)
	-rm -f *.$(OBJEXT) core *.core
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)

Changes to README.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
README.sha	A description of the extension itself.

aclocal.m4	Generated file.  Do not edit.  Autoconf uses this as input
		when generating the final configure script.  See "tcl.m4"
		below.

configure	Generated file.  Do not edit.  This must be regenerated
		anytime configure.in or tclconfig/tcl.m4 changes.

configure.in	Configure script template.  Autoconf uses this file as input
		to produce the final configure script.

pkgIndex.tcl.in Package index template.  The configure script will use
		this file as input to create pkgIndex.tcl.

sample.c	Core Secure Hash Algorithm code.

................................................................................
to create a Makefile. See the tcl/win/README file for the URL of
the Msys + Mingw download.

If you have VC++ then you may wish to use the files in the win
subdirectory and build the extension using just VC++. These files have
been designed to be as generic as possible but will require some
additional maintenance by the project developer to synchronise with
the TEA configure.in and Makefile.in files. Instructions for using the
VC++ makefile are written in the first part of the Makefile.vc
file.

INSTALLATION
============

The installation of a TEA package is structure like so:







|

|







 







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
README.sha	A description of the extension itself.

aclocal.m4	Generated file.  Do not edit.  Autoconf uses this as input
		when generating the final configure script.  See "tcl.m4"
		below.

configure	Generated file.  Do not edit.  This must be regenerated
		anytime configure.ac or tclconfig/tcl.m4 changes.

configure.ac	Configure script template.  Autoconf uses this file as input
		to produce the final configure script.

pkgIndex.tcl.in Package index template.  The configure script will use
		this file as input to create pkgIndex.tcl.

sample.c	Core Secure Hash Algorithm code.

................................................................................
to create a Makefile. See the tcl/win/README file for the URL of
the Msys + Mingw download.

If you have VC++ then you may wish to use the files in the win
subdirectory and build the extension using just VC++. These files have
been designed to be as generic as possible but will require some
additional maintenance by the project developer to synchronise with
the TEA configure.ac and Makefile.in files. Instructions for using the
VC++ makefile are written in the first part of the Makefile.vc
file.

INSTALLATION
============

The installation of a TEA package is structure like so:

Changes to configure.

more than 10,000 changes

Changes to configure.ac.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.

#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.
#






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.

#-----------------------------------------------------------------------
# Sample configure.ac for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.
#

doc/man.macros became executable.

doc/sha1.n became executable.

generic/sample.c became executable.

generic/sample.h became executable.

Changes to generic/tclsample.c.

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*
 *----------------------------------------------------------------------
 *
 * Sample_Init --
 *
 *	Initialize the new package.  The string "Sample" in the
 *	function name must match the PACKAGE declaration at the top of
 *	configure.in.
 *
 * Results:
 *	A standard Tcl result
 *
 * Side effects:
 *	The Sample package is created.
 *	One new command "sha1" is added to the Tcl interpreter.







|







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*
 *----------------------------------------------------------------------
 *
 * Sample_Init --
 *
 *	Initialize the new package.  The string "Sample" in the
 *	function name must match the PACKAGE declaration at the top of
 *	configure.ac.
 *
 * Results:
 *	A standard Tcl result
 *
 * Side effects:
 *	The Sample package is created.
 *	One new command "sha1" is added to the Tcl interpreter.

tea/app_config_options.txt became executable.

tea/app_makefiles.txt became executable.

tea/codingstyle.txt became executable.

Changes to tea/design.txt.

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
      unix/                  unix-specific sources (here: nothing???)
      win/                   Windows-specific sources (here: the
                             project-file for building on Windows)
      ChangeLog              description of changes
      Makefile.in            TEA-template for the makefile
      aclocal.m4             "include" file required by Autoconf
      configure              configure script generated by Autoconf
      configure.in           TEA-template for the configure script
      ...                    (others files, not related to the building
                             process itself)
}]

In this overview you will see some files related to the TEA, most
notably, [emph Makefile.in] and [emph configure.in]. These will be described in
great detail in Chapter 7 (fortunately the details have become less and
less painful with the further development of TEA).

[para]
The most important thing is that this extension uses the [emph same]
directory structure as Tcl/Tk itself. This may not always seem necessary
(for instance, a Windows-specific extension might do without the unix
................................................................................
like strtod() are notorious in this respect)

[list_end]

The directory structure described in the previous section is
quite useable in this case too. The platform-dependencies are expressed
in the mac, unix and win directories containing one or more source files
(not just project or make files), but also in the configure.in and
Makefile.in files containing extra code to find the relevant
OS libraries or checks for deficiencies.

[section {Extensions exporting their own functions}]

Complications arise when extensions need to export their own
(compiled) functions, to provide their functionality. Again, this is not







|





|







 







|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
      unix/                  unix-specific sources (here: nothing???)
      win/                   Windows-specific sources (here: the
                             project-file for building on Windows)
      ChangeLog              description of changes
      Makefile.in            TEA-template for the makefile
      aclocal.m4             "include" file required by Autoconf
      configure              configure script generated by Autoconf
      configure.ac           TEA-template for the configure script
      ...                    (others files, not related to the building
                             process itself)
}]

In this overview you will see some files related to the TEA, most
notably, [emph Makefile.in] and [emph configure.ac]. These will be described in
great detail in Chapter 7 (fortunately the details have become less and
less painful with the further development of TEA).

[para]
The most important thing is that this extension uses the [emph same]
directory structure as Tcl/Tk itself. This may not always seem necessary
(for instance, a Windows-specific extension might do without the unix
................................................................................
like strtod() are notorious in this respect)

[list_end]

The directory structure described in the previous section is
quite useable in this case too. The platform-dependencies are expressed
in the mac, unix and win directories containing one or more source files
(not just project or make files), but also in the configure.ac and
Makefile.in files containing extra code to find the relevant
OS libraries or checks for deficiencies.

[section {Extensions exporting their own functions}]

Complications arise when extensions need to export their own
(compiled) functions, to provide their functionality. Again, this is not

tea/introduction.txt became executable.

Changes to tea/makefiles.txt.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
...
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
again TEA has the task to make the preparation of the build process for
your specific extension as smooth and painless as possible.
Nevertheless, you will have to do something:

[list_begin bullet]

[bullet]
Prepare at least two template files, configure.in and Makefile.in,
that contain information about what sources your extension is made of,
under what name your extension will be known and so on.

[bullet]
Create a [emph {shell script}] (*), called [emph configure], via the Autoconf
program.

................................................................................
older versions) and processes the macros it finds in there. These
macros have been developed to take care of all the nasty little details
that can bother a programmer. (If you familiarise yourself with the
Autoconf tool, you will be able to create new macros. This is actually
one of the great advantages of Autoconf.)

[para]
While Autoconf takes a template file "configure.ac" or "configure.in",
TEA provides you with a template for this template. All you need to do is:

[list_begin bullet]

[bullet]
replace the name of the sample extension (exampleA) by the name
of your extension

................................................................................
[example {
  CFLAGS_DEBUG = @CFLAGS_DEBUG@
}]
The first is a variable in the make file that is used to set the flags
for a debug version of your extension. The configure script
replaces the string "@CFLAGS_DEBUG@" by whatever is appropriate for that
platform, often "-g -c". This is accomplished by a command
AC_SUBST([lb]CFLAGS_DEBUG[rb]) somewhere in the configure.in file (or
the macros it uses).


[section {The macros used by TEA}]

The template files that come with TEA are very well documented,
but still some explanation is required, if you are not familiar with
................................................................................

[bullet]
The last line, AC_OUTPUT(), lists all the files that need to be
created by the configure script.

[list_end]

You can use a number of other macros in your configure.in file:

[list_begin bullet]

[bullet]
AC_DEFINE(variable,value,?description?):
[nl]
Add a C compiler macro "variable" with the given value to the list of
................................................................................
[list_begin bullet]

[bullet]
Define a file INSTALL.in which has a line "@MY_EXTENSION_TEXT@"
in it.

[bullet]
Define a variable MY_EXTENSION_TEXT in the configure.in file:
[example {
     AC_DEFINE([MY_EXTENSION_TEXT])
     MY_EXTENSION_TEXT="Whatever text you want inserted"
     AC_SUBST([MY_EXTENSION_TEXT])
}]

[bullet]







|







 







|
|







 







|







 







|







 







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
...
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
again TEA has the task to make the preparation of the build process for
your specific extension as smooth and painless as possible.
Nevertheless, you will have to do something:

[list_begin bullet]

[bullet]
Prepare at least two template files, configure.ac and Makefile.in,
that contain information about what sources your extension is made of,
under what name your extension will be known and so on.

[bullet]
Create a [emph {shell script}] (*), called [emph configure], via the Autoconf
program.

................................................................................
older versions) and processes the macros it finds in there. These
macros have been developed to take care of all the nasty little details
that can bother a programmer. (If you familiarise yourself with the
Autoconf tool, you will be able to create new macros. This is actually
one of the great advantages of Autoconf.)

[para]
While Autoconf takes a template file "configure.ac", TEA provides you
with a template for this template. All you need to do is:

[list_begin bullet]

[bullet]
replace the name of the sample extension (exampleA) by the name
of your extension

................................................................................
[example {
  CFLAGS_DEBUG = @CFLAGS_DEBUG@
}]
The first is a variable in the make file that is used to set the flags
for a debug version of your extension. The configure script
replaces the string "@CFLAGS_DEBUG@" by whatever is appropriate for that
platform, often "-g -c". This is accomplished by a command
AC_SUBST([lb]CFLAGS_DEBUG[rb]) somewhere in the configure.ac file (or
the macros it uses).


[section {The macros used by TEA}]

The template files that come with TEA are very well documented,
but still some explanation is required, if you are not familiar with
................................................................................

[bullet]
The last line, AC_OUTPUT(), lists all the files that need to be
created by the configure script.

[list_end]

You can use a number of other macros in your configure.ac file:

[list_begin bullet]

[bullet]
AC_DEFINE(variable,value,?description?):
[nl]
Add a C compiler macro "variable" with the given value to the list of
................................................................................
[list_begin bullet]

[bullet]
Define a file INSTALL.in which has a line "@MY_EXTENSION_TEXT@"
in it.

[bullet]
Define a variable MY_EXTENSION_TEXT in the configure.ac file:
[example {
     AC_DEFINE([MY_EXTENSION_TEXT])
     MY_EXTENSION_TEXT="Whatever text you want inserted"
     AC_SUBST([MY_EXTENSION_TEXT])
}]

[bullet]

Changes to tea/packages.txt.

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
 *----------------------------------------------------------------------
 *
 * Sample_Init --
 *
 *      Initialize the new package.  The string "Sample" in the
 *      function name must match the PACKAGE declaration at the top of
 *      configure.in.
 *
 * Results:
 *      A standard Tcl result
 *
 * Side effects:
 *      The Sample package is created.
 *      One new command "sha1" is added to the Tcl interpreter.
................................................................................

[list_end]

For this reason, the TEA defines a C macro, VERSION, that holds the
version string (you can see how it is used in the code for the sample
extension). This string is built up of the major version and a
combination of the minor version and the patchlevel. From the file
"configure.in" (see Chapter 6) we have:
[example {
   #--------------------------------------------------------------------
   # __CHANGE__
   # Set your package name and version numbers here.  The NODOT_VERSION is
   # required for constructing the library name on systems that don't like
   # dots in library names (Windows).  The VERSION variable is used on the
   # other systems.







|







 







|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
 *----------------------------------------------------------------------
 *
 * Sample_Init --
 *
 *      Initialize the new package.  The string "Sample" in the
 *      function name must match the PACKAGE declaration at the top of
 *      configure.ac.
 *
 * Results:
 *      A standard Tcl result
 *
 * Side effects:
 *      The Sample package is created.
 *      One new command "sha1" is added to the Tcl interpreter.
................................................................................

[list_end]

For this reason, the TEA defines a C macro, VERSION, that holds the
version string (you can see how it is used in the code for the sample
extension). This string is built up of the major version and a
combination of the minor version and the patchlevel. From the file
"configure.ac" (see Chapter 6) we have:
[example {
   #--------------------------------------------------------------------
   # __CHANGE__
   # Set your package name and version numbers here.  The NODOT_VERSION is
   # required for constructing the library name on systems that don't like
   # dots in library names (Windows).  The VERSION variable is used on the
   # other systems.

tea/stubs.txt became executable.

tea/toman.tcl became executable.

tea/writingdocs.txt became executable.

tea/writingtests.txt became executable.

tests/all.tcl became executable.

tests/sample.test became executable.

tests/tclsample.test became executable.

Changes to win/makefile.vc.

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#	number and returns all character until a character not in [0-9.ab]
#	is read.

!if [echo REM = This file is generated from Makefile.vc > versions.vc]
!endif
# get project version from row "AC_INIT([project], [????])"
!if [echo DOTVERSION = \>> versions.vc] \
   && [nmakehlp -V ..\configure.in sample >> versions.vc]
!endif
!include "versions.vc"

VERSION         = $(DOTVERSION:.=)
STUBPREFIX      = $(PROJECT)stub

DLLOBJS = \







|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#	number and returns all character until a character not in [0-9.ab]
#	is read.

!if [echo REM = This file is generated from Makefile.vc > versions.vc]
!endif
# get project version from row "AC_INIT([project], [????])"
!if [echo DOTVERSION = \>> versions.vc] \
   && [nmakehlp -V ..\configure.ac sample >> versions.vc]
!endif
!include "versions.vc"

VERSION         = $(DOTVERSION:.=)
STUBPREFIX      = $(PROJECT)stub

DLLOBJS = \

win/nmakehlp.c became executable.

win/rules.vc became executable.

win/sample.rc became executable.