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 EXEXT. 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# 12module-options { 13 host:host-alias => {a complete or partial cpu-vendor-opsys for the system where 14 the application will run (defaults to the same value as --build)} 15 build:build-alias => {a complete or partial cpu-vendor-opsys for the system 16 where the application will be built (defaults to the 17 result of running config.guess)} 18 prefix:dir => {the target directory for the build (defaults to /usr/local)} 19 20 # These (hidden) options are supported for autoconf/automake compatibility 21 exec-prefix: 22 bindir: 23 sbindir: 24 includedir: 25 mandir: 26 infodir: 27 libexecdir: 28 datadir: 29 libdir: 30 sysconfdir: 31 sharedstatedir: 32 localstatedir: 33 maintainer-mode=0 34 dependency-tracking=0 35} 36 37# Returns 1 if exists, or 0 if not 38# 39proc check-feature {name code} { 40 msg-checking "Checking for $name..." 41 set r [uplevel 1 $code] 42 define-feature $name $r 43 if {$r} { 44 msg-result "ok" 45 } else { 46 msg-result "not found" 47 } 48 return $r 49} 50 51# @have-feature name ?default=0? 52# 53# Returns the value of the feature if defined, or $default if not. 54# See 'feature-define-name' for how the feature name 55# is translated into the define name. 56# 57proc have-feature {name {default 0}} { 58 get-define [feature-define-name $name] $default 59} 60 61# @define-feature name ?value=1? 62# 63# Sets the feature 'define' to the given value. 64# See 'feature-define-name' for how the feature name 65# is translated into the define name. 66# 67proc define-feature {name {value 1}} { 68 define [feature-define-name $name] $value 69} 70 71# @feature-checked name 72# 73# Returns 1 if the feature has been checked, whether true or not 74# 75proc feature-checked {name} { 76 is-defined [feature-define-name $name] 77} 78 79# @feature-define-name name ?prefix=HAVE_? 80# 81# Converts a name to the corresponding define, 82# e.g. sys/stat.h becomes HAVE_SYS_STAT_H. 83# 84# Converts * to P and all non-alphanumeric to underscore. 85# 86proc feature-define-name {name {prefix HAVE_}} { 87 string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _] 88} 89 90# If $file doesn't exist, or it's contents are different than $buf, 91# the file is written and $script is executed. 92# Otherwise a "file is unchanged" message is displayed. 93proc write-if-changed {file buf {script {}}} { 94 set old [readfile $file ""] 95 if {$old eq $buf && [file exists $file]} { 96 msg-result "$file is unchanged" 97 } else { 98 writefile $file $buf\n 99 uplevel 1 $script 100 } 101} 102 103# @make-template template ?outfile? 104# 105# Reads the input file <srcdir>/$template and writes the output file $outfile. 106# If $outfile is blank/omitted, $template should end with ".in" which 107# is removed to create the output file name. 108# 109# Each pattern of the form @define@ is replaced the the corresponding 110# define, if it exists, or left unchanged if not. 111# 112# The special value @srcdir@ is subsituted with the relative 113# path to the source directory from the directory where the output 114# file is created. Use @top_srcdir@ for the absolute path. 115# 116# Conditional sections may be specified as follows: 117## @if name == value 118## lines 119## @else 120## lines 121## @endif 122# 123# Where 'name' is a defined variable name and @else is optional. 124# If the expression does not match, all lines through '@endif' are ignored. 125# 126# The alternative forms may also be used: 127## @if name 128## @if name != value 129# 130# Where the first form is true if the variable is defined, but not empty or 0 131# 132# Currently these expressions can't be nested. 133# 134proc make-template {template {out {}}} { 135 set infile [file join $::autosetup(srcdir) $template] 136 137 if {![file exists $infile]} { 138 user-error "Template $template is missing" 139 } 140 141 # Define this as late as possible 142 define AUTODEPS $::autosetup(deps) 143 144 if {$out eq ""} { 145 if {[file ext $template] ne ".in"} { 146 autosetup-error "make_template $template has no target file and can't guess" 147 } 148 set out [file rootname $template] 149 } 150 151 set outdir [file dirname $out] 152 153 # Make sure the directory exists 154 file mkdir $outdir 155 156 # Set up srcdir to be relative to the target dir 157 define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir] 158 159 set mapping {} 160 foreach {n v} [array get ::define] { 161 lappend mapping @$n@ $v 162 } 163 set result {} 164 foreach line [split [readfile $infile] \n] { 165 if {[info exists cond]} { 166 set l [string trimright $line] 167 if {$l eq "@endif"} { 168 unset cond 169 continue 170 } 171 if {$l eq "@else"} { 172 set cond [expr {!$cond}] 173 continue 174 } 175 if {$cond} { 176 lappend result $line 177 } 178 continue 179 } 180 if {[regexp {^@if\s+(\w+)(.*)} $line -> name expression]} { 181 lassign $expression equal value 182 set varval [get-define $name ""] 183 if {$equal eq ""} { 184 set cond [expr {$varval ni {"" 0}}] 185 } else { 186 set cond [expr {$varval eq $value}] 187 if {$equal ne "=="} { 188 set cond [expr {!$cond}] 189 } 190 } 191 continue 192 } 193 lappend result $line 194 } 195 writefile $out [string map $mapping [join $result \n]]\n 196 197 msg-result "Created [relative-path $out] from [relative-path $template]" 198} 199 200# build/host tuples and cross-compilation prefix 201set build [opt-val build] 202define build_alias $build 203if {$build eq ""} { 204 define build [config_guess] 205} else { 206 define build [config_sub $build] 207} 208 209set host [opt-val host] 210define host_alias $host 211if {$host eq ""} { 212 define host [get-define build] 213 set cross "" 214} else { 215 define host [config_sub $host] 216 set cross $host- 217} 218define cross [get-env CROSS $cross] 219 220set prefix [opt-val prefix /usr/local] 221 222# These are for compatibility with autoconf 223define target [get-define host] 224define prefix $prefix 225define builddir $autosetup(builddir) 226define srcdir $autosetup(srcdir) 227# Allow this to come from the environment 228define top_srcdir [get-env top_srcdir [get-define srcdir]] 229 230# autoconf supports all of these 231set exec_prefix [opt-val exec-prefix $prefix] 232define exec_prefix $exec_prefix 233foreach {name defpath} { 234 bindir /bin 235 sbindir /sbin 236 libexecdir /libexec 237 libdir /lib 238} { 239 define $name [opt-val $name $exec_prefix$defpath] 240} 241foreach {name defpath} { 242 datadir /share 243 sysconfdir /etc 244 sharedstatedir /com 245 localstatedir /var 246 infodir /share/info 247 mandir /share/man 248 includedir /include 249} { 250 define $name [opt-val $name $prefix$defpath] 251} 252 253define SHELL [get-env SHELL [find-an-executable sh bash ksh]] 254 255# Windows vs. non-Windows 256switch -glob -- [get-define host] { 257 *-*-ming* - *-*-cygwin { 258 define-feature windows 259 define EXEEXT .exe 260 } 261 default { 262 define EXEEXT "" 263 } 264} 265 266# Display 267msg-result "Host System...[get-define host]" 268msg-result "Build System...[get-define build]" 269