| 1 | # Copyright 2003, 2005 Dave Abrahams
|
|---|
| 2 | # Copyright 2005, 2006 Rene Rivera
|
|---|
| 3 | # Copyright 2005 Toon Knapen
|
|---|
| 4 | # Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
|
|---|
| 5 | # Distributed under the Boost Software License, Version 1.0.
|
|---|
| 6 | # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
|---|
| 7 |
|
|---|
| 8 | # Provides actions common to all toolsets, such as creating directories and
|
|---|
| 9 | # removing files.
|
|---|
| 10 |
|
|---|
| 11 | import os ;
|
|---|
| 12 | import modules ;
|
|---|
| 13 | import utility ;
|
|---|
| 14 | import print ;
|
|---|
| 15 | import type ;
|
|---|
| 16 | import feature ;
|
|---|
| 17 | import errors ;
|
|---|
| 18 | import path ;
|
|---|
| 19 | import sequence ;
|
|---|
| 20 | import toolset ;
|
|---|
| 21 | import virtual-target ;
|
|---|
| 22 |
|
|---|
| 23 | if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
|
|---|
| 24 | {
|
|---|
| 25 | .debug-configuration = true ;
|
|---|
| 26 | }
|
|---|
| 27 | if [ MATCH (--show-configuration) : [ modules.peek : ARGV ] ]
|
|---|
| 28 | {
|
|---|
| 29 | .show-configuration = true ;
|
|---|
| 30 | }
|
|---|
| 31 |
|
|---|
| 32 | # Configurations
|
|---|
| 33 | #
|
|---|
| 34 | # The following class helps to manage toolset configurations. Each configuration
|
|---|
| 35 | # has a unique ID and one or more parameters. A typical example of a unique ID
|
|---|
| 36 | # is a condition generated by 'common.check-init-parameters' rule. Other kinds
|
|---|
| 37 | # of IDs can be used. Parameters may include any details about the configuration
|
|---|
| 38 | # like 'command', 'path', etc.
|
|---|
| 39 | #
|
|---|
| 40 | # A toolset configuration may be in one of the following states:
|
|---|
| 41 | #
|
|---|
| 42 | # - registered
|
|---|
| 43 | # Configuration has been registered (e.g. explicitly or by auto-detection
|
|---|
| 44 | # code) but has not yet been marked as used, i.e. 'toolset.using' rule has
|
|---|
| 45 | # not yet been called for it.
|
|---|
| 46 | # - used
|
|---|
| 47 | # Once called 'toolset.using' rule marks the configuration as 'used'.
|
|---|
| 48 | #
|
|---|
| 49 | # The main difference between the states above is that while a configuration is
|
|---|
| 50 | # 'registered' its options can be freely changed. This is useful in particular
|
|---|
| 51 | # for autodetection code - all detected configurations may be safely overwritten
|
|---|
| 52 | # by user code.
|
|---|
| 53 |
|
|---|
| 54 | class configurations
|
|---|
| 55 | {
|
|---|
| 56 | import errors ;
|
|---|
| 57 |
|
|---|
| 58 | rule __init__ ( )
|
|---|
| 59 | {
|
|---|
| 60 | }
|
|---|
| 61 |
|
|---|
| 62 | # Registers a configuration.
|
|---|
| 63 | #
|
|---|
| 64 | # Returns 'true' if the configuration has been added and an empty value if
|
|---|
| 65 | # it already exists. Reports an error if the configuration is 'used'.
|
|---|
| 66 | #
|
|---|
| 67 | rule register ( id )
|
|---|
| 68 | {
|
|---|
| 69 | if $(id) in $(self.used)
|
|---|
| 70 | {
|
|---|
| 71 | errors.error "common: the configuration '$(id)' is in use" ;
|
|---|
| 72 | }
|
|---|
| 73 |
|
|---|
| 74 | local retval ;
|
|---|
| 75 |
|
|---|
| 76 | if ! $(id) in $(self.all)
|
|---|
| 77 | {
|
|---|
| 78 | self.all += $(id) ;
|
|---|
| 79 |
|
|---|
| 80 | # Indicate that a new configuration has been added.
|
|---|
| 81 | retval = true ;
|
|---|
| 82 | }
|
|---|
| 83 |
|
|---|
| 84 | return $(retval) ;
|
|---|
| 85 | }
|
|---|
| 86 |
|
|---|
| 87 | # Mark a configuration as 'used'.
|
|---|
| 88 | #
|
|---|
| 89 | # Returns 'true' if the state of the configuration has been changed to
|
|---|
| 90 | # 'used' and an empty value if it the state has not been changed. Reports an
|
|---|
| 91 | # error if the configuration is not known.
|
|---|
| 92 | #
|
|---|
| 93 | rule use ( id )
|
|---|
| 94 | {
|
|---|
| 95 | if ! $(id) in $(self.all)
|
|---|
| 96 | {
|
|---|
| 97 | errors.error "common: the configuration '$(id)' is not known" ;
|
|---|
| 98 | }
|
|---|
| 99 |
|
|---|
| 100 | local retval ;
|
|---|
| 101 |
|
|---|
| 102 | if ! $(id) in $(self.used)
|
|---|
| 103 | {
|
|---|
| 104 | self.used += $(id) ;
|
|---|
| 105 |
|
|---|
| 106 | # Indicate that the configuration has been marked as 'used'.
|
|---|
| 107 | retval = true ;
|
|---|
| 108 | }
|
|---|
| 109 |
|
|---|
| 110 | return $(retval) ;
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | # Return all registered configurations.
|
|---|
| 114 | #
|
|---|
| 115 | rule all ( )
|
|---|
| 116 | {
|
|---|
| 117 | return $(self.all) ;
|
|---|
| 118 | }
|
|---|
| 119 |
|
|---|
| 120 | # Return all used configurations.
|
|---|
| 121 | #
|
|---|
| 122 | rule used ( )
|
|---|
| 123 | {
|
|---|
| 124 | return $(self.used) ;
|
|---|
| 125 | }
|
|---|
| 126 |
|
|---|
| 127 | # Returns the value of a configuration parameter.
|
|---|
| 128 | #
|
|---|
| 129 | rule get ( id : param )
|
|---|
| 130 | {
|
|---|
| 131 | return $(self.$(param).$(id)) ;
|
|---|
| 132 | }
|
|---|
| 133 |
|
|---|
| 134 | # Sets the value of a configuration parameter.
|
|---|
| 135 | #
|
|---|
| 136 | rule set ( id : param : value * )
|
|---|
| 137 | {
|
|---|
| 138 | self.$(param).$(id) = $(value) ;
|
|---|
| 139 | }
|
|---|
| 140 | }
|
|---|
| 141 |
|
|---|
| 142 |
|
|---|
| 143 | # The rule for checking toolset parameters. Trailing parameters should all be
|
|---|
| 144 | # parameter name/value pairs. The rule will check that each parameter either has
|
|---|
| 145 | # a value in each invocation or has no value in each invocation. Also, the rule
|
|---|
| 146 | # will check that the combination of all parameter values is unique in all
|
|---|
| 147 | # invocations.
|
|---|
| 148 | #
|
|---|
| 149 | # Each parameter name corresponds to a subfeature. This rule will declare a
|
|---|
| 150 | # subfeature the first time a non-empty parameter value is passed and will
|
|---|
| 151 | # extend it with all the values.
|
|---|
| 152 | #
|
|---|
| 153 | # The return value from this rule is a condition to be used for flags settings.
|
|---|
| 154 | #
|
|---|
| 155 | rule check-init-parameters ( toolset requirement * : * )
|
|---|
| 156 | {
|
|---|
| 157 | local sig = $(toolset) ;
|
|---|
| 158 | local condition = <toolset>$(toolset) ;
|
|---|
| 159 | local subcondition ;
|
|---|
| 160 | for local index in 2 3 4 5 6 7 8 9
|
|---|
| 161 | {
|
|---|
| 162 | local name = $($(index)[1]) ;
|
|---|
| 163 | local value = $($(index)[2]) ;
|
|---|
| 164 |
|
|---|
| 165 | if $(value)-is-not-empty
|
|---|
| 166 | {
|
|---|
| 167 | condition = $(condition)-$(value) ;
|
|---|
| 168 | if $(.had-unspecified-value.$(toolset).$(name))
|
|---|
| 169 | {
|
|---|
| 170 | errors.user-error
|
|---|
| 171 | "$(toolset) initialization: parameter '$(name)'"
|
|---|
| 172 | "inconsistent" : "no value was specified in earlier"
|
|---|
| 173 | "initialization" : "an explicit value is specified now" ;
|
|---|
| 174 | }
|
|---|
| 175 | # The below logic is for intel compiler. It calls this rule with
|
|---|
| 176 | # 'intel-linux' and 'intel-win' as toolset, so we need to get the
|
|---|
| 177 | # base part of toolset name. We can not pass 'intel' as toolset
|
|---|
| 178 | # because in that case it will be impossible to register versionless
|
|---|
| 179 | # intel-linux and intel-win toolsets of a specific version.
|
|---|
| 180 | local t = $(toolset) ;
|
|---|
| 181 | local m = [ MATCH ([^-]*)- : $(toolset) ] ;
|
|---|
| 182 | if $(m)
|
|---|
| 183 | {
|
|---|
| 184 | t = $(m[1]) ;
|
|---|
| 185 | }
|
|---|
| 186 | if ! $(.had-value.$(toolset).$(name))
|
|---|
| 187 | {
|
|---|
| 188 | if ! $(.declared-subfeature.$(t).$(name))
|
|---|
| 189 | {
|
|---|
| 190 | feature.subfeature toolset $(t) : $(name) : : propagated ;
|
|---|
| 191 | .declared-subfeature.$(t).$(name) = true ;
|
|---|
| 192 | }
|
|---|
| 193 | .had-value.$(toolset).$(name) = true ;
|
|---|
| 194 | }
|
|---|
| 195 | feature.extend-subfeature toolset $(t) : $(name) : $(value) ;
|
|---|
| 196 | subcondition += <toolset-$(t):$(name)>$(value) ;
|
|---|
| 197 | }
|
|---|
| 198 | else
|
|---|
| 199 | {
|
|---|
| 200 | if $(.had-value.$(toolset).$(name))
|
|---|
| 201 | {
|
|---|
| 202 | errors.user-error
|
|---|
| 203 | "$(toolset) initialization: parameter '$(name)'"
|
|---|
| 204 | "inconsistent" : "an explicit value was specified in an"
|
|---|
| 205 | "earlier initialization" : "no value is specified now" ;
|
|---|
| 206 | }
|
|---|
| 207 | .had-unspecified-value.$(toolset).$(name) = true ;
|
|---|
| 208 | }
|
|---|
| 209 | sig = $(sig)$(value:E="")- ;
|
|---|
| 210 | }
|
|---|
| 211 | if $(sig) in $(.all-signatures)
|
|---|
| 212 | {
|
|---|
| 213 | local message =
|
|---|
| 214 | "duplicate initialization of $(toolset) with the following parameters: " ;
|
|---|
| 215 | for local index in 2 3 4 5 6 7 8 9
|
|---|
| 216 | {
|
|---|
| 217 | local p = $($(index)) ;
|
|---|
| 218 | if $(p)
|
|---|
| 219 | {
|
|---|
| 220 | message += "$(p[1]) = $(p[2]:E=<unspecified>)" ;
|
|---|
| 221 | }
|
|---|
| 222 | }
|
|---|
| 223 | message += "previous initialization at $(.init-loc.$(sig))" ;
|
|---|
| 224 | errors.user-error
|
|---|
| 225 | $(message[1]) : $(message[2]) : $(message[3]) : $(message[4]) :
|
|---|
| 226 | $(message[5]) : $(message[6]) : $(message[7]) : $(message[8]) ;
|
|---|
| 227 | }
|
|---|
| 228 | .all-signatures += $(sig) ;
|
|---|
| 229 | .init-loc.$(sig) = [ errors.nearest-user-location ] ;
|
|---|
| 230 |
|
|---|
| 231 | # If we have a requirement, this version should only be applied under that
|
|---|
| 232 | # condition. To accomplish this we add a toolset requirement that imposes
|
|---|
| 233 | # the toolset subcondition, which encodes the version.
|
|---|
| 234 | if $(requirement)
|
|---|
| 235 | {
|
|---|
| 236 | local r = <toolset>$(toolset) $(requirement) ;
|
|---|
| 237 | r = $(r:J=,) ;
|
|---|
| 238 | toolset.add-requirements $(r):$(subcondition) ;
|
|---|
| 239 | }
|
|---|
| 240 |
|
|---|
| 241 | # We add the requirements, if any, to the condition to scope the toolset
|
|---|
| 242 | # variables and options to this specific version.
|
|---|
| 243 | condition += $(requirement) ;
|
|---|
| 244 |
|
|---|
| 245 | if $(.show-configuration)
|
|---|
| 246 | {
|
|---|
| 247 | ECHO notice: $(condition) ;
|
|---|
| 248 | }
|
|---|
| 249 | return $(condition:J=/) ;
|
|---|
| 250 | }
|
|---|
| 251 |
|
|---|
| 252 |
|
|---|
| 253 | # A helper rule to get the command to invoke some tool. If
|
|---|
| 254 | # 'user-provided-command' is not given, tries to find binary named 'tool' in
|
|---|
| 255 | # PATH and in the passed 'additional-path'. Otherwise, verifies that the first
|
|---|
| 256 | # element of 'user-provided-command' is an existing program.
|
|---|
| 257 | #
|
|---|
| 258 | # This rule returns the command to be used when invoking the tool. If we can not
|
|---|
| 259 | # find the tool, a warning is issued. If 'path-last' is specified, PATH is
|
|---|
| 260 | # checked after 'additional-paths' when searching for 'tool'.
|
|---|
| 261 | #
|
|---|
| 262 | rule get-invocation-command-nodefault ( toolset : tool :
|
|---|
| 263 | user-provided-command * : additional-paths * : path-last ? )
|
|---|
| 264 | {
|
|---|
| 265 | local command ;
|
|---|
| 266 | if ! $(user-provided-command)
|
|---|
| 267 | {
|
|---|
| 268 | command = [ find-tool $(tool) : $(additional-paths) : $(path-last) ] ;
|
|---|
| 269 | if ! $(command) && $(.debug-configuration)
|
|---|
| 270 | {
|
|---|
| 271 | ECHO warning: toolset $(toolset) initialization: can not find tool
|
|---|
| 272 | $(tool) ;
|
|---|
| 273 | ECHO warning: initialized from [ errors.nearest-user-location ] ;
|
|---|
| 274 | }
|
|---|
| 275 | }
|
|---|
| 276 | else
|
|---|
| 277 | {
|
|---|
| 278 | command = [ check-tool $(user-provided-command) ] ;
|
|---|
| 279 | if ! $(command) && $(.debug-configuration)
|
|---|
| 280 | {
|
|---|
| 281 | ECHO warning: toolset $(toolset) initialization: ;
|
|---|
| 282 | ECHO warning: can not find user-provided command
|
|---|
| 283 | '$(user-provided-command)' ;
|
|---|
| 284 | ECHO warning: initialized from [ errors.nearest-user-location ] ;
|
|---|
| 285 | }
|
|---|
| 286 | }
|
|---|
| 287 |
|
|---|
| 288 | return $(command) ;
|
|---|
| 289 | }
|
|---|
| 290 |
|
|---|
| 291 |
|
|---|
| 292 | # Same as get-invocation-command-nodefault, except that if no tool is found,
|
|---|
| 293 | # returns either the user-provided-command, if present, or the 'tool' parameter.
|
|---|
| 294 | #
|
|---|
| 295 | rule get-invocation-command ( toolset : tool : user-provided-command * :
|
|---|
| 296 | additional-paths * : path-last ? )
|
|---|
| 297 | {
|
|---|
| 298 | local result = [ get-invocation-command-nodefault $(toolset) : $(tool) :
|
|---|
| 299 | $(user-provided-command) : $(additional-paths) : $(path-last) ] ;
|
|---|
| 300 |
|
|---|
| 301 | if ! $(result)
|
|---|
| 302 | {
|
|---|
| 303 | if $(user-provided-command)
|
|---|
| 304 | {
|
|---|
| 305 | result = $(user-provided-command) ;
|
|---|
| 306 | }
|
|---|
| 307 | else
|
|---|
| 308 | {
|
|---|
| 309 | result = $(tool) ;
|
|---|
| 310 | }
|
|---|
| 311 | }
|
|---|
| 312 | return $(result) ;
|
|---|
| 313 | }
|
|---|
| 314 |
|
|---|
| 315 |
|
|---|
| 316 | # Given an invocation command return the absolute path to the command. This
|
|---|
| 317 | # works even if command has no path element and was found on the PATH.
|
|---|
| 318 | #
|
|---|
| 319 | rule get-absolute-tool-path ( command )
|
|---|
| 320 | {
|
|---|
| 321 | if $(command:D)
|
|---|
| 322 | {
|
|---|
| 323 | return $(command:D) ;
|
|---|
| 324 | }
|
|---|
| 325 | else
|
|---|
| 326 | {
|
|---|
| 327 | local m = [ GLOB [ modules.peek : PATH Path path ] : $(command)
|
|---|
| 328 | $(command).exe ] ;
|
|---|
| 329 | return $(m[1]:D) ;
|
|---|
| 330 | }
|
|---|
| 331 | }
|
|---|
| 332 |
|
|---|
| 333 |
|
|---|
| 334 | # Attempts to find tool (binary) named 'name' in PATH and in 'additional-paths'.
|
|---|
| 335 | # If found in PATH, returns 'name' and if found in additional paths, returns
|
|---|
| 336 | # absolute name. If the tool is found in several directories, returns the first
|
|---|
| 337 | # path found. Otherwise, returns an empty string. If 'path-last' is specified,
|
|---|
| 338 | # PATH is searched after 'additional-paths'.
|
|---|
| 339 | #
|
|---|
| 340 | rule find-tool ( name : additional-paths * : path-last ? )
|
|---|
| 341 | {
|
|---|
| 342 | local path = [ path.programs-path ] ;
|
|---|
| 343 | local match = [ path.glob $(path) : $(name) $(name).exe ] ;
|
|---|
| 344 | local additional-match = [ path.glob $(additional-paths) : $(name)
|
|---|
| 345 | $(name).exe ] ;
|
|---|
| 346 |
|
|---|
| 347 | local result ;
|
|---|
| 348 | if $(path-last)
|
|---|
| 349 | {
|
|---|
| 350 | result = $(additional-match) ;
|
|---|
| 351 | if ! $(result) && $(match)
|
|---|
| 352 | {
|
|---|
| 353 | result = $(name) ;
|
|---|
| 354 | }
|
|---|
| 355 | }
|
|---|
| 356 | else
|
|---|
| 357 | {
|
|---|
| 358 | if $(match)
|
|---|
| 359 | {
|
|---|
| 360 | result = $(name) ;
|
|---|
| 361 | }
|
|---|
| 362 | else
|
|---|
| 363 | {
|
|---|
| 364 | result = $(additional-match) ;
|
|---|
| 365 | }
|
|---|
| 366 | }
|
|---|
| 367 | if $(result)
|
|---|
| 368 | {
|
|---|
| 369 | return [ path.native $(result[1]) ] ;
|
|---|
| 370 | }
|
|---|
| 371 | }
|
|---|
| 372 |
|
|---|
| 373 | # Checks if 'command' can be found either in path or is a full name to an
|
|---|
| 374 | # existing file.
|
|---|
| 375 | #
|
|---|
| 376 | local rule check-tool-aux ( command )
|
|---|
| 377 | {
|
|---|
| 378 | if $(command:D)
|
|---|
| 379 | {
|
|---|
| 380 | if [ path.exists $(command) ]
|
|---|
| 381 | # Both NT and Cygwin will run .exe files by their unqualified names.
|
|---|
| 382 | || ( [ os.on-windows ] && [ path.exists $(command).exe ] )
|
|---|
| 383 | # Only NT will run .bat & .cmd files by their unqualified names.
|
|---|
| 384 | || ( ( [ os.name ] = NT ) && ( [ path.exists $(command).bat ] ||
|
|---|
| 385 | [ path.exists $(command).cmd ] ) )
|
|---|
| 386 | {
|
|---|
| 387 | return $(command) ;
|
|---|
| 388 | }
|
|---|
| 389 | }
|
|---|
| 390 | else
|
|---|
| 391 | {
|
|---|
| 392 | if [ GLOB [ modules.peek : PATH Path path ] : $(command) ]
|
|---|
| 393 | {
|
|---|
| 394 | return $(command) ;
|
|---|
| 395 | }
|
|---|
| 396 | }
|
|---|
| 397 | }
|
|---|
| 398 |
|
|---|
| 399 |
|
|---|
| 400 | # Checks that a tool can be invoked by 'command'. If command is not an absolute
|
|---|
| 401 | # path, checks if it can be found in 'path'. If comand is an absolute path,
|
|---|
| 402 | # check that it exists. Returns 'command' if ok or empty string otherwise.
|
|---|
| 403 | #
|
|---|
| 404 | local rule check-tool ( xcommand + )
|
|---|
| 405 | {
|
|---|
| 406 | if [ check-tool-aux $(xcommand[1]) ] ||
|
|---|
| 407 | [ check-tool-aux $(xcommand[-1]) ]
|
|---|
| 408 | {
|
|---|
| 409 | return $(xcommand) ;
|
|---|
| 410 | }
|
|---|
| 411 | }
|
|---|
| 412 |
|
|---|
| 413 |
|
|---|
| 414 | # Handle common options for toolset, specifically sets the following flag
|
|---|
| 415 | # variables:
|
|---|
| 416 | # - CONFIG_COMMAND to $(command)
|
|---|
| 417 | # - OPTIONS for compile to the value of <compileflags> in $(options)
|
|---|
| 418 | # - OPTIONS for compile.c to the value of <cflags> in $(options)
|
|---|
| 419 | # - OPTIONS for compile.c++ to the value of <cxxflags> in $(options)
|
|---|
| 420 | # - OPTIONS for compile.fortran to the value of <fflags> in $(options)
|
|---|
| 421 | # - OPTIONS for link to the value of <linkflags> in $(options)
|
|---|
| 422 | #
|
|---|
| 423 | rule handle-options ( toolset : condition * : command * : options * )
|
|---|
| 424 | {
|
|---|
| 425 | if $(.debug-configuration)
|
|---|
| 426 | {
|
|---|
| 427 | ECHO notice: will use '$(command)' for $(toolset), condition
|
|---|
| 428 | $(condition:E=(empty)) ;
|
|---|
| 429 | }
|
|---|
| 430 |
|
|---|
| 431 | # The last parameter ('unchecked') says it is OK to set flags for another
|
|---|
| 432 | # module.
|
|---|
| 433 | toolset.flags $(toolset) CONFIG_COMMAND $(condition) : $(command)
|
|---|
| 434 | : unchecked ;
|
|---|
| 435 |
|
|---|
| 436 | toolset.flags $(toolset).compile OPTIONS $(condition) :
|
|---|
| 437 | [ feature.get-values <compileflags> : $(options) ] : unchecked ;
|
|---|
| 438 |
|
|---|
| 439 | toolset.flags $(toolset).compile.c OPTIONS $(condition) :
|
|---|
| 440 | [ feature.get-values <cflags> : $(options) ] : unchecked ;
|
|---|
| 441 |
|
|---|
| 442 | toolset.flags $(toolset).compile.c++ OPTIONS $(condition) :
|
|---|
| 443 | [ feature.get-values <cxxflags> : $(options) ] : unchecked ;
|
|---|
| 444 |
|
|---|
| 445 | toolset.flags $(toolset).compile.fortran OPTIONS $(condition) :
|
|---|
| 446 | [ feature.get-values <fflags> : $(options) ] : unchecked ;
|
|---|
| 447 |
|
|---|
| 448 | toolset.flags $(toolset).link OPTIONS $(condition) :
|
|---|
| 449 | [ feature.get-values <linkflags> : $(options) ] : unchecked ;
|
|---|
| 450 | }
|
|---|
| 451 |
|
|---|
| 452 |
|
|---|
| 453 | # Returns the location of the "program files" directory on a Windows platform.
|
|---|
| 454 | #
|
|---|
| 455 | rule get-program-files-dir ( )
|
|---|
| 456 | {
|
|---|
| 457 | local ProgramFiles = [ modules.peek : ProgramFiles ] ;
|
|---|
| 458 | if $(ProgramFiles)
|
|---|
| 459 | {
|
|---|
| 460 | ProgramFiles = "$(ProgramFiles:J= )" ;
|
|---|
| 461 | }
|
|---|
| 462 | else
|
|---|
| 463 | {
|
|---|
| 464 | ProgramFiles = "c:\\Program Files" ;
|
|---|
| 465 | }
|
|---|
| 466 | return $(ProgramFiles) ;
|
|---|
| 467 | }
|
|---|
| 468 |
|
|---|
| 469 |
|
|---|
| 470 | if [ os.name ] = NT
|
|---|
| 471 | {
|
|---|
| 472 | RM = del /f /q ;
|
|---|
| 473 | CP = copy /b ;
|
|---|
| 474 | IGNORE = "2>nul >nul & setlocal" ;
|
|---|
| 475 | LN ?= $(CP) ;
|
|---|
| 476 | # Ugly hack to convince copy to set the timestamp of the destination to the
|
|---|
| 477 | # current time by concatenating the source with a nonexistent file. Note
|
|---|
| 478 | # that this requires /b (binary) as the default when concatenating files is
|
|---|
| 479 | # /a (ascii).
|
|---|
| 480 | WINDOWS-CP-HACK = "+ this-file-does-not-exist-A698EE7806899E69" ;
|
|---|
| 481 | }
|
|---|
| 482 | else
|
|---|
| 483 | {
|
|---|
| 484 | RM = rm -f ;
|
|---|
| 485 | CP = cp ;
|
|---|
| 486 | LN = ln ;
|
|---|
| 487 | }
|
|---|
| 488 |
|
|---|
| 489 |
|
|---|
| 490 | rule rm-command ( )
|
|---|
| 491 | {
|
|---|
| 492 | return $(RM) ;
|
|---|
| 493 | }
|
|---|
| 494 |
|
|---|
| 495 |
|
|---|
| 496 | rule copy-command ( )
|
|---|
| 497 | {
|
|---|
| 498 | return $(CP) ;
|
|---|
| 499 | }
|
|---|
| 500 |
|
|---|
| 501 |
|
|---|
| 502 | if "\n" = "n"
|
|---|
| 503 | {
|
|---|
| 504 | # Escape characters not supported so use ugly hacks. Will not work on Cygwin
|
|---|
| 505 | # - see below.
|
|---|
| 506 | nl = "
|
|---|
| 507 | " ;
|
|---|
| 508 | q = "" ;
|
|---|
| 509 | }
|
|---|
| 510 | else
|
|---|
| 511 | {
|
|---|
| 512 | nl = "\n" ;
|
|---|
| 513 | q = "\"" ;
|
|---|
| 514 | }
|
|---|
| 515 |
|
|---|
| 516 | # Returns the command needed to set an environment variable on the current
|
|---|
| 517 | # platform. The variable setting persists through all following commands and is
|
|---|
| 518 | # visible in the environment seen by subsequently executed commands. In other
|
|---|
| 519 | # words, on Unix systems, the variable is exported, which is consistent with the
|
|---|
| 520 | # only possible behavior on Windows systems.
|
|---|
| 521 | #
|
|---|
| 522 | rule variable-setting-command ( variable : value )
|
|---|
| 523 | {
|
|---|
| 524 | if [ os.name ] = NT
|
|---|
| 525 | {
|
|---|
| 526 | return "set $(variable)=$(value)$(nl)" ;
|
|---|
| 527 | }
|
|---|
| 528 | else
|
|---|
| 529 | {
|
|---|
| 530 | # If we do not have escape character support in bjam, the cod below
|
|---|
| 531 | # blows up on CYGWIN, since the $(nl) variable holds a Windows new-line
|
|---|
| 532 | # \r\n sequence that messes up the executed export command which then
|
|---|
| 533 | # reports that the passed variable name is incorrect.
|
|---|
| 534 | # But we have a check for cygwin in kernel/bootstrap.jam already.
|
|---|
| 535 | return "$(variable)=$(q)$(value)$(q)$(nl)export $(variable)$(nl)" ;
|
|---|
| 536 | }
|
|---|
| 537 | }
|
|---|
| 538 |
|
|---|
| 539 |
|
|---|
| 540 | # Returns a command to sets a named shell path variable to the given NATIVE
|
|---|
| 541 | # paths on the current platform.
|
|---|
| 542 | #
|
|---|
| 543 | rule path-variable-setting-command ( variable : paths * )
|
|---|
| 544 | {
|
|---|
| 545 | local sep = [ os.path-separator ] ;
|
|---|
| 546 | return [ variable-setting-command $(variable) : $(paths:J=$(sep)) ] ;
|
|---|
| 547 | }
|
|---|
| 548 |
|
|---|
| 549 |
|
|---|
| 550 | # Returns a command that prepends the given paths to the named path variable on
|
|---|
| 551 | # the current platform.
|
|---|
| 552 | #
|
|---|
| 553 | rule prepend-path-variable-command ( variable : paths * )
|
|---|
| 554 | {
|
|---|
| 555 | return [ path-variable-setting-command $(variable)
|
|---|
| 556 | : $(paths) [ os.expand-variable $(variable) ] ] ;
|
|---|
| 557 | }
|
|---|
| 558 |
|
|---|
| 559 |
|
|---|
| 560 | # Return a command which can create a file. If 'r' is result of invocation, then
|
|---|
| 561 | # 'r foobar' will create foobar with unspecified content. What happens if file
|
|---|
| 562 | # already exists is unspecified.
|
|---|
| 563 | #
|
|---|
| 564 | rule file-creation-command ( )
|
|---|
| 565 | {
|
|---|
| 566 | if [ os.name ] = NT
|
|---|
| 567 | {
|
|---|
| 568 | # A few alternative implementations on Windows:
|
|---|
| 569 | #
|
|---|
| 570 | # 'type NUL >> '
|
|---|
| 571 | # That would construct an empty file instead of a file containing
|
|---|
| 572 | # a space and an end-of-line marker but it would also not change
|
|---|
| 573 | # the target's timestamp in case the file already exists.
|
|---|
| 574 | #
|
|---|
| 575 | # 'type NUL > '
|
|---|
| 576 | # That would construct an empty file instead of a file containing
|
|---|
| 577 | # a space and an end-of-line marker but it would also destroy an
|
|---|
| 578 | # already existing file by overwriting it with an empty one.
|
|---|
| 579 | #
|
|---|
| 580 | # I guess the best solution would be to allow Boost Jam to define
|
|---|
| 581 | # built-in functions such as 'create a file', 'touch a file' or 'copy a
|
|---|
| 582 | # file' which could be used from inside action code. That would allow
|
|---|
| 583 | # completely portable operations without this kind of kludge.
|
|---|
| 584 | # (22.02.2009.) (Jurko)
|
|---|
| 585 | return "echo. > " ;
|
|---|
| 586 | }
|
|---|
| 587 | else
|
|---|
| 588 | {
|
|---|
| 589 | return "touch " ;
|
|---|
| 590 | }
|
|---|
| 591 | }
|
|---|
| 592 |
|
|---|
| 593 |
|
|---|
| 594 | # Returns a command that may be used for 'touching' files. It is not a real
|
|---|
| 595 | # 'touch' command on NT because it adds an empty line at the end of file but it
|
|---|
| 596 | # works with source files.
|
|---|
| 597 | #
|
|---|
| 598 | rule file-touch-command ( )
|
|---|
| 599 | {
|
|---|
| 600 | if [ os.name ] = NT
|
|---|
| 601 | {
|
|---|
| 602 | return "echo. >> " ;
|
|---|
| 603 | }
|
|---|
| 604 | else
|
|---|
| 605 | {
|
|---|
| 606 | return "touch " ;
|
|---|
| 607 | }
|
|---|
| 608 | }
|
|---|
| 609 |
|
|---|
| 610 |
|
|---|
| 611 | rule MkDir
|
|---|
| 612 | {
|
|---|
| 613 | # If dir exists, do not update it. Do this even for $(DOT).
|
|---|
| 614 | NOUPDATE $(<) ;
|
|---|
| 615 |
|
|---|
| 616 | if $(<) != $(DOT) && ! $($(<)-mkdir)
|
|---|
| 617 | {
|
|---|
| 618 | # Cheesy gate to prevent multiple invocations on same dir.
|
|---|
| 619 | $(<)-mkdir = true ;
|
|---|
| 620 |
|
|---|
| 621 | # Schedule the mkdir build action.
|
|---|
| 622 | common.mkdir $(<) ;
|
|---|
| 623 |
|
|---|
| 624 | # Prepare a Jam 'dirs' target that can be used to make the build only
|
|---|
| 625 | # construct all the target directories.
|
|---|
| 626 | DEPENDS dirs : $(<) ;
|
|---|
| 627 |
|
|---|
| 628 | # Recursively create parent directories. $(<:P) = $(<)'s parent & we
|
|---|
| 629 | # recurse until root.
|
|---|
| 630 |
|
|---|
| 631 | local s = $(<:P) ;
|
|---|
| 632 | if [ os.name ] = NT
|
|---|
| 633 | {
|
|---|
| 634 | switch $(s)
|
|---|
| 635 | {
|
|---|
| 636 | case *: : s = ;
|
|---|
| 637 | case *:\\ : s = ;
|
|---|
| 638 | }
|
|---|
| 639 | }
|
|---|
| 640 |
|
|---|
| 641 | if $(s)
|
|---|
| 642 | {
|
|---|
| 643 | if $(s) != $(<)
|
|---|
| 644 | {
|
|---|
| 645 | DEPENDS $(<) : $(s) ;
|
|---|
| 646 | MkDir $(s) ;
|
|---|
| 647 | }
|
|---|
| 648 | else
|
|---|
| 649 | {
|
|---|
| 650 | NOTFILE $(s) ;
|
|---|
| 651 | }
|
|---|
| 652 | }
|
|---|
| 653 | }
|
|---|
| 654 | }
|
|---|
| 655 |
|
|---|
| 656 |
|
|---|
| 657 | #actions MkDir1
|
|---|
| 658 | #{
|
|---|
| 659 | # mkdir "$(<)"
|
|---|
| 660 | #}
|
|---|
| 661 |
|
|---|
| 662 | # The following quick-fix actions should be replaced using the original MkDir1
|
|---|
| 663 | # action once Boost Jam gets updated to correctly detect different paths leading
|
|---|
| 664 | # up to the same filesystem target and triggers their build action only once.
|
|---|
| 665 | # (todo) (04.07.2008.) (Jurko)
|
|---|
| 666 |
|
|---|
| 667 | if [ os.name ] = NT
|
|---|
| 668 | {
|
|---|
| 669 | actions mkdir
|
|---|
| 670 | {
|
|---|
| 671 | if not exist "$(<)\\" mkdir "$(<)"
|
|---|
| 672 | }
|
|---|
| 673 | }
|
|---|
| 674 | else
|
|---|
| 675 | {
|
|---|
| 676 | actions mkdir
|
|---|
| 677 | {
|
|---|
| 678 | mkdir -p "$(<)"
|
|---|
| 679 | }
|
|---|
| 680 | }
|
|---|
| 681 |
|
|---|
| 682 | actions piecemeal together existing Clean
|
|---|
| 683 | {
|
|---|
| 684 | $(RM) "$(>)"
|
|---|
| 685 | }
|
|---|
| 686 |
|
|---|
| 687 |
|
|---|
| 688 | rule copy
|
|---|
| 689 | {
|
|---|
| 690 | }
|
|---|
| 691 |
|
|---|
| 692 |
|
|---|
| 693 | actions copy
|
|---|
| 694 | {
|
|---|
| 695 | $(CP) "$(>)" $(WINDOWS-CP-HACK) "$(<)"
|
|---|
| 696 | }
|
|---|
| 697 |
|
|---|
| 698 |
|
|---|
| 699 | rule RmTemps
|
|---|
| 700 | {
|
|---|
| 701 | }
|
|---|
| 702 |
|
|---|
| 703 |
|
|---|
| 704 | actions quietly updated piecemeal together RmTemps
|
|---|
| 705 | {
|
|---|
| 706 | $(RM) "$(>)" $(IGNORE)
|
|---|
| 707 | }
|
|---|
| 708 |
|
|---|
| 709 |
|
|---|
| 710 | actions hard-link
|
|---|
| 711 | {
|
|---|
| 712 | $(RM) "$(<)" 2$(NULL_OUT) $(NULL_OUT)
|
|---|
| 713 | $(LN) "$(>)" "$(<)" $(NULL_OUT)
|
|---|
| 714 | }
|
|---|
| 715 |
|
|---|
| 716 |
|
|---|
| 717 | # Given a target, as given to a custom tag rule, returns a string formatted
|
|---|
| 718 | # according to the passed format. Format is a list of properties that is
|
|---|
| 719 | # represented in the result. For each element of format the corresponding target
|
|---|
| 720 | # information is obtained and added to the result string. For all, but the
|
|---|
| 721 | # literal, the format value is taken as the as string to prepend to the output
|
|---|
| 722 | # to join the item to the rest of the result. If not given "-" is used as a
|
|---|
| 723 | # joiner.
|
|---|
| 724 | #
|
|---|
| 725 | # The format options can be:
|
|---|
| 726 | #
|
|---|
| 727 | # <base>[joiner]
|
|---|
| 728 | # :: The basename of the target name.
|
|---|
| 729 | # <toolset>[joiner]
|
|---|
| 730 | # :: The abbreviated toolset tag being used to build the target.
|
|---|
| 731 | # <threading>[joiner]
|
|---|
| 732 | # :: Indication of a multi-threaded build.
|
|---|
| 733 | # <runtime>[joiner]
|
|---|
| 734 | # :: Collective tag of the build runtime.
|
|---|
| 735 | # <version:/version-feature | X.Y[.Z]/>[joiner]
|
|---|
| 736 | # :: Short version tag taken from the given "version-feature" in the
|
|---|
| 737 | # build properties. Or if not present, the literal value as the
|
|---|
| 738 | # version number.
|
|---|
| 739 | # <property:/property-name/>[joiner]
|
|---|
| 740 | # :: Direct lookup of the given property-name value in the build
|
|---|
| 741 | # properties. /property-name/ is a regular expression. E.g.
|
|---|
| 742 | # <property:toolset-.*:flavor> will match every toolset.
|
|---|
| 743 | # /otherwise/
|
|---|
| 744 | # :: The literal value of the format argument.
|
|---|
| 745 | #
|
|---|
| 746 | # For example this format:
|
|---|
| 747 | #
|
|---|
| 748 | # boost_ <base> <toolset> <threading> <runtime> <version:boost-version>
|
|---|
| 749 | #
|
|---|
| 750 | # Might return:
|
|---|
| 751 | #
|
|---|
| 752 | # boost_thread-vc80-mt-gd-1_33.dll, or
|
|---|
| 753 | # boost_regex-vc80-gd-1_33.dll
|
|---|
| 754 | #
|
|---|
| 755 | # The returned name also has the target type specific prefix and suffix which
|
|---|
| 756 | # puts it in a ready form to use as the value from a custom tag rule.
|
|---|
| 757 | #
|
|---|
| 758 | rule format-name ( format * : name : type ? : property-set )
|
|---|
| 759 | {
|
|---|
| 760 | local result = "" ;
|
|---|
| 761 | for local f in $(format)
|
|---|
| 762 | {
|
|---|
| 763 | switch $(f:G)
|
|---|
| 764 | {
|
|---|
| 765 | case <base> :
|
|---|
| 766 | result += $(name:B) ;
|
|---|
| 767 |
|
|---|
| 768 | case <toolset> :
|
|---|
| 769 | result += [ join-tag $(f:G=) : [ toolset-tag $(name) : $(type) :
|
|---|
| 770 | $(property-set) ] ] ;
|
|---|
| 771 |
|
|---|
| 772 | case <threading> :
|
|---|
| 773 | result += [ join-tag $(f:G=) : [ threading-tag $(name) : $(type)
|
|---|
| 774 | : $(property-set) ] ] ;
|
|---|
| 775 |
|
|---|
| 776 | case <runtime> :
|
|---|
| 777 | result += [ join-tag $(f:G=) : [ runtime-tag $(name) : $(type) :
|
|---|
| 778 | $(property-set) ] ] ;
|
|---|
| 779 |
|
|---|
| 780 | case <qt> :
|
|---|
| 781 | result += [ join-tag $(f:G=) : [ qt-tag $(name) : $(type) :
|
|---|
| 782 | $(property-set) ] ] ;
|
|---|
| 783 |
|
|---|
| 784 | case <address-model> :
|
|---|
| 785 | result += [ join-tag $(f:G=) : [ address-model-tag $(name) :
|
|---|
| 786 | $(type) : $(property-set) ] ] ;
|
|---|
| 787 |
|
|---|
| 788 | case <version:*> :
|
|---|
| 789 | local key = [ MATCH <version:(.*)> : $(f:G) ] ;
|
|---|
| 790 | local version = [ $(property-set).get <$(key)> ] ;
|
|---|
| 791 | version ?= $(key) ;
|
|---|
| 792 | version = [ MATCH "^([^.]+)[.]([^.]+)[.]?([^.]*)" : $(version) ] ;
|
|---|
| 793 | result += [ join-tag $(f:G=) : $(version[1])_$(version[2]) ] ;
|
|---|
| 794 |
|
|---|
| 795 | case <property:*> :
|
|---|
| 796 | local key = [ MATCH <property:(.*)> : $(f:G) ] ;
|
|---|
| 797 | local p0 = [ MATCH <($(key))> : [ $(property-set).raw ] ] ;
|
|---|
| 798 | if $(p0)
|
|---|
| 799 | {
|
|---|
| 800 | local p = [ $(property-set).get <$(p0)> ] ;
|
|---|
| 801 | if $(p)
|
|---|
| 802 | {
|
|---|
| 803 | result += [ join-tag $(f:G=) : $(p) ] ;
|
|---|
| 804 | }
|
|---|
| 805 | }
|
|---|
| 806 |
|
|---|
| 807 | case * :
|
|---|
| 808 | result += $(f:G=) ;
|
|---|
| 809 | }
|
|---|
| 810 | }
|
|---|
| 811 | return [ virtual-target.add-prefix-and-suffix $(result:J=) : $(type) :
|
|---|
| 812 | $(property-set) ] ;
|
|---|
| 813 | }
|
|---|
| 814 |
|
|---|
| 815 |
|
|---|
| 816 | local rule join-tag ( joiner ? : tag ? )
|
|---|
| 817 | {
|
|---|
| 818 | if ! $(joiner) { joiner = - ; }
|
|---|
| 819 | return $(joiner)$(tag) ;
|
|---|
| 820 | }
|
|---|
| 821 |
|
|---|
| 822 |
|
|---|
| 823 | local rule toolset-tag ( name : type ? : property-set )
|
|---|
| 824 | {
|
|---|
| 825 | local tag = ;
|
|---|
| 826 |
|
|---|
| 827 | local properties = [ $(property-set).raw ] ;
|
|---|
| 828 | switch [ $(property-set).get <toolset> ]
|
|---|
| 829 | {
|
|---|
| 830 | case borland* : tag += bcb ;
|
|---|
| 831 | case clang* :
|
|---|
| 832 | {
|
|---|
| 833 | switch [ $(property-set).get <toolset-clang:platform> ]
|
|---|
| 834 | {
|
|---|
| 835 | case darwin : tag += clang-darwin ;
|
|---|
| 836 | case linux : tag += clang ;
|
|---|
| 837 | case win : tag += clang ;
|
|---|
| 838 | }
|
|---|
| 839 | }
|
|---|
| 840 | case como* : tag += como ;
|
|---|
| 841 | case cw : tag += cw ;
|
|---|
| 842 | case darwin* : tag += xgcc ;
|
|---|
| 843 | case edg* : tag += edg ;
|
|---|
| 844 | case gcc* :
|
|---|
| 845 | {
|
|---|
| 846 | switch [ $(property-set).get <toolset-gcc:flavor> ]
|
|---|
| 847 | {
|
|---|
| 848 | case *mingw* : tag += mgw ;
|
|---|
| 849 | case * : tag += gcc ;
|
|---|
| 850 | }
|
|---|
| 851 | }
|
|---|
| 852 | case intel :
|
|---|
| 853 | if [ $(property-set).get <toolset-intel:platform> ] = win
|
|---|
| 854 | {
|
|---|
| 855 | tag += iw ;
|
|---|
| 856 | }
|
|---|
| 857 | else
|
|---|
| 858 | {
|
|---|
| 859 | tag += il ;
|
|---|
| 860 | }
|
|---|
| 861 | case kcc* : tag += kcc ;
|
|---|
| 862 | case kylix* : tag += bck ;
|
|---|
| 863 | #case metrowerks* : tag += cw ;
|
|---|
| 864 | #case mingw* : tag += mgw ;
|
|---|
| 865 | case mipspro* : tag += mp ;
|
|---|
| 866 | case msvc* : tag += vc ;
|
|---|
| 867 | case qcc* : tag += qcc ;
|
|---|
| 868 | case sun* : tag += sw ;
|
|---|
| 869 | case tru64cxx* : tag += tru ;
|
|---|
| 870 | case vacpp* : tag += xlc ;
|
|---|
| 871 | }
|
|---|
| 872 | local version = [ MATCH <toolset.*version>([0123456789]+)[.]([0123456789]*)
|
|---|
| 873 | : $(properties) ] ;
|
|---|
| 874 | # For historical reasons, vc6.0 and vc7.0 use different naming.
|
|---|
| 875 | if $(tag) = vc
|
|---|
| 876 | {
|
|---|
| 877 | if $(version[1]) = 6
|
|---|
| 878 | {
|
|---|
| 879 | # Cancel minor version.
|
|---|
| 880 | version = 6 ;
|
|---|
| 881 | }
|
|---|
| 882 | else if $(version[1]) = 7 && $(version[2]) = 0
|
|---|
| 883 | {
|
|---|
| 884 | version = 7 ;
|
|---|
| 885 | }
|
|---|
| 886 | }
|
|---|
| 887 | # On intel, version is not added, because it does not matter and it is the
|
|---|
| 888 | # version of vc used as backend that matters. Ideally, we should encode the
|
|---|
| 889 | # backend version but that would break compatibility with V1.
|
|---|
| 890 | if $(tag) = iw
|
|---|
| 891 | {
|
|---|
| 892 | version = ;
|
|---|
| 893 | }
|
|---|
| 894 |
|
|---|
| 895 | # On borland, version is not added for compatibility with V1.
|
|---|
| 896 | if $(tag) = bcb
|
|---|
| 897 | {
|
|---|
| 898 | version = ;
|
|---|
| 899 | }
|
|---|
| 900 |
|
|---|
| 901 | tag += $(version) ;
|
|---|
| 902 |
|
|---|
| 903 | return $(tag:J=) ;
|
|---|
| 904 | }
|
|---|
| 905 |
|
|---|
| 906 |
|
|---|
| 907 | local rule threading-tag ( name : type ? : property-set )
|
|---|
| 908 | {
|
|---|
| 909 | if <threading>multi in [ $(property-set).raw ]
|
|---|
| 910 | {
|
|---|
| 911 | return mt ;
|
|---|
| 912 | }
|
|---|
| 913 | }
|
|---|
| 914 |
|
|---|
| 915 |
|
|---|
| 916 | local rule runtime-tag ( name : type ? : property-set )
|
|---|
| 917 | {
|
|---|
| 918 | local tag = ;
|
|---|
| 919 |
|
|---|
| 920 | local properties = [ $(property-set).raw ] ;
|
|---|
| 921 | if <runtime-link>static in $(properties) { tag += s ; }
|
|---|
| 922 |
|
|---|
| 923 | # This is an ugly thing. In V1, there is code to automatically detect which
|
|---|
| 924 | # properties affect a target. So, if <runtime-debugging> does not affect gcc
|
|---|
| 925 | # toolset, the tag rules will not even see <runtime-debugging>. Similar
|
|---|
| 926 | # functionality in V2 is not implemented yet, so we just check for toolsets
|
|---|
| 927 | # known to care about runtime debugging.
|
|---|
| 928 | if ( <toolset>msvc in $(properties) ) ||
|
|---|
| 929 | ( <stdlib>stlport in $(properties) ) ||
|
|---|
| 930 | ( <toolset-intel:platform>win in $(properties) )
|
|---|
| 931 | {
|
|---|
| 932 | if <runtime-debugging>on in $(properties) { tag += g ; }
|
|---|
| 933 | }
|
|---|
| 934 |
|
|---|
| 935 | if <python-debugging>on in $(properties) { tag += y ; }
|
|---|
| 936 | if <variant>debug in $(properties) { tag += d ; }
|
|---|
| 937 | if <stdlib>stlport in $(properties) { tag += p ; }
|
|---|
| 938 | if <stdlib-stlport:iostream>hostios in $(properties) { tag += n ; }
|
|---|
| 939 |
|
|---|
| 940 | return $(tag:J=) ;
|
|---|
| 941 | }
|
|---|
| 942 |
|
|---|
| 943 |
|
|---|
| 944 | # Create a tag for the Qt library version
|
|---|
| 945 | # "<qt>4.6.0" will result in tag "qt460"
|
|---|
| 946 | local rule qt-tag ( name : type ? : property-set )
|
|---|
| 947 | {
|
|---|
| 948 | local v = [ MATCH ([0123456789]+)[.]?([0123456789]*)[.]?([0123456789]*) :
|
|---|
| 949 | [ $(property-set).get <qt> ] ] ;
|
|---|
| 950 | return qt$(v:J=) ;
|
|---|
| 951 | }
|
|---|
| 952 |
|
|---|
| 953 |
|
|---|
| 954 | # Create a tag for the address-model
|
|---|
| 955 | # <address-model>64 will simply generate "64"
|
|---|
| 956 | local rule address-model-tag ( name : type ? : property-set )
|
|---|
| 957 | {
|
|---|
| 958 | return [ $(property-set).get <address-model> ] ;
|
|---|
| 959 | }
|
|---|
| 960 |
|
|---|
| 961 |
|
|---|
| 962 | rule __test__ ( )
|
|---|
| 963 | {
|
|---|
| 964 | import assert ;
|
|---|
| 965 |
|
|---|
| 966 | local save-os = [ modules.peek os : .name ] ;
|
|---|
| 967 |
|
|---|
| 968 | modules.poke os : .name : LINUX ;
|
|---|
| 969 | assert.result "PATH=\"foo:bar:baz\"\nexport PATH\n"
|
|---|
| 970 | : path-variable-setting-command PATH : foo bar baz ;
|
|---|
| 971 | assert.result "PATH=\"foo:bar:$PATH\"\nexport PATH\n"
|
|---|
| 972 | : prepend-path-variable-command PATH : foo bar ;
|
|---|
| 973 |
|
|---|
| 974 | modules.poke os : .name : NT ;
|
|---|
| 975 | assert.result "set PATH=foo;bar;baz\n"
|
|---|
| 976 | : path-variable-setting-command PATH : foo bar baz ;
|
|---|
| 977 | assert.result "set PATH=foo;bar;%PATH%\n"
|
|---|
| 978 | : prepend-path-variable-command PATH : foo bar ;
|
|---|
| 979 |
|
|---|
| 980 | modules.poke os : .name : $(save-os) ;
|
|---|
| 981 | }
|
|---|