source: git/ppcc/autosetup/system.tcl @ 2b7db4b

fieker-DuValspielwiese
Last change on this file since 2b7db4b was 54b24c, checked in by Reimer Behrends <behrends@…>, 5 years ago
Finalizing thread support.
  • Property mode set to 100644
File size: 9.7 KB
Line 
1# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
2# All rights reserved
3
4# @synopsis:
5#
6# This module supports common system interrogation and options
7# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'.
8#
9# It also support the "feature" naming convention, where searching
10# for a feature such as 'sys/type.h' defines 'HAVE_SYS_TYPES_H'.
11#
12# It defines the following variables, based on '--prefix' unless overridden by the user:
13#
14## datadir
15## sysconfdir
16## sharedstatedir
17## localstatedir
18## infodir
19## mandir
20## includedir
21#
22# If '--prefix' is not supplied, it defaults to '/usr/local' unless 'defaultprefix' is defined *before*
23# including the 'system' module.
24
25if {[is-defined defaultprefix]} {
26        user-notice "Note: defaultprefix is deprecated. Use options-defaults to set default options"
27        options-defaults [list prefix [get-define defaultprefix]]
28}
29
30module-options [subst -noc -nob {
31        host:host-alias =>              {a complete or partial cpu-vendor-opsys for the system where
32                                                        the application will run (defaults to the same value as --build)}
33        build:build-alias =>    {a complete or partial cpu-vendor-opsys for the system
34                                                        where the application will be built (defaults to the
35                                                        result of running config.guess)}
36        prefix:dir=/usr/local => {the target directory for the build (default: '@default@')}
37
38        # These (hidden) options are supported for autoconf/automake compatibility
39        exec-prefix:
40        bindir:
41        sbindir:
42        includedir:
43        mandir:
44        infodir:
45        libexecdir:
46        datadir:
47        libdir:
48        sysconfdir:
49        sharedstatedir:
50        localstatedir:
51        runstatedir:
52        maintainer-mode=0
53        dependency-tracking=0
54        silent-rules=0
55}]
56
57# @check-feature name { script }
58#
59# defines feature '$name' to the return value of '$script',
60# which should be 1 if found or 0 if not found.
61#
62# e.g. the following will define 'HAVE_CONST' to 0 or 1.
63#
64## check-feature const {
65##     cctest -code {const int _x = 0;}
66## }
67proc check-feature {name code} {
68        msg-checking "Checking for $name..."
69        set r [uplevel 1 $code]
70        define-feature $name $r
71        if {$r} {
72                msg-result "ok"
73        } else {
74                msg-result "not found"
75        }
76        return $r
77}
78
79# @have-feature name ?default=0?
80#
81# Returns the value of feature '$name' if defined, or '$default' if not.
82#
83# See 'feature-define-name' for how the "feature" name
84# is translated into the "define" name.
85#
86proc have-feature {name {default 0}} {
87        get-define [feature-define-name $name] $default
88}
89
90# @define-feature name ?value=1?
91#
92# Sets the feature 'define' to '$value'.
93#
94# See 'feature-define-name' for how the "feature" name
95# is translated into the "define" name.
96#
97proc define-feature {name {value 1}} {
98        define [feature-define-name $name] $value
99}
100
101# @feature-checked name
102#
103# Returns 1 if feature '$name' has been checked, whether true or not.
104#
105proc feature-checked {name} {
106        is-defined [feature-define-name $name]
107}
108
109# @feature-define-name name ?prefix=HAVE_?
110#
111# Converts a "feature" name to the corresponding "define",
112# e.g. 'sys/stat.h' becomes 'HAVE_SYS_STAT_H'.
113#
114# Converts '*' to 'P' and all non-alphanumeric to underscore.
115#
116proc feature-define-name {name {prefix HAVE_}} {
117        string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _]
118}
119
120# @write-if-changed filename contents ?script?
121#
122# If '$filename' doesn't exist, or it's contents are different to '$contents',
123# the file is written and '$script' is evaluated.
124#
125# Otherwise a "file is unchanged" message is displayed.
126proc write-if-changed {file buf {script {}}} {
127        set old [readfile $file ""]
128        if {$old eq $buf && [file exists $file]} {
129                msg-result "$file is unchanged"
130        } else {
131                writefile $file $buf\n
132                uplevel 1 $script
133        }
134}
135
136# @make-template template ?outfile?
137#
138# Reads the input file '<srcdir>/$template' and writes the output file '$outfile'
139# (unless unchanged).
140# If '$outfile' is blank/omitted, '$template' should end with '.in' which
141# is removed to create the output file name.
142#
143# Each pattern of the form '@define@' is replaced with the corresponding
144# "define", if it exists, or left unchanged if not.
145#
146# The special value '@srcdir@' is substituted with the relative
147# path to the source directory from the directory where the output
148# file is created, while the special value '@top_srcdir@' is substituted
149# with the relative path to the top level source directory.
150#
151# Conditional sections may be specified as follows:
152## @if NAME eq "value"
153## lines
154## @else
155## lines
156## @endif
157#
158# Where 'NAME' is a defined variable name and '@else' is optional.
159# Note that variables names *must* start with an uppercase letter.
160# If the expression does not match, all lines through '@endif' are ignored.
161#
162# The alternative forms may also be used:
163## @if NAME  (true if the variable is defined, but not empty and not "0")
164## @if !NAME  (opposite of the form above)
165## @if <general-tcl-expression>
166#
167# In the general Tcl expression, any words beginning with an uppercase letter
168# are translated into [get-define NAME]
169#
170# Expressions may be nested
171#
172proc make-template {template {out {}}} {
173        set infile [file join $::autosetup(srcdir) $template]
174
175        if {![file exists $infile]} {
176                user-error "Template $template is missing"
177        }
178
179        # Define this as late as possible
180        define AUTODEPS $::autosetup(deps)
181
182        if {$out eq ""} {
183                if {[file ext $template] ne ".in"} {
184                        autosetup-error "make_template $template has no target file and can't guess"
185                }
186                set out [file rootname $template]
187        }
188
189        set outdir [file dirname $out]
190
191        # Make sure the directory exists
192        file mkdir $outdir
193
194        # Set up srcdir and top_srcdir to be relative to the target dir
195        define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir]
196        define top_srcdir [relative-path $::autosetup(srcdir) $outdir]
197
198        set mapping {}
199        foreach {n v} [array get ::define] {
200                lappend mapping @$n@ $v
201        }
202
203        # A stack of true/false conditions, one for each nested conditional
204        # starting with "true"
205        set condstack {1}
206        set result {}
207        set linenum 0
208        foreach line [split [readfile $infile] \n] {
209                incr linenum
210                if {[regexp {^@(if|else|endif)\s*(.*)} $line -> condtype condargs]} {
211                        if {$condtype eq "if"} {
212                                if {[llength $condargs] == 1} {
213                                        # ABC => [get-define ABC] ni {0 ""}
214                                        # !ABC => [get-define ABC] in {0 ""}
215                                        lassign $condargs condvar
216                                        if {[regexp {^!(.*)} $condvar -> condvar]} {
217                                                set op in
218                                        } else {
219                                                set op ni
220                                        }
221                                        set condexpr "\[[list get-define $condvar]\] $op {0 {}}"
222                                } else {
223                                        # Translate alphanumeric ABC into [get-define ABC] and leave the
224                                        # rest of the expression untouched
225                                        regsub -all {([A-Z][[:alnum:]_]*)} $condargs {[get-define \1]} condexpr
226                                }
227                                if {[catch [list expr $condexpr] condval]} {
228                                        dputs $condval
229                                        autosetup-error "$infile:$linenum: Invalid expression: $line"
230                                }
231                                dputs "@$condtype: $condexpr => $condval"
232                        }
233                        if {$condtype ne "if" && [llength $condstack] <= 1} {
234                                autosetup-error "$infile:$linenum: Error: @$condtype missing @if"
235                        }
236                        switch -exact $condtype {
237                                if {
238                                        # push condval
239                                        lappend condstack $condval
240                                }
241                                else {
242                                        # Toggle the last entry
243                                        set condval [lpop condstack]
244                                        set condval [expr {!$condval}]
245                                        lappend condstack $condval
246                                }
247                                endif {
248                                        if {[llength $condstack] == 0} {
249                                                user-notice "$infile:$linenum: Error: @endif missing @if"
250                                        }
251                                        lpop condstack
252                                }
253                        }
254                        continue
255                }
256                # Only output this line if the stack contains all "true"
257                if {"0" in $condstack} {
258                        continue
259                }
260                lappend result $line
261        }
262        write-if-changed $out [string map $mapping [join $result \n]] {
263                msg-result "Created [relative-path $out] from [relative-path $template]"
264        }
265}
266
267# build/host tuples and cross-compilation prefix
268opt-str build build ""
269define build_alias $build
270if {$build eq ""} {
271        define build [config_guess]
272} else {
273        define build [config_sub $build]
274}
275
276opt-str host host ""
277define host_alias $host
278if {$host eq ""} {
279        define host [get-define build]
280        set cross ""
281} else {
282        define host [config_sub $host]
283        set cross $host-
284}
285define cross [get-env CROSS $cross]
286
287# build/host _cpu, _vendor and _os
288foreach type {build host} {
289        set v [get-define $type]
290        if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} {
291                user-error "Invalid canonical $type: $v"
292        }
293        define ${type}_cpu $cpu
294        define ${type}_vendor $vendor
295        define ${type}_os $os
296}
297
298opt-str prefix prefix /usr/local
299
300# These are for compatibility with autoconf
301define target [get-define host]
302define prefix $prefix
303define builddir $autosetup(builddir)
304define srcdir $autosetup(srcdir)
305define top_srcdir $autosetup(srcdir)
306define abs_top_srcdir [file-normalize $autosetup(srcdir)]
307define abs_top_builddir [file-normalize $autosetup(builddir)]
308
309# autoconf supports all of these
310define exec_prefix [opt-str exec-prefix exec_prefix $prefix]
311foreach {name defpath} {
312        bindir /bin
313        sbindir /sbin
314        libexecdir /libexec
315        libdir /lib
316} {
317        define $name [opt-str $name o $exec_prefix$defpath]
318}
319foreach {name defpath} {
320        datadir /share
321        sharedstatedir /com
322        infodir /share/info
323        mandir /share/man
324        includedir /include
325} {
326        define $name [opt-str $name o $prefix$defpath]
327}
328if {$prefix ne {/usr}} {
329        opt-str sysconfdir sysconfdir $prefix/etc
330} else {
331        opt-str sysconfdir sysconfdir /etc
332}
333define sysconfdir $sysconfdir
334
335define localstatedir [opt-str localstatedir o /var]
336define runstatedir [opt-str runstatedir o /run]
337
338define SHELL [get-env SHELL [find-an-executable sh bash ksh]]
339
340# These could be used to generate Makefiles following some automake conventions
341define AM_SILENT_RULES [opt-bool silent-rules]
342define AM_MAINTAINER_MODE [opt-bool maintainer-mode]
343define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking]
344
345# Windows vs. non-Windows
346switch -glob -- [get-define host] {
347        *-*-ming* - *-*-cygwin - *-*-msys {
348                define-feature windows
349                define EXEEXT .exe
350        }
351        default {
352                define EXEEXT ""
353        }
354}
355
356# Display
357msg-result "Host System...[get-define host]"
358msg-result "Build System...[get-define build]"
Note: See TracBrowser for help on using the repository browser.