Add support for [apply]
[jimtcl.git] / build-jim-ext.in
blob9566b837fb889800e3613b8ec293e187ce45ba5f
1 #!/usr/bin/env jimsh
3 # Separate command line arguments into options and source files
4 set opts {}
5 set sources {}
7 proc usage {{msg {}}} {
8         puts stderr "Usage: build-jim-ext ?--notest? ?--install? ?--static? ?cc-options? ?-o modname? sources..."
9         if {$msg ne ""} {
10                 puts stderr \n$msg
11         }
12         exit 1
15 proc readfile {filename {default_value ""}} {
16         set result $default_value
17         catch {
18                 set f [open $filename]
19                 set result [$f read -nonewline]
20                 $f close
21         }
22         return $result
25 set linker "@CC@"
26 set testmod 1
27 set install 0
28 set static 0
29 set verbose 0
30 set keep 0
31 set includepaths {}
32 set libpaths {}
33 set libs {}
34 for {set i 0} {$i < [llength $argv]} {incr i} {
35         set arg [lindex $argv $i]
36         switch -glob -- $arg {
37                 *.c {
38                         lappend sources $arg
39                 }
40                 *.cpp {
41                         lappend sources $arg
42                         set linker "@CXX@"
43                 }
44                 --notest {
45                         set testmod 0
46                 }
47                 --install {
48                         set install 1
49                 }
50                 --static {
51                         set static 1
52                 }
53                 --verbose {
54                         set verbose 1
55                 }
56                 --keep {
57                         set keep 1
58                 }
59                 --help {
60                         usage "Easily builds dynamic (loadable) modules for jim"
61                 }
62                 -o {
63                         incr i
64                         set modname [file rootname [lindex $argv $i]]
65                         if {$modname eq ""} {
66                                 usage "Option -o requires an argument"
67                         }
68                 }
69                 -I* {
70                         lappend includepaths $arg
71                         if {$arg eq "-I"} {
72                                 lappend includepaths [lindex $argv $i]
73                         }
74                 }
75                 -L* {
76                         lappend libpaths $arg
77                         if {$arg eq "-L"} {
78                                 lappend libpaths [lindex $argv $i]
79                         }
80                 }
81                 -l* {
82                         lappend libs $arg
83                 }
84                 -* {
85                         lappend opts $arg
86                 }
87                 default {
88                         usage "Unexpected '$arg'"
89                 }
90         }
93 if {$sources eq ""} {
94         usage "No sources provided"
96 if {![info exists modname]} {
97         set modname [file rootname [file tail [lindex $sources 0]]]
98         # Remove jim- prefix if one exists
99         regsub "^jim-" $modname "" modname
102 if {$static} {
103         set target libjim-$modname.a
104 } else {
105         set target $modname.so
107 puts "Building $target from $sources\n"
109 # Now add the standard location after any user include paths
110 lappend includepaths -I@prefix@/include
112 set CPPFLAGS "-D_GNU_SOURCE"
114 set ljim ""
115 set shobj_cflags ""
116 set shobj_ldflags ""
117 if {!$static} {
118         set shobj_cflags "@SHOBJ_CFLAGS@"
119         if {"@JIM_STATICLIB@" eq "1"} {
120                 puts stderr "Warning: libjim is static. Dynamic module may not work on some platforms.\n"
121                 set shobj_ldflags "@SHOBJ_LDFLAGS@"
122         } else {
123                 # If shared, link against the shared libjim to resolve symbols
124                 set ljim -ljim
125                 set shobj_ldflags "@SHOBJ_LDFLAGS_R@"
126         }
129 set objs {}
130 foreach source $sources {
131         set obj [file rootname [file tail $source]].o
132         if {[string match *.c $source]} {
133                 set compiler "@CC@"
134         } else {
135                 set compiler "@CXX@"
136         }
137         set compile "$compiler @CFLAGS@ $CPPFLAGS $shobj_cflags $includepaths $opts -c -o $obj $source"
138         puts "Compile: $obj"
139         lappend objs $obj
140         flush stdout
141         set rc [catch {
142                 if {$verbose} {
143                         puts $compile
144                 }
145                 exec 2>jimerr.out {*}$compile
146         } msg]
148         set errmsg [readfile jimerr.out]
149         file delete jimerr.out
151         if {$rc} {
152                 if {!$verbose} {
153                         puts stderr $compile
154                 }
155                 puts stderr $msg
156                 if {$errmsg ne ""} {
157                         puts stderr $errmsg
158                 }
159                 file delete {*}$objs
160                 exit 1
161         } else {
162                 if {$errmsg ne ""} {
163                         puts $errmsg
164                 }
165         }
168 if {$static} {
169         set ar "@AR@ cq $target $objs"
170         set ranlib "@RANLIB@ $target"
172         puts "Ar:      $target"
173         set rc [catch {
174                 file delete $target
175                 exec {*}$ar
176                 exec {*}$ranlib
177                 if {$verbose} {
178                         puts stderr $ar
179                 }
180         } msg]
182         file delete {*}$objs
184         if {$rc} {
185                 puts stderr $ar
186                 puts stderr $ranlib
187                 puts stderr $msg
188                 file delete $target
189                 exit 1
190         }
191 } else {
192         # Add the standard location after any user lib paths
193         lappend libpaths -L@prefix@/lib
195         set link "$linker @CFLAGS@ @LDFLAGS@ $shobj_ldflags $libpaths $opts -o $target $objs $ljim @LIBS@ $libs"
197         puts "Link:    $target"
198         set rc [catch {
199                 if {$verbose} {
200                         puts stderr $link
201                 }
202                 exec 2>jimerr.out {*}$link
203         } msg]
205         set errmsg [readfile jimerr.out]
206         file delete jimerr.out
208         if {!$keep} {
209                 file delete {*}$objs
210         }
212         if {$rc} {
213                 file delete $target
214                 puts stderr $link
215                 puts stderr $msg
216                 if {$errmsg ne ""} {
217                         puts stderr $errmsg
218                 }
219                 exit 1
220         }
221         if {$errmsg ne ""} {
222                 puts $errmsg
223         }
225         if {$testmod} {
226                 # Now, is testing even possible?
227                 # We must be running a compatible jimsh with the load command at least
228                 set testmod 0
229                 set rc [catch {
230                         # This will avoid attempting on Tcl and on jimsh without load
231                         # How to tell if we are cross compiling?
232                         if {[info version] > 0.73 && [exists -command load]} {
233                                 set testmod 1
234                         }
235                 } msg]
236         }
238         set rc [catch {
239                 if {$testmod} {
240                         puts "Test:    load $target"
241                         load $target
242                 }
243                 if {$install} {
244                         set dest [env DESTDIR ""]@prefix@/lib/jim
245                         puts "Install: $target => $dest"
246                         file mkdir $dest
247                         file copy $target $dest/$target
248                 }
249                 puts "\nSuccess!"
250         } msg]
251         if {$rc} {
252                 puts stderr $msg
253                 exit 1
254         }