-
Notifications
You must be signed in to change notification settings - Fork 19
/
kbs.tcl
214 lines (178 loc) · 5.52 KB
/
kbs.tcl
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
# kbs.tcl -- Kitgen Build System
#
# Launch as "8.4/base-std/tclkit-cli kbs.tcl" to get a brief help text
#
# jcw, 2007-03-30
cd [file dirname [info nameofexe]]
proc kbs {command args} {
uplevel 1 ::kbs::$command $args
}
namespace eval kbs {
variable seq 0
}
proc kbs::help {} {
puts "Kitgen Build System
kbs build target build the specified extension
kbs ?help? this text
kbs list list all the extensions which can be built
kbs make build all extensions which haven't been built before
"
}
proc kbs::list {} {
puts [lsort -dict [glob -directory ../../extdefs -tails *.kbs]]
}
proc kbs::make {} {
foreach f [lsort -dict [glob -directory ../../extdefs -tails *.kbs]] {
set target [file root $f]
if {![file exists build/$target]} {
puts $target:
build $target
}
}
}
proc kbs::build {target} {
set pwd [pwd]
config::init $target
cd $pwd
}
namespace eval config {
proc init {name} {
namespace eval v {}
set v::package $name
set v::maindir [pwd]
file mkdir build/$name
cd build/$name
source [Topdir]/extdefs/$name.kbs
}
proc Version {{ver ""}} {
if {$ver ne ""} { set v::version $ver }
return $v::version
}
proc Requires {args} {
# build all the other required extensions first, then resume this one
# this recurses into kbs::build, so we need to save/restore all state
foreach target $args {
if {![file exists $v::maindir/build/$target]} {
puts ">>> $target (required by $v::package)"
set pwd [pwd]
cd $v::maindir
set keep {}
foreach x [info vars v::*] { lappend keep $x [set $x] }
namespace delete ::config::v
set r [catch { kbs build $target } err]
namespace delete ::config::v
namespace eval v {}
foreach {x y} $keep { set $x $y }
cd $pwd
if {$r} { return -code error $err}
puts "<<< $target (resuming build of $v::package)"
}
}
}
proc Sources {type args} {
if {![file exists [Srcdir]]} {
eval [linsert $args 0 src-$type]
}
}
proc src-cvs {path {module ""}} {
if {$module eq ""} { set module [file tail $path]}
if {[string first @ $path] < 0} { set path :pserver:anonymous@$path }
Run cvs -d $path -z3 co -P -d tmp $module
file rename tmp [Srcdir]
}
proc src-svn {path} {
Run svn co $path [Srcdir]
}
proc src-fetch {path} {
set file [Topdir]/downloads/[file tail $path]
if {![file exists $file]} {
package require http
file mkdir [Topdir]/downloads
puts " fetching $file"
set fd [open $file w]
set t [http::geturl $path -channel $fd]
close $fd
scan [http::code $t] {HTTP/%f %d} ver ncode
#puts [http::status $t]
http::cleanup $t
if {$ncode != 200 || [file size $file] == 0} {
file delete $file
error "fetch failed"
}
}
Untar $file [Srcdir]
}
proc src-symlink {path} {
file link -symbolic [Srcdir] $path
}
proc Build {script} {
puts [Srcdir]
eval $script
}
proc Topdir {} {
file normalize $v::maindir/../..
}
proc Srcdir {} {
file mkdir [Topdir]/sources
return [Topdir]/sources/$v::package-$v::version
}
proc Destdir {} {
return $v::maindir/build
}
proc Incdir {} {
return $v::maindir/build/include
}
proc Libdir {} {
return $v::maindir/build/lib
}
proc Unglob {match} {
set paths [glob $match]
if {[llength $paths] != 1} { error "not unique: $match" }
lindex $paths 0
}
proc Untar {file dest} {
set path [file normalize $file]
file mkdir tmp
cd tmp
# use explicit gzip in case tar command doesn't understand the z flag
set r [catch {exec gzip -dc $path | tar xf -} err]
cd ..
if {$r} {
file delete -force tmp
return -code error $err
}
# cover both cases: untar to single dir and untar all into current dir
set untarred [glob tmp/*]
if {[llength $untarred] == 1 && [file isdir [lindex $untarred 0]]} {
file rename [lindex $untarred 0] $dest
file delete tmp
} else {
file rename tmp $dest
}
}
proc Run {args} {
lappend args >@stdout 2>@stderr
eval [linsert $args 0 exec]
}
proc Result {path} {
file mkdir $v::maindir/ext
file delete -force $v::maindir/ext/$v::package-$v::version
file copy $path $v::maindir/ext/$v::package-$v::version
}
}
# now process the command line to call one of the kbs::* procs
namespace eval kbs {
set cmd [lindex $argv 0]
if {[info commands ::kbs::$cmd] ne ""} {
eval $argv
} elseif {$cmd eq ""} {
help
} else {
set cmdlist {}
foreach knowncmd [lsort [info commands ::kbs::*]] {
lappend cmdlist [namespace tail $knowncmd]
}
puts "'$cmd' not found, should be one of: [join $cmdlist {, }]"
exit 1
}
}