📄 boost-base.jam
字号:
# toolset and not variant, we specify the toolset where
# select-properties expects a variant name. The first toolset parameter
# is necessary to get the relevant-features correctly set. We supply
# the variant name as the target name, so that error messages will look
# coherent.
local name-properties
= [ select-properties $(toolset) $(toolset) $(name) : $(tool-properties) ] ;
if $(parents)
{
local parent ;
for parent in $(parents)
{
local parent-properties
= $(gBASE_PROPERTIES($(toolset),$(parent))) ;
local inherited-features
= [ unique
[ difference $(parent-properties:G) : $(name-properties:G) ]
$(gFREE_FEATURES)
$(gPATH_FEATURES)
$(gDEPENDENCY_FEATURES ] ;
local inherited-properties
= [ get-properties $(inherited-features) : $(parent-properties) ] ;
name-properties
+= $(inherited-properties) ;
}
}
gBASE_PROPERTIES($(toolset),$(name)) = [ sort $(name-properties) ] ;
}
}
# select-properties toolset variant target : qualified-properties...
#
# Returns
rule select-properties ( toolset variant target ? : qualified-properties * )
{
local relevant_features = [ relevant-features $(toolset) ] ;
local normalized = [ normalize-properties $(>) ] ;
# Classify properties by the specificity of their qualification.
# First, grab those that apply to this toolset, or all toolsets
local this_toolset = [ get-values <$(toolset)> : $(normalized) ] ;
local all_toolsets = [ get-values <*> : $(normalized) ] ;
local 0-stars = [ get-values <$(variant)> : $(this_toolset) ] ;
local 1-stars = [ get-values <*> : $(this_toolset) ] [ get-values <$(variant)> : $(all_toolsets) ] ;
local 2-stars = [ get-values <*> : $(all_toolsets) ] ;
# Select feature names from the features relevant to the toolset.
local features = [ intersection $(relevant_features)
: $(0-stars:G) $(1-stars:G) $(2-stars:G) ] ;
local result f ;
for f in $(features)
{
local is_free = [ intersection $(f) : $(gFREE_FEATURES) ] ;
# Go through the $(n-stars) lists from most- to least- specific;
# collect the best set of values of a simple feature, and /all/
# values of a free feature.
local r n ;
for n in 0 1 2
{
if ! $(r) || $(is_free)
{
r += [ get-values $(f) : $($(n)-stars) ] ;
}
}
r = [ unique $(r) ] ;
if $(r[2]) && ! $(is_free) # Check for conflicting simple-feature requests
{
EXIT "Error: Ambiguous properties requested for"
$(target) <$(toolset)><$(variant)> ":" $(f)$(r) ;
}
result += $(f)$(r) ;
}
return $(result) ;
}
# get toolset features
SEARCH on <jam-module>features.jam = $(BOOST_BUILD_PATH) ;
include <jam-module>features.jam ;
# ungrist-properties properties...
#
# Transforms a list of properties of the form:
# <feature1>value1 [<feature2>value2... ]
# into a list of the form:
# feature1-value1 feature2-value2
# suitable for use as directory path elements
#
rule ungrist-properties
{
local property ;
local result = ;
for property in $(<)
{
result += $(gUNGRISTED($(property:G)))-$(property:G=) ;
}
return $(result) ;
}
# set-target-variables target
#
# attach global build tool settings to the given file-target, so that they can be
# used in build actions.
rule set-target-variables ( targets * )
{
local s ;
for s in $(gTARGET_VARIABLES)
{
$(s) on $(targets) = $($(s)) ;
# set up dependencies if the target is a "top-level" target
if ( $(s) in $(gDEPENDENCY_VARIABLES($(gCURRENT_TOOLSET))) ) && $(gTARGET_TYPE($(<)))
{
DEPENDS $(targets) : $($(s)) ;
}
}
local libpath = [ get-properties <library-path> : $(gBUILD_PROPERTIES) ] ;
gRUN_PATH($(targets)) += $(libpath:G=) ;
gRUN_LD_LIBRARY_PATH($(targets)) += $(libpath:G=) ;
}
# For path properties, add a relative path prefix to the value as
# necessary to locate the path relative to the given subproject
# directory.
rule fixup-path-properties ( properties * : subproject-directory ? )
{
local result ;
for local p in $(properties)
{
if $(p:G) in $(gPATH_FEATURES)
{
# If the path property value is project-relative, re-root
# it appropriately for that project
local parse-project = [ MATCH ^@([^/$(SLASH)]+)[/$(SLASH)]?(.*) : $(p:G=) ] ;
if $(parse-project)
{
local project = $(parse-project[1]) ;
local subproject = $(parse-project[2]) ;
p = [ root-paths $(subproject:G=$(p:G)) : $(gPROJECT($(project))) ] ;
}
else if $(subproject-directory) # re-root it relative to this directory
{
p = [ root-paths $(p) : $(subproject-directory) ] ;
}
}
result += $(p) ;
}
return $(result) ;
}
# remove-incompatible-builds requirements... : build-request... : target-name
#
# If any element of requirements has the same grist but a different ungristed
# part as any element of build-request, exits with an error report about target-name
rule remove-incompatible-builds ( requirements * : build-request * : target-name + )
{
local all-properties = [ unique $(<) $(>) ] ;
local all-features = $(all-properties:G) ;
local unique-features = [ unique $(all-features) ] ;
if $(all-features) != $(unique-features)
{
local result ;
local skip ;
for local p in $(build-request)
{
# if a feature of the build request is also in the
# requirements, but with differing value(s)
if ( $(p:G) in $(requirements:G) )
&& ! ( $(p) in $(requirements) )
{
# decide what to do.
local value = [ get-values $(p:G) : $(requirements) ] ;
if $(value[2])
{
EXIT Unexpectedly found multiple build requests
for feature $(p:G) with values $(values) ;
}
local requested = [ split-path $(p:G=) ] ;
if $(requested[2])
{
local skipped = [ difference $(requested) : $(value) ] ;
if ! $(gNOWARN_INCOMPATIBLE_BUILDS)
{
ECHO $(target-name) requires $(p:G)$(value),
skipping requested build configuration(s) $(p:G)$(skipped). ;
}
result += $(p:G)$(value) ;
}
else
{
if ! $(gNOWARN_INCOMPATIBLE_BUILDS)
{
ECHO skipping $(target-name) due to incompatible
build requirements $(p:G)$(value). ;
}
skip = true ;
}
}
else
{
result += $(p) ;
}
}
if $(skip)
{
build-request = SKIP ;
}
else
{
build-request = $(result) ;
}
}
return $(build-request) ;
}
# multiply-property-sets [<feature>value1[/value2...] ]...
#
# Expands a set of (possibly multi-valued) properties into all the combinations
# that include every feature in the set. Each combination is given as a path,
# with the slash separating the properties, sorted in feature order.
rule multiply-property-sets
{
local result p ;
for p in [ sort $(<) ]
{
# expand any multi-valued simple features from the default build
local multiple = [ distribute-feature $(p) ] ;
# concatenation produces a product, so the tree branches for each
# multi-valued simple feature.
result = $(result)/$(multiple) ;
result ?= $(multiple) ; # this trick allows us to get started
}
return $(result) ;
}
# Return a list consisting of all the elements of properties which
# aren't the defaults for their features.
rule remove-default-properties ( properties * )
{
return [ difference $(properties) : [ feature-default $(properties:G) ] ] ;
}
# make-path-property-sets base-path : common-properties : property-sets
#
# Returns a list of paths where the initial ungristed part of each element is a
# relative path to a subvariant directory from a target's build root and the
# rest of the element is a slash-separated property set describing the
# properties of the target to be built.
#
# Each path returned is base-path extended by one of the ungristed property-sets
# (or just the base-path if no property-sets are supplied). Each property set
# returned is formed by extending common-properties with one of the property-sets.
#
# For example,
#
# make-path-property-sets gcc/release : <p1>v1 : <p2>v2/<p3>v3
#
# returns this single-element list:
#
# gcc/release/p2-v2/p3-v3/<p1>v1/<p2>v2/<p3>v3
# |<-- subvariant path -->|<-- property-set -->|
rule make-path-property-sets ( base-path : common-properties * : property-sets * )
{
local result ;
local s ;
for s in $(property-sets)
{
local x =
# directory components
$(base-path)
[ ungrist-properties
[ remove-default-properties [ split-path $(s) ] ]
]
# properties
$(common-properties) $(s)
;
result += $(x:J=$(SLASH)) ;
}
# if there were no overrides, just add the base variant and properties
if ! $(result)
{
result = [ join $(base-path) $(common-properties) : $(SLASH) ] ;
}
return $(result) ;
}
# segregate-overrides override-var base-var
#
# removes elements of $(base-var) from $(override-var), and removes elements
# whose grist is in $(override-var:G) from $(base-var).
rule segregate-overrides
{
$(<) = [ difference $($(<)) : $($(>)) ] ;
# Which features, and thus properties, of the base variant are we keeping?
local kept-features = [ difference $($(>):G) : $($(<):G) ] ;
$(>) = [ get-properties $(kept-features) : $($(>)) ] ;
}
# If any single-valued free-feature appears more than once in free-property...,
# exit with an appropriate error message.
rule report-free-property-conflicts ( free-property * : target + )
{
local p = [ get-properties $(gSINGLE_VALUED_FREE_FEATURES) : $(free-property) ] ;
local f = [ unique $(p:G) ] ;
if $(p:G) != $(f)
{
EXIT $(>): multiple values for single-valued free feature(s)
[ difference $(p:G) $(f) ] requested ;
}
}
# Returns a list of path-property-sets (see make-path-property-sets above) for
# all build configurations based on the given toolset, requirements, and
# build-request. Target-name is just used for error reporting.
rule expand-build-request ( toolset variant target : raw-requirements * : raw-build-request * )
{
# grab the requirements and BUILD-request relevant to this toolset and variant
local requirements = [ select-properties $(toolset) $(variant) : $(raw-requirements) ] ;
local build-request = [ select-properties $(toolset) $(variant) : $(raw-build-request) ] ;
# Separate the free features (e.g. <define>, <undef>, <include>) from the others
local free-properties = [ segregate-free-properties requirements build-request ] ;
# Check for conflicts
report-free-property-conflicts $(free-properties) : $(target) ;
build-request = [ remove-incompatible-builds $(requirements)
: $(build-request) : $(target) ] ;
if $(build-request) != SKIP
{
# Get the base variant for the toolset. Includes free features
local base-properties = $(gBASE_PROPERTIES($(toolset),$(variant))) ;
# Which properties will override settings in the base variant?
local override-properties = [ unique $(requirements) $(build-request) ] ;
segregate-overrides override-properties : base-properties ;
# Which features will pick up a default value because they are not in
# the base variant or in the overrides?
local relevant-features = [ relevant-features $(toolset) ] ;
local override-free-features = [ intersection $(gSINGLE_VALUED_FREE_FEATURES)
: $(free-properties:G) ] ;
local defaulted-features = [ difference $(relevant-features)
: $(override-properties:G) $(base-properties:G)
$(override-free-features)
] ;
local defaulted-properties = [ feature-default $(defaulted-features) ] ;
# VP: defaulted-properties have the form <feature>value and there's 1 value.
# Hence, each element of defaulted-properties will be part of each
# component of override-sets and will be a part of each property-set
# returned. By segregating them, the result is changed in only one
# way: free properties does not show up in target path.
local defaulted-free-properties = [ segregate-free-properties defaulted-properties ] ;
#
# Allow <default> properties and rules to take effect.
#
local default-requirements = [ get-values <default> : $(free-properties) ] ;
defaulted-properties = [ replace-properties $(defaulted-properties)
: [ select-gristed $(default-requirements) ] ] ;
local non-defaults = $(requirements) $(build-request) $(free-properties) ;
for local r in [ select-ungristed $(default-requirements) ]
{
local x = [ $(r) $(toolset) $(variant) : $(non-defaults) ] ;
# ECHO $(r) yields $(x) ;
# ECHO defaulted-properties= $(defaulted-properties) ;
defaulted-properties = [
replace-properties $(defaulted-properties) : $(x) ] ;
}
# In case any defaults should conflict with the requirements,
# force them to match up.
defaulted-properties = [ replace-properties $(defaulted-properties) : $(requirements) ] ;
# form override property sets of the form (property1[/property2...] )+,
# sorted in feature order. These represent the properties of subvariants
# that differ from the base variant
local override-sets
= [ multiply-property-sets $(override-properties) $(defaulted-properties) ] ;
# return path-property-sets corresponding to each (sub)variant build
# described.
return [ make-path-property-sets
$(toolset)$(SLASH)$(variant)
: [ fixup-path-properties
$(base-properties)
$(free-properties)
$(defaulted-free-properties)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -