1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
|
all:
#
# This makefile is part of the teaish framework, a tool for building
# Tcl extensions, conceptually related to TEA/tclconfig but using the
# Autosetup configuration system instead of the GNU Autotools.
#
# A copy of this makefile gets processed for each extension separately
# and populated with info about how to build, test, and install the
# extension.
#
# Maintenance reminder: this file needs to stay portable with POSIX
# Make, not just GNU Make. Yes, that's unfortunate because it makes
# some things impossible (like skipping over swathes of rules when
# 'make distclean' is invoked).
#
CC = @CC@
INSTALL = @BIN_INSTALL@
INSTALL.noexec = $(INSTALL) -m 0644
#
# Var name prefixes:
#
# teaish. => teaish core
# tx. => teaish extension
#
# Vars with a "tx." or "teaish." prefix are all "public" for purposes
# of the extension makefile, but the extension must not any "teaish."
# vars and must only modify "tx." vars where that allowance is
# specifically noted.
#
# Vars with a "teaish__" prefix are "private" and must not be used by
# the extension makefile. They may change semantics or be removed in
# any given teaish build.
#
tx.name = @TEAISH_NAME@
tx.version = @TEAISH_VERSION@
tx.name.pkg = @TEAISH_PKGNAME@
tx.libdir = @TEAISH_LIBDIR_NAME@
tx.loadPrefix = @TEAISH_LOAD_PREFIX@
tx.tcl = @TEAISH_TCL@
tx.makefile = @TEAISH_MAKEFILE@
tx.makefile.in = @TEAISH_MAKEFILE_IN@
tx.dll8.basename = @TEAISH_DLL8_BASENAME@
tx.dll9.basename = @TEAISH_DLL9_BASENAME@
tx.dll8 = @TEAISH_DLL8@
tx.dll9 = @TEAISH_DLL9@
tx.dll = $(tx.dll$(TCL_MAJOR_VERSION))
tx.dir = @TEAISH_EXT_DIR@
@if TEAISH_DIST_NAME
tx.name.dist = @TEAISH_DIST_NAME@
@else
tx.name.dist = $(teaish.name)
@endif
teaish.dir = @abs_top_srcdir@
#teaish.dir.autosetup = @TEAISH_AUTOSETUP_DIR@
teaish.makefile = Makefile
teaish.makefile.in = $(teaish.dir)/Makefile.in
teaish__auto.def = $(teaish.dir)/auto.def
#
# Autotools-conventional vars. We don't actually use these in this
# makefile but some may be referenced by vars imported via
# tclConfig.sh. They are part of the public API and may be reliably
# depended on from teaish.make.in.
#
bindir = @bindir@
datadir = @datadir@
exec_prefix = @exec_prefix@
includedir = @includedir@
infodir = @infodir@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
prefix = @prefix@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
#
# Vars derived (mostly) from tclConfig.sh. These may be reliably
# used from the extension makefile.
#
TCLSH = @TCLSH_CMD@
TCL_CONFIG_SH = @TCL_CONFIG_SH@
TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@
TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@
TCL_LIBS = @TCL_LIBS@
TCL_LIB_SPEC = @TCL_LIB_SPEC@
TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@
TCL_MINOR_VERSION = @TCL_MINOR_VERSION@
TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@
TCL_PREFIX = @TCL_PREFIX@
TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
TCL_VERSION = @TCL_VERSION@
TCLLIBDIR = @TCLLIBDIR@
#
# CFLAGS.configure = CFLAGS as known at configure-time.
#
# This ordering is deliberate: flags populated via tcl's
# [teaish-cflags-add] should preceed CFLAGS and CPPFLAGS (which
# typically come from the ./configure command-line invocation).
#
CFLAGS.configure = @SH_CFLAGS@ @TEAISH_CFLAGS@ @CFLAGS@ @CPPFLAGS@ $(TCL_INCLUDE_SPEC)
#CFLAGS.configure += -DUSE_TCL_STUBS=1
#
# LDFLAGS.configure = LDFLAGS as known at configure-time.
#
# This ordering is deliberate: flags populated via tcl's
# [teaish-ldflags-add] should precede LDFLAGS (which typically
# comes from the ./configure command-line invocation).
#
LDFLAGS.configure = @TEAISH_LDFLAGS@ @LDFLAGS@
#
# Linker flags for linkhing a shared library.
#
LDFLAGS.shlib = @SH_LDFLAGS@
#
# The following tx.XYZ vars may be populated/modified by teaish.tcl
# and/or teaish.make.
#
#
# tx.src is the list of source or object files to include in the
# (single) compiler/linker invocation. This will initially contain any
# sources passed to [teaish-src-add], but may also be appended to by
# teaish.make.
#
tx.src =@TEAISH_EXT_SRC@
#
# tx.CFLAGS is typically set by teaish.make, whereas TEAISH_CFLAGS
# gets set up via the configure script.
#
tx.CFLAGS =
#
# tx.LDFLAGS is typically set by teaish.make, whereas TEAISH_LDFLAGS
# gets set up via the configure script.
#
tx.LDFLAGS =
#
# The list of 'dist' files may be appended to from teaish.make.in.
# It can also be set up from teaish.tcl using [teaish-dist-add]
# and/or [teaish-src-add -dist ...].
#
tx.dist.files = @TEAISH_DIST_FILES@
#
# May get amended with generated file names. They are cleaned up by
# the 'clean' rules. Client code which wants to clean up extra stuff
# should do so by adding their cleanup target (e.g. clean-extension)
# as a dependency to the 'clean' target, like so:
#
# clean: distclean-extension
# distclean: distclean-extension
#
teaish__cleanExtra =
# List of deps which may trigger an auto-reconfigure.
#
teaish__autogen.deps = \
$(tx.makefile.in) $(teaish.makefile.in) \
$(tx.tcl) \
@TEAISH_PKGINDEX_TCL_IN@ \
@AUTODEPS@
@if TEAISH_MAKEFILE_IN
$(tx.makefile): $(tx.makefile.in)
@endif
teaish.autoreconfig = \
@TEAISH_AUTORECONFIG@
#
# Problem: when more than one target can invoke TEAISH_AUTORECONFIG,
# we can get parallel reconfigures running. Thus, targets which
# may require reconfigure should depend on...
#
config.log: $(teaish__autogen.deps)
$(teaish.autoreconfig)
# ^^^ We would love to skip this when running [dist]clean, but there's
# no POSIX Make-portable way to do that. GNU Make can.
.PHONY: reconfigure
reconfigure:
$(teaish.autoreconfig)
$(teaish.makefile): $(teaish__auto.def) $(teaish.makefile.in) \
@AUTODEPS@
@if TEAISH_TESTER_TCL_IN
@TEAISH_TESTER_TCL_IN@:
@TEAISH_TESTER_TCL@: @TEAISH_TESTER_TCL_IN@
config.log: @TEAISH_TESTER_TCL@
@endif
#
# CC variant for compiling Tcl-using sources.
#
CC.tcl = \
$(CC) -o $@ $(CFLAGS.configure) $(CFLAGS) $(tx.CFLAGS)
#
# CC variant for linking $(tx.src) into an extension DLL. Note that
# $(tx.src) must come before $(LDFLAGS...) for linking to third-party
# libs to work.
#
CC.dll = \
$(CC.tcl) $(tx.src) $(LDFLAGS.shlib) \
$(LDFLAGS.configure) $(LDFLAGS) $(tx.LDFLAGS) $(TCL_STUB_LIB_SPEC)
@if TEAISH_ENABLE_DLL
#
# The rest of this makefile exists solely to support this brief
# target: the extension shared lib.
#
$(tx.dll): $(tx.src) config.log
@if [ "x" = "x$(tx.src)" ]; then \
echo "Makefile var tx.src (source/object files) is empty" 1>&2; \
exit 1; \
fi
$(CC.dll)
all: $(tx.dll)
@endif # TEAISH_ENABLE_DLL
tclsh: $(teaish.makefile) config.log
@{ echo "#!/bin/sh"; echo 'exec $(TCLSH) "$$@"'; } > $@
@chmod +x $@
@echo "Created $@"
#
# Run the generated test script.
#
.PHONY: test-pre test-prepre test-core test test-post test-extension
test-extension: # this name is reserved for use by teaish.make[.in]
@if TEAISH_ENABLE_DLL
test-prepre: $(tx.dll)
@endif
@if TEAISH_TESTER_TCL
test-core.args = @TEAISH_TESTER_TCL@
@if TEAISH_ENABLE_DLL
test-core.args += '$(tx.dll)' '$(tx.loadPrefix)'
@else
test-core.args += '' ''
@endif
test-core.args += @TEAISH_TESTUTIL_TCL@
test-core: test-pre
$(TCLSH) $(test-core.args)
test-prepre: @TEAISH_TESTER_TCL@
@else # !TEAISH_TESTER_TCL
test-prepre:
@endif # TEAISH_TESTER_TCL
test-pre: test-prepre
test-core: test-pre
test-post: test-core
test: test-post
#
# Cleanup rules...
#
#.PHONY: clean-pre clean-core clean-post clean-extension
clean-extension: # this name is reserved for use by teaish.make
clean-pre:
clean-core: clean-pre
rm -f $(tx.dll8) $(tx.dll9) tclsh $(teaish__cleanExtra)
clean-post: clean-core
clean: clean-post
.PHONY: distclean-pre distclean-core distclean-post clean-extension
distclean-pre: clean
distclean-core: distclean-pre
rm -f Makefile
rm -f config.log config.defines.txt
@if TEAISH_MAKEFILE_IN
@if TEAISH_MAKEFILE
rm -f @TEAISH_MAKEFILE@
@endif
@endif
@if TEAISH_TESTER_TCL_IN
rm -f @TEAISH_TESTER_TCL@
@endif
@if TEAISH_PKGINDEX_TCL_IN
rm -f @TEAISH_PKGINDEX_TCL@
@endif
@if TEAISH_PKGINIT_TCL_IN
rm -f @TEAISH_PKGINIT_TCL@
@endif
@if TEAISH_TEST_TCL_IN
rm -f @TEAISH_TEST_TCL@
@endif
distclean-extension: # this name is reserved for use by teaish.make
distclean-post: distclean-core
distclean: distclean-post
#
# Installation rules...
#
.PHONY: install-pre install-core install-post install-test install-prepre install-extension
install-extension: # this name is reserved for use by teaish.make
install-prepre: $(tx.dll)
install-pre: install-prepre
install-core: install-pre
@if [ ! -d "$(DESTDIR)$(TCLLIBDIR)" ]; then \
set -x; $(INSTALL) -d "$(DESTDIR)$(TCLLIBDIR)"; \
fi
# ^^^^ on some platforms, install -d fails if the target already exists.
$(INSTALL) $(tx.dll) "$(DESTDIR)$(TCLLIBDIR)"
$(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$(TCLLIBDIR)"
@if TEAISH_PKGINIT_TCL
$(INSTALL.noexec) @TEAISH_PKGINIT_TCL@ "$(DESTDIR)$(TCLLIBDIR)"
@endif
install-test: install-core
@echo "Post-install test of [package require $(tx.name.pkg) $(tx.version)]..."; \
if echo \
'set c 0;' \
'if {[catch {package require $(tx.name.pkg) $(tx.version)}]} {incr c};' \
'exit $$c' \
| $(TCLSH) ; then \
echo "passed"; \
else \
echo "FAILED"; \
exit 1; \
fi
install-post: install-test
install: install-post
#
# Uninstall rules...
#
.PHONY: uninstall uninstall-pre uninstall-core uninstall-post uninstall-extension
uninstall-extension: # this name is reserved for use by teaish.make
uninstall-pre:
uninstall-core: uninstall-pre
rm -fr "$(DESTDIR)$(TCLLIBDIR)"
uninstall-post: uninstall-core
@echo "Uninstalled Tcl extension $(tx.name) $(tx.version)"
uninstall: uninstall-post
@if TEAISH_MAKEFILE_IN
Makefile: $(tx.makefile.in)
config.log: $(teaish.makefile.in)
@endif
#
# Package archive generation ("dist") rules...
#
@if TEAISH_ENABLE_DIST
@if BIN_TAR
@if BIN_ZIP
# When installing teaish as part of "make dist", we need to run
# configure with similar flags to what we last configured with but we
# must not pass on any extension-specific flags, as those won't be
# recognized when running in --teaish-install mode, causing
# the sub-configure to fail.
dist.flags = --with-tclsh=$(TCLSH)
dist.reconfig = $(teaish.dir)/configure $(dist.flags)
# Temp dir for dist.zip. Must be different than dist.tgz or else
# parallel builds may hose the dist.
teaish__dist.tmp.zip = teaish__dist_zip
#
# Make a distribution zip file...
#
dist.basename = $(tx.name.dist)-$(tx.version)
dist.zip = $(dist.basename).zip
.PHONY: dist.zip dist.zip-core dist.zip-post
#dist.zip-pre:
# We apparently can't add a pre-hook here, else "make dist" rebuilds
# the archive each time it's run.
$(dist.zip): $(tx.dist.files)
@rm -fr $(teaish__dist.tmp.zip)
@mkdir -p $(teaish__dist.tmp.zip)/$(dist.basename)
@tar cf $(teaish__dist.tmp.zip)/tmp.tar $(tx.dist.files)
@tar xf $(teaish__dist.tmp.zip)/tmp.tar -C $(teaish__dist.tmp.zip)/$(dist.basename)
@if TEAISH_DIST_FULL
@$(dist.reconfig) \
--teaish-install=$(teaish__dist.tmp.zip)/$(dist.basename) \
--t-e-d=$(teaish__dist.tmp.zip)/$(dist.basename) >/dev/null
@endif
@rm -f $(dist.basename)/tmp.tar $(dist.zip)
@cd $(teaish__dist.tmp.zip) && zip -q -r ../$(dist.zip) $(dist.basename)
@rm -fr $(teaish__dist.tmp.zip)
@ls -la $(dist.zip)
dist.zip-core: $(dist.zip)
dist.zip-post: dist.zip-core
dist.zip: dist.zip-post
dist: dist.zip
undist-zip:
rm -f $(dist.zip)
undist: undist-zip
@endif #BIN_ZIP
#
# Make a distribution tarball...
#
teaish__dist.tmp.tgz = teaish__dist_tgz
dist.tgz = $(dist.basename).tar.gz
.PHONY: dist.tgz dist.tgz-core dist.tgz-post
# dist.tgz-pre:
# see notes in dist.zip
$(dist.tgz): $(tx.dist.files)
@rm -fr $(teaish__dist.tmp.tgz)
@mkdir -p $(teaish__dist.tmp.tgz)/$(dist.basename)
@tar cf $(teaish__dist.tmp.tgz)/tmp.tar $(tx.dist.files)
@tar xf $(teaish__dist.tmp.tgz)/tmp.tar -C $(teaish__dist.tmp.tgz)/$(dist.basename)
@if TEAISH_DIST_FULL
@rm -f $(teaish__dist.tmp.tgz)/$(dist.basename)/pkgIndex.tcl.in; # kludge
@$(dist.reconfig) \
--teaish-install=$(teaish__dist.tmp.tgz)/$(dist.basename) \
--t-e-d=$(teaish__dist.tmp.zip)/$(dist.basename) >/dev/null
@endif
@rm -f $(dist.basename)/tmp.tar $(dist.tgz)
@cd $(teaish__dist.tmp.tgz) && tar czf ../$(dist.tgz) $(dist.basename)
@rm -fr $(teaish__dist.tmp.tgz)
@ls -la $(dist.tgz)
dist.tgz-core: $(dist.tgz)
dist.tgz-post: dist.tgz-core
dist.tgz: dist.tgz-post
dist: dist.tgz
undist-tgz:
rm -f $(dist.tgz)
undist: undist-tgz
@else #!BIN_TAR
dist:
@echo "The dist rules require tar, which configure did not find." 1>&2; exit 1
@endif #BIN_TAR
@else #!TEAISH_ENABLE_DIST
undist:
dist:
@if TEAISH_OUT_OF_EXT_TREE
@echo "'dist' can only be used from an extension's home dir" 1>&2; \
echo "In this case: @TEAISH_EXT_DIR@" 1>&2; exit 1
@endif
@endif #TEAISH_ENABLE_DIST
Makefile: @TEAISH_TCL@
@if TEAISH_MAKEFILE_CODE
#
# TEAISH_MAKEFILE_CODE may contain literal makefile code, which
# gets pasted verbatim here. Either [define TEAISH_MAKEFILE_CODE
# ...] or use [teaish-make-add] to incrementally build up this
# content.
#
# <TEAISH_MAKEFILE_CODE>
@TEAISH_MAKEFILE_CODE@
# </TEAISH_MAKEFILE_CODE>
@endif
@if TEAISH_MAKEFILE
#
# TEAISH_MAKEFILE[_IN] defines any extension-specific state this file
# needs.
#
# It must set the following vars if they're not already accounted for
# via teaish.tcl.
#
# - tx.src = list of the extension's source files, being sure to
# prefix each with $(tx.dir) (if it's in the same dir as the
# extension) so that out-of-tree builds can find them. Optionally,
# [define] TEAISH_EXT_SRC or pass them to [teaish-src-add].
#
# It may optionally set the following vars:
#
# - tx.CFLAGS = CFLAGS/CPPFLAGS. Optionally, [define] TEAISH_CFLAGS
# or pass them to [teaish-cflags-add].
#
# - tx.LDFLAGS = LDFLAGS. Optionally, [define] TEAISH_LDFLAGS or
# pass them to [teaish-ldflags-add].
#
# It may optionally hook into various targets as documented in
# /doc/extensions.md in the canonical teaish source tree.
#
# Interestingly, we don't have to pre-filter teaish.makefile.in - we
# can just @include it here. That skips its teaish-specific validation
# though. Hmm.
#
# <TEAISH_MAKEFILE>
Makefile: @TEAISH_MAKEFILE@
@include @TEAISH_MAKEFILE@
# </TEAISH_MAKEFILE>
@endif
|