📄 virtual-target.jam
字号:
rule actualize ( )
{
if ! $(self.actualized)
{
self.actualized = true ;
for local i in [ targets ]
{
$(i).actualize ;
}
}
}
}
# Creates a virtual target with approariate name and type from 'file'.
# If a target with that name in that project was already created, returns that already
# created target.
# FIXME: more correct way would be to compute path to the file, based on name and source location
# for the project, and use that path to determine if the target was already created.
# TODO: passing project with all virtual targets starts to be annoying.
rule from-file ( file : file-loc : project )
{
import type ; # had to do this here to break a circular dependency
# Check if we've created a target corresponding to this file.
local path = [ path.root [ path.root $(file) $(file-loc) ]
[ path.pwd ] ] ;
if $(.files.$(path))
{
return $(.files.$(path)) ;
}
else
{
local name = [ path.make $(file) ] ;
local type = [ type.type $(file) ] ;
local result ;
result = [ new file-target $(file)
: $(type)
: $(project)
: #action
: $(file-loc) ] ;
.files.$(path) = $(result) ;
return $(result) ;
}
}
# Registers a new virtual target. Checks if there's already registered target, with the same
# name, type, project and subvariant properties, and also with the same sources
# and equal action. If such target is found it is retured and 'target' is not registers.
# Otherwise, 'target' is registered and returned.
rule register ( target )
{
local signature = [ sequence.join
[ $(target).name ] : - ] ;
local result ;
for local t in $(.cache.$(signature))
{
local a1 = [ $(t).action ] ;
local a2 = [ $(target).action ] ;
if ! $(result)
{
if ! $(a1) && ! $(a2)
{
result = $(t) ;
}
else
{
if $(a1) && $(a2) && [ $(a1).action-name ] = [ $(a2).action-name ] &&
[ $(a1).sources ] = [ $(a2).sources ]
{
local ps1 = [ $(a1).properties ] ;
local ps2 = [ $(a2).properties ] ;
local p1 = [ $(ps1).base ] [ $(ps1).free ] [ $(ps1).dependency ] ;
local p2 = [ $(ps2).base ] [ $(ps2).free ] [ $(ps2).dependency ] ;
if $(p1) = $(p2)
{
result = $(t) ;
}
}
}
}
}
if ! $(result)
{
.cache.$(signature) += $(target) ;
result = $(target) ;
}
return $(result) ;
}
rule register-actual-name ( actual-name : virtual-target )
{
if $(.actual.$(actual-name))
{
local cs1 = [ $(.actual.$(actual-name)).creating-subvariant ] ;
local cs2 = [ $(virtual-target).creating-subvariant ] ;
local cmt1 = [ $(cs1).main-target ] ;
local cmt2 = [ $(cs2).main-target ] ;
local action1 = [ $(.actual.$(actual-name)).action ] ;
local action2 = [ $(virtual-target).action ] ;
local properties-added ;
local properties-removed ;
if $(action1) && $(action2)
{
local p1 = [ $(action1).properties ] ;
p1 = [ $(p1).raw ] ;
local p2 = [ $(action2).properties ] ;
p2 = [ $(p2).raw ] ;
properties-removed = [ set.difference $(p1) : $(p2) ] ;
properties-removed ?= "none" ;
properties-added = [ set.difference $(p2) : $(p1) ] ;
properties-added ?= "none" ;
}
errors.error "Duplicate name of actual target:" $(actual-name)
: "previous virtual target" [ $(.actual.$(actual-name)).str ]
: "created from" [ $(cmt1).full-name ]
: "another virtual target" [ $(virtual-target).str ]
: "created from" [ $(cmt2).full-name ]
: "added properties: " $(properties-added)
: "removed properties: " $(properties-removed) ;
}
else
{
.actual.$(actual-name) = $(virtual-target) ;
}
}
# Traverses the dependency graph of 'target' and return all targets that will
# be created before this one is created. If root of some dependency graph is
# found during traversal, it's either included or not, dependencing of the
# value of 'include-roots'. In either case, sources of root are not traversed.
rule traverse ( target : include-roots ? : include-sources ? )
{
local result ;
if [ $(target).action ]
{
local action = [ $(target).action ] ;
# This includes 'target' as well
result += [ $(action).targets ] ;
for local t in [ $(action).sources ]
{
if ! [ $(t).root ]
{
result += [ traverse $(t) : $(include-roots) : $(include-sources) ] ;
}
else if $(include-roots)
{
result += $(t) ;
}
}
}
else if $(include-sources)
{
result = $(target) ;
}
return $(result) ;
}
# Takes an 'action' instances and creates new instance of it
# and all produced target. The rule-name and properties are set
# to 'new-rule-name' and 'new-properties', if those are specified.
# Returns the cloned action.
rule clone-action ( action : new-project : new-action-name ? : new-properties ? )
{
if ! $(new-action-name)
{
new-action-name = [ $(action).action-name ] ;
}
if ! $(new-properties)
{
new-properties = [ $(action).properties ] ;
}
local action-class = [ modules.peek $(action) : __class__ ] ;
local cloned-action = [ class.new $(action-class)
[ $(action).sources ] : $(new-action-name) : $(new-properties) ] ;
local cloned-targets ;
for local target in [ $(action).targets ]
{
local n = [ $(target).name ] ;
# Don't modify the name of the produced targets.Strip the directory f
local cloned-target = [ class.new file-target $(n) exact : [ $(target).type ]
: $(new-project) : $(cloned-action) ] ;
local d = [ $(target).dependencies ] ;
if $(d)
{
$(cloned-target).depends $(d) ;
}
$(cloned-target).root [ $(target).root ] ;
$(cloned-target).creating-subvariant [ $(target).creating-subvariant ] ;
cloned-targets += $(cloned-target) ;
}
return $(cloned-action) ;
}
class subvariant
{
import sequence ;
import type ;
rule __init__ ( main-target # The instance of main-target class
: property-set # Properties requested for this target
: sources *
: build-properties # Actually used properties
: sources-usage-requirements # Properties propagated from sources
: created-targets * ) # Top-level created targets
{
self.main-target = $(main-target) ;
self.properties = $(property-set) ;
self.sources = $(sources) ;
self.build-properties = $(build-properties) ;
self.sources-usage-requirements = $(sources-usage-requirements) ;
self.created-targets = $(created-targets) ;
# Pre-compose the list of other dependency graphs, on which this one
# depends
local deps = [ $(build-properties).get <implicit-dependency> ] ;
for local d in $(deps)
{
self.other-dg += [ $(d:G=).creating-subvariant ] ;
}
self.other-dg = [ sequence.unique $(self.other-dg) ] ;
}
rule main-target ( )
{
return $(self.main-target) ;
}
rule created-targets ( )
{
return $(self.created-targets) ;
}
rule requested-properties ( )
{
return $(self.properties) ;
}
rule build-properties ( )
{
return $(self.build-properties) ;
}
rule sources-usage-requirements ( )
{
return $(self.sources-usage-requirements) ;
}
rule set-usage-requirements ( usage-requirements )
{
self.usage-requirements = $(usage-requirements) ;
}
rule usage-requirements ( )
{
return $(self.usage-requirements) ;
}
# Returns all targets referenced by this subvariant,
# either directly or indirectly, and
# either as sources, or as dependency properties.
# Targets referred with dependency property are returned a properties,
# not targets.
rule all-referenced-targets ( )
{
# Find directly referenced targets.
local deps = [ $(self.build-properties).dependency ] ;
local all-targets = $(self.sources) $(deps) ;
# Find other subvariants.
local r ;
for local t in $(all-targets)
{
r += [ $(t:G=).creating-subvariant ] ;
}
r = [ sequence.unique $(r) ] ;
for local s in $(r)
{
if $(s) != $(__name__)
{
all-targets += [ $(s).all-referenced-targets ] ;
}
}
return $(all-targets) ;
}
# Returns the properties which specify implicit include paths to
# generated headers. This traverses all targets in this subvariant,
# and subvariants referred by <implcit-dependecy>properties.
# For all targets which are of type 'target-type' (or for all targets,
# if 'target-type' is not specified), the result will contain
# <$(feature)>path-to-that-target.
rule implicit-includes ( feature : target-type ? )
{
local key = ii$(feature)-$(target-type:E="") ;
if ! $($(key))-is-nonempty
{
local target-paths = [ all-target-directories $(target-type) ] ;
target-paths = [ sequence.unique $(target-paths) ] ;
local result = $(target-paths:G=$(feature)) ;
if ! $(result)
{
result = "" ;
}
$(key) = $(result) ;
}
if $($(key)) = ""
{
return ;
}
else
{
return $($(key)) ;
}
}
rule all-target-directories ( target-type ? )
{
if ! $(self.target-directories)
{
compute-target-directories $(target-type) ;
}
return $(self.target-directories) ;
}
rule compute-target-directories ( target-type ? )
{
local result ;
for local t in $(self.created-targets)
{
if $(target-type) && ! [ type.is-derived [ $(t).type ] $(target-type) ]
{
# Skip target which is of wrong type.
}
else
{
result = [ sequence.merge $(result) : [ $(t).path ] ] ;
}
}
for local d in $(self.other-dg)
{
result += [ $(d).all-target-directories $(target-type) ] ;
}
self.target-directories = $(result) ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -