1# vim:se syn=tcl:
2#
3
4# Note: modules which support options *must* be included before 'options'
5use cc cc-shared
6
7options {
8    utf8            => "include support for utf8-encoded strings"
9    lineedit=1      => "disable line editing"
10    references=1    => "disable support for references"
11    math            => "include support for math functions"
12    ipv6            => "include ipv6 support in the aio extension"
13    maintainer      => {enable the [debug] command and JimPanic}
14    full            => "Enable some optional features: ipv6, math, utf8, binary, oo, tree"
15    with-jim-shared shared => "build a shared library instead of a static library"
16    jim-regexp      => "use the built-in (Tcl-compatible) regexp, even if POSIX regex is available"
17    with-jim-ext: {with-ext:"ext1 ext2 ..."} => {
18        Specify additional jim extensions to include.
19        These are enabled by default:
20
21        aio       - ANSI I/O, including open and socket
22        eventloop - after, vwait, update
23        array     - Tcl-compatible array command
24        clock     - Tcl-compatible clock command
25        exec      - Tcl-compatible exec command
26        file      - Tcl-compatible file command
27        glob      - Tcl-compatible glob command
28        readdir   - Required for glob
29        package   - Package management with the package command
30        load      - Load binary extensions at runtime with load or package
31        posix     - Posix APIs including os.fork, os.wait, pid
32        regexp    - Tcl-compatible regexp, regsub commands
33        signal    - Signal handling
34        stdlib    - Built-in commands including lassign, lambda, alias
35        syslog    - System logging with syslog
36        tclcompat - Tcl compatible read, gets, puts, parray, case, ...
37
38        These are disabled by default:
39
40        nvp       - Name-value pairs C-only API
41        oo        - Jim OO extension
42        tree      - OO tree structure, similar to tcllib ::struct::tree
43        binary    - Tcl-compatible 'binary' command
44        readline  - Interface to libreadline
45        rlprompt  - Tcl wrapper around the readline extension
46        mk        - Interface to Metakit
47        sqlite    - Interface to sqlite
48        sqlite3   - Interface to sqlite3
49        win32     - Interface to win32
50    }
51    with-out-jim-ext: {without-ext:"default|ext1 ext2 ..."} => {
52        Specify jim extensions to exclude.
53        If 'default' is given, the default extensions will not be added.
54    }
55    with-jim-extmod: {with-mod:"ext1 ext2 ..."} => {
56        Specify jim extensions to build as separate modules (either C or Tcl).
57        Note that not all extensions can be built as loadable modules.
58    }
59    # To help out openocd with automake
60    install-jim=1
61}
62
63cc-check-types "long long"
64
65cc-check-includes sys/socket.h netinet/in.h arpa/inet.h netdb.h
66cc-check-includes sys/un.h dlfcn.h unistd.h crt_externs.h
67
68define LDLIBS ""
69
70# Haiku needs -lnetwork, Solaris needs -lnsl
71if {[cc-check-function-in-lib inet_ntop {nsl network}]} {
72    # This does nothing if no libs are needed
73    cc-with [list -libs [get-define lib_inet_ntop]]
74    define-append LDLIBS [get-define lib_inet_ntop]
75}
76# Solaris needs -lsocket, Windows needs -lwsock32
77if {[cc-check-function-in-lib socket socket]} {
78    define-append LDLIBS [get-define lib_socket]
79}
80
81cc-check-functions ualarm lstat fork vfork system select
82cc-check-functions backtrace geteuid mkstemp realpath strptime gettimeofday
83cc-check-functions regcomp waitpid sigaction sys_signame sys_siglist
84cc-check-functions syslog opendir readlink sleep usleep pipe getaddrinfo utimes
85if {[cc-check-functions sysinfo]} {
86    cc-with {-includes sys/sysinfo.h} {
87        cc-check-members "struct sysinfo.uptime"
88    }
89}
90
91define TCL_LIBRARY [get-define prefix]/lib/jim
92
93lassign [split [get-define host] -] host_cpu host_vendor host_os
94# Scrub revision from the host_os
95regsub -all {[0-9.]} $host_os {} host_os
96
97switch -glob -- $host_os {
98    mingw* {
99        # We provide our own implementation of dlopen for mingw32
100        define-feature dlopen-compat
101        define-feature winconsole
102        define TCL_PLATFORM_OS $host_os
103        define TCL_PLATFORM_PLATFORM windows
104        define TCL_PLATFORM_PATH_SEPARATOR {;}
105    }
106    default {
107        # Note that cygwin is considered a unix platform
108        define TCL_PLATFORM_OS $host_os
109        define TCL_PLATFORM_PLATFORM unix
110        define TCL_PLATFORM_PATH_SEPARATOR :
111    }
112}
113
114# Find some tools
115cc-check-tools ar ranlib strip
116define tclsh [info nameofexecutable]
117
118if {![cc-check-functions _NSGetEnviron]} {
119    msg-checking "Checking environ declared in unistd.h..."
120    if {[cctest -cflags -D_GNU_SOURCE -includes unistd.h -code {char **ep = environ;}]} {
121        define NO_ENVIRON_EXTERN
122        msg-result "yes"
123    } else {
124        msg-result "no"
125    }
126}
127
128# Windows has a mkdir with no permission arg
129cc-check-includes sys/types.h sys/stat.h
130msg-checking "Checking for mkdir with one arg..."
131if {[cctest -includes {sys/types.h sys/stat.h} -code {mkdir("/dummy");}]} {
132    define HAVE_MKDIR_ONE_ARG
133    msg-result yes
134} else {
135    msg-result no
136}
137
138# autosetup can't handle C++ libraries
139proc check-metakit {} {
140    set found 0
141    cc-with {-lang c++} {
142        msg-checking "Checking for Metakit..."
143        if {[cctest -includes mk4.h -libs -lmk4 -code {c4_Storage dummy();}]} {
144            msg-result ok
145            define lib_mk -lmk4
146            incr found
147        } else {
148            msg-result "not found"
149        }
150    }
151    return $found
152}
153
154set extra_objs {}
155set jimregexp 0
156
157if {[opt-bool utf8 full]} {
158    msg-result "Enabling UTF-8"
159    define JIM_UTF8
160    incr jimregexp
161} else {
162    define JIM_UTF8 0
163}
164if {[opt-bool maintainer]} {
165    msg-result "Enabling maintainer settings"
166    define JIM_MAINTAINER
167}
168if {[opt-bool math full]} {
169    msg-result "Enabling math functions"
170    define JIM_MATH_FUNCTIONS
171    cc-check-function-in-lib sin m
172    define-append LDLIBS [get-define lib_sin]
173}
174if {[opt-bool ipv6 full]} {
175    msg-result "Enabling IPv6"
176    define JIM_IPV6
177}
178if {[opt-bool lineedit full]} {
179    if {([cc-check-includes termios.h] && [cc-check-functions isatty]) || [have-feature winconsole]} {
180        msg-result "Enabling line editing"
181        define USE_LINENOISE
182        lappend extra_objs linenoise.o
183    }
184}
185if {[opt-bool references]} {
186    msg-result "Enabling references"
187    define JIM_REFERENCES
188}
189if {[opt-bool shared with-jim-shared]} {
190    msg-result "Building shared library"
191} else {
192    msg-result "Building static library"
193    define JIM_STATICLIB
194}
195define JIM_INSTALL [opt-bool install-jim]
196
197# Note: Extension handling is mapped directly from the configure.ac
198# implementation
199
200set without [join [opt-val {without-ext with-out-jim-ext}]]
201set withext [join [opt-val {with-ext with-jim-ext}]]
202set withmod [join [opt-val {with-mod with-jim-extmod}]]
203
204# Tcl extensions
205set ext_tcl "stdlib glob tclcompat tree rlprompt oo binary"
206# Native extensions
207set ext_c "load package readdir array clock exec file posix regexp signal aio eventloop pack syslog nvp readline mk sqlite sqlite3 win32 sdl"
208
209# C++ extensions
210set ext_cxx "mk"
211
212# Tcl extensions which can be modules
213set ext_tcl_mod "glob tree rlprompt oo binary"
214# Native extensions which can be modules
215set ext_c_mod "readdir array clock file posix regexp syslog readline pack mk sqlite sqlite3 win32 sdl"
216
217# All extensions
218set ext_all [concat $ext_c $ext_tcl]
219
220# Default static extensions
221set ext_default "stdlib load package readdir glob array clock exec file posix regexp signal tclcompat aio eventloop syslog"
222
223if {[opt-bool full]} {
224    lappend ext_default tree binary
225}
226
227if {$without eq "default"} {
228    set ext_default stdlib
229    set without {}
230}
231
232# Check valid extension names
233foreach i [concat $withext $without $withmod] {
234    if {$i ni $ext_all} {
235        user-error "Unknown extension: $i"
236    }
237}
238
239# needs_xxx="expression" means that the expr must eval to 1 to select the extension
240# dep_xxx="yyy zzz" means that if xxx is selected, so is yyy and zzz
241set dep(glob) readdir
242set dep(rlprompt) readline
243set dep(tree) oo
244set dep(binary) pack
245
246set needs(exec) {expr {([have-feature vfork] && [have-feature waitpid]) || [have-feature system]}}
247set needs(load) {expr {[cc-check-function-in-lib dlopen dl] || [have-feature dlopen-compat]}}
248set libdep(load) lib_dlopen
249set needs(posix) {have-feature waitpid}
250set needs(readdir) {have-feature opendir}
251set needs(readline) {cc-check-function-in-lib readline readline}
252set libdep(readline) lib_readline
253set needs(signal) {expr {[have-feature sigaction] && [have-feature vfork]}}
254set needs(mk) {check-metakit}
255set libdep(mk) lib_mk
256set needs(sqlite) {cc-check-function-in-lib sqlite_open sqlite}
257set libdep(sqlite) lib_sqlite_open
258set needs(sqlite3) {cc-check-function-in-lib sqlite3_open sqlite3}
259set libdep(sqlite3) lib_sqlite3_open
260set needs(syslog) {have-feature syslog}
261set needs(win32) {have-feature windows}
262set needs(sdl) {expr {[cc-check-function-in-lib SDL_SetVideoMode SDL] && [cc-check-function-in-lib rectangleRGBA SDL_gfx]}}
263set libdep(sdl) {lib_SDL_SetVideoMode lib_rectangleRGBA}
264
265# First handle dependencies. If an extension is enabled, also enable its dependency
266foreach i [concat $ext_default $withext] {
267    if {$i in $without} {
268        continue
269    }
270    if {[info exists dep($i)]} {
271        lappend withext {*}$dep($i)
272    }
273}
274
275foreach i $withmod {
276    if {[info exists dep($i)]} {
277        # Theoretically, a mod could depend upon something which must be static
278        # If already configured static, don't make it a module
279        foreach d $dep($i) {
280            if {$d ni $withext} {
281                lappend withmod $d
282            }
283        }
284    }
285}
286
287# Now that we know what the platform supports:
288
289# For all known extensions:
290# - If it is disabled, remove it
291# - Otherwise, check to see if it's pre-requisites are met
292# -   If yes, add it if it is enabled or is a default
293# -   If no, error if it is enabled, or do nothing otherwise
294# - Modules may be either C or Tcl
295
296set extmodtcl {}
297set extmod {}
298set ext {}
299
300foreach i [lsort $ext_all] {
301    # First discard the extension if disabled or not enabled
302    if {$i in $without} {
303        msg-result "Extension $i...disabled"
304        continue
305    }
306    if {$i ni [concat $withext $withmod $ext_default]} {
307        msg-result "Extension $i...not enabled"
308        continue
309    }
310
311    # Check dependencies
312    set met 1
313    if {[info exists needs($i)]} {
314        set met [eval $needs($i)]
315    }
316
317    define LDLIBS_$i ""
318
319    msg-checking "Extension $i..."
320
321    # Selected as a module?
322    if {$i in $withmod} {
323        if {$i in $ext_tcl_mod} {
324            # Easy, a Tcl module
325            msg-result "tcl"
326            lappend extmodtcl $i
327            continue
328        }
329        if {$i ni $ext_c_mod} {
330            user-error "not a module"
331        }
332        if {!$met} {
333            user-error "dependencies not met"
334        }
335        msg-result "module"
336        lappend extmod $i
337        if {[info exists libdep($i)]} {
338            foreach j $libdep($i) {
339                define-append LDLIBS_$i [get-define $j ""]
340            }
341        }
342        continue
343    }
344
345    # Selected as a static extension?
346    if {$i in $withext} {
347        if {!$met} {
348            user-error "dependencies not met"
349        }
350        msg-result "enabled"
351    } elseif {$i in $ext_default} {
352        if {!$met} {
353            msg-result "disabled (dependencies)"
354            continue
355        }
356        msg-result "enabled (default)"
357    } else {
358        continue
359    }
360
361    lappend ext $i
362    if {[info exists libdep($i)]} {
363        foreach j $libdep($i) {
364            define-append LDLIBS [get-define $j ""]
365        }
366    }
367}
368
369if {[have-feature windows]} {
370    lappend extra_objs jim-win32compat.o
371
372    if {$extmod ne "" && [get-define JIM_LIBTYPE] eq "static"} {
373        user-error "cygwin/mingw require --shared for dynamic modules"
374    }
375}
376
377if {"regexp" in "$ext $extmod"} {
378    # No regcomp means we need to use the built-in version
379    if {![have-feature regcomp]} {
380        incr jimregexp
381    }
382}
383
384if {$jimregexp || [opt-bool jim-regexp]} {
385    msg-result "Using built-in regexp"
386    define JIM_REGEXP
387
388    # If the built-in regexp overrides the system regcomp, etc.
389    # jim must be built shared so that the correct symbols are found
390    if {"regexp" in $extmod && [get-define JIM_LIBTYPE] eq "static" && [have-feature regcomp]} {
391        user-error "Must use --shared with regexp module and built-in regexp"
392    }
393}
394if {"load" ni $ext} {
395    # If we don't have load, no need to support shared objects
396    define SH_LINKFLAGS ""
397}
398
399msg-result "Jim static extensions: [lsort $ext]"
400if {$extmodtcl ne ""} {
401    msg-result "Jim Tcl extensions: [lsort $extmodtcl]"
402}
403if {$extmod ne ""} {
404    msg-result "Jim dynamic extensions: [lsort $extmod]"
405}
406
407# Separate out the static extensions into C and Tcl
408set ext_static_c {}
409set ext_static_tcl {}
410foreach e $ext {
411    define jim_ext_$e
412    if {$e in $ext_tcl} {
413        lappend ext_static_tcl $e
414    } else {
415        lappend ext_static_c $e
416    }
417}
418
419# If there are any static C++ extensions, jimsh must be linked using
420# the C++ compiler
421foreach e $ext_static_c {
422    if {$e in $ext_cxx} {
423        define HAVE_CXX_EXTENSIONS
424    }
425}
426
427define STATIC_EXTS [concat $ext_static_c $ext_static_tcl]
428define C_EXT_OBJS [prefix jim- [suffix .o $ext_static_c]]
429define TCL_EXT_OBJS [suffix .o $ext_static_tcl]
430define C_EXT_SHOBJS [suffix .so $extmod]
431define TCL_EXTS [suffix .tcl $extmodtcl]
432define EXTRA_OBJS $extra_objs
433
434make-config-header jim-config.h -auto {HAVE_LONG_LONG* JIM_UTF8} -none *
435make-config-header jimautoconf.h -auto {jim_ext_* TCL_PLATFORM_* TCL_LIBRARY USE_* JIM_*}
436make-template Makefile.in
437