📄 property-set.jam
字号:
# Copyright 2003 Dave Abrahams# Copyright 2003, 2004, 2005, 2006 Vladimir Prus# Distributed under the Boost Software License, Version 1.0.# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)import "class" : new ;import feature ;import path ;import project ;import property ;import sequence ;import set ;# Class for storing a set of properties.## There is 1<->1 correspondence between identity and value. No two instances# of the class are equal. To maintain this property, the 'property-set.create'# rule should be used to create new instances. Instances are immutable.## Each property is classified with regard to its effect on build results.# Incidental properties have no effect on build results, from Boost.Build's# point of view. Others are either free, or non-free and we refer to non-free# ones as 'base'. Each property belongs to exactly one of those categories.## It is possible to get a list of properties belonging to each category as# well as a list of properties with a specific attribute.## Several operations, like and refine and as-path are provided. They all use# caching whenever possible.#class property-set{ import errors ; import feature ; import path ; import property ; import property-set ; import set ; rule __init__ ( raw-properties * ) { self.raw = $(raw-properties) ; for local p in $(raw-properties) { if ! $(p:G) { errors.error "Invalid property: '$(p)'" ; } local att = [ feature.attributes $(p:G) ] ; # A feature can be both incidental and free, in which case we add it # to incidental. if incidental in $(att) { self.incidental += $(p) ; } else if free in $(att) { self.free += $(p) ; } else { self.base += $(p) ; } if dependency in $(att) { self.dependency += $(p) ; } else { self.non-dependency += $(p) ; } if [ MATCH (:) : $(p:G=) ] { self.conditional += $(p) ; } else { self.non-conditional += $(p) ; } if propagated in $(att) { self.propagated += $(p) ; } if link-incompatible in $(att) { self.link-incompatible += $(p) ; } } } # Returns Jam list of stored properties. # rule raw ( ) { return $(self.raw) ; } rule str ( ) { return "[" $(self.raw) "]" ; } # Returns properties that are neither incidental nor free. # rule base ( ) { return $(self.base) ; } # Returns free properties which are not incidental. # rule free ( ) { return $(self.free) ; } # Returns dependency properties. # rule dependency ( ) { return $(self.dependency) ; } rule non-dependency ( ) { return $(self.non-dependency) ; } rule conditional ( ) { return $(self.conditional) ; } rule non-conditional ( ) { return $(self.non-conditional) ; } # Returns incidental properties. # rule incidental ( ) { return $(self.incidental) ; } rule refine ( ps ) { if ! $(self.refined.$(ps)) { local r = [ property.refine $(self.raw) : [ $(ps).raw ] ] ; if $(r[1]) != "@error" { self.refined.$(ps) = [ property-set.create $(r) ] ; } else { self.refined.$(ps) = $(r) ; } } return $(self.refined.$(ps)) ; } rule expand ( ) { if ! $(self.expanded) { self.expanded = [ property-set.create [ feature.expand $(self.raw) ] ] ; } return $(self.expanded) ; } rule expand-composites ( ) { if ! $(self.composites) { self.composites = [ property-set.create [ feature.expand-composites $(self.raw) ] ] ; } return $(self.composites) ; } rule evaluate-conditionals ( context ? ) { context ?= $(__name__) ; if ! $(self.evaluated.$(context)) { self.evaluated.$(context) = [ property-set.create [ property.evaluate-conditionals-in-context $(self.raw) : [ $(context).raw ] ] ] ; } return $(self.evaluated.$(context)) ; } rule propagated ( ) { if ! $(self.propagated-ps) { self.propagated-ps = [ property-set.create $(self.propagated) ] ; } return $(self.propagated-ps) ; } rule link-incompatible ( ) { if ! $(self.link-incompatible-ps) { self.link-incompatible-ps = [ property-set.create $(self.link-incompatible) ] ; } return $(self.link-incompatible-ps) ; } rule run-actions ( ) { if ! $(self.run) { self.run = [ property-set.create [ feature.run-actions $(self.raw) ] ] ; } return $(self.run) ; } rule add-defaults ( ) { if ! $(self.defaults) { self.defaults = [ property-set.create [ feature.add-defaults $(self.raw) ] ] ; } return $(self.defaults) ; } rule as-path ( ) { if ! $(self.as-path) { self.as-path = [ property.as-path $(self.base) ] ; } return $(self.as-path) ; } # Computes the path to be used for a target with the given properties. # Returns a list of # - the computed path # - if the path is relative to the build directory, a value of 'true'. # rule target-path ( ) { if ! $(self.target-path) { # The <location> feature can be used to explicitly change the # location of generated targets. local l = [ get <location> ] ; if $(l) { self.target-path = $(l) ; } else { local p = [ as-path ] ; # A real ugly hack. Boost regression test system requires # specific target paths, and it seems that changing it to handle # other directory layout is really hard. For that reason, we # teach V2 to do the things regression system requires. The # value of '<location-prefix>' is prepended to the path. local prefix = [ get <location-prefix> ] ; if $(prefix) { self.target-path = [ path.join $(prefix) $(p) ] ; } else { self.target-path = $(p) ; } if ! $(self.target-path) { self.target-path = . ; } # The path is relative to build dir. self.target-path += true ; } } return $(self.target-path) ; } rule add ( ps ) { if ! $(self.added.$(ps)) { self.added.$(ps) = [ property-set.create $(self.raw) [ $(ps).raw ] ] ; } return $(self.added.$(ps)) ; } rule add-raw ( properties * ) { return [ add [ property-set.create $(properties) ] ] ; } rule link-incompatible-with ( ps ) { if ! $(.li.$(ps)) { local li1 = [ $(__name__).link-incompatible ] ; local li2 = [ $(ps).link-incompatible ] ; if [ set.equal $(li1) : $(li2) ] { .li.$(ps) = false ; } else { .li.$(ps) = true ; } } if $(.li.$(ps)) = true { return true ; } else { return ; } } # Returns all values of 'feature'. # rule get ( feature ) { if ! $(self.map-built) { # For each feature, create a member var and assign all values to it. # Since all regular member vars start with 'self', there will be no # conflicts between names. self.map-built = true ; for local v in $(self.raw) { $(v:G) += $(v:G=) ; } } return $($(feature)) ; }}# Creates a new 'property-set' instance for the given raw properties or returns# an already existing ones.#rule create ( raw-properties * ){ raw-properties = [ sequence.unique [ sequence.insertion-sort $(raw-properties) ] ] ; local key = $(raw-properties:J=-:E=) ; if ! $(.ps.$(key)) { .ps.$(key) = [ new property-set $(raw-properties) ] ; } return $(.ps.$(key)) ;}NATIVE_RULE property-set : create ;# Creates a new 'property-set' instance after checking that all properties are# valid and converting incidental properties into gristed form.#rule create-with-validation ( raw-properties * ){ property.validate $(raw-properties) ; return [ create [ property.make $(raw-properties) ] ] ;}# Creates a property-set from the input given by the user, in the context of# 'jamfile-module' at 'location'.#rule create-from-user-input ( raw-properties * : jamfile-module location ){ local specification = [ property.translate-paths $(raw-properties) : $(location) ] ; specification = [ property.translate-indirect $(specification) : $(jamfile-module) ] ; local project-id = [ project.attribute $(jamfile-module) id ] ; project-id ?= [ path.root $(location) [ path.pwd ] ] ; specification = [ property.translate-dependencies $(specification) : $(project-id) : $(location) ] ; specification = [ property.expand-subfeatures-in-conditions $(specification) ] ; specification = [ property.make $(specification) ] ; return [ property-set.create $(specification) ] ;}# Refines requirements with requirements provided by the user. Specially handles# "-<property>value" syntax in specification to remove given requirements.# - parent-requirements -- property-set object with requirements to refine.# - specification -- string list of requirements provided by the user.# - project-module -- module to which context indirect features will be# bound.# - location -- path to which path features are relative.#rule refine-from-user-input ( parent-requirements : specification * : project-module : location ){ if ! $(specification) { return $(parent-requirements) ; } else { local add-requirements ; local remove-requirements ; for local r in $(specification) { local m = [ MATCH "^-(.*)" : $(r) ] ; if $(m) { remove-requirements += $(m) ; } else { add-requirements += $(r) ; } } if $(remove-requirements) { # Need to create a property set, so that path features and indirect # features are translated just like they are in project # requirements. local ps = [ property-set.create-from-user-input $(remove-requirements) : $(project-module) $(location) ] ; parent-requirements = [ property-set.create [ set.difference [ $(parent-requirements).raw ] : [ $(ps).raw ] ] ] ; specification = $(add-requirements) ; } local requirements = [ property-set.create-from-user-input $(specification) : $(project-module) $(location) ] ; return [ $(parent-requirements).refine $(requirements) ] ; }}# Returns a property-set with an empty set of properties.#rule empty ( ){ if ! $(.empty) { .empty = [ create ] ; } return $(.empty) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -