|
Packit |
58578d |
# Copyright 2003, 2005 Dave Abrahams
|
|
Packit |
58578d |
# Copyright 2005, 2006 Rene Rivera
|
|
Packit |
58578d |
# Copyright 2005 Toon Knapen
|
|
Packit |
58578d |
# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
|
|
Packit |
58578d |
# Distributed under the Boost Software License, Version 1.0.
|
|
Packit |
58578d |
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Provides actions common to all toolsets, such as creating directories and
|
|
Packit |
58578d |
# removing files.
|
|
Packit |
58578d |
|
|
Packit |
58578d |
import os ;
|
|
Packit |
58578d |
import modules ;
|
|
Packit |
58578d |
import utility ;
|
|
Packit |
58578d |
import print ;
|
|
Packit |
58578d |
import type ;
|
|
Packit |
58578d |
import feature ;
|
|
Packit |
58578d |
import errors ;
|
|
Packit |
58578d |
import path ;
|
|
Packit |
58578d |
import sequence ;
|
|
Packit |
58578d |
import toolset ;
|
|
Packit |
58578d |
import virtual-target ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
.debug-configuration = true ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
if [ MATCH (--show-configuration) : [ modules.peek : ARGV ] ]
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
.show-configuration = true ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Configurations
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# The following class helps to manage toolset configurations. Each configuration
|
|
Packit |
58578d |
# has a unique ID and one or more parameters. A typical example of a unique ID
|
|
Packit |
58578d |
# is a condition generated by 'common.check-init-parameters' rule. Other kinds
|
|
Packit |
58578d |
# of IDs can be used. Parameters may include any details about the configuration
|
|
Packit |
58578d |
# like 'command', 'path', etc.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# A toolset configuration may be in one of the following states:
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# - registered
|
|
Packit |
58578d |
# Configuration has been registered (e.g. explicitly or by auto-detection
|
|
Packit |
58578d |
# code) but has not yet been marked as used, i.e. 'toolset.using' rule has
|
|
Packit |
58578d |
# not yet been called for it.
|
|
Packit |
58578d |
# - used
|
|
Packit |
58578d |
# Once called 'toolset.using' rule marks the configuration as 'used'.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# The main difference between the states above is that while a configuration is
|
|
Packit |
58578d |
# 'registered' its options can be freely changed. This is useful in particular
|
|
Packit |
58578d |
# for autodetection code - all detected configurations may be safely overwritten
|
|
Packit |
58578d |
# by user code.
|
|
Packit |
58578d |
|
|
Packit |
58578d |
class configurations
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
import errors ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule __init__ ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Registers a configuration.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# Returns 'true' if the configuration has been added and an empty value if
|
|
Packit |
58578d |
# it already exists. Reports an error if the configuration is 'used'.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule register ( id )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(id) in $(self.used)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
errors.error "common: the configuration '$(id)' is in use" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local retval ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if ! $(id) in $(self.all)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
self.all += $(id) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Indicate that a new configuration has been added.
|
|
Packit |
58578d |
retval = true ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return $(retval) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Mark a configuration as 'used'.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# Returns 'true' if the state of the configuration has been changed to
|
|
Packit |
58578d |
# 'used' and an empty value if it the state has not been changed. Reports an
|
|
Packit |
58578d |
# error if the configuration is not known.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule use ( id )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if ! $(id) in $(self.all)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
errors.error "common: the configuration '$(id)' is not known" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local retval ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if ! $(id) in $(self.used)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
self.used += $(id) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Indicate that the configuration has been marked as 'used'.
|
|
Packit |
58578d |
retval = true ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return $(retval) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Return all registered configurations.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule all ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(self.all) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Return all used configurations.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule used ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(self.used) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Returns the value of a configuration parameter.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule get ( id : param )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(self.$(param).$(id)) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Sets the value of a configuration parameter.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule set ( id : param : value * )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
self.$(param).$(id) = $(value) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# The rule for checking toolset parameters. Trailing parameters should all be
|
|
Packit |
58578d |
# parameter name/value pairs. The rule will check that each parameter either has
|
|
Packit |
58578d |
# a value in each invocation or has no value in each invocation. Also, the rule
|
|
Packit |
58578d |
# will check that the combination of all parameter values is unique in all
|
|
Packit |
58578d |
# invocations.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# Each parameter name corresponds to a subfeature. This rule will declare a
|
|
Packit |
58578d |
# subfeature the first time a non-empty parameter value is passed and will
|
|
Packit |
58578d |
# extend it with all the values.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# The return value from this rule is a condition to be used for flags settings.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule check-init-parameters ( toolset requirement * : * )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local sig = $(toolset) ;
|
|
Packit |
58578d |
local condition = <toolset>$(toolset) ;
|
|
Packit |
58578d |
local subcondition ;
|
|
Packit |
58578d |
for local index in 2 3 4 5 6 7 8 9
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local name = $($(index)[1]) ;
|
|
Packit |
58578d |
local value = $($(index)[2]) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if $(value)-is-not-empty
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
condition = $(condition)-$(value) ;
|
|
Packit |
58578d |
if $(.had-unspecified-value.$(toolset).$(name))
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
errors.user-error
|
|
Packit |
58578d |
"$(toolset) initialization: parameter '$(name)'"
|
|
Packit |
58578d |
"inconsistent" : "no value was specified in earlier"
|
|
Packit |
58578d |
"initialization" : "an explicit value is specified now" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
# The below logic is for intel compiler. It calls this rule with
|
|
Packit |
58578d |
# 'intel-linux' and 'intel-win' as toolset, so we need to get the
|
|
Packit |
58578d |
# base part of toolset name. We can not pass 'intel' as toolset
|
|
Packit |
58578d |
# because in that case it will be impossible to register versionless
|
|
Packit |
58578d |
# intel-linux and intel-win toolsets of a specific version.
|
|
Packit |
58578d |
local t = $(toolset) ;
|
|
Packit |
58578d |
local m = [ MATCH ([^-]*)- : $(toolset) ] ;
|
|
Packit |
58578d |
if $(m)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
t = $(m[1]) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
if ! $(.had-value.$(toolset).$(name))
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if ! $(.declared-subfeature.$(t).$(name))
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
feature.subfeature toolset $(t) : $(name) : : propagated ;
|
|
Packit |
58578d |
.declared-subfeature.$(t).$(name) = true ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
.had-value.$(toolset).$(name) = true ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
feature.extend-subfeature toolset $(t) : $(name) : $(value) ;
|
|
Packit |
58578d |
subcondition += <toolset-$(t):$(name)>$(value) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(.had-value.$(toolset).$(name))
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
errors.user-error
|
|
Packit |
58578d |
"$(toolset) initialization: parameter '$(name)'"
|
|
Packit |
58578d |
"inconsistent" : "an explicit value was specified in an"
|
|
Packit |
58578d |
"earlier initialization" : "no value is specified now" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
.had-unspecified-value.$(toolset).$(name) = true ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
sig = $(sig)$(value:E="")- ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
# We also need to consider requirements on the toolset as we can
|
|
Packit |
58578d |
# configure the same toolset multiple times with different options that
|
|
Packit |
58578d |
# are selected with the requirements.
|
|
Packit |
58578d |
if $(requirement)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
sig = $(sig)$(requirement:J=,) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
if $(sig) in $(.all-signatures)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local message =
|
|
Packit |
58578d |
"duplicate initialization of $(toolset) with the following parameters: " ;
|
|
Packit |
58578d |
for local index in 2 3 4 5 6 7 8 9
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local p = $($(index)) ;
|
|
Packit |
58578d |
if $(p)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
message += "$(p[1]) = $(p[2]:E=<unspecified>)" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
message += "previous initialization at $(.init-loc.$(sig))" ;
|
|
Packit |
58578d |
errors.user-error
|
|
Packit |
58578d |
$(message[1]) : $(message[2]) : $(message[3]) : $(message[4]) :
|
|
Packit |
58578d |
$(message[5]) : $(message[6]) : $(message[7]) : $(message[8]) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
.all-signatures += $(sig) ;
|
|
Packit |
58578d |
.init-loc.$(sig) = [ errors.nearest-user-location ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# If we have a requirement, this version should only be applied under that
|
|
Packit |
58578d |
# condition. To accomplish this we add a toolset requirement that imposes
|
|
Packit |
58578d |
# the toolset subcondition, which encodes the version.
|
|
Packit |
58578d |
if $(requirement)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local r = <toolset>$(toolset) $(requirement) ;
|
|
Packit |
58578d |
r = $(r:J=,) ;
|
|
Packit |
58578d |
toolset.add-requirements $(r):$(subcondition) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# We add the requirements, if any, to the condition to scope the toolset
|
|
Packit |
58578d |
# variables and options to this specific version.
|
|
Packit |
58578d |
condition += $(requirement) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if $(.show-configuration)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
ECHO notice: $(condition) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return $(condition:J=/) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# A helper rule to get the command to invoke some tool. If
|
|
Packit |
58578d |
# 'user-provided-command' is not given, tries to find binary named 'tool' in
|
|
Packit |
58578d |
# PATH and in the passed 'additional-path'. Otherwise, verifies that the first
|
|
Packit |
58578d |
# element of 'user-provided-command' is an existing program.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# This rule returns the command to be used when invoking the tool. If we can not
|
|
Packit |
58578d |
# find the tool, a warning is issued. If 'path-last' is specified, PATH is
|
|
Packit |
58578d |
# checked after 'additional-paths' when searching for 'tool'.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule get-invocation-command-nodefault ( toolset : tool :
|
|
Packit |
58578d |
user-provided-command * : additional-paths * : path-last ? )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local command ;
|
|
Packit |
58578d |
if ! $(user-provided-command)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
command = [ find-tool $(tool) : $(additional-paths) : $(path-last) ] ;
|
|
Packit |
58578d |
if ! $(command) && $(.debug-configuration)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
ECHO warning: toolset $(toolset) initialization: can not find tool
|
|
Packit |
58578d |
$(tool) ;
|
|
Packit |
58578d |
ECHO warning: initialized from [ errors.nearest-user-location ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
command = [ check-tool $(user-provided-command) ] ;
|
|
Packit |
58578d |
if ! $(command) && $(.debug-configuration)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
ECHO warning: toolset $(toolset) initialization: ;
|
|
Packit |
58578d |
ECHO warning: can not find user-provided command
|
|
Packit |
58578d |
'$(user-provided-command)' ;
|
|
Packit |
58578d |
ECHO warning: initialized from [ errors.nearest-user-location ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return $(command) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Same as get-invocation-command-nodefault, except that if no tool is found,
|
|
Packit |
58578d |
# returns either the user-provided-command, if present, or the 'tool' parameter.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule get-invocation-command ( toolset : tool : user-provided-command * :
|
|
Packit |
58578d |
additional-paths * : path-last ? )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local result = [ get-invocation-command-nodefault $(toolset) : $(tool) :
|
|
Packit |
58578d |
$(user-provided-command) : $(additional-paths) : $(path-last) ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if ! $(result)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(user-provided-command)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
result = $(user-provided-command) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
result = $(tool) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return $(result) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Given an invocation command return the absolute path to the command. This
|
|
Packit |
58578d |
# works even if command has no path element and was found on the PATH.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule get-absolute-tool-path ( command )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(command:D)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(command:D) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local m = [ GLOB [ modules.peek : PATH Path path ] : $(command)
|
|
Packit |
58578d |
$(command).exe ] ;
|
|
Packit |
58578d |
return $(m[1]:D) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Attempts to find tool (binary) named 'name' in PATH and in 'additional-paths'.
|
|
Packit |
58578d |
# If found in PATH, returns 'name' and if found in additional paths, returns
|
|
Packit |
58578d |
# absolute name. If the tool is found in several directories, returns the first
|
|
Packit |
58578d |
# path found. Otherwise, returns an empty string. If 'path-last' is specified,
|
|
Packit |
58578d |
# PATH is searched after 'additional-paths'.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule find-tool ( name : additional-paths * : path-last ? )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(name:D)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return [ check-tool-aux $(name) ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
local path = [ path.programs-path ] ;
|
|
Packit |
58578d |
local match = [ path.glob $(path) : $(name) $(name).exe ] ;
|
|
Packit |
58578d |
local additional-match = [ path.glob $(additional-paths) : $(name)
|
|
Packit |
58578d |
$(name).exe ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local result ;
|
|
Packit |
58578d |
if $(path-last)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
result = $(additional-match) ;
|
|
Packit |
58578d |
if ! $(result) && $(match)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
result = $(name) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(match)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
result = $(name) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
result = $(additional-match) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
if $(result)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return [ path.native $(result[1]) ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Checks if 'command' can be found either in path or is a full name to an
|
|
Packit |
58578d |
# existing file.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
local rule check-tool-aux ( command )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(command:D)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if [ path.exists $(command) ]
|
|
Packit |
58578d |
# Both NT and Cygwin will run .exe files by their unqualified names.
|
|
Packit |
58578d |
|| ( [ os.on-windows ] && [ path.exists $(command).exe ] )
|
|
Packit |
58578d |
# Only NT will run .bat & .cmd files by their unqualified names.
|
|
Packit |
58578d |
|| ( ( [ os.name ] = NT ) && ( [ path.exists $(command).bat ] ||
|
|
Packit |
58578d |
[ path.exists $(command).cmd ] ) )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(command) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if [ GLOB [ modules.peek : PATH Path path ] : $(command) ]
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(command) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Checks that a tool can be invoked by 'command'. If command is not an absolute
|
|
Packit |
58578d |
# path, checks if it can be found in 'path'. If comand is an absolute path,
|
|
Packit |
58578d |
# check that it exists. Returns 'command' if ok or empty string otherwise.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
local rule check-tool ( xcommand + )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if [ check-tool-aux $(xcommand[1]) ] ||
|
|
Packit |
58578d |
[ check-tool-aux $(xcommand[-1]) ]
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(xcommand) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Handle common options for toolset, specifically sets the following flag
|
|
Packit |
58578d |
# variables:
|
|
Packit |
58578d |
# - CONFIG_COMMAND to $(command)
|
|
Packit |
58578d |
# - OPTIONS for compile to the value of <compileflags> in $(options)
|
|
Packit |
58578d |
# - OPTIONS for compile.c to the value of <cflags> in $(options)
|
|
Packit |
58578d |
# - OPTIONS for compile.c++ to the value of <cxxflags> in $(options)
|
|
Packit |
58578d |
# - OPTIONS for compile.fortran to the value of <fflags> in $(options)
|
|
Packit |
58578d |
# - OPTIONS for link to the value of <linkflags> in $(options)
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule handle-options ( toolset : condition * : command * : options * )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(.debug-configuration)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
ECHO notice: will use '$(command)' for $(toolset), condition
|
|
Packit |
58578d |
$(condition:E=(empty)) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# The last parameter ('unchecked') says it is OK to set flags for another
|
|
Packit |
58578d |
# module.
|
|
Packit |
58578d |
toolset.flags $(toolset) CONFIG_COMMAND $(condition) : $(command)
|
|
Packit |
58578d |
: unchecked ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
toolset.flags $(toolset).compile OPTIONS $(condition) :
|
|
Packit |
58578d |
[ feature.get-values <compileflags> : $(options) ] : unchecked ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
toolset.flags $(toolset).compile.c OPTIONS $(condition) :
|
|
Packit |
58578d |
[ feature.get-values <cflags> : $(options) ] : unchecked ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
toolset.flags $(toolset).compile.c++ OPTIONS $(condition) :
|
|
Packit |
58578d |
[ feature.get-values <cxxflags> : $(options) ] : unchecked ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
toolset.flags $(toolset).compile.fortran OPTIONS $(condition) :
|
|
Packit |
58578d |
[ feature.get-values <fflags> : $(options) ] : unchecked ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
toolset.flags $(toolset).link OPTIONS $(condition) :
|
|
Packit |
58578d |
[ feature.get-values <linkflags> : $(options) ] : unchecked ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Returns the location of the "program files" directory on a Windows platform.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule get-program-files-dir ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local ProgramFiles = [ modules.peek : ProgramFiles ] ;
|
|
Packit |
58578d |
if $(ProgramFiles)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
ProgramFiles = "$(ProgramFiles:J= )" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
ProgramFiles = "c:\\Program Files" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return $(ProgramFiles) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if [ os.name ] = NT
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
NULL_DEVICE = "NUL" ;
|
|
Packit |
58578d |
IGNORE = "2>$(NULL_DEVICE) >$(NULL_DEVICE) & setlocal" ;
|
|
Packit |
58578d |
RM = del /f /q ;
|
|
Packit |
58578d |
CP = copy /b ;
|
|
Packit |
58578d |
LN ?= $(CP) ;
|
|
Packit |
58578d |
# Ugly hack to convince copy to set the timestamp of the destination to the
|
|
Packit |
58578d |
# current time by concatenating the source with a nonexistent file. Note
|
|
Packit |
58578d |
# that this requires /b (binary) as the default when concatenating files is
|
|
Packit |
58578d |
# /a (ascii).
|
|
Packit |
58578d |
WINDOWS-CP-HACK = "+ this-file-does-not-exist-A698EE7806899E69" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else if [ os.name ] = VMS
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
NULL_DEVICE = "NL:" ;
|
|
Packit |
58578d |
PIPE = PIPE ;
|
|
Packit |
58578d |
IGNORE = "2>$(NULL_DEVICE) >$(NULL_DEVICE)" ;
|
|
Packit |
58578d |
RM = DELETE /NOCONF ;
|
|
Packit |
58578d |
CP = COPY /OVERWRITE ;
|
|
Packit |
58578d |
LN = $(CP) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
NULL_DEVICE = "/dev/null" ;
|
|
Packit |
58578d |
IGNORE = "2>$(NULL_DEVICE) >$(NULL_DEVICE)" ;
|
|
Packit |
58578d |
RM = rm -f ;
|
|
Packit |
58578d |
CP = cp ;
|
|
Packit |
58578d |
LN = ln ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
NULL_OUT = ">$(NULL_DEVICE)" ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule null-device ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(NULL_DEVICE) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule rm-command ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(RM) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule copy-command ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(CP) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if "\n" = "n"
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
# Escape characters not supported so use ugly hacks. Will not work on Cygwin
|
|
Packit |
58578d |
# - see below.
|
|
Packit |
58578d |
nl = "
|
|
Packit |
58578d |
" ;
|
|
Packit |
58578d |
q = "" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
nl = "\n" ;
|
|
Packit |
58578d |
q = "\"" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule newline-char ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return $(nl) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Returns the command needed to set an environment variable on the current
|
|
Packit |
58578d |
# platform. The variable setting persists through all following commands and is
|
|
Packit |
58578d |
# visible in the environment seen by subsequently executed commands. In other
|
|
Packit |
58578d |
# words, on Unix systems, the variable is exported, which is consistent with the
|
|
Packit |
58578d |
# only possible behavior on Windows systems.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule variable-setting-command ( variable : value )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if [ os.name ] = NT
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return "set $(variable)=$(value)$(nl)" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else if [ os.name ] = VMS
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return "$(variable) == $(q)$(value)$(q)$(nl)" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
# If we do not have escape character support in bjam, the cod below
|
|
Packit |
58578d |
# blows up on CYGWIN, since the $(nl) variable holds a Windows new-line
|
|
Packit |
58578d |
# \r\n sequence that messes up the executed export command which then
|
|
Packit |
58578d |
# reports that the passed variable name is incorrect.
|
|
Packit |
58578d |
# But we have a check for cygwin in kernel/bootstrap.jam already.
|
|
Packit |
58578d |
return "$(variable)=$(q)$(value)$(q)$(nl)export $(variable)$(nl)" ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Returns a command to sets a named shell path variable to the given NATIVE
|
|
Packit |
58578d |
# paths on the current platform.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule path-variable-setting-command ( variable : paths * )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local sep = [ os.path-separator ] ;
|
|
Packit |
58578d |
return [ variable-setting-command $(variable) : $(paths:J=$(sep)) ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Returns a command that prepends the given paths to the named path variable on
|
|
Packit |
58578d |
# the current platform.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule prepend-path-variable-command ( variable : paths * )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return [ path-variable-setting-command $(variable)
|
|
Packit |
58578d |
: $(paths) [ os.expand-variable $(variable) ] ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Return a command which can create a file. If 'r' is result of invocation, then
|
|
Packit |
58578d |
# 'r foobar' will create foobar with unspecified content. What happens if file
|
|
Packit |
58578d |
# already exists is unspecified.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule file-creation-command ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if [ os.name ] = NT
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
# A few alternative implementations on Windows:
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# 'type NUL >> '
|
|
Packit |
58578d |
# That would construct an empty file instead of a file containing
|
|
Packit |
58578d |
# a space and an end-of-line marker but it would also not change
|
|
Packit |
58578d |
# the target's timestamp in case the file already exists.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# 'type NUL > '
|
|
Packit |
58578d |
# That would construct an empty file instead of a file containing
|
|
Packit |
58578d |
# a space and an end-of-line marker but it would also destroy an
|
|
Packit |
58578d |
# already existing file by overwriting it with an empty one.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# I guess the best solution would be to allow Boost Jam to define
|
|
Packit |
58578d |
# built-in functions such as 'create a file', 'touch a file' or 'copy a
|
|
Packit |
58578d |
# file' which could be used from inside action code. That would allow
|
|
Packit |
58578d |
# completely portable operations without this kind of kludge.
|
|
Packit |
58578d |
# (22.02.2009.) (Jurko)
|
|
Packit |
58578d |
return "echo. > " ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else if [ os.name ] = VMS
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return "APPEND /NEW NL: " ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return "touch " ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Returns a command that may be used for 'touching' files. It is not a real
|
|
Packit |
58578d |
# 'touch' command on NT because it adds an empty line at the end of file but it
|
|
Packit |
58578d |
# works with source files.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule file-touch-command ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if [ os.name ] = NT
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return "echo. >> " ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else if [ os.name ] = VMS
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return "APPEND /NEW NL: " ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return "touch " ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule MkDir
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
# If dir exists, do not update it. Do this even for $(DOT).
|
|
Packit |
58578d |
NOUPDATE $(<) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if $(<) != $(DOT) && ! $($(<)-mkdir)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
# Cheesy gate to prevent multiple invocations on same dir.
|
|
Packit |
58578d |
$(<)-mkdir = true ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Schedule the mkdir build action.
|
|
Packit |
58578d |
common.mkdir $(<) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Prepare a Jam 'dirs' target that can be used to make the build only
|
|
Packit |
58578d |
# construct all the target directories.
|
|
Packit |
58578d |
DEPENDS dirs : $(<) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Recursively create parent directories. $(<:P) = $(<)'s parent & we
|
|
Packit |
58578d |
# recurse until root.
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local s = $(<:P) ;
|
|
Packit |
58578d |
if [ os.name ] = NT
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
switch $(s)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
case *: : s = ;
|
|
Packit |
58578d |
case *:\\ : s = ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if $(s)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(s) != $(<)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
DEPENDS $(<) : $(s) ;
|
|
Packit |
58578d |
MkDir $(s) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
NOTFILE $(s) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
#actions MkDir1
|
|
Packit |
58578d |
#{
|
|
Packit |
58578d |
# mkdir "$(<)"
|
|
Packit |
58578d |
#}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# The following quick-fix actions should be replaced using the original MkDir1
|
|
Packit |
58578d |
# action once Boost Jam gets updated to correctly detect different paths leading
|
|
Packit |
58578d |
# up to the same filesystem target and triggers their build action only once.
|
|
Packit |
58578d |
# (todo) (04.07.2008.) (Jurko)
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if [ os.name ] = NT
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
actions quietly mkdir
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if not exist "$(<)\\" mkdir "$(<)"
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
actions quietly mkdir
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
mkdir -p "$(<)"
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
actions piecemeal together existing Clean
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
$(RM) "$(>)"
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule copy
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
actions copy
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
$(CP) "$(>)" $(WINDOWS-CP-HACK) "$(<)"
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule RmTemps
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
actions quietly updated piecemeal together RmTemps
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
$(RM) "$(>)" $(IGNORE)
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
actions hard-link
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
$(RM) "$(<)" 2$(NULL_OUT) $(NULL_OUT)
|
|
Packit |
58578d |
$(LN) "$(>)" "$(<)" $(NULL_OUT)
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if [ os.name ] = VMS
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
actions mkdir
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
IF F$PARSE("$(<:W)") .EQS. "" THEN CREATE /DIR $(<:W)
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
actions piecemeal together existing Clean
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
$(RM) $(>:WJ=;*,);*
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
actions copy
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
$(CP) $(>:WJ=,) $(<:W)
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
actions quietly updated piecemeal together RmTemps
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
$(PIPE) $(RM) $(>:WJ=;*,);* $(IGNORE)
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
actions hard-link
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
$(PIPE) $(RM) $(>[1]:W);* $(IGNORE)
|
|
Packit |
58578d |
$(PIPE) $(LN) $(>[1]:W) $(<:W) $(NULL_OUT)
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Given a target, as given to a custom tag rule, returns a string formatted
|
|
Packit |
58578d |
# according to the passed format. Format is a list of properties that is
|
|
Packit |
58578d |
# represented in the result. For each element of format the corresponding target
|
|
Packit |
58578d |
# information is obtained and added to the result string. For all, but the
|
|
Packit |
58578d |
# literal, the format value is taken as the as string to prepend to the output
|
|
Packit |
58578d |
# to join the item to the rest of the result. If not given "-" is used as a
|
|
Packit |
58578d |
# joiner.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# The format options can be:
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# <base>[joiner]
|
|
Packit |
58578d |
# :: The basename of the target name.
|
|
Packit |
58578d |
# <toolset>[joiner]
|
|
Packit |
58578d |
# :: The abbreviated toolset tag being used to build the target.
|
|
Packit |
58578d |
# <threading>[joiner]
|
|
Packit |
58578d |
# :: Indication of a multi-threaded build.
|
|
Packit |
58578d |
# <runtime>[joiner]
|
|
Packit |
58578d |
# :: Collective tag of the build runtime.
|
|
Packit |
58578d |
# <version:/version-feature | X.Y[.Z]/>[joiner]
|
|
Packit |
58578d |
# :: Short version tag taken from the given "version-feature" in the
|
|
Packit |
58578d |
# build properties. Or if not present, the literal value as the
|
|
Packit |
58578d |
# version number.
|
|
Packit |
58578d |
# <property:/property-name/>[joiner]
|
|
Packit |
58578d |
# :: Direct lookup of the given property-name value in the build
|
|
Packit |
58578d |
# properties. /property-name/ is a regular expression. E.g.
|
|
Packit |
58578d |
# <property:toolset-.*:flavor> will match every toolset.
|
|
Packit |
58578d |
# /otherwise/
|
|
Packit |
58578d |
# :: The literal value of the format argument.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# For example this format:
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# boost_ <base> <toolset> <threading> <runtime> <version:boost-version>
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# Might return:
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# boost_thread-vc80-mt-gd-1_33.dll, or
|
|
Packit |
58578d |
# boost_regex-vc80-gd-1_33.dll
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
# The returned name also has the target type specific prefix and suffix which
|
|
Packit |
58578d |
# puts it in a ready form to use as the value from a custom tag rule.
|
|
Packit |
58578d |
#
|
|
Packit |
58578d |
rule format-name ( format * : name : type ? : property-set )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local result = "" ;
|
|
Packit |
58578d |
for local f in $(format)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
switch $(f:G)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
case <base> :
|
|
Packit |
58578d |
result += $(name:B) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case <toolset> :
|
|
Packit |
58578d |
result += [ join-tag $(f:G=) : [ toolset-tag $(name) : $(type) :
|
|
Packit |
58578d |
$(property-set) ] ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case <threading> :
|
|
Packit |
58578d |
result += [ join-tag $(f:G=) : [ threading-tag $(name) : $(type)
|
|
Packit |
58578d |
: $(property-set) ] ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case <runtime> :
|
|
Packit |
58578d |
result += [ join-tag $(f:G=) : [ runtime-tag $(name) : $(type) :
|
|
Packit |
58578d |
$(property-set) ] ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case <qt> :
|
|
Packit |
58578d |
result += [ join-tag $(f:G=) : [ qt-tag $(name) : $(type) :
|
|
Packit |
58578d |
$(property-set) ] ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case <address-model> :
|
|
Packit |
58578d |
result += [ join-tag $(f:G=) : [ address-model-tag $(name) :
|
|
Packit |
58578d |
$(type) : $(property-set) ] ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case <arch-and-model> :
|
|
Packit |
58578d |
result += [ join-tag $(f:G=) : [ arch-and-model-tag $(name) :
|
|
Packit |
58578d |
$(type) : $(property-set) ] ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case <version:*> :
|
|
Packit |
58578d |
local key = [ MATCH <version:(.*)> : $(f:G) ] ;
|
|
Packit |
58578d |
local version = [ $(property-set).get <$(key)> ] ;
|
|
Packit |
58578d |
version ?= $(key) ;
|
|
Packit |
58578d |
version = [ MATCH "^([^.]+)[.]([^.]+)[.]?([^.]*)" : $(version) ] ;
|
|
Packit |
58578d |
result += [ join-tag $(f:G=) : $(version[1])_$(version[2]) ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case <property:*> :
|
|
Packit |
58578d |
local key = [ MATCH <property:(.*)> : $(f:G) ] ;
|
|
Packit |
58578d |
local p0 = [ MATCH <($(key))> : [ $(property-set).raw ] ] ;
|
|
Packit |
58578d |
if $(p0)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local p = [ $(property-set).get <$(p0)> ] ;
|
|
Packit |
58578d |
if $(p)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
result += [ join-tag $(f:G=) : $(p) ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
case * :
|
|
Packit |
58578d |
result += $(f:G=) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return [ virtual-target.add-prefix-and-suffix $(result:J=) : $(type) :
|
|
Packit |
58578d |
$(property-set) ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local rule join-tag ( joiner ? : tag ? )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if ! $(joiner) { joiner = - ; }
|
|
Packit |
58578d |
return $(joiner)$(tag) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local rule toolset-tag ( name : type ? : property-set )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local tag = ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local properties = [ $(property-set).raw ] ;
|
|
Packit |
58578d |
switch [ $(property-set).get <toolset> ]
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
case borland* : tag += bcb ;
|
|
Packit |
58578d |
case clang* :
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
switch [ $(property-set).get <toolset-clang:platform> ]
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
case darwin : tag += clang-darwin ;
|
|
Packit |
58578d |
case linux : tag += clang ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
case como* : tag += como ;
|
|
Packit |
58578d |
case cw : tag += cw ;
|
|
Packit |
58578d |
case darwin* : tag += xgcc ;
|
|
Packit |
58578d |
case edg* : tag += edg ;
|
|
Packit |
58578d |
case gcc* :
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
switch [ $(property-set).get <toolset-gcc:flavor> ]
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
case *mingw* : tag += mgw ;
|
|
Packit |
58578d |
case * : tag += gcc ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
case intel :
|
|
Packit |
58578d |
if [ $(property-set).get <toolset-intel:platform> ] = win
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
tag += iw ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
tag += il ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
case kcc* : tag += kcc ;
|
|
Packit |
58578d |
case kylix* : tag += bck ;
|
|
Packit |
58578d |
#case metrowerks* : tag += cw ;
|
|
Packit |
58578d |
#case mingw* : tag += mgw ;
|
|
Packit |
58578d |
case mipspro* : tag += mp ;
|
|
Packit |
58578d |
case msvc* : tag += vc ;
|
|
Packit |
58578d |
case qcc* : tag += qcc ;
|
|
Packit |
58578d |
case sun* : tag += sw ;
|
|
Packit |
58578d |
case tru64cxx* : tag += tru ;
|
|
Packit |
58578d |
case vacpp* : tag += xlc ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
local version = [ MATCH <toolset.*version>([0123456789]+)[.]([0123456789]*)
|
|
Packit |
58578d |
: $(properties) ] ;
|
|
Packit |
58578d |
# For historical reasons, vc6.0 and vc7.0 use different naming.
|
|
Packit |
58578d |
if $(tag) = vc
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if $(version[1]) = 6
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
# Cancel minor version.
|
|
Packit |
58578d |
version = 6 ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else if $(version[1]) = 7 && $(version[2]) = 0
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
version = 7 ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
# On intel, version is not added, because it does not matter and it is the
|
|
Packit |
58578d |
# version of vc used as backend that matters. Ideally, we should encode the
|
|
Packit |
58578d |
# backend version but that would break compatibility with V1.
|
|
Packit |
58578d |
if $(tag) = iw
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
version = ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# On borland, version is not added for compatibility with V1.
|
|
Packit |
58578d |
if $(tag) = bcb
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
version = ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
tag += $(version) ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return $(tag:J=) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local rule threading-tag ( name : type ? : property-set )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if <threading>multi in [ $(property-set).raw ]
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return mt ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local rule runtime-tag ( name : type ? : property-set )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local tag = ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local properties = [ $(property-set).raw ] ;
|
|
Packit |
58578d |
if <runtime-link>static in $(properties) { tag += s ; }
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# This is an ugly thing. In V1, there is code to automatically detect which
|
|
Packit |
58578d |
# properties affect a target. So, if <runtime-debugging> does not affect gcc
|
|
Packit |
58578d |
# toolset, the tag rules will not even see <runtime-debugging>. Similar
|
|
Packit |
58578d |
# functionality in V2 is not implemented yet, so we just check for toolsets
|
|
Packit |
58578d |
# known to care about runtime debugging.
|
|
Packit |
58578d |
if ( <toolset>msvc in $(properties) ) ||
|
|
Packit |
58578d |
( <stdlib>stlport in $(properties) ) ||
|
|
Packit |
58578d |
( <toolset-intel:platform>win in $(properties) )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
if <runtime-debugging>on in $(properties) { tag += g ; }
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if <python-debugging>on in $(properties) { tag += y ; }
|
|
Packit |
58578d |
if <variant>debug in $(properties) { tag += d ; }
|
|
Packit |
58578d |
if <stdlib>stlport in $(properties) { tag += p ; }
|
|
Packit |
58578d |
if <stdlib-stlport:iostream>hostios in $(properties) { tag += n ; }
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return $(tag:J=) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Create a tag for the Qt library version
|
|
Packit |
58578d |
# "<qt>4.6.0" will result in tag "qt460"
|
|
Packit |
58578d |
local rule qt-tag ( name : type ? : property-set )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local v = [ MATCH ([0123456789]+)[.]?([0123456789]*)[.]?([0123456789]*) :
|
|
Packit |
58578d |
[ $(property-set).get <qt> ] ] ;
|
|
Packit |
58578d |
return qt$(v:J=) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Create a tag for the address-model
|
|
Packit |
58578d |
# <address-model>64 will simply generate "64"
|
|
Packit |
58578d |
local rule address-model-tag ( name : type ? : property-set )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return [ $(property-set).get <address-model> ] ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
# Create a tag for the architecture and model
|
|
Packit |
58578d |
# <architecture>x86 <address-model>32 would generate "x32"
|
|
Packit |
58578d |
# This relies on the fact that all architectures start with
|
|
Packit |
58578d |
# unique letters.
|
|
Packit |
58578d |
local rule arch-and-model-tag ( name : type ? : property-set )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
local architecture = [ $(property-set).get <architecture> ] ;
|
|
Packit |
58578d |
local address-model = [ $(property-set).get <address-model> ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local arch = [ MATCH ^(.) : $(architecture) ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return $(arch)$(address-model) ;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
rule __test__ ( )
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
import assert ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
local save-os = [ modules.peek os : .name ] ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
modules.poke os : .name : LINUX ;
|
|
Packit |
58578d |
assert.result "PATH=\"foo:bar:baz\"\nexport PATH\n"
|
|
Packit |
58578d |
: path-variable-setting-command PATH : foo bar baz ;
|
|
Packit |
58578d |
assert.result "PATH=\"foo:bar:$PATH\"\nexport PATH\n"
|
|
Packit |
58578d |
: prepend-path-variable-command PATH : foo bar ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
modules.poke os : .name : NT ;
|
|
Packit |
58578d |
assert.result "set PATH=foo;bar;baz\n"
|
|
Packit |
58578d |
: path-variable-setting-command PATH : foo bar baz ;
|
|
Packit |
58578d |
assert.result "set PATH=foo;bar;%PATH%\n"
|
|
Packit |
58578d |
: prepend-path-variable-command PATH : foo bar ;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
modules.poke os : .name : $(save-os) ;
|
|
Packit |
58578d |
}
|