#!/bin/sh
#
# Generate TclKit - run "tclsh genkit", or see info at end of this script.
#
# Written by Coen Siegerink, as part of Tclkit.
# March 2003 - placed in the public domain by the author.
# October 2005 - modified to support both 8.4 and 8.5 builds (and lite)
# December 2006 - removed vlerq/thrive code, this is now handled by "kitgen"
#
# For latest version of this tool see
# $Id: genkit 1675 2007-06-16 14:22:03Z jcw $
# \
TCL_LIBRARY=noarch/lib/tcl8.${KIT_VERSION-4}; export TCL_LIBRARY
# \
exec "install/`hostname`/bin/tclsh8.${KIT_VERSION-4}" "$0" ${1+"$@"}
# To build an 8.4 version of tclkit[sh], use "tclsh genkit A", etc.
# To build an 8.5 version, use "KIT_VERSION=5 tclsh genkit A", etc.
if {[info exists env(KIT_VERSION)]} { set V $env(KIT_VERSION) } else { set V 4 }
# The following is needed to launch a tclsh or kitsh which does not yet
# have the necessary runtime VFS appended at the end of the executable.
if {![info exists env(TCL_LIBRARY)]} {
set env(TCL_LIBRARY) [file join [pwd] noarch/lib/tcl8.$V]
}
# This code is dual-mode, it can be run as tcl or as sh script, which is
# needed to bootstrap this stuff. Make sure Tcl is not too old, though.
package require Tcl 8.0
# This is the base url to fetch source tars from if not already present:
set origurl https://www.equi4.com/pub/tk
# All platform differences are collected below for easy reference.
#
# The idea is quite straightforward:
# - the X array is set up so "$X(anything)" defaults to "anything"
# - the Z array is set up so "$Z(anything)" defaults to ""
# - i.e. "$X(foo)" defaults to "foo" and "$Z(foo)" defaults to ""
# - then for each platform, we can add overrides to alter defaults
#
# NOTE that if the file "genkit.local" exists, it will be sourced before
# actual processing begins - this allows adding more elaborate tweaks.
array set X {}
array set Z {}
if {$V != "4"} { set Z(85) 8$V }
switch -glob $tcl_platform(os) {
AIX { array set Z {tclsuff "-Wl,-bshared -lcrypt" tksuff -lIM}
array set X {gcc xlC g++ xlC} }
BSD/OS { array set X {make gmake} }
HP-UX { array set X {gcc cc g++ aCC} }
NetBSD { array set X {. ""}
set env(LD_RUN_PATH) /usr/X11R6/lib }
OpenBSD { array set Z {vso .1.0}
array set X {. ""} }
#OSF1 { array set X {gcc cc g++ cxx} }
#SunOS { array set X {g++ gcc}; set env(CC) gcc }
SunOS { array set Z {tclsuff "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic"
tksuff "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic"}
set env(CC) gcc }
Windows* { array set Z {s s .exe .exe}
array set X {. "" unix win}
set X(tclsh8.$V) tclsh8${V}s.exe
}
default { array set X {} }
}
# this case is too messy to include in the above switch
if {$tcl_platform(os) == "Darwin"} {
array set Z {tclmakesuff
{CFLAGS_OPTIMIZE=-gfull\ -Os \
CC_SWITCHES=\$(STUB_CC_SWITCHES)\ -mdynamic-no-pic \
LDFLAGS_OPTIMIZE=-Wl,-dead_strip,-s}
stripopt -x
tkdynmakesuff {-o wish TK_SHLIB_LD_EXTRAS=}}
array set X {make {make SHLIB_LD=g++\ -bundle\ \$(LDFLAGS)}}
if {[info exists env(TCLKIT_AQUA)] && "$env(TCLKIT_AQUA)" == "1"} {
append Z(tkdynmakesuff) \
{ TK_SHLIB_LD_EXTRAS=-sectcreate\ __TEXT\ __tk_rsrc\ \$\(TK_RSRC_FILE\)}
lappend Z(tkconfig) --enable-aqua
}
}
# make $X(anything) default to the value "anything"
proc xdefval {a e op} { if {![info exists ::X($e)]} { set ::X($e) $e } }
trace var X r xdefval
if {[info exists env(EXTRA_MAKE_FLAGS)]} {
set X(make) "$X(make) $env(EXTRA_MAKE_FLAGS)"
}
# make $Z(anything) default to the empty string
proc zdefval {a e op} { if {![info exists ::Z($e)]} { set ::Z($e) "" } }
trace var Z r zdefval
# copy one file and adjust modification to same as original
proc dupfile {from to} {
set mod [file mtime $from]
if {![file exists $to] || $mod != [file mtime $to]} {
file copy -force $from $to
file mtime $to $mod
}
}
# recursively copy subdirs and files, if modification times differ
proc sync {from to} {
foreach path [glob -nocomplain [file join $from *]] {
set tail [file tail $path]
set dest [file join $to $tail]
if {[file isdir $path]} {
file mkdir $dest
sync $path $dest
} else {
dupfile $path $dest
}
}
}
# return file contents as a string
proc readfile {name {binary 0}} {
set fd [open $name]
if {$binary} {
fconfigure $fd -translation binary -encoding binary
}
set contents [read $fd]
close $fd
return $contents
}
# calculate a simple 4-digit sum of a string
proc simplesum {str} {
set s 0
foreach x [split $str ""] {
binary scan $x c v
set s [expr {7*$s+$v}]
}
return [format %04d [expr {abs($s) % 9000 + 1000}]]
}
# calculate an md5 checksum for a file
proc md5sum {name} {
if {[catch { lindex [exec md5sum -b $name] 0 } result]} {
set result [lindex [exec md5 $name] end]
}
return $result
}
# create a tag for a file and delete it
proc tagfile {name} {
if {[catch { md5sum $name } tag]} {
set tag ""
} else {
lappend tag [file size $name] [file mtime $name]
}
file delete name
return [linsert $tag 0 $name]
}
# compare tag, if same then restore its modification time
proc untagfile {tag} {
foreach {nm md sz mtime} $tag break
if {[file exists $nm] && [file size $nm] == $sz && [md5sum $nm] == $md} {
file mtime $nm $mtime
}
}
# convert seconds to readable date/time format
proc timestamp {{now ""} {sep -}} {
if {$now == ""} { set now [clock seconds] }
return [clock format $now -format "%Y/%m/%d$sep%H:%M:%S"]
}
# convert possibly globbed path specifier to real name, if unique
proc unglob {path} {
set f [glob -nocomplain $path]
if {[llength $f] == 1} { set path [lindex $f 0] }
return $path
}
# execute external command
proc run {args} {
puts -nonewline [format { %-30.30s... } $args]
flush stdout
puts $::F "\nRUN: $args\n"
flush $::F
set err [catch { eval exec $args >>& $::P/out/$::H/$::target } msg]
seek $::F 0 end
if {$err == 0} {
puts "ok"
} else {
puts "FAILED:"
puts "-[string repeat {=-} 39]\n$args\n-[string repeat {#-} 39]"
puts ">>> Look in the file 'out/$::H/$::target' for details."
return -code error $msg
}
}
# run a configure script
proc config {dir args} {
if {![file exists Makefile]} {
eval [list run sh [file join ../../../src $dir configure] \
--prefix=$::P/noarch --exec-prefix=$::I] $args
}
}
# parse and load tcl/tk config files into global vars
proc loadconf {name} {
set vars {}
foreach x {AR CC CFLAGS DBGX LDFLAGS LIBS \
LIB_RUNTIME_DIR NODOT_VERSION VERSION} {
global $x
set $x ""
}
set fd [open $name]
while {[gets $fd line] >= 0} {
if {[regexp {^(\w+)=$} $line - name]} {
set value ""
} elseif {![regexp {^(\w+)='(.*)'$} $line - name value]} {
continue
}
global $name
set $name [subst $value]
lappend vars $name
}
close $fd
return $vars
}
# summarize all available results
proc summarize {aref {modules {kitsh itcldyn tkdyn mkdyn builds}}} {
global V
upvar $aref summary
array set targets {}
array set platforms {}
foreach file [glob -nocomplain out/*/*] {
set platform [lindex [file split $file] 1]
set platforms($platform) 1
set target [lindex [file split $file] 2]
set targets($target) 1
set log [readfile $file]
switch -regexp $log {
"\nERROR:" { set status ERR }
"\nEND\." { set status (+) }
default { set status BAD }
}
set ${target}($platform) $status
array set info:$platform {}
if {$target == "tcl"} {
foreach line [split $log \n] {
if {[regexp {^tcl_platform\((\w+)\)\s+= (.*)} $line - key value]} {
set info:${platform}($key) $value
}
}
}
}
array set files {}
foreach {target mask} {
kit kit{,.exe}
kitsh kitsh{,.exe}
mkdyn lib/Mk4tcl.{so,so.1.0,sl,dylib,dll}
itcldyn lib/itcl3.4/libitcl3{,.}4.{so,so.1.0,sl,dylib,dll}
tkdyn lib/libtk8{,.}[45].{so,so.1.0,sl,dylib,dll}
tcl bin/tclsh8{,.}[45]{,s.exe}
} {
array set $target {}
foreach file [glob -nocomplain install/*/$mask] {
set platform [lindex [file split $file] 1]
set mtime [timestamp [file mtime $file]]
lappend ${target}($platform) $mtime [file size $file]b
lappend files($platform) $target
}
}
foreach target [lsort [array names targets]] {
foreach {k v} [array get $target] {
set info:${k}($target) $v
}
}
set platlist {}
array set summary {}
foreach platform [lsort [array names platforms]] {
if {[info exists info:${platform}(machine)] > 0} {
lappend platlist $platform
set summary($platform,id) [simplesum $platform]
foreach k "machine os osVersion wordSize byteOrder $modules" {
set x {}
if {[info exists info:${platform}($k)]} {
set x [set info:${platform}($k)]
switch $k {
byteOrder { regsub {Endian} $x {} x }
}
regsub {^\(\+\)} $x {OK} x
regsub {^OK } $x {} x
if {$k != "builds"} { set x [lindex $x 0] }
if {[regsub {^20(0\d)/(\d\d)/(\d\d)-.*$} $x {\1\2\3} x]} {
switch $k kitsh - itcldyn - tkdyn - mkdyn {
set v [string map {kitsh sh tkdyn tdyn itcldyn idyn \
mkdyn mdyn vdyn} $k]
lappend info:${platform}(builds) $v
}
}
}
set summary($platform,$k) $x
}
}
}
return $platlist
}
# Copy a URL to a file and print meta-data
# (this sample code was adapted from the Tcl manual page)
proc origfetch {file} {
package require http
if {[info exists ::env(http_proxy)]} {
regexp {//(.*):(.*)} $::env(http_proxy) m h p
http::config -proxyhost $h -proxyport $p
}
puts -nonewline " fetching tars/$file ... "
flush stdout
set fd [open tars/$file w]
set t [http::geturl $::origurl/tars/$file -channel $fd -blocksize 4096]
close $fd
scan [http::code $t] {HTTP/%f %d} ver ncode
puts [http::status $t]
http::cleanup $t
if {$ncode != 200 || [file size tars/$file] == 0} {
file delete tars/$file
}
}
namespace eval commands {
# Step 1: acquire and unpack all the necessary sources
# The goal is to end up with a src/ dir and tcl/tk/etc dirs in it
proc A {args} {
global origurl Z
file mkdir src
set packages $args
if {[llength $packages] == 0} {
set packages [list tcl$Z(85) tk$Z(85) itcl mk vfs kit zlib]
}
foreach pkg $packages {
if {[file exists src/$pkg]} {
continue
}
set cvs "cvs/$pkg"
if {[file isdir $cvs]} {
puts " symlinking to $cvs"
cd src
exec ln -s ../$cvs $pkg
cd ..
continue
}
set tar $pkg.tar.gz
if {![file isfile tars/$tar]} {
file mkdir tars
origfetch $tar
}
if {[file isfile tars/$tar]} {
puts " unpacking tars/$tar"
cd src
# on HP-UX, gzip|tar generates a non-zero status code
# ignore it, check for the result being created instead
catch { exec gzip -d < ../tars/$tar | tar xf - }
if {![file isdirectory $pkg]} {
puts stderr "$pkg: ungzip or untar failed"
}
cd ..
continue
}
puts stderr "$pkg: not found"
}
if {![file exists tars/runtime$Z(85).kit]} {
origfetch runtime$Z(85).kit
}
if {![file exists tars/runtime$Z(85)-sh.kit]} {
origfetch runtime$Z(85)-sh.kit
}
}
# Step 2: build all the components of TclKit
proc B {args} {
global target F H P B I S V X Z
switch -- $args {
"" { set args {zlib vfs mk kitsh itcldyn tkdyn} }
static { set args {itcl tk kit} }
all { set args {zlib vfs mk itcl tk kitsh kit itcldyn tkdyn} }
}
set P [pwd]
set B $P/build/$H
set I $P/install/$H
set S $P/src
foreach target $args {
puts " $target:"
file mkdir out/$H
set F [open $P/out/$H/$target w]
fconfigure $F -buffering line
if {[catch {
file mkdir $B/$target
cd $B/$target
switch $target {
tcl {
config tcl$Z(85)/$X(unix) --disable-shared
#run $X(make) genstubs
eval run $X(make) binaries \
LD_SEARCH_FLAGS= CC_SEARCH_FLAGS= TCL_LIBRARY= TCL_PACKAGE_PATH= \
$Z(tclmakesuff)
file mkdir $I
eval run $X(make) install-binaries install-libraries
# results have been installed so tclsh can be used
run $I/bin/$X(tclsh8.$V) << "parray tcl_platform"
}
tk {
eval [list config tk$Z(85)/$X(unix) --with-tcl=$B/tcl \
--disable-shared] $Z(tkconfig)
#run $X(make) genstubs
eval run $X(make) binaries \
LD_SEARCH_FLAGS= CC_SEARCH_FLAGS= TK_LIBRARY=
}
tkdyn {
eval [list config tk$Z(85)/unix --with-tcl=$B/tcl] $Z(tkconfig)
#run $X(make) genstubs
close [open wish w]
eval run $X(make) binaries \
LD_SEARCH_FLAGS= CC_SEARCH_FLAGS= TK_LIBRARY= $Z(tkdynmakesuff)
file mkdir $I
eval run $X(make) install-binaries $Z(tkdynmakesuff)
# don't keep the installed wish, just the shared lib
file delete $I/bin/wish8.$V
set tklib [unglob $I/lib/libtk8*]
exec chmod +w $tklib
catch { eval exec strip $Z(stripopt) $tklib } }
itcl {
config itcl/itcl --with-tcl=$B/tcl --disable-shared
eval run $X(make) binaries ITCL_LIBRARY=
}
itcldyn {
config itcl/itcl --with-tcl=$B/tcl
eval run $X(make) binaries ITCL_LIBRARY=
file mkdir $I
eval run $X(make) install-binaries
catch {
eval exec strip $Z(stripopt) [unglob $I/lib/itcl3*/libitcl3*]
}
}
mk {
config mk/unix --with-tcl=$S/tcl$Z(85)/generic --disable-shared
eval run $X(make) Mk4tcl.a
}
mkdyn {
config mk/unix --with-tcl=$S/tcl$Z(85)/generic
eval run $X(make) tcl
# MK installs in completely wrong spot, do a manual copy instead
file mkdir $I/lib
file copy -force [unglob $B/mkdyn/Mk4tcl*] $I/lib
catch { eval exec strip $Z(stripopt) [unglob $I/lib/Mk4tcl*] }
}
vfs {
config vfs --with-tcl=$B/tcl --disable-shared
eval run $X(make) binaries
}
zlib {
# copy all files to build area, it doesn't build in another spot
sync $S/zlib .
config [pwd]
eval run $X(make) CC=$X(gcc) libz.a
}
kitsh -
kitsh-static -
kit {
# copy all files to build area, it doesn't build in another spot
sync $S/kit .
eval global [loadconf $B/tcl/tclConfig.sh]
# work around a quoting bug when 64-bit ints are supported
regsub {long long} $TCL_DEFS {long\ long} TCL_DEFS
# work around a quoting bug in -DPACKAGE_STRING
regsub {tcl 8} $TCL_DEFS {tcl\ 8} TCL_DEFS
# work around a quoting bug in -DMODULE_SCOPE
regsub {extern __attribute__} $TCL_DEFS {extern\ __attribute__} TCL_DEFS
set D [list -DNDEBUG -DTCL_LOCAL_APPINIT=TclKit_AppInit]
set O [list -I. -I$S/tcl$Z(85)/unix -I$S/tcl$Z(85)/generic \
-I$S/mk/include -I$S/zlib]
set L [list ../tcl/libtcl8$X(.)$V$Z(s).a ../vfs/libvfs1$X(.)3.a \
../zlib/libz.a ../mk/Mk4tcl.a]
eval lappend L $TCL_LD_FLAGS
switch $target {
kitsh {
eval lappend L $TCL_LIB_SPEC $TCL_LIBS $Z(tclsuff)
set gcc $X(g++)
}
kitsh-static {
lappend D -DKIT_INCLUDES_ITCL
lappend L ../itcl/libitcl3$X(.)4.a
eval lappend L $TCL_LIB_SPEC $TCL_LIBS $Z(tclsuff)
set gcc [list $X(g++) -static]
set target kitsh
}
kit {
eval global [loadconf $B/tk/tkConfig.sh]
set gcc $X(g++)
lappend D -DKIT_INCLUDES_TK -DKIT_INCLUDES_ITCL
eval lappend O -I$S/tk$Z(85)/generic $TK_XINCLUDES
lappend L ../itcl/libitcl3$X(.)4.a
eval lappend L $TK_BUILD_LIB_SPEC $TK_LIBS $Z(tksuff)
}
}
append target $Z(.exe)
eval run $X(gcc) -c $O $D $TCL_DEFS $TCL_CFLAGS_OPTIMIZE \
[glob src/*.c] [list $S/tcl$Z(85)/unix/tclAppInit.c] $Z(gccsuff)
eval run $gcc -o $target [glob *.o] $L $Z(ldsuff)
run strip $target
file mkdir $I
file delete $I/$target
file copy $target $I
run ls -l $I
}
}
puts $F "\nEND."
} err]} {
puts " ERROR: $err"
puts $F "\nERROR: $::errorInfo"
}
close $F
cd $P
}
puts " Done."
}
# Step 3: collect results
proc C {} {
global H Z
exec tar cf - install/$H out/$H | gzip >result$Z(85)-$H.tar.gz
}
# Step 4: create a dummy tclkit and try it
proc D {{type ""} {runtime ""}} {
global H V X Z
set I install/$H
set E [info sharedlibext]
file copy -force $I/kitsh$type dummy$type$Z(85)-$H
file attributes dummy$type$Z(85)-$H -permissions +x
if {$runtime == ""} { set runtime tars/runtime$Z(85).kit }
exec cat $runtime >>dummy$type$Z(85)-$H
set script [string map [list @H $H @I $I @E $E$Z(vso) @. $X(.) @V $V] {
puts " info loaded = [info loaded]"
puts " tclkit_version = $vfs::tclkit_version"
parray tcl_platform
if {[file exists @I/lib/itcl3.4/libitcl3@.4@E]} {
load @I/lib/itcl3.4/libitcl3@.4@E
}
puts " package Itcl = [package require Itcl]"
if {[info exists env(DISPLAY)] && $env(DISPLAY) != ""} {
if {[file exists @I/lib/libtk8@.@V@E]} {
load @I/lib/libtk8@.@V@E
puts " package Tk = [package require Tk]"
pack [label .l -text " @H says HELLO! "] -padx 50 -pady 50
} else {
puts " *** Tk not present, skipping Tk test ***"
}
} else {
puts " *** DISPLAY has not been defined, skipping Tk test ***"
}
after 3000 destroy .
puts " running [file tail [info nameofexe]]"
}]
exec ./dummy$type$Z(85)-$H <<$script >@stdout 2>@stderr
}
# Step 5: extended version includes incrtcl and tk
proc E {{type ""}} {
global H V X Z
set I install/$H
set E [info sharedlibext]
set R tars/runtime$Z(85).kit
file copy -force $I/kitsh$type tclkit$type$Z(85)-$H
file attributes tclkit$type$Z(85)-$H -permissions +x
foreach x {itcl3.4/libitcl3$X(.)4$E$Z(vso) libtk8$X(.)$V$E$Z(vso)} {
if {[file exists $I/lib/$x]} {
# needed for OpenBSD, which leaves them as 0555
file attributes $I/lib/$x -permissions +w
# MacOS X needs to strip shared libs with -x
eval exec strip $Z(stripopt) $I/lib/$x
}
}
# the following approach makes sure the result is optimally packed
set script [string map [list @H $H @I $I @E $E @R $R @. $X(.) @O $Z(vso) \
@Y $type$Z(85) @V $V] {
set db [vfs::mk4::Mount @R @R -readonly]
vfs::attributes @R -state translucent
file copy @I/lib/itcl3.4/libitcl3@.4@E@O @R/lib/itcl3.4/libitcl3.4@E
file copy @I/lib/libtk8@.@V@E@O @R/lib/tk8.@V/libtk8.@V@E
set fd [open tclkit@Y-@H a]
mk::file save $db $fd
close $fd
vfs::unmount @R
}]
exec ./dummy$Z(85)-$H <<$script
puts " tclkit$type$Z(85)-$H: [file size dummy$type$Z(85)-$H] ->\
[file size tclkit$type$Z(85)-$H]"
}
# Private use: freeze build results for packaging
proc F {} {
global V
file mkdir parts
foreach pf [summarize ia] {
if {$ia($pf,builds) == ""} continue
set info(seq) [simplesum $pf]
set info(name) [string tolower $ia($pf,os)-$ia($pf,machine)]
regsub -all {[^a-z0-9-]} $info(name) {} info(name)
set iprefix install/$pf
set oprefix parts/$info(name).$info(seq)
set lib $iprefix/lib
set sfx ".{so,so.1.0,sl,dylib,dll}"
set tag [tagfile $oprefix,in]
foreach build $ia($pf,builds) {
switch $build {
sh {
dupfile $iprefix/kitsh $oprefix,sh
}
idyn {
dupfile [unglob $lib/itcl3.4/libitcl3{,.}4$sfx] $oprefix,it
}
tdyn {
dupfile [unglob $lib/libtk8{,.}$V$sfx] $oprefix,tk
}
full {
dupfile $iprefix/kit $oprefix,ui
}
mdyn {
dupfile [unglob $lib/Mk4tcl$sfx] $oprefix,mk
}
}
}
foreach x [glob -nocomplain $oprefix,*] {
regsub {.*,} $x {} k
if {$k != "in"} {
set info($k) [list [file mtime $x] [md5sum $x] [file size $x]]
file attributes $x -permissions 0755
}
}
foreach x [array names ia $pf,*] {
set k [lindex [split $x ,] 1]
switch $k kit - kitsh - idyn - tdyn - mdyn - vdyn continue
set info($k) $ia($x)
}
foreach x {tcl tk} {
if {[file exists $iprefix/lib/${x}Config.sh]} {
foreach y [loadconf $iprefix/lib/${x}Config.sh] {
set info($y) [string trim [set ::$y]]
}
}
}
set fd [open $oprefix,in w]
foreach x [lsort [array names info]] {
puts $fd [list $x $info($x)]
}
close $fd
untagfile $tag
unset info
}
}
# Private use: generate all builds
proc G {} {
global V Z
file mkdir head
foreach x [glob -nocomplain parts/*,in] {
regexp {.*/(.*-.*)\.(\d+),in} $x - pf seq
regsub {,in} $x {} prefix
array set info [readfile $x]
set mtime [file mtime $x]
set dll $info(TCL_SHLIB_SUFFIX)
if {[info exist info(sh)]} {
if {[info exist info(tk)]} {
set f head/$pf.$seq-dyn.bin
set g ""
exec cat $prefix,sh tars/runtime$Z(85).kit > $f
vfs::mk4::Mount $f kit -nocommit
dupfile $prefix,tk kit/lib/tk8.$V/libtk8.$V$dll
if {[info exist info(it)]} {
dupfile $prefix,it kit/lib/itcl3.4/libitcl3.4$dll
}
vfs::unmount kit
} else {
set f head/$pf.$seq-sh.bin
set g -sh
exec cat $prefix,sh tars/runtime$Z(85)$g.kit > $f
}
if {$mtime < [file mtime tars/runtime$Z(85)$g.kit]} {
set mtime [file mtime tars/runtime$Z(85)$g.kit]
}
file mtime $f $mtime
file attributes $f -permissions 0755
}
if {[info exist info(ui)]} {
set f head/$pf.$seq.bin
exec cat $prefix,ui tars/runtime$Z(85).kit > $f
file attributes $f -permissions 0755
if {$mtime < [file mtime tars/runtime$Z(85).kit]} {
set mtime [file mtime tars/runtime$Z(85).kit]
}
file mtime $f $mtime
}
unset info
}
}
# Produce a build status summary as a concise HTML table
proc S {{outfile status.html}} {
set modules {tcl mk vfs kitsh itcldyn tkdyn mkdyn builds}
set fd [open $outfile w]
puts $fd {
TclKit Build Status
}
puts $fd "
TclKit build status as of [timestamp]
"
puts $fd "
"
set tags "os machine version word endian $modules id host"
puts $fd "
[join $tags {
}]
"
foreach pf [summarize info $modules] {
set all($info($pf,os),$info($pf,machine),$info($pf,osVersion),$pf) $pf
}
set lastfull {}
foreach x [lsort -dictionary [array names all]] {
set pf $all($x)
set show {}
set full {}
set blanking 1
foreach k "os machine osVersion wordSize \
byteOrder $modules id" l $lastfull {
set x $info($pf,$k)
set x [string range $x 0 19]
regsub -all { } $x {\ } x
regsub {^ERR} $x {ERR} x
lappend full $x
if {$blanking && $x == $l} { set x "" } else { set blanking 0 }
lappend show $x
}
lappend show [lindex [split $pf .] 0]
puts $fd "
[join $show {
}]
"
set lastfull $full
}
puts $fd "
"
close $fd
}
}
set cmd [lindex $argv 0]
set argv [lrange $argv 1 end]
if {$cmd == "G"} {
package require vfs::mk4
}
set H [exec hostname]
if {[file exists genkit.local]} { source genkit.local }
# avoid confusing errors further down the line
if {$H == ""} {
puts "genkit requires a hostname, this machine does not have one."
exit 1
}
if {[namespace eval commands [list info procs $cmd]] == ""} {
puts "Generate TclKit - by Coen Siegerink
(a tool to help build TclKit runtime releases)
Usage: $::argv0 cmd ?args...?
Cmd: A = Step 1: acquire source packages
B = Step 2: build binaries
C = Step 3: collect results
D = Step 4: create a dummy tclkit and try it
E = Step 5: extended version includes incrtcl and tk
A few more commands, not for general use:
F = Freeze build results for packaging
G = Generate tclkit* executables
S = Generate an HTML build summary
"
exit
}
if {[catch { namespace eval commands [concat $cmd $argv] } msg]} {
puts stderr $msg
exit 1
}
# vim: ft=tcl