Mercurial
comparison third_party/sqlite3/autosetup/system.tcl @ 173:827c6ac504cd hg-web
Merged in default here.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 19 Jan 2026 18:59:10 -0800 |
| parents | 589bab390fb4 |
| children |
comparison
equal
deleted
inserted
replaced
| 151:c033667da5f9 | 173:827c6ac504cd |
|---|---|
| 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 'options-defaults { prefix ... }' is used *before* | |
| 23 # including the 'system' module. | |
| 24 | |
| 25 if {[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 | |
| 30 options { | |
| 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 program-prefix: | |
| 56 program-suffix: | |
| 57 program-transform-name: | |
| 58 x-includes: | |
| 59 x-libraries: | |
| 60 } | |
| 61 | |
| 62 # @check-feature name { script } | |
| 63 # | |
| 64 # defines feature '$name' to the return value of '$script', | |
| 65 # which should be 1 if found or 0 if not found. | |
| 66 # | |
| 67 # e.g. the following will define 'HAVE_CONST' to 0 or 1. | |
| 68 # | |
| 69 ## check-feature const { | |
| 70 ## cctest -code {const int _x = 0;} | |
| 71 ## } | |
| 72 proc check-feature {name code} { | |
| 73 msg-checking "Checking for $name..." | |
| 74 set r [uplevel 1 $code] | |
| 75 define-feature $name $r | |
| 76 if {$r} { | |
| 77 msg-result "ok" | |
| 78 } else { | |
| 79 msg-result "not found" | |
| 80 } | |
| 81 return $r | |
| 82 } | |
| 83 | |
| 84 # @have-feature name ?default=0? | |
| 85 # | |
| 86 # Returns the value of feature '$name' if defined, or '$default' if not. | |
| 87 # | |
| 88 # See 'feature-define-name' for how the "feature" name | |
| 89 # is translated into the "define" name. | |
| 90 # | |
| 91 proc have-feature {name {default 0}} { | |
| 92 get-define [feature-define-name $name] $default | |
| 93 } | |
| 94 | |
| 95 # @define-feature name ?value=1? | |
| 96 # | |
| 97 # Sets the feature 'define' to '$value'. | |
| 98 # | |
| 99 # See 'feature-define-name' for how the "feature" name | |
| 100 # is translated into the "define" name. | |
| 101 # | |
| 102 proc define-feature {name {value 1}} { | |
| 103 define [feature-define-name $name] $value | |
| 104 } | |
| 105 | |
| 106 # @feature-checked name | |
| 107 # | |
| 108 # Returns 1 if feature '$name' has been checked, whether true or not. | |
| 109 # | |
| 110 proc feature-checked {name} { | |
| 111 is-defined [feature-define-name $name] | |
| 112 } | |
| 113 | |
| 114 # @feature-define-name name ?prefix=HAVE_? | |
| 115 # | |
| 116 # Converts a "feature" name to the corresponding "define", | |
| 117 # e.g. 'sys/stat.h' becomes 'HAVE_SYS_STAT_H'. | |
| 118 # | |
| 119 # Converts '*' to 'P' and all non-alphanumeric to underscore. | |
| 120 # | |
| 121 proc feature-define-name {name {prefix HAVE_}} { | |
| 122 string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _] | |
| 123 } | |
| 124 | |
| 125 # @write-if-changed filename contents ?script? | |
| 126 # | |
| 127 # If '$filename' doesn't exist, or it's contents are different to '$contents', | |
| 128 # the file is written and '$script' is evaluated. | |
| 129 # | |
| 130 # Otherwise a "file is unchanged" message is displayed. | |
| 131 proc write-if-changed {file buf {script {}}} { | |
| 132 set old [readfile $file ""] | |
| 133 if {$old eq $buf && [file exists $file]} { | |
| 134 msg-result "$file is unchanged" | |
| 135 } else { | |
| 136 writefile $file $buf\n | |
| 137 uplevel 1 $script | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 | |
| 142 # @include-file infile mapping | |
| 143 # | |
| 144 # The core of make-template, called recursively for each @include | |
| 145 # directive found within that template so that this proc's result | |
| 146 # is the fully-expanded template. | |
| 147 # | |
| 148 # The mapping parameter is how we expand @varname@ within the template. | |
| 149 # We do that inline within this step only for @include directives which | |
| 150 # can have variables in the filename arg. A separate substitution pass | |
| 151 # happens when this recursive function returns, expanding the rest of | |
| 152 # the variables. | |
| 153 # | |
| 154 proc include-file {infile mapping} { | |
| 155 # A stack of true/false conditions, one for each nested conditional | |
| 156 # starting with "true" | |
| 157 set condstack {1} | |
| 158 set result {} | |
| 159 set linenum 0 | |
| 160 foreach line [split [readfile $infile] \n] { | |
| 161 incr linenum | |
| 162 if {[regexp {^@(if|else|endif)(\s*)(.*)} $line -> condtype condspace condargs]} { | |
| 163 if {$condtype eq "if"} { | |
| 164 if {[string length $condspace] == 0} { | |
| 165 autosetup-error "$infile:$linenum: Invalid expression: $line" | |
| 166 } | |
| 167 if {[llength $condargs] == 1} { | |
| 168 # ABC => [get-define ABC] ni {0 ""} | |
| 169 # !ABC => [get-define ABC] in {0 ""} | |
| 170 lassign $condargs condvar | |
| 171 if {[regexp {^!(.*)} $condvar -> condvar]} { | |
| 172 set op in | |
| 173 } else { | |
| 174 set op ni | |
| 175 } | |
| 176 set condexpr "\[[list get-define $condvar]\] $op {0 {}}" | |
| 177 } else { | |
| 178 # Translate alphanumeric ABC into [get-define ABC] and leave the | |
| 179 # rest of the expression untouched | |
| 180 regsub -all {([A-Z][[:alnum:]_]*)} $condargs {[get-define \1]} condexpr | |
| 181 } | |
| 182 if {[catch [list expr $condexpr] condval]} { | |
| 183 dputs $condval | |
| 184 autosetup-error "$infile:$linenum: Invalid expression: $line" | |
| 185 } | |
| 186 dputs "@$condtype: $condexpr => $condval" | |
| 187 } | |
| 188 if {$condtype ne "if"} { | |
| 189 if {[llength $condstack] <= 1} { | |
| 190 autosetup-error "$infile:$linenum: Error: @$condtype missing @if" | |
| 191 } elseif {[string length $condargs] && [string index $condargs 0] ne "#"} { | |
| 192 autosetup-error "$infile:$linenum: Error: Extra arguments after @$condtype" | |
| 193 } | |
| 194 } | |
| 195 switch -exact $condtype { | |
| 196 if { | |
| 197 # push condval | |
| 198 lappend condstack $condval | |
| 199 } | |
| 200 else { | |
| 201 # Toggle the last entry | |
| 202 set condval [lpop condstack] | |
| 203 set condval [expr {!$condval}] | |
| 204 lappend condstack $condval | |
| 205 } | |
| 206 endif { | |
| 207 if {[llength $condstack] == 0} { | |
| 208 user-notice "$infile:$linenum: Error: @endif missing @if" | |
| 209 } | |
| 210 lpop condstack | |
| 211 } | |
| 212 } | |
| 213 continue | |
| 214 } | |
| 215 # Only continue if the stack contains all "true" | |
| 216 if {"0" in $condstack} { | |
| 217 continue | |
| 218 } | |
| 219 if {[regexp {^@include\s+(.*)} $line -> filearg]} { | |
| 220 set incfile [string map $mapping $filearg] | |
| 221 if {[file exists $incfile]} { | |
| 222 lappend ::autosetup(deps) [file-normalize $incfile] | |
| 223 lappend result {*}[include-file $incfile $mapping] | |
| 224 } else { | |
| 225 user-error "$infile:$linenum: Include file $incfile is missing" | |
| 226 } | |
| 227 continue | |
| 228 } | |
| 229 if {[regexp {^@define\s+(\w+)\s+(.*)} $line -> var val]} { | |
| 230 define $var $val | |
| 231 continue | |
| 232 } | |
| 233 lappend result $line | |
| 234 } | |
| 235 return $result | |
| 236 } | |
| 237 | |
| 238 | |
| 239 # @make-template template ?outfile? | |
| 240 # | |
| 241 # Reads the input file '<srcdir>/$template' and writes the output file '$outfile' | |
| 242 # (unless unchanged). | |
| 243 # If '$outfile' is blank/omitted, '$template' should end with '.in' which | |
| 244 # is removed to create the output file name. | |
| 245 # | |
| 246 # Each pattern of the form '@define@' is replaced with the corresponding | |
| 247 # "define", if it exists, or left unchanged if not. | |
| 248 # | |
| 249 # The special value '@srcdir@' is substituted with the relative | |
| 250 # path to the source directory from the directory where the output | |
| 251 # file is created, while the special value '@top_srcdir@' is substituted | |
| 252 # with the relative path to the top level source directory. | |
| 253 # | |
| 254 # Conditional sections may be specified as follows: | |
| 255 ## @if NAME eq "value" | |
| 256 ## lines | |
| 257 ## @else | |
| 258 ## lines | |
| 259 ## @endif | |
| 260 # | |
| 261 # Where 'NAME' is a defined variable name and '@else' is optional. | |
| 262 # Note that variables names *must* start with an uppercase letter. | |
| 263 # If the expression does not match, all lines through '@endif' are ignored. | |
| 264 # | |
| 265 # The alternative forms may also be used: | |
| 266 ## @if NAME (true if the variable is defined, but not empty and not "0") | |
| 267 ## @if !NAME (opposite of the form above) | |
| 268 ## @if <general-tcl-expression> | |
| 269 # | |
| 270 # In the general Tcl expression, any words beginning with an uppercase letter | |
| 271 # are translated into [get-define NAME] | |
| 272 # | |
| 273 # Expressions may be nested | |
| 274 # | |
| 275 proc make-template {template {out {}}} { | |
| 276 set infile [file join $::autosetup(srcdir) $template] | |
| 277 | |
| 278 if {![file exists $infile]} { | |
| 279 user-error "Template $template is missing" | |
| 280 } | |
| 281 | |
| 282 # Define this as late as possible | |
| 283 define AUTODEPS $::autosetup(deps) | |
| 284 | |
| 285 if {$out eq ""} { | |
| 286 if {[file ext $template] ne ".in"} { | |
| 287 autosetup-error "make_template $template has no target file and can't guess" | |
| 288 } | |
| 289 set out [file rootname $template] | |
| 290 } | |
| 291 | |
| 292 set outdir [file dirname $out] | |
| 293 | |
| 294 # Make sure the directory exists | |
| 295 file mkdir $outdir | |
| 296 | |
| 297 # Set up srcdir and top_srcdir to be relative to the target dir | |
| 298 define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir] | |
| 299 define top_srcdir [relative-path $::autosetup(srcdir) $outdir] | |
| 300 | |
| 301 # Build map from global defines to their values so they can be | |
| 302 # substituted into @include file names. | |
| 303 proc build-define-mapping {} { | |
| 304 set mapping {} | |
| 305 foreach {n v} [array get ::define] { | |
| 306 lappend mapping @$n@ $v | |
| 307 } | |
| 308 return $mapping | |
| 309 } | |
| 310 set mapping [build-define-mapping] | |
| 311 | |
| 312 set result [include-file $infile $mapping] | |
| 313 | |
| 314 # Rebuild the define mapping in case we ran across @define | |
| 315 # directives in the template or a file it @included, then | |
| 316 # apply that mapping to the expanded template. | |
| 317 set mapping [build-define-mapping] | |
| 318 write-if-changed $out [string map $mapping [join $result \n]] { | |
| 319 msg-result "Created [relative-path $out] from [relative-path $template]" | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 proc system-init {} { | |
| 324 global autosetup | |
| 325 | |
| 326 # build/host tuples and cross-compilation prefix | |
| 327 opt-str build build "" | |
| 328 define build_alias $build | |
| 329 if {$build eq ""} { | |
| 330 define build [config_guess] | |
| 331 } else { | |
| 332 define build [config_sub $build] | |
| 333 } | |
| 334 | |
| 335 opt-str host host "" | |
| 336 define host_alias $host | |
| 337 if {$host eq ""} { | |
| 338 define host [get-define build] | |
| 339 set cross "" | |
| 340 } else { | |
| 341 define host [config_sub $host] | |
| 342 set cross $host- | |
| 343 } | |
| 344 define cross [get-env CROSS $cross] | |
| 345 | |
| 346 # build/host _cpu, _vendor and _os | |
| 347 foreach type {build host} { | |
| 348 set v [get-define $type] | |
| 349 if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} { | |
| 350 user-error "Invalid canonical $type: $v" | |
| 351 } | |
| 352 define ${type}_cpu $cpu | |
| 353 define ${type}_vendor $vendor | |
| 354 define ${type}_os $os | |
| 355 } | |
| 356 | |
| 357 opt-str prefix prefix /usr/local | |
| 358 | |
| 359 # These are for compatibility with autoconf | |
| 360 define target [get-define host] | |
| 361 define prefix $prefix | |
| 362 define builddir $autosetup(builddir) | |
| 363 define srcdir $autosetup(srcdir) | |
| 364 define top_srcdir $autosetup(srcdir) | |
| 365 define abs_top_srcdir [file-normalize $autosetup(srcdir)] | |
| 366 define abs_top_builddir [file-normalize $autosetup(builddir)] | |
| 367 | |
| 368 # autoconf supports all of these | |
| 369 define exec_prefix [opt-str exec-prefix exec_prefix $prefix] | |
| 370 foreach {name defpath} { | |
| 371 bindir /bin | |
| 372 sbindir /sbin | |
| 373 libexecdir /libexec | |
| 374 libdir /lib | |
| 375 } { | |
| 376 define $name [opt-str $name o $exec_prefix$defpath] | |
| 377 } | |
| 378 foreach {name defpath} { | |
| 379 datadir /share | |
| 380 sharedstatedir /com | |
| 381 infodir /share/info | |
| 382 mandir /share/man | |
| 383 includedir /include | |
| 384 } { | |
| 385 define $name [opt-str $name o $prefix$defpath] | |
| 386 } | |
| 387 if {$prefix ne {/usr}} { | |
| 388 opt-str sysconfdir sysconfdir $prefix/etc | |
| 389 } else { | |
| 390 opt-str sysconfdir sysconfdir /etc | |
| 391 } | |
| 392 define sysconfdir $sysconfdir | |
| 393 | |
| 394 define localstatedir [opt-str localstatedir o /var] | |
| 395 define runstatedir [opt-str runstatedir o /run] | |
| 396 | |
| 397 define SHELL [get-env SHELL [find-an-executable sh bash ksh]] | |
| 398 | |
| 399 # These could be used to generate Makefiles following some automake conventions | |
| 400 define AM_SILENT_RULES [opt-bool silent-rules] | |
| 401 define AM_MAINTAINER_MODE [opt-bool maintainer-mode] | |
| 402 define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking] | |
| 403 | |
| 404 # Windows vs. non-Windows | |
| 405 switch -glob -- [get-define host] { | |
| 406 *-*-ming* - *-*-cygwin - *-*-msys { | |
| 407 define-feature windows | |
| 408 define EXEEXT .exe | |
| 409 } | |
| 410 default { | |
| 411 define EXEEXT "" | |
| 412 } | |
| 413 } | |
| 414 | |
| 415 # Display | |
| 416 msg-result "Host System...[get-define host]" | |
| 417 msg-result "Build System...[get-define build]" | |
| 418 } | |
| 419 | |
| 420 system-init |