mirror of
https://github.com/boostorg/build.git
synced 2026-02-15 13:02:11 +00:00
Introduce the 'property-set' class, which is used instead of
plain old lists of properties in most cases where we need property sets. The changes are too numerous and mostly automatic to comment each one. [SVN r17305]
This commit is contained in:
@@ -6,6 +6,7 @@ import project ;
|
||||
import sequence ;
|
||||
import modules ;
|
||||
import feature ;
|
||||
import property-set ;
|
||||
import build-request ;
|
||||
import errors : error ;
|
||||
|
||||
@@ -109,8 +110,9 @@ if $(expanded)
|
||||
for local p in $(expanded)
|
||||
{
|
||||
for local t in $(targets)
|
||||
{
|
||||
$(t).direct-build-request [ feature.split $(p) ] ;
|
||||
{
|
||||
$(t).direct-build-request
|
||||
[ property-set.create [ feature.split $(p) ] ] ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +120,8 @@ if $(expanded)
|
||||
{
|
||||
for local t in $(targets)
|
||||
{
|
||||
virtual-targets += [ $(t).generate [ feature.split $(p) ] ] ;
|
||||
virtual-targets += [ $(t).generate
|
||||
[ property-set.create [ feature.split $(p) ] ] ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,7 +129,7 @@ else
|
||||
{
|
||||
for local t in $(targets)
|
||||
{
|
||||
virtual-targets += [ $(t).generate ] ;
|
||||
virtual-targets += [ $(t).generate [ property-set.empty ] ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -293,8 +293,9 @@ rule lib-generator ( )
|
||||
{
|
||||
composing-generator.__init__ lib-generator : : LIB : <main-target-type>LIB ;
|
||||
|
||||
rule run ( project name ? : properties * : sources * )
|
||||
rule run ( project name ? : property-set : sources * )
|
||||
{
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
# Determine the needed target type
|
||||
local actual-type ;
|
||||
if <search> in $(properties:G) || <name> in $(properties:G)
|
||||
@@ -311,8 +312,8 @@ rule lib-generator ( )
|
||||
}
|
||||
# Construct the target. Pass 'allow-composing', since generators for
|
||||
# library types are composing and we need to find them.
|
||||
return [ generators.construct $(project) $(name) : $(actual-type) : $(properties)
|
||||
: $(sources) : allow-composing ] ;
|
||||
return [ generators.construct $(project) $(name) : $(actual-type)
|
||||
: $(property-set) : $(sources) : allow-composing ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ rule generator (
|
||||
# in returned set must be present in build properties if this
|
||||
# generator is to be used. If result has grist-only element,
|
||||
# that build properties must include some value of that feature.
|
||||
# XXX: remove this method?
|
||||
rule requirements ( )
|
||||
{
|
||||
return $(self.requirements) ;
|
||||
@@ -173,7 +174,7 @@ rule generator (
|
||||
# Returns a number telling how good generator's properties match
|
||||
# the passed properties, or empty list if generator can't be run
|
||||
# at all.
|
||||
rule match-rank ( properties * )
|
||||
rule match-rank ( property-set )
|
||||
{
|
||||
# See if generator's requirements are satisfied by 'properties'.
|
||||
# Treat feature name in requirements (i.e. grist-only element),
|
||||
@@ -192,7 +193,8 @@ rule generator (
|
||||
features += $(r) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
if $(requirements) in $(properties) && $(features) in $(properties:G)
|
||||
{
|
||||
return [ sequence.length [ set.intersection
|
||||
@@ -217,7 +219,7 @@ rule generator (
|
||||
rule run ( project # Project for which the targets are generated
|
||||
name ? # Determines the name of 'name' attribute for
|
||||
# all generated targets. See 'generated-targets' method.
|
||||
: properties * # Desired properties for generated targets.
|
||||
: property-set # Desired properties for generated targets.
|
||||
: sources + : # Source targets.
|
||||
multiple ? # Allows the rule to run generator several times and return
|
||||
# multiple targets of the same type. When this argument is not
|
||||
@@ -230,7 +232,7 @@ rule generator (
|
||||
{
|
||||
generators.dout [ indent ] " generator" $(self.id) ;
|
||||
generators.dout [ indent ] " multiple:" $(mutliple) ;
|
||||
|
||||
|
||||
# Ordinary generators take only one source targets
|
||||
if $(sources[2])
|
||||
{
|
||||
@@ -248,7 +250,7 @@ rule generator (
|
||||
local bypassed = ;
|
||||
|
||||
convert-to-consumable-types $(project) $(name) :
|
||||
$(properties) : $(sources) : $(multiple)
|
||||
$(property-set) : $(sources) : $(multiple)
|
||||
:
|
||||
: consumed bypassed ;
|
||||
|
||||
@@ -256,7 +258,7 @@ rule generator (
|
||||
if $(consumed)
|
||||
{
|
||||
result = [ construct-result $(consumed) : $(project) $(name)
|
||||
: $(properties) ] ;
|
||||
: $(property-set) ] ;
|
||||
}
|
||||
|
||||
if $(result)
|
||||
@@ -301,7 +303,7 @@ rule generator (
|
||||
# Otherwise, might contain several targets with the type of
|
||||
# $(self.source-types[1])
|
||||
: project name ?
|
||||
: properties * # Properties to be used for all actions create here
|
||||
: property-set # Properties to be used for all actions create here
|
||||
)
|
||||
{
|
||||
local result ;
|
||||
@@ -311,7 +313,7 @@ rule generator (
|
||||
generators.dout [ indent ] "alt1" ;
|
||||
for local r in $(consumed)
|
||||
{
|
||||
result += [ generated-targets $(r) : $(properties) : $(project) $(name) ] ; #(targets) ;
|
||||
result += [ generated-targets $(r) : $(property-set) : $(project) $(name) ] ; #(targets) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -320,7 +322,8 @@ rule generator (
|
||||
generators.dout [ indent ] "alt2 : consumed is" [ $(v).str ] ;
|
||||
if $(consumed)
|
||||
{
|
||||
result += [ generated-targets $(consumed) : $(properties) : $(project) $(name) ] ;
|
||||
result += [ generated-targets $(consumed) : $(property-set)
|
||||
: $(project) $(name) ] ;
|
||||
}
|
||||
}
|
||||
return $(result) ;
|
||||
@@ -346,7 +349,7 @@ rule generator (
|
||||
# Note that this pattern mechanism has nothing to do with implicit patterns
|
||||
# in make. It's a way to produce target which name is different for name of
|
||||
# source.
|
||||
rule generated-targets ( sources + : properties * : project name ? )
|
||||
rule generated-targets ( sources + : property-set : project name ? )
|
||||
{
|
||||
if ! $(name)
|
||||
{
|
||||
@@ -382,7 +385,8 @@ rule generator (
|
||||
}
|
||||
# Assign an action for each target
|
||||
local action = [ action-class ] ;
|
||||
local a = [ new $(action) $(targets) : $(sources) : $(self.id) : $(properties) ] ;
|
||||
local a = [ new $(action) $(targets) : $(sources) : $(self.id) :
|
||||
$(property-set) ] ;
|
||||
for local t in $(targets)
|
||||
{
|
||||
$(t).action $(a) ;
|
||||
@@ -395,7 +399,7 @@ rule generator (
|
||||
# handle. The intention is to produce the set of targets can should be
|
||||
# used when generator is run.
|
||||
rule convert-to-consumable-types ( project name ? :
|
||||
properties * : source : multiple ?
|
||||
property-set : source : multiple ?
|
||||
: only-one ? # convert 'source' to only one of source types
|
||||
# if there's more that one possibility, report an
|
||||
# error
|
||||
@@ -449,7 +453,7 @@ rule generator (
|
||||
if $(missing-types)
|
||||
{
|
||||
local transformed = [ generators.construct-types $(project) $(name)
|
||||
: $(missing-types) : $(multiple) : $(properties) : $(source) ] ;
|
||||
: $(missing-types) : $(multiple) : $(property-set) : $(source) ] ;
|
||||
|
||||
# Add targets of right type to 'consumed'. Add others to
|
||||
# 'bypassed'. The 'generators.construct' rule has done
|
||||
@@ -468,8 +472,7 @@ rule generator (
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(consumed-var) += $(_consumed) ;
|
||||
$(bypassed-var) += $(_bypassed) ;
|
||||
}
|
||||
@@ -492,7 +495,7 @@ rule composing-generator ( id : source-types * : target-types + :
|
||||
generator.__init__ $(id) : $(source-types) : $(target-types) :
|
||||
$(requirements) ;
|
||||
|
||||
rule run ( project name ? : properties * : sources + )
|
||||
rule run ( project name ? : property-set : sources + )
|
||||
{
|
||||
generators.dout [ indent ] " composing generator" $(self.id) ;
|
||||
|
||||
@@ -507,7 +510,7 @@ rule composing-generator ( id : source-types * : target-types + :
|
||||
local c ;
|
||||
local b ;
|
||||
# TODO: need to check for failure on each source.
|
||||
convert-to-consumable-types $(project) : $(properties)
|
||||
convert-to-consumable-types $(project) : $(property-set)
|
||||
: $(sources[1]) : * : true : c b ;
|
||||
if ! $(c)
|
||||
{
|
||||
@@ -523,7 +526,8 @@ rule composing-generator ( id : source-types * : target-types + :
|
||||
if ! $(failed)
|
||||
{
|
||||
generators.dout [ indent ] " SUCCESS" ;
|
||||
result += [ generated-targets $(consumed) : $(properties) : $(project) $(name) ] ;
|
||||
result += [ generated-targets $(consumed) : $(property-set)
|
||||
: $(project) $(name) ] ;
|
||||
result += $(bypassed) ;
|
||||
}
|
||||
else
|
||||
@@ -622,9 +626,9 @@ rule base-to-derived-type-conversion ( targets * : target-types +
|
||||
|
||||
|
||||
rule try-one-generator ( project name ? : generator multiple ? :
|
||||
target-types + : properties * : sources * )
|
||||
target-types + : property-set : sources * )
|
||||
{
|
||||
local targets = [ $(generator).run $(project) $(name) : $(properties) : $(sources)
|
||||
local targets = [ $(generator).run $(project) $(name) : $(property-set) : $(sources)
|
||||
: $(multiple) ] ;
|
||||
|
||||
# Generated targets that are of required types
|
||||
@@ -644,8 +648,8 @@ rule try-one-generator ( project name ? : generator multiple ? :
|
||||
{
|
||||
for local e in $(extra)
|
||||
{
|
||||
local try2 = [ construct-types $(project) $(name) : $(target-types) : : $(properties)
|
||||
: $(e) ] ;
|
||||
local try2 = [ construct-types $(project) $(name)
|
||||
: $(target-types) : : $(property-set) : $(e) ] ;
|
||||
|
||||
result += $(try2) ;
|
||||
}
|
||||
@@ -662,13 +666,13 @@ rule try-one-generator ( project name ? : generator multiple ? :
|
||||
}
|
||||
|
||||
rule construct-types ( project name ? : target-types + : multiple ? :
|
||||
properties * : source )
|
||||
property-set : source )
|
||||
{
|
||||
local result ;
|
||||
local matched-types ;
|
||||
for local t in $(target-types)
|
||||
{
|
||||
local r = [ construct $(project) $(name) : $(t) $(multiple) : $(properties) :
|
||||
local r = [ construct $(project) $(name) : $(t) $(multiple) : $(property-set) :
|
||||
$(source) ] ;
|
||||
if $(r)
|
||||
{
|
||||
@@ -719,7 +723,7 @@ local rule ensure-type ( targets * )
|
||||
#
|
||||
# Note: this algorithm explicitly ignores generators for base classes if there's
|
||||
# at least one generator for requested target-type.
|
||||
local rule find-viable-generators ( target-type : properties * : allow-composing ? )
|
||||
local rule find-viable-generators ( target-type : property-set : allow-composing ? )
|
||||
{
|
||||
# Select generators that can create the required target type.
|
||||
local viable-generators = ;
|
||||
@@ -738,7 +742,7 @@ local rule find-viable-generators ( target-type : properties * : allow-composing
|
||||
if ! $(g) in $(.active-generators)
|
||||
&& ! ( [ is-a $(g) : composing-generator ] && ! $(allow-composing) )
|
||||
{
|
||||
local m = [ $(g).match-rank $(properties) ] ;
|
||||
local m = [ $(g).match-rank $(property-set) ] ;
|
||||
if $(m)
|
||||
{
|
||||
viable-generators += $(g) ;
|
||||
@@ -803,7 +807,7 @@ local rule select-dependency-graph ( options )
|
||||
|
||||
# Attempt to construct the target by looking at transformation cache.
|
||||
local rule construct-with-caching (
|
||||
project name ? : target-type multiple ? : properties * : sources * )
|
||||
project name ? : target-type multiple ? : property-set : sources * )
|
||||
{
|
||||
local result ;
|
||||
if ! $(.caching) && ! $(sources[2]) && $(sources[1]) && ! $(name)
|
||||
@@ -812,7 +816,7 @@ local rule construct-with-caching (
|
||||
|
||||
local t = $(sources[1]) ;
|
||||
|
||||
local signature = [ sequence.join [ $(t).type ] $(target-type) $(properties) : - ] ;
|
||||
local signature = [ sequence.join [ $(t).type ] $(target-type) $(property-set) : - ] ;
|
||||
|
||||
# Get a transformation template from cache or create it.
|
||||
local cresult ;
|
||||
@@ -823,7 +827,8 @@ local rule construct-with-caching (
|
||||
else
|
||||
{
|
||||
local ut = [ new file-target % : [ $(t).type ] : "no project" ] ;
|
||||
cresult = [ construct $(project) : $(target-type) $(multiple) : $(properties) : $(ut) ] ;
|
||||
cresult = [ construct $(project) : $(target-type) $(multiple)
|
||||
: $(property-set) : $(ut) ] ;
|
||||
.transformation.cache.$(signature) = $(cresult) ;
|
||||
}
|
||||
|
||||
@@ -846,9 +851,9 @@ local rule construct-with-caching (
|
||||
# Attempts to construct target by finding viable generators, running them
|
||||
# and selecting the dependency graph
|
||||
local rule construct-without-caching (
|
||||
project name ? : target-type multiple ? : properties * : sources * )
|
||||
project name ? : target-type multiple ? : property-set : sources * )
|
||||
{
|
||||
viable-generators = [ find-viable-generators $(target-type) : $(properties)
|
||||
viable-generators = [ find-viable-generators $(target-type) : $(property-set)
|
||||
: $(allow-composing) ] ;
|
||||
|
||||
local results = [ new vector ] ;
|
||||
@@ -862,7 +867,7 @@ local rule construct-without-caching (
|
||||
local .active-generators = $(g) $(.active-generators) ;
|
||||
|
||||
local r = [ try-one-generator $(project) $(name) : $(g) $(multiple) : $(target-type) :
|
||||
$(properties) : $(sources) ] ;
|
||||
$(property-set) : $(sources) ] ;
|
||||
|
||||
if $(r)
|
||||
{
|
||||
@@ -885,7 +890,7 @@ local rule construct-without-caching (
|
||||
# 'construct' in stack, returns only targets of requested 'target-type',
|
||||
# otherwise, returns also unused sources and additionally generated
|
||||
# targets.
|
||||
rule construct ( project name ? : target-type multiple ? : properties * : sources *
|
||||
rule construct ( project name ? : target-type multiple ? : property-set * : sources *
|
||||
: allow-composing ? # Allows to use composing generators for constructing this
|
||||
# target. This will be typically set when creating main targets,
|
||||
# and unset when called recursively from 'run' method of
|
||||
@@ -905,8 +910,8 @@ rule construct ( project name ? : target-type multiple ? : properties * : source
|
||||
usage-requirements += [ $(e).usage-requirements ] ;
|
||||
}
|
||||
}
|
||||
properties += $(usage-requirements) ;
|
||||
properties = [ sequence.unique $(properties) ] ;
|
||||
property-set = [ $(property-set).add
|
||||
[ property-set.create $(usage-requirements) ] ] ;
|
||||
|
||||
.construct-stack += 1 ;
|
||||
|
||||
@@ -926,11 +931,11 @@ rule construct ( project name ? : target-type multiple ? : properties * : source
|
||||
generators.dout [ indent ] " properties:" $(properties) ;
|
||||
|
||||
local result = [ construct-with-caching $(project) $(name)
|
||||
: $(target-type) $(multiple) : $(properties) : $(sources) ] ;
|
||||
: $(target-type) $(multiple) : $(property-set) : $(sources) ] ;
|
||||
|
||||
if ! $(result) {
|
||||
result = [ construct-without-caching $(project) $(name)
|
||||
: $(target-type) $(multiple) : $(properties) : $(sources) ] ;
|
||||
: $(target-type) $(multiple) : $(property-set) : $(sources) ] ;
|
||||
}
|
||||
|
||||
decrease-indent ;
|
||||
@@ -940,8 +945,8 @@ rule construct ( project name ? : target-type multiple ? : properties * : source
|
||||
if ! $(.construct-stack) # This is first invocation in stack
|
||||
{
|
||||
# Make roots of dependency graph depend on all 'dependency' features.
|
||||
local dp = [ property.take dependency : $(properties) ] ;
|
||||
|
||||
local dp = [ $(property-set).dependency ] ;
|
||||
|
||||
if $(dp)
|
||||
{
|
||||
for local t in $(result)
|
||||
|
||||
@@ -12,21 +12,23 @@ import property ;
|
||||
import errors : error ;
|
||||
import type : type ;
|
||||
import regex ;
|
||||
import property-set ;
|
||||
|
||||
rule make-target-class ( name : project : sources * : requirements *
|
||||
: make-rule + : default-build * )
|
||||
{
|
||||
basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements)
|
||||
: $(default-build) ;
|
||||
|
||||
self.make-rule = $(make-rule) ;
|
||||
|
||||
rule construct ( source-targets * : properties * )
|
||||
rule construct ( source-targets * : property-set )
|
||||
{
|
||||
local t = [ new file-target $(self.name:S=) : [ type.type $(self.name:S) ]
|
||||
: $(self.project) ] ;
|
||||
$(t).suffix [ regex.match .(.*) : $(self.name:S) ] ;
|
||||
local a = [ new action $(t) : $(source-targets) : $(self.make-rule)
|
||||
: $(properties) ] ;
|
||||
: $(property-set) ] ;
|
||||
$(t).action $(a) ;
|
||||
return $(t) ;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ rule prebuilt-file-generator
|
||||
{
|
||||
generator.__init__ prebuilt-file-generator : : * : <file> ;
|
||||
|
||||
rule run ( project name ? : properties * : sources * )
|
||||
rule run ( project name ? : property-set : sources * )
|
||||
{
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
local name = [ feature.get-values <file> : $(properties) ] ;
|
||||
local type = [ type.type $(name:S) ] ;
|
||||
if ! $(type)
|
||||
@@ -42,7 +43,7 @@ rule prebuilt-file-generator
|
||||
# Therefore, we encode properties via 'extra-grist', which is ugly.
|
||||
# Maybe, we should just introduce 'do-nothing-action', which only
|
||||
# keps properties.
|
||||
$(t).extra-grist [ property.as-path $(properties) ] ;
|
||||
$(t).extra-grist [ $(property-set).as-path ] ;
|
||||
$(t).suffix [ MATCH .(.*) : $(name:S) ] ;
|
||||
return $(t) ;
|
||||
|
||||
|
||||
@@ -386,6 +386,14 @@ local rule initialize (
|
||||
[ path.relative $(our-dir) $(parent-dir) ] ] : exact ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$(attributes).set requirements
|
||||
: [ property-set.empty ] : exact ;
|
||||
$(attributes).set usage-requirements
|
||||
: [ property-set.empty ] : exact ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Associate the given id with the given location
|
||||
@@ -416,9 +424,16 @@ rule project-attributes ( location )
|
||||
{
|
||||
specification = [ property.translate-paths $(specification)
|
||||
: $(self.location) ] ;
|
||||
local current = $(self.requirements) ;
|
||||
local result = [ property.refine $(current) :
|
||||
[ property.make $(specification) ] ] ;
|
||||
specification = [ property.make $(specification) ] ;
|
||||
result = [ property-set.create $(specification) ] ;
|
||||
|
||||
# If we have inherited properties, need to refine them with the
|
||||
# specified.
|
||||
local current = $(self.requirements) ;
|
||||
if $(current)
|
||||
{
|
||||
result = [ $(current).refine $(result) ] ;
|
||||
}
|
||||
|
||||
if $(result[1]) = "@error"
|
||||
{
|
||||
@@ -439,8 +454,17 @@ rule project-attributes ( location )
|
||||
{
|
||||
errors.error "usage-requirements" $($(real-pos2)) "have non-free properties" $(non-free) ;
|
||||
}
|
||||
self.usage-requirements += [ property.translate-paths $(specification)
|
||||
local t = [ property.translate-paths $(specification)
|
||||
: $(self.location) ] ;
|
||||
if $(self.usage-requirements)
|
||||
{
|
||||
self.usage-requirements = [ property-set.create
|
||||
[ $(self.usage-requirements).raw ] $(t) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.usage-requirements = [ property-set.create $(t) ] ;
|
||||
}
|
||||
}
|
||||
else if $(attribute) = "source-location"
|
||||
{
|
||||
@@ -480,7 +504,7 @@ rule project-attributes ( location )
|
||||
print.list-start ;
|
||||
print.list-item "Project root:" $(self.project-root) ;
|
||||
print.list-item "Parent project:" $(parent) ;
|
||||
print.list-item "Requirements:" $(self.requirements) ;
|
||||
print.list-item "Requirements:" [ $(self.requirements).raw ] ;
|
||||
print.list-item "Default build:" $(self.default-build) ;
|
||||
print.list-item "Source location:" $(self.source-location) ;
|
||||
print.list-item "Projects to build:"
|
||||
|
||||
187
new/targets.jam
187
new/targets.jam
@@ -72,6 +72,7 @@ import regex ;
|
||||
import property ;
|
||||
import errors ;
|
||||
import common ;
|
||||
import property-set ;
|
||||
|
||||
|
||||
# Base class for all abstract targets.
|
||||
@@ -109,7 +110,7 @@ rule abstract-target ( name # name of the target in Jamfile
|
||||
# Adds one more direct build request for this target. If later generate
|
||||
# is called with the same non-free non-incidental properties as in one
|
||||
# of direct build requests, then that build request is used instead.
|
||||
rule direct-build-request ( properties * )
|
||||
rule direct-build-request ( property-set )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -122,7 +123,7 @@ rule abstract-target ( name # name of the target in Jamfile
|
||||
#
|
||||
# If 'properties' are empty, performs default build of this target, in a way specific
|
||||
# to derived class.
|
||||
rule generate ( properties * )
|
||||
rule generate ( property-set )
|
||||
{
|
||||
errors.error "method should be defined in derived classes" ;
|
||||
}
|
||||
@@ -137,29 +138,30 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
self.requirements = $(requirements) ;
|
||||
self.default-build = $(default-build) ;
|
||||
|
||||
rule direct-build-request ( properties * )
|
||||
rule direct-build-request ( property-set )
|
||||
{
|
||||
for local name in $(self.main-targets)
|
||||
{
|
||||
local t = [ main-target $(name) ] ;
|
||||
result += [ $(t).direct-build-request $(properties) ] ;
|
||||
result += [ $(t).direct-build-request $(property-set) ] ;
|
||||
}
|
||||
for local pn in [ project.attribute $(self.project) projects-to-build ]
|
||||
{
|
||||
local p = [ project.module-name $(pn) ] ;
|
||||
local t = [ project.target [ project.attribute $(p) location ] ] ;
|
||||
result += [ $(t).direct-build-request $(properties) ] ;
|
||||
result += [ $(t).direct-build-request $(property-set) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# Generates all possible targets contained in this project.
|
||||
rule generate ( properties * )
|
||||
rule generate ( property-set * )
|
||||
{
|
||||
# Project properties are directly imposed on all main targets.
|
||||
# However, we'd need to check if this project can be build at
|
||||
# all.
|
||||
local xproperties =
|
||||
[ property.refine $(properties) : $(self.requirements) ] ;
|
||||
|
||||
local xproperties = [ $(property-set).refine $(self.requirements) ] ;
|
||||
|
||||
if $(xproperties[1]) = "@error"
|
||||
{
|
||||
local id = [ project.attribute $(self.project) id ] ;
|
||||
@@ -168,7 +170,7 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
"due to unsatisfied requirements." ;
|
||||
print.wrapped-text "warning: explanation: " $(xproperties[2-]) ;
|
||||
print.wrapped-text "warning: build-request: " $(properties) ;
|
||||
print.wrapped-text "warning: requirements: " $(self.requirements) ;
|
||||
print.wrapped-text "warning: requirements: " [ $(self.requirements).raw ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -176,14 +178,14 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
for local name in $(self.main-targets)
|
||||
{
|
||||
local t = [ main-target $(name) ] ;
|
||||
result += [ $(t).generate $(properties) ] ;
|
||||
result += [ $(t).generate $(property-set) ] ;
|
||||
}
|
||||
local self-location = [ project.attribute $(self.project) location ] ;
|
||||
for local pn in [ project.attribute $(self.project) projects-to-build ]
|
||||
{
|
||||
local p = [ project.module-name [ path.join $(self-location) $(pn) ] ] ;
|
||||
local t = [ project.target [ project.attribute $(p) location ] ] ;
|
||||
result += [ $(t).generate $(properties) ] ;
|
||||
result += [ $(t).generate $(property-set) ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
@@ -215,19 +217,19 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
# target in this project, if generation with
|
||||
# 'properties' is requested, and that main target
|
||||
# does not have any requirements of its own.
|
||||
rule reference-properties ( properties * )
|
||||
rule reference-properties ( property-set )
|
||||
{
|
||||
# Note that free properties can appear on 'properties' only
|
||||
# from direct build request, because free properties are not
|
||||
# allowed to be propagated.
|
||||
|
||||
local ref = [ project.attribute $(self.project) requirements ] ;
|
||||
ref = [ property.refine $(properties) : $(ref) ] ;
|
||||
ref = [ property.evaluate-conditionals $(ref) ] ;
|
||||
ref = [ property.take free : [ property.remove incidental : $(ref) ] ] ;
|
||||
ref = [ targets.generate-dependencies $(ref) : $(self.project) ] ;
|
||||
return $(ref) ;
|
||||
}
|
||||
if ! $(self.ref-props.$(property-set))
|
||||
{
|
||||
local ref = [ project.attribute $(self.project) requirements ] ;
|
||||
local ps = [ $(property-set).refine $(ref) ] ;
|
||||
ps = [ $(ps).evaluate-conditionals ] ;
|
||||
|
||||
ps = [ targets.generate-dependencies $(ps) : $(self.project) : $(ps) ] ;
|
||||
self.ref-props.$(property-set) = $(ps) ;
|
||||
}
|
||||
return $(self.ref-props.$(property-set)) ;
|
||||
}
|
||||
|
||||
}
|
||||
class project-target : abstract-target ;
|
||||
@@ -246,9 +248,9 @@ rule main-target ( name : project )
|
||||
self.alternatives += $(target) ;
|
||||
}
|
||||
|
||||
rule direct-build-request ( properties * )
|
||||
rule direct-build-request ( property-set )
|
||||
{
|
||||
local base = [ property.remove free incidental : $(properties) ] ;
|
||||
local base = [ $(property-set).base ] ;
|
||||
local ep = $(self.direct-request.$(base:J=-)) ;
|
||||
if $(ep) && $(ep) != $(properties)
|
||||
{
|
||||
@@ -256,7 +258,7 @@ rule main-target ( name : project )
|
||||
}
|
||||
else
|
||||
{
|
||||
self.direct-request.$(base:J=-) = $(properties) ;
|
||||
self.direct-request.$(base:J=-) = $(property-set) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,13 +267,13 @@ rule main-target ( name : project )
|
||||
# which requirements are satisfied by 'properties' and picking the one with
|
||||
# longest requirements set.
|
||||
# Returns the result of calling 'generate' on that alternative.
|
||||
rule generate ( properties * )
|
||||
rule generate ( property-set )
|
||||
{
|
||||
local base = [ property.remove free incidental : $(properties) ] ;
|
||||
local base = [ $(property-set).base ] ;
|
||||
local ep = $(self.direct-request.$(base:J=-)) ;
|
||||
if $(ep)
|
||||
{
|
||||
properties = $(ep) ;
|
||||
property-set = $(ep) ;
|
||||
}
|
||||
|
||||
# Try to generate all the alternatives.
|
||||
@@ -279,7 +281,7 @@ rule main-target ( name : project )
|
||||
|
||||
for local v in $(self.alternatives)
|
||||
{
|
||||
local vtargets = [ $(v).generate $(properties) ] ;
|
||||
local vtargets = [ $(v).generate $(property-set) ] ;
|
||||
if $(vtargets) && $(vtargets[1]) != "@error"
|
||||
{
|
||||
$(alternatives).push-back [ new vector $(v) $(vtargets) ] ;
|
||||
@@ -291,7 +293,7 @@ rule main-target ( name : project )
|
||||
# why it can't be build.
|
||||
print.wrapped-text
|
||||
"warning: skipped build of" [ full-name ]
|
||||
"with properties" $(properties) ;
|
||||
"with properties" [ $(property-set).raw ] ;
|
||||
} else {
|
||||
local result ;
|
||||
if [ $(alternatives).size ] = 1
|
||||
@@ -314,9 +316,9 @@ rule main-target ( name : project )
|
||||
# have 'requirements' method.
|
||||
# assert.equal [ is-a $(target) : basic-target ] : true ;
|
||||
local req = [ $(target).requirements ] ;
|
||||
req = [ property.remove free incidental : $(req) ] ;
|
||||
req = [ $(req).base ] ;
|
||||
req-length += [ sequence.length
|
||||
[ set.intersection $(req) : $(properties) ] ] ;
|
||||
[ set.intersection $(req) : [ $(property-set).raw ] ] ] ;
|
||||
}
|
||||
|
||||
local best = [ sequence.select-highest-ranked $(r) : $(req-length) ] ;
|
||||
@@ -343,7 +345,7 @@ rule main-target ( name : project )
|
||||
# is created.
|
||||
local all-targets =
|
||||
[ sequence.transform virtual-target.traverse : $(result) ] ;
|
||||
local dg = [ new subvariant-dg $(__name__) : $(properties) : $(all-targets) ] ;
|
||||
local dg = [ new subvariant-dg $(__name__) : $(property-set) : $(all-targets) ] ;
|
||||
for local v in $(all-targets)
|
||||
{
|
||||
$(v).dg $(dg) ;
|
||||
@@ -361,7 +363,7 @@ class main-target : abstract-target ;
|
||||
# reference.
|
||||
rule generate ( target-reference # Target reference
|
||||
: project # Project where the reference is made
|
||||
: properties * # Properties of the main target that
|
||||
: property-set # Properties of the main target that
|
||||
# makes the reference
|
||||
)
|
||||
{
|
||||
@@ -382,8 +384,9 @@ rule generate ( target-reference # Target reference
|
||||
if $(main-target) {
|
||||
# Take properties which should be propagated and refine them
|
||||
# with source-specific requirements.
|
||||
local propagated = [ property.take propagated : $(properties) ] ;
|
||||
local rproperties = [ property.refine $(propagated) : $(sproperties) ] ;
|
||||
local propagated = [ $(property-set).propagated ] ;
|
||||
local rproperties = [ $(propagated).refine
|
||||
[ property-set.create $(sproperties) ] ] ;
|
||||
if $(rproperties[1]) = "@error"
|
||||
{
|
||||
errors.error
|
||||
@@ -395,42 +398,32 @@ rule generate ( target-reference # Target reference
|
||||
}
|
||||
}
|
||||
|
||||
# Returns a list of properties, where all dependency properties are
|
||||
# replaced as follows:
|
||||
# - the value of dependency property is treated as target reference,
|
||||
# which is generated with 'properties' + 'extra-properties'
|
||||
# - the created virtual target's become replace the property value,
|
||||
# for example <library>a/b might become
|
||||
# <library>object(virtual-target)@1
|
||||
# In addition, usage requirements for all created virtual targets
|
||||
# are added to the properties.
|
||||
# Returns new property set which inclues all properties from
|
||||
# 'property-set', except that all dependency properties are
|
||||
# generated with 'generation-ps', and the obtained virtual targets
|
||||
# are added as the values of original features.
|
||||
#
|
||||
# The purpose of 'extra-properties' is to be able to replace dependency
|
||||
# features only in certain set of properties, which does not include
|
||||
# all build properties. A concrete example is when we process use properties.
|
||||
# Dependency features must be replaced using full build properties of target,
|
||||
# but we don't want to add build properties to usage requirements.
|
||||
rule generate-dependencies ( properties * : project : extra-properties * )
|
||||
# For example, <library>a/b might become <library>object(virtual-target)@1
|
||||
# In addition, usage requirements for all created virtual targets
|
||||
# are added to the created property set.
|
||||
rule generate-dependencies ( property-set : project : generation-ps )
|
||||
{
|
||||
local xproperties ;
|
||||
for local p in $(properties)
|
||||
local xproperties ;
|
||||
for local p in [ $(property-set).dependency ]
|
||||
{
|
||||
if dependency in [ feature.attributes $(p:G) ]
|
||||
local g = [ targets.generate $(p:TG=) : $(project) : $(generation-ps) ] ;
|
||||
if ! $(g)
|
||||
{
|
||||
local g = [ targets.generate $(p:TG=) : $(project)
|
||||
: $(properties) $(extra-properties) ] ;
|
||||
if ! $(g)
|
||||
{
|
||||
errors.error "cannot generate dependency " $(p) ;
|
||||
}
|
||||
xproperties += $(p:G)$(g) [ $(g).usage-requirements ] ;
|
||||
errors.error "cannot generate dependency " $(p) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
xproperties += $(p) ;
|
||||
}
|
||||
xproperties += $(p:G)$(g) [ $(g).usage-requirements ] ;
|
||||
}
|
||||
return $(xproperties) ;
|
||||
local r = [ property-set.create
|
||||
[ $(property-set).base ]
|
||||
[ $(property-set).free ]
|
||||
$(xproperties)
|
||||
[ $(property-set).incidental ] ] ;
|
||||
return $(r) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -448,8 +441,15 @@ rule basic-target ( name : project
|
||||
abstract-target.__init__ $(name) : $(project) ;
|
||||
|
||||
self.sources = $(sources) ;
|
||||
if ! $(requirements) {
|
||||
requirements = [ property-set.empty ] ;
|
||||
}
|
||||
self.requirements = $(requirements) ;
|
||||
self.default-build = $(default-build) ;
|
||||
if ! $(usage-requirements)
|
||||
{
|
||||
usage-requirements = [ property-set.empty ] ;
|
||||
}
|
||||
self.usage-requirements = $(usage-requirements) ;
|
||||
|
||||
if $(sources:G)
|
||||
@@ -463,35 +463,31 @@ rule basic-target ( name : project
|
||||
# Generates sources. Calls 'construct'
|
||||
# This method should not be overriden.
|
||||
#
|
||||
rule generate ( properties * )
|
||||
rule generate ( property-set )
|
||||
{
|
||||
if ! $(properties) || $(properties:G) = <toolset>
|
||||
if ! [ $(property-set).raw ]
|
||||
{
|
||||
# CONSIDER: I'm really not sure if this is correct...
|
||||
# FIXME: as in 'build-system' we stick default toolset
|
||||
properties = [ build-request.expand $(properties)
|
||||
$(self.default-build) ] ;
|
||||
properties = [ build-request.expand $(self.default-build) ] ;
|
||||
|
||||
local result = ;
|
||||
for local p in $(properties)
|
||||
{
|
||||
result += [ generate [ feature.split $(p) ] ] ;
|
||||
result += [ generate [ property-set.create [ feature.split $(p) ] ] ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
} else {
|
||||
|
||||
property-path = [ property.as-path
|
||||
[ property.remove free incidental : $(properties) ] ] ;
|
||||
|
||||
property-path = [ property.as-path [ $(property-set).base ] ] ;
|
||||
if ! $(property-path)
|
||||
{
|
||||
property-path = X ;
|
||||
}
|
||||
if ! $(self.generated.$(property-path))
|
||||
{
|
||||
local rproperties =
|
||||
[ property.refine $(properties) : $(self.requirements) ] ;
|
||||
|
||||
rproperties = [ property.evaluate-conditionals $(rproperties) ] ;
|
||||
local rproperties = [ $(property-set).refine $(self.requirements) ] ;
|
||||
|
||||
if $(rproperties[1]) != "@error"
|
||||
{
|
||||
@@ -503,9 +499,12 @@ rule basic-target ( name : project
|
||||
# requirements may also code from dependencies. However, when they
|
||||
# come from dependencies, the value is not target id, but rather
|
||||
# virtual target names, so generators.construct can use them.
|
||||
|
||||
rproperties = [ $(rproperties).evaluate-conditionals ] ;
|
||||
|
||||
local xproperties =
|
||||
[ targets.generate-dependencies $(rproperties) : $(self.project) ] ;
|
||||
[ targets.generate-dependencies $(rproperties) : $(self.project)
|
||||
: $(rproperties) ] ;
|
||||
|
||||
|
||||
local source-targets ;
|
||||
@@ -513,7 +512,7 @@ rule basic-target ( name : project
|
||||
{
|
||||
# Try treating this source as reference to main target
|
||||
local more-targets =
|
||||
[ targets.generate $(s) : $(self.project) : $(properties) ] ;
|
||||
[ targets.generate $(s) : $(self.project) : $(property-set) ] ;
|
||||
if $(more-targets)
|
||||
{
|
||||
source-targets += $(more-targets) ;
|
||||
@@ -529,16 +528,19 @@ rule basic-target ( name : project
|
||||
# unqual to project's reference properties. As the
|
||||
# result, we create per-target bin directory while
|
||||
# it's not really needed.
|
||||
xproperties = [ feature.run-actions $(xproperties) ] ;
|
||||
|
||||
|
||||
xproperties = [ $(xproperties).run-actions ] ;
|
||||
|
||||
self.generated.$(property-path) =
|
||||
[ construct $(source-targets) : $(xproperties) ] ;
|
||||
|
||||
# Apply use requirement of this target to all generated
|
||||
# virtual targets.
|
||||
local xusage-requirements =
|
||||
[ targets.generate-dependencies $(self.usage-requirements)
|
||||
[ targets.generate-dependencies
|
||||
$(self.usage-requirements)
|
||||
: $(self.project) : $(rproperties) ] ;
|
||||
xusage-requirements = [ $(xusage-requirements).raw ] ;
|
||||
|
||||
for local e in $(self.generated.$(property-path))
|
||||
{
|
||||
@@ -579,11 +581,11 @@ rule typed-target ( name : project : type
|
||||
|
||||
self.type = $(type) ;
|
||||
|
||||
rule construct ( source-targets * : properties * )
|
||||
rule construct ( source-targets * : property-set )
|
||||
{
|
||||
local r = [ generators.construct $(self.project) $(self.name) : $(self.type)
|
||||
: $(properties) # [ feature.expand
|
||||
<main-target-type>$(self.type)
|
||||
: [ property-set.create [ $(property-set).raw ] # [ feature.expand
|
||||
<main-target-type>$(self.type) ]
|
||||
# ]
|
||||
: $(source-targets)
|
||||
: allow-composing ] ;
|
||||
@@ -609,8 +611,9 @@ rule main-target-requirements (
|
||||
{
|
||||
local loc = [ project.attribute $(project) location ] ;
|
||||
local requirements = [ property.translate-paths $(specification) : $(loc) ] ;
|
||||
local requirements = [ property-set.create $(requirements) ] ;
|
||||
local project-requirements = [ project.attribute $(project) requirements ] ;
|
||||
requirements = [ property.refine $(project-requirements) : $(requirements) ] ;
|
||||
requirements = [ $(project-requirements).refine $(requirements) ] ;
|
||||
if $(requirements[1]) = "@error"
|
||||
{
|
||||
errors.error "Conflicting requirements for target:" $(requirements) ;
|
||||
@@ -629,11 +632,11 @@ rule main-target-usage-requirements (
|
||||
{
|
||||
local loc = [ project.attribute $(project) location ] ;
|
||||
local project-usage-requirements = [ project.attribute $(project) usage-requirements ] ;
|
||||
|
||||
local usage-requirements = [ property.translate-paths $(specification) : $(loc) ] ;
|
||||
usage-requirements += $(project-usage-requirements) ;
|
||||
|
||||
return $(usage-requirements) ;
|
||||
|
||||
local usage-requirements = [ property-set.create
|
||||
[ property.translate-paths $(specification) : $(loc) ] ] ;
|
||||
|
||||
return [ $(project-usage-requirements).add $(usage-requirements) ] ;
|
||||
}
|
||||
|
||||
# Return the default build value to use when declaring a main target,
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
import class : class new ;
|
||||
import type ;
|
||||
import property-set ;
|
||||
import utility ;
|
||||
|
||||
# +--------------------------+
|
||||
# | virtual-target |
|
||||
@@ -349,8 +351,8 @@ rule abstract-file-target ( name
|
||||
local properties ;
|
||||
if $(self.action)
|
||||
{
|
||||
properties = [ property.remove free incidental : [ $(self.action).properties ] ] ;
|
||||
local property-grist = [ property.as-path $(properties) ] ;
|
||||
local ps = [ $(self.action).properties-ps ] ;
|
||||
local property-grist = [ $(ps).as-path ] ;
|
||||
grist = $(location-grist)/$(property-grist) ;
|
||||
}
|
||||
if ! $(grist)
|
||||
@@ -447,21 +449,16 @@ rule file-target (
|
||||
{
|
||||
if $(self.action)
|
||||
{
|
||||
local properties = [ property.take free : [ property.remove incidental :
|
||||
[ $(self.action).properties ] ] ] ;
|
||||
|
||||
local ps = [ $(self.action).properties-ps ] ;
|
||||
|
||||
local main-target = [ $(self.dg).main-target ] ;
|
||||
local project = [ $(main-target).project ] ;
|
||||
local plocation = [ project.attribute $(project) location ] ;
|
||||
local ptarget = [ project.target $(plocation) ] ;
|
||||
local ref = [ $(ptarget).reference-properties [ $(self.dg).properties ] ] ;
|
||||
local ref-ps = [ $(ptarget).reference-properties [ $(self.dg).properties-ps ] ] ;
|
||||
|
||||
properties = [ sequence.insertion-sort
|
||||
[ sequence.unique $(properties) ] ] ;
|
||||
ref = [ sequence.insertion-sort
|
||||
[ sequence.unique $(ref) ] ] ;
|
||||
|
||||
if $(properties) != $(ref)
|
||||
if [ $(ps).free ] != [ $(ref-ps).free ]
|
||||
{
|
||||
self.extra-path = [ sequence.join main-target- [ $(main-target).name ] ] ;
|
||||
}
|
||||
@@ -491,7 +488,7 @@ rule file-target (
|
||||
[ $(self.action).path ]
|
||||
$(self.extra-path)
|
||||
] ;
|
||||
|
||||
|
||||
return [ path.native $(path) ] ;
|
||||
}
|
||||
}
|
||||
@@ -522,13 +519,24 @@ rule remember-binding ( target : bound-path )
|
||||
# rule action-name ( targets + : sources * : properties * )
|
||||
# Targets and sources are passed as actual jam targets. The rule may
|
||||
# not establish dependency relationship, but should do everything else.
|
||||
rule action ( targets + : sources * : action-name : properties * )
|
||||
rule action ( targets + : sources * : action-name : property-set ? )
|
||||
{
|
||||
self.targets = $(targets) ;
|
||||
self.sources = $(sources) ;
|
||||
self.action-name = $(action-name) ;
|
||||
self.properties = $(properties) ;
|
||||
|
||||
|
||||
if ! $(property-set)
|
||||
{
|
||||
property-set = [ property-set.empty ] ;
|
||||
}
|
||||
|
||||
if ! [ class.is-instance $(property-set) ]
|
||||
{
|
||||
errors.error "Property set instance required" ;
|
||||
}
|
||||
|
||||
self.properties = $(property-set) ;
|
||||
|
||||
rule targets ( )
|
||||
{
|
||||
return $(self.targets) ;
|
||||
@@ -544,7 +552,7 @@ rule action ( targets + : sources * : action-name : properties * )
|
||||
return $(self.action-name) ;
|
||||
}
|
||||
|
||||
rule properties ( )
|
||||
rule properties-ps ( )
|
||||
{
|
||||
return $(self.properties) ;
|
||||
}
|
||||
@@ -556,7 +564,8 @@ rule action ( targets + : sources * : action-name : properties * )
|
||||
{
|
||||
self.actualized = true ;
|
||||
|
||||
local properties = [ adjust-properties [ properties ] ] ;
|
||||
local ps = [ properties-ps ] ;
|
||||
local properties = [ adjust-properties [ $(ps).raw ] ] ;
|
||||
|
||||
|
||||
local actual-targets ;
|
||||
@@ -601,12 +610,10 @@ rule action ( targets + : sources * : action-name : properties * )
|
||||
|
||||
rule path ( )
|
||||
{
|
||||
local subvariant = [ property.remove free incidental : $(self.properties) ] ;
|
||||
local pp = [ property.as-path $(subvariant) ] ;
|
||||
return $(pp) ;
|
||||
local p = [ $(self.properties).as-path ] ;
|
||||
return $(p) ;
|
||||
}
|
||||
|
||||
|
||||
# Determined real properties when trying building with 'properties'.
|
||||
# This is last chance to fix properties, for example to adjust includes
|
||||
# to get generated headers correctly. Default implementation returns
|
||||
@@ -678,7 +685,7 @@ rule register ( target )
|
||||
result = $(t) ;
|
||||
}
|
||||
else if $(a1) && $(a2) && [ $(a1).action-name ] = [ $(a2).action-name ]
|
||||
&& [ $(a1).properties ] = [ $(a2).properties ] && [ $(a1).sources ] = [ $(a2).sources ]
|
||||
&& [ $(a1).properties-ps ] = [ $(a2).properties-ps ] && [ $(a1).sources ] = [ $(a2).sources ]
|
||||
{
|
||||
result = $(t) ;
|
||||
}
|
||||
@@ -801,18 +808,19 @@ local rule clone-action-template ( action from cloned-from : new-source )
|
||||
|
||||
local action-class = [ modules.peek $(action) : __class__ ] ;
|
||||
|
||||
local ps = [ $(action).properties-ps ] ;
|
||||
local cloned = [ new $(action-class) [ $(action).targets ] : $(sources)
|
||||
: [ $(action).action-name ] : [ $(action).properties ] ] ;
|
||||
: [ $(action).action-name ] : $(ps) ] ;
|
||||
|
||||
return $(cloned) ;
|
||||
}
|
||||
|
||||
local rule subvariant-dg ( main-target # The instance of main-target class
|
||||
: properties * # Properties requested for this target
|
||||
: property-set # Properties requested for this target
|
||||
: virtual-targets * )
|
||||
{
|
||||
self.main-target = $(main-target) ;
|
||||
self.properties = $(properties) ;
|
||||
self.properties = $(property-set) ;
|
||||
self.virtual-targets = $(virtual-targets) ;
|
||||
|
||||
# Pre-compose the list of other dependency graphs, on which this one
|
||||
@@ -836,19 +844,28 @@ local rule subvariant-dg ( main-target # The instance of main-target class
|
||||
}
|
||||
}
|
||||
self.other-dg = [ sequence.unique $(self.other-dg) ] ;
|
||||
|
||||
|
||||
rule main-target ( )
|
||||
{
|
||||
return $(self.main-target) ;
|
||||
}
|
||||
|
||||
rule properties ( )
|
||||
rule properties-ps ( )
|
||||
{
|
||||
return $(self.properties) ;
|
||||
}
|
||||
|
||||
|
||||
rule all-target-directories ( )
|
||||
{
|
||||
if ! $(self.target-directories)
|
||||
{
|
||||
compute-target-directories ;
|
||||
}
|
||||
return $(self.target-directories) ;
|
||||
}
|
||||
|
||||
rule compute-target-directories ( )
|
||||
{
|
||||
local result ;
|
||||
for local t in $(self.virtual-targets)
|
||||
{
|
||||
@@ -858,8 +875,8 @@ local rule subvariant-dg ( main-target # The instance of main-target class
|
||||
{
|
||||
result += [ $(d).all-target-directories ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
self.target-directories = $(result) ;
|
||||
}
|
||||
}
|
||||
|
||||
class subvariant-dg ;
|
||||
|
||||
@@ -157,6 +157,7 @@ rule generator (
|
||||
# in returned set must be present in build properties if this
|
||||
# generator is to be used. If result has grist-only element,
|
||||
# that build properties must include some value of that feature.
|
||||
# XXX: remove this method?
|
||||
rule requirements ( )
|
||||
{
|
||||
return $(self.requirements) ;
|
||||
@@ -173,7 +174,7 @@ rule generator (
|
||||
# Returns a number telling how good generator's properties match
|
||||
# the passed properties, or empty list if generator can't be run
|
||||
# at all.
|
||||
rule match-rank ( properties * )
|
||||
rule match-rank ( property-set )
|
||||
{
|
||||
# See if generator's requirements are satisfied by 'properties'.
|
||||
# Treat feature name in requirements (i.e. grist-only element),
|
||||
@@ -192,7 +193,8 @@ rule generator (
|
||||
features += $(r) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
if $(requirements) in $(properties) && $(features) in $(properties:G)
|
||||
{
|
||||
return [ sequence.length [ set.intersection
|
||||
@@ -217,7 +219,7 @@ rule generator (
|
||||
rule run ( project # Project for which the targets are generated
|
||||
name ? # Determines the name of 'name' attribute for
|
||||
# all generated targets. See 'generated-targets' method.
|
||||
: properties * # Desired properties for generated targets.
|
||||
: property-set # Desired properties for generated targets.
|
||||
: sources + : # Source targets.
|
||||
multiple ? # Allows the rule to run generator several times and return
|
||||
# multiple targets of the same type. When this argument is not
|
||||
@@ -230,7 +232,7 @@ rule generator (
|
||||
{
|
||||
generators.dout [ indent ] " generator" $(self.id) ;
|
||||
generators.dout [ indent ] " multiple:" $(mutliple) ;
|
||||
|
||||
|
||||
# Ordinary generators take only one source targets
|
||||
if $(sources[2])
|
||||
{
|
||||
@@ -248,7 +250,7 @@ rule generator (
|
||||
local bypassed = ;
|
||||
|
||||
convert-to-consumable-types $(project) $(name) :
|
||||
$(properties) : $(sources) : $(multiple)
|
||||
$(property-set) : $(sources) : $(multiple)
|
||||
:
|
||||
: consumed bypassed ;
|
||||
|
||||
@@ -256,7 +258,7 @@ rule generator (
|
||||
if $(consumed)
|
||||
{
|
||||
result = [ construct-result $(consumed) : $(project) $(name)
|
||||
: $(properties) ] ;
|
||||
: $(property-set) ] ;
|
||||
}
|
||||
|
||||
if $(result)
|
||||
@@ -301,7 +303,7 @@ rule generator (
|
||||
# Otherwise, might contain several targets with the type of
|
||||
# $(self.source-types[1])
|
||||
: project name ?
|
||||
: properties * # Properties to be used for all actions create here
|
||||
: property-set # Properties to be used for all actions create here
|
||||
)
|
||||
{
|
||||
local result ;
|
||||
@@ -311,7 +313,7 @@ rule generator (
|
||||
generators.dout [ indent ] "alt1" ;
|
||||
for local r in $(consumed)
|
||||
{
|
||||
result += [ generated-targets $(r) : $(properties) : $(project) $(name) ] ; #(targets) ;
|
||||
result += [ generated-targets $(r) : $(property-set) : $(project) $(name) ] ; #(targets) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -320,7 +322,8 @@ rule generator (
|
||||
generators.dout [ indent ] "alt2 : consumed is" [ $(v).str ] ;
|
||||
if $(consumed)
|
||||
{
|
||||
result += [ generated-targets $(consumed) : $(properties) : $(project) $(name) ] ;
|
||||
result += [ generated-targets $(consumed) : $(property-set)
|
||||
: $(project) $(name) ] ;
|
||||
}
|
||||
}
|
||||
return $(result) ;
|
||||
@@ -346,7 +349,7 @@ rule generator (
|
||||
# Note that this pattern mechanism has nothing to do with implicit patterns
|
||||
# in make. It's a way to produce target which name is different for name of
|
||||
# source.
|
||||
rule generated-targets ( sources + : properties * : project name ? )
|
||||
rule generated-targets ( sources + : property-set : project name ? )
|
||||
{
|
||||
if ! $(name)
|
||||
{
|
||||
@@ -382,7 +385,8 @@ rule generator (
|
||||
}
|
||||
# Assign an action for each target
|
||||
local action = [ action-class ] ;
|
||||
local a = [ new $(action) $(targets) : $(sources) : $(self.id) : $(properties) ] ;
|
||||
local a = [ new $(action) $(targets) : $(sources) : $(self.id) :
|
||||
$(property-set) ] ;
|
||||
for local t in $(targets)
|
||||
{
|
||||
$(t).action $(a) ;
|
||||
@@ -395,7 +399,7 @@ rule generator (
|
||||
# handle. The intention is to produce the set of targets can should be
|
||||
# used when generator is run.
|
||||
rule convert-to-consumable-types ( project name ? :
|
||||
properties * : source : multiple ?
|
||||
property-set : source : multiple ?
|
||||
: only-one ? # convert 'source' to only one of source types
|
||||
# if there's more that one possibility, report an
|
||||
# error
|
||||
@@ -449,7 +453,7 @@ rule generator (
|
||||
if $(missing-types)
|
||||
{
|
||||
local transformed = [ generators.construct-types $(project) $(name)
|
||||
: $(missing-types) : $(multiple) : $(properties) : $(source) ] ;
|
||||
: $(missing-types) : $(multiple) : $(property-set) : $(source) ] ;
|
||||
|
||||
# Add targets of right type to 'consumed'. Add others to
|
||||
# 'bypassed'. The 'generators.construct' rule has done
|
||||
@@ -468,8 +472,7 @@ rule generator (
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(consumed-var) += $(_consumed) ;
|
||||
$(bypassed-var) += $(_bypassed) ;
|
||||
}
|
||||
@@ -492,7 +495,7 @@ rule composing-generator ( id : source-types * : target-types + :
|
||||
generator.__init__ $(id) : $(source-types) : $(target-types) :
|
||||
$(requirements) ;
|
||||
|
||||
rule run ( project name ? : properties * : sources + )
|
||||
rule run ( project name ? : property-set : sources + )
|
||||
{
|
||||
generators.dout [ indent ] " composing generator" $(self.id) ;
|
||||
|
||||
@@ -507,7 +510,7 @@ rule composing-generator ( id : source-types * : target-types + :
|
||||
local c ;
|
||||
local b ;
|
||||
# TODO: need to check for failure on each source.
|
||||
convert-to-consumable-types $(project) : $(properties)
|
||||
convert-to-consumable-types $(project) : $(property-set)
|
||||
: $(sources[1]) : * : true : c b ;
|
||||
if ! $(c)
|
||||
{
|
||||
@@ -523,7 +526,8 @@ rule composing-generator ( id : source-types * : target-types + :
|
||||
if ! $(failed)
|
||||
{
|
||||
generators.dout [ indent ] " SUCCESS" ;
|
||||
result += [ generated-targets $(consumed) : $(properties) : $(project) $(name) ] ;
|
||||
result += [ generated-targets $(consumed) : $(property-set)
|
||||
: $(project) $(name) ] ;
|
||||
result += $(bypassed) ;
|
||||
}
|
||||
else
|
||||
@@ -622,9 +626,9 @@ rule base-to-derived-type-conversion ( targets * : target-types +
|
||||
|
||||
|
||||
rule try-one-generator ( project name ? : generator multiple ? :
|
||||
target-types + : properties * : sources * )
|
||||
target-types + : property-set : sources * )
|
||||
{
|
||||
local targets = [ $(generator).run $(project) $(name) : $(properties) : $(sources)
|
||||
local targets = [ $(generator).run $(project) $(name) : $(property-set) : $(sources)
|
||||
: $(multiple) ] ;
|
||||
|
||||
# Generated targets that are of required types
|
||||
@@ -644,8 +648,8 @@ rule try-one-generator ( project name ? : generator multiple ? :
|
||||
{
|
||||
for local e in $(extra)
|
||||
{
|
||||
local try2 = [ construct-types $(project) $(name) : $(target-types) : : $(properties)
|
||||
: $(e) ] ;
|
||||
local try2 = [ construct-types $(project) $(name)
|
||||
: $(target-types) : : $(property-set) : $(e) ] ;
|
||||
|
||||
result += $(try2) ;
|
||||
}
|
||||
@@ -662,13 +666,13 @@ rule try-one-generator ( project name ? : generator multiple ? :
|
||||
}
|
||||
|
||||
rule construct-types ( project name ? : target-types + : multiple ? :
|
||||
properties * : source )
|
||||
property-set : source )
|
||||
{
|
||||
local result ;
|
||||
local matched-types ;
|
||||
for local t in $(target-types)
|
||||
{
|
||||
local r = [ construct $(project) $(name) : $(t) $(multiple) : $(properties) :
|
||||
local r = [ construct $(project) $(name) : $(t) $(multiple) : $(property-set) :
|
||||
$(source) ] ;
|
||||
if $(r)
|
||||
{
|
||||
@@ -719,7 +723,7 @@ local rule ensure-type ( targets * )
|
||||
#
|
||||
# Note: this algorithm explicitly ignores generators for base classes if there's
|
||||
# at least one generator for requested target-type.
|
||||
local rule find-viable-generators ( target-type : properties * : allow-composing ? )
|
||||
local rule find-viable-generators ( target-type : property-set : allow-composing ? )
|
||||
{
|
||||
# Select generators that can create the required target type.
|
||||
local viable-generators = ;
|
||||
@@ -738,7 +742,7 @@ local rule find-viable-generators ( target-type : properties * : allow-composing
|
||||
if ! $(g) in $(.active-generators)
|
||||
&& ! ( [ is-a $(g) : composing-generator ] && ! $(allow-composing) )
|
||||
{
|
||||
local m = [ $(g).match-rank $(properties) ] ;
|
||||
local m = [ $(g).match-rank $(property-set) ] ;
|
||||
if $(m)
|
||||
{
|
||||
viable-generators += $(g) ;
|
||||
@@ -803,7 +807,7 @@ local rule select-dependency-graph ( options )
|
||||
|
||||
# Attempt to construct the target by looking at transformation cache.
|
||||
local rule construct-with-caching (
|
||||
project name ? : target-type multiple ? : properties * : sources * )
|
||||
project name ? : target-type multiple ? : property-set : sources * )
|
||||
{
|
||||
local result ;
|
||||
if ! $(.caching) && ! $(sources[2]) && $(sources[1]) && ! $(name)
|
||||
@@ -812,7 +816,7 @@ local rule construct-with-caching (
|
||||
|
||||
local t = $(sources[1]) ;
|
||||
|
||||
local signature = [ sequence.join [ $(t).type ] $(target-type) $(properties) : - ] ;
|
||||
local signature = [ sequence.join [ $(t).type ] $(target-type) $(property-set) : - ] ;
|
||||
|
||||
# Get a transformation template from cache or create it.
|
||||
local cresult ;
|
||||
@@ -823,7 +827,8 @@ local rule construct-with-caching (
|
||||
else
|
||||
{
|
||||
local ut = [ new file-target % : [ $(t).type ] : "no project" ] ;
|
||||
cresult = [ construct $(project) : $(target-type) $(multiple) : $(properties) : $(ut) ] ;
|
||||
cresult = [ construct $(project) : $(target-type) $(multiple)
|
||||
: $(property-set) : $(ut) ] ;
|
||||
.transformation.cache.$(signature) = $(cresult) ;
|
||||
}
|
||||
|
||||
@@ -846,9 +851,9 @@ local rule construct-with-caching (
|
||||
# Attempts to construct target by finding viable generators, running them
|
||||
# and selecting the dependency graph
|
||||
local rule construct-without-caching (
|
||||
project name ? : target-type multiple ? : properties * : sources * )
|
||||
project name ? : target-type multiple ? : property-set : sources * )
|
||||
{
|
||||
viable-generators = [ find-viable-generators $(target-type) : $(properties)
|
||||
viable-generators = [ find-viable-generators $(target-type) : $(property-set)
|
||||
: $(allow-composing) ] ;
|
||||
|
||||
local results = [ new vector ] ;
|
||||
@@ -862,7 +867,7 @@ local rule construct-without-caching (
|
||||
local .active-generators = $(g) $(.active-generators) ;
|
||||
|
||||
local r = [ try-one-generator $(project) $(name) : $(g) $(multiple) : $(target-type) :
|
||||
$(properties) : $(sources) ] ;
|
||||
$(property-set) : $(sources) ] ;
|
||||
|
||||
if $(r)
|
||||
{
|
||||
@@ -885,7 +890,7 @@ local rule construct-without-caching (
|
||||
# 'construct' in stack, returns only targets of requested 'target-type',
|
||||
# otherwise, returns also unused sources and additionally generated
|
||||
# targets.
|
||||
rule construct ( project name ? : target-type multiple ? : properties * : sources *
|
||||
rule construct ( project name ? : target-type multiple ? : property-set * : sources *
|
||||
: allow-composing ? # Allows to use composing generators for constructing this
|
||||
# target. This will be typically set when creating main targets,
|
||||
# and unset when called recursively from 'run' method of
|
||||
@@ -905,8 +910,8 @@ rule construct ( project name ? : target-type multiple ? : properties * : source
|
||||
usage-requirements += [ $(e).usage-requirements ] ;
|
||||
}
|
||||
}
|
||||
properties += $(usage-requirements) ;
|
||||
properties = [ sequence.unique $(properties) ] ;
|
||||
property-set = [ $(property-set).add
|
||||
[ property-set.create $(usage-requirements) ] ] ;
|
||||
|
||||
.construct-stack += 1 ;
|
||||
|
||||
@@ -926,11 +931,11 @@ rule construct ( project name ? : target-type multiple ? : properties * : source
|
||||
generators.dout [ indent ] " properties:" $(properties) ;
|
||||
|
||||
local result = [ construct-with-caching $(project) $(name)
|
||||
: $(target-type) $(multiple) : $(properties) : $(sources) ] ;
|
||||
: $(target-type) $(multiple) : $(property-set) : $(sources) ] ;
|
||||
|
||||
if ! $(result) {
|
||||
result = [ construct-without-caching $(project) $(name)
|
||||
: $(target-type) $(multiple) : $(properties) : $(sources) ] ;
|
||||
: $(target-type) $(multiple) : $(property-set) : $(sources) ] ;
|
||||
}
|
||||
|
||||
decrease-indent ;
|
||||
@@ -940,8 +945,8 @@ rule construct ( project name ? : target-type multiple ? : properties * : source
|
||||
if ! $(.construct-stack) # This is first invocation in stack
|
||||
{
|
||||
# Make roots of dependency graph depend on all 'dependency' features.
|
||||
local dp = [ property.take dependency : $(properties) ] ;
|
||||
|
||||
local dp = [ $(property-set).dependency ] ;
|
||||
|
||||
if $(dp)
|
||||
{
|
||||
for local t in $(result)
|
||||
|
||||
@@ -386,6 +386,14 @@ local rule initialize (
|
||||
[ path.relative $(our-dir) $(parent-dir) ] ] : exact ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$(attributes).set requirements
|
||||
: [ property-set.empty ] : exact ;
|
||||
$(attributes).set usage-requirements
|
||||
: [ property-set.empty ] : exact ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Associate the given id with the given location
|
||||
@@ -416,9 +424,16 @@ rule project-attributes ( location )
|
||||
{
|
||||
specification = [ property.translate-paths $(specification)
|
||||
: $(self.location) ] ;
|
||||
local current = $(self.requirements) ;
|
||||
local result = [ property.refine $(current) :
|
||||
[ property.make $(specification) ] ] ;
|
||||
specification = [ property.make $(specification) ] ;
|
||||
result = [ property-set.create $(specification) ] ;
|
||||
|
||||
# If we have inherited properties, need to refine them with the
|
||||
# specified.
|
||||
local current = $(self.requirements) ;
|
||||
if $(current)
|
||||
{
|
||||
result = [ $(current).refine $(result) ] ;
|
||||
}
|
||||
|
||||
if $(result[1]) = "@error"
|
||||
{
|
||||
@@ -439,8 +454,17 @@ rule project-attributes ( location )
|
||||
{
|
||||
errors.error "usage-requirements" $($(real-pos2)) "have non-free properties" $(non-free) ;
|
||||
}
|
||||
self.usage-requirements += [ property.translate-paths $(specification)
|
||||
local t = [ property.translate-paths $(specification)
|
||||
: $(self.location) ] ;
|
||||
if $(self.usage-requirements)
|
||||
{
|
||||
self.usage-requirements = [ property-set.create
|
||||
[ $(self.usage-requirements).raw ] $(t) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.usage-requirements = [ property-set.create $(t) ] ;
|
||||
}
|
||||
}
|
||||
else if $(attribute) = "source-location"
|
||||
{
|
||||
@@ -480,7 +504,7 @@ rule project-attributes ( location )
|
||||
print.list-start ;
|
||||
print.list-item "Project root:" $(self.project-root) ;
|
||||
print.list-item "Parent project:" $(parent) ;
|
||||
print.list-item "Requirements:" $(self.requirements) ;
|
||||
print.list-item "Requirements:" [ $(self.requirements).raw ] ;
|
||||
print.list-item "Default build:" $(self.default-build) ;
|
||||
print.list-item "Source location:" $(self.source-location) ;
|
||||
print.list-item "Projects to build:"
|
||||
|
||||
@@ -72,6 +72,7 @@ import regex ;
|
||||
import property ;
|
||||
import errors ;
|
||||
import common ;
|
||||
import property-set ;
|
||||
|
||||
|
||||
# Base class for all abstract targets.
|
||||
@@ -109,7 +110,7 @@ rule abstract-target ( name # name of the target in Jamfile
|
||||
# Adds one more direct build request for this target. If later generate
|
||||
# is called with the same non-free non-incidental properties as in one
|
||||
# of direct build requests, then that build request is used instead.
|
||||
rule direct-build-request ( properties * )
|
||||
rule direct-build-request ( property-set )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -122,7 +123,7 @@ rule abstract-target ( name # name of the target in Jamfile
|
||||
#
|
||||
# If 'properties' are empty, performs default build of this target, in a way specific
|
||||
# to derived class.
|
||||
rule generate ( properties * )
|
||||
rule generate ( property-set )
|
||||
{
|
||||
errors.error "method should be defined in derived classes" ;
|
||||
}
|
||||
@@ -137,29 +138,30 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
self.requirements = $(requirements) ;
|
||||
self.default-build = $(default-build) ;
|
||||
|
||||
rule direct-build-request ( properties * )
|
||||
rule direct-build-request ( property-set )
|
||||
{
|
||||
for local name in $(self.main-targets)
|
||||
{
|
||||
local t = [ main-target $(name) ] ;
|
||||
result += [ $(t).direct-build-request $(properties) ] ;
|
||||
result += [ $(t).direct-build-request $(property-set) ] ;
|
||||
}
|
||||
for local pn in [ project.attribute $(self.project) projects-to-build ]
|
||||
{
|
||||
local p = [ project.module-name $(pn) ] ;
|
||||
local t = [ project.target [ project.attribute $(p) location ] ] ;
|
||||
result += [ $(t).direct-build-request $(properties) ] ;
|
||||
result += [ $(t).direct-build-request $(property-set) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# Generates all possible targets contained in this project.
|
||||
rule generate ( properties * )
|
||||
rule generate ( property-set * )
|
||||
{
|
||||
# Project properties are directly imposed on all main targets.
|
||||
# However, we'd need to check if this project can be build at
|
||||
# all.
|
||||
local xproperties =
|
||||
[ property.refine $(properties) : $(self.requirements) ] ;
|
||||
|
||||
local xproperties = [ $(property-set).refine $(self.requirements) ] ;
|
||||
|
||||
if $(xproperties[1]) = "@error"
|
||||
{
|
||||
local id = [ project.attribute $(self.project) id ] ;
|
||||
@@ -168,7 +170,7 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
"due to unsatisfied requirements." ;
|
||||
print.wrapped-text "warning: explanation: " $(xproperties[2-]) ;
|
||||
print.wrapped-text "warning: build-request: " $(properties) ;
|
||||
print.wrapped-text "warning: requirements: " $(self.requirements) ;
|
||||
print.wrapped-text "warning: requirements: " [ $(self.requirements).raw ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -176,14 +178,14 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
for local name in $(self.main-targets)
|
||||
{
|
||||
local t = [ main-target $(name) ] ;
|
||||
result += [ $(t).generate $(properties) ] ;
|
||||
result += [ $(t).generate $(property-set) ] ;
|
||||
}
|
||||
local self-location = [ project.attribute $(self.project) location ] ;
|
||||
for local pn in [ project.attribute $(self.project) projects-to-build ]
|
||||
{
|
||||
local p = [ project.module-name [ path.join $(self-location) $(pn) ] ] ;
|
||||
local t = [ project.target [ project.attribute $(p) location ] ] ;
|
||||
result += [ $(t).generate $(properties) ] ;
|
||||
result += [ $(t).generate $(property-set) ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
@@ -215,19 +217,19 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
# target in this project, if generation with
|
||||
# 'properties' is requested, and that main target
|
||||
# does not have any requirements of its own.
|
||||
rule reference-properties ( properties * )
|
||||
rule reference-properties ( property-set )
|
||||
{
|
||||
# Note that free properties can appear on 'properties' only
|
||||
# from direct build request, because free properties are not
|
||||
# allowed to be propagated.
|
||||
|
||||
local ref = [ project.attribute $(self.project) requirements ] ;
|
||||
ref = [ property.refine $(properties) : $(ref) ] ;
|
||||
ref = [ property.evaluate-conditionals $(ref) ] ;
|
||||
ref = [ property.take free : [ property.remove incidental : $(ref) ] ] ;
|
||||
ref = [ targets.generate-dependencies $(ref) : $(self.project) ] ;
|
||||
return $(ref) ;
|
||||
}
|
||||
if ! $(self.ref-props.$(property-set))
|
||||
{
|
||||
local ref = [ project.attribute $(self.project) requirements ] ;
|
||||
local ps = [ $(property-set).refine $(ref) ] ;
|
||||
ps = [ $(ps).evaluate-conditionals ] ;
|
||||
|
||||
ps = [ targets.generate-dependencies $(ps) : $(self.project) : $(ps) ] ;
|
||||
self.ref-props.$(property-set) = $(ps) ;
|
||||
}
|
||||
return $(self.ref-props.$(property-set)) ;
|
||||
}
|
||||
|
||||
}
|
||||
class project-target : abstract-target ;
|
||||
@@ -246,9 +248,9 @@ rule main-target ( name : project )
|
||||
self.alternatives += $(target) ;
|
||||
}
|
||||
|
||||
rule direct-build-request ( properties * )
|
||||
rule direct-build-request ( property-set )
|
||||
{
|
||||
local base = [ property.remove free incidental : $(properties) ] ;
|
||||
local base = [ $(property-set).base ] ;
|
||||
local ep = $(self.direct-request.$(base:J=-)) ;
|
||||
if $(ep) && $(ep) != $(properties)
|
||||
{
|
||||
@@ -256,7 +258,7 @@ rule main-target ( name : project )
|
||||
}
|
||||
else
|
||||
{
|
||||
self.direct-request.$(base:J=-) = $(properties) ;
|
||||
self.direct-request.$(base:J=-) = $(property-set) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,13 +267,13 @@ rule main-target ( name : project )
|
||||
# which requirements are satisfied by 'properties' and picking the one with
|
||||
# longest requirements set.
|
||||
# Returns the result of calling 'generate' on that alternative.
|
||||
rule generate ( properties * )
|
||||
rule generate ( property-set )
|
||||
{
|
||||
local base = [ property.remove free incidental : $(properties) ] ;
|
||||
local base = [ $(property-set).base ] ;
|
||||
local ep = $(self.direct-request.$(base:J=-)) ;
|
||||
if $(ep)
|
||||
{
|
||||
properties = $(ep) ;
|
||||
property-set = $(ep) ;
|
||||
}
|
||||
|
||||
# Try to generate all the alternatives.
|
||||
@@ -279,7 +281,7 @@ rule main-target ( name : project )
|
||||
|
||||
for local v in $(self.alternatives)
|
||||
{
|
||||
local vtargets = [ $(v).generate $(properties) ] ;
|
||||
local vtargets = [ $(v).generate $(property-set) ] ;
|
||||
if $(vtargets) && $(vtargets[1]) != "@error"
|
||||
{
|
||||
$(alternatives).push-back [ new vector $(v) $(vtargets) ] ;
|
||||
@@ -291,7 +293,7 @@ rule main-target ( name : project )
|
||||
# why it can't be build.
|
||||
print.wrapped-text
|
||||
"warning: skipped build of" [ full-name ]
|
||||
"with properties" $(properties) ;
|
||||
"with properties" [ $(property-set).raw ] ;
|
||||
} else {
|
||||
local result ;
|
||||
if [ $(alternatives).size ] = 1
|
||||
@@ -314,9 +316,9 @@ rule main-target ( name : project )
|
||||
# have 'requirements' method.
|
||||
# assert.equal [ is-a $(target) : basic-target ] : true ;
|
||||
local req = [ $(target).requirements ] ;
|
||||
req = [ property.remove free incidental : $(req) ] ;
|
||||
req = [ $(req).base ] ;
|
||||
req-length += [ sequence.length
|
||||
[ set.intersection $(req) : $(properties) ] ] ;
|
||||
[ set.intersection $(req) : [ $(property-set).raw ] ] ] ;
|
||||
}
|
||||
|
||||
local best = [ sequence.select-highest-ranked $(r) : $(req-length) ] ;
|
||||
@@ -343,7 +345,7 @@ rule main-target ( name : project )
|
||||
# is created.
|
||||
local all-targets =
|
||||
[ sequence.transform virtual-target.traverse : $(result) ] ;
|
||||
local dg = [ new subvariant-dg $(__name__) : $(properties) : $(all-targets) ] ;
|
||||
local dg = [ new subvariant-dg $(__name__) : $(property-set) : $(all-targets) ] ;
|
||||
for local v in $(all-targets)
|
||||
{
|
||||
$(v).dg $(dg) ;
|
||||
@@ -361,7 +363,7 @@ class main-target : abstract-target ;
|
||||
# reference.
|
||||
rule generate ( target-reference # Target reference
|
||||
: project # Project where the reference is made
|
||||
: properties * # Properties of the main target that
|
||||
: property-set # Properties of the main target that
|
||||
# makes the reference
|
||||
)
|
||||
{
|
||||
@@ -382,8 +384,9 @@ rule generate ( target-reference # Target reference
|
||||
if $(main-target) {
|
||||
# Take properties which should be propagated and refine them
|
||||
# with source-specific requirements.
|
||||
local propagated = [ property.take propagated : $(properties) ] ;
|
||||
local rproperties = [ property.refine $(propagated) : $(sproperties) ] ;
|
||||
local propagated = [ $(property-set).propagated ] ;
|
||||
local rproperties = [ $(propagated).refine
|
||||
[ property-set.create $(sproperties) ] ] ;
|
||||
if $(rproperties[1]) = "@error"
|
||||
{
|
||||
errors.error
|
||||
@@ -395,42 +398,32 @@ rule generate ( target-reference # Target reference
|
||||
}
|
||||
}
|
||||
|
||||
# Returns a list of properties, where all dependency properties are
|
||||
# replaced as follows:
|
||||
# - the value of dependency property is treated as target reference,
|
||||
# which is generated with 'properties' + 'extra-properties'
|
||||
# - the created virtual target's become replace the property value,
|
||||
# for example <library>a/b might become
|
||||
# <library>object(virtual-target)@1
|
||||
# In addition, usage requirements for all created virtual targets
|
||||
# are added to the properties.
|
||||
# Returns new property set which inclues all properties from
|
||||
# 'property-set', except that all dependency properties are
|
||||
# generated with 'generation-ps', and the obtained virtual targets
|
||||
# are added as the values of original features.
|
||||
#
|
||||
# The purpose of 'extra-properties' is to be able to replace dependency
|
||||
# features only in certain set of properties, which does not include
|
||||
# all build properties. A concrete example is when we process use properties.
|
||||
# Dependency features must be replaced using full build properties of target,
|
||||
# but we don't want to add build properties to usage requirements.
|
||||
rule generate-dependencies ( properties * : project : extra-properties * )
|
||||
# For example, <library>a/b might become <library>object(virtual-target)@1
|
||||
# In addition, usage requirements for all created virtual targets
|
||||
# are added to the created property set.
|
||||
rule generate-dependencies ( property-set : project : generation-ps )
|
||||
{
|
||||
local xproperties ;
|
||||
for local p in $(properties)
|
||||
local xproperties ;
|
||||
for local p in [ $(property-set).dependency ]
|
||||
{
|
||||
if dependency in [ feature.attributes $(p:G) ]
|
||||
local g = [ targets.generate $(p:TG=) : $(project) : $(generation-ps) ] ;
|
||||
if ! $(g)
|
||||
{
|
||||
local g = [ targets.generate $(p:TG=) : $(project)
|
||||
: $(properties) $(extra-properties) ] ;
|
||||
if ! $(g)
|
||||
{
|
||||
errors.error "cannot generate dependency " $(p) ;
|
||||
}
|
||||
xproperties += $(p:G)$(g) [ $(g).usage-requirements ] ;
|
||||
errors.error "cannot generate dependency " $(p) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
xproperties += $(p) ;
|
||||
}
|
||||
xproperties += $(p:G)$(g) [ $(g).usage-requirements ] ;
|
||||
}
|
||||
return $(xproperties) ;
|
||||
local r = [ property-set.create
|
||||
[ $(property-set).base ]
|
||||
[ $(property-set).free ]
|
||||
$(xproperties)
|
||||
[ $(property-set).incidental ] ] ;
|
||||
return $(r) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -448,8 +441,15 @@ rule basic-target ( name : project
|
||||
abstract-target.__init__ $(name) : $(project) ;
|
||||
|
||||
self.sources = $(sources) ;
|
||||
if ! $(requirements) {
|
||||
requirements = [ property-set.empty ] ;
|
||||
}
|
||||
self.requirements = $(requirements) ;
|
||||
self.default-build = $(default-build) ;
|
||||
if ! $(usage-requirements)
|
||||
{
|
||||
usage-requirements = [ property-set.empty ] ;
|
||||
}
|
||||
self.usage-requirements = $(usage-requirements) ;
|
||||
|
||||
if $(sources:G)
|
||||
@@ -463,35 +463,31 @@ rule basic-target ( name : project
|
||||
# Generates sources. Calls 'construct'
|
||||
# This method should not be overriden.
|
||||
#
|
||||
rule generate ( properties * )
|
||||
rule generate ( property-set )
|
||||
{
|
||||
if ! $(properties) || $(properties:G) = <toolset>
|
||||
if ! [ $(property-set).raw ]
|
||||
{
|
||||
# CONSIDER: I'm really not sure if this is correct...
|
||||
# FIXME: as in 'build-system' we stick default toolset
|
||||
properties = [ build-request.expand $(properties)
|
||||
$(self.default-build) ] ;
|
||||
properties = [ build-request.expand $(self.default-build) ] ;
|
||||
|
||||
local result = ;
|
||||
for local p in $(properties)
|
||||
{
|
||||
result += [ generate [ feature.split $(p) ] ] ;
|
||||
result += [ generate [ property-set.create [ feature.split $(p) ] ] ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
} else {
|
||||
|
||||
property-path = [ property.as-path
|
||||
[ property.remove free incidental : $(properties) ] ] ;
|
||||
|
||||
property-path = [ property.as-path [ $(property-set).base ] ] ;
|
||||
if ! $(property-path)
|
||||
{
|
||||
property-path = X ;
|
||||
}
|
||||
if ! $(self.generated.$(property-path))
|
||||
{
|
||||
local rproperties =
|
||||
[ property.refine $(properties) : $(self.requirements) ] ;
|
||||
|
||||
rproperties = [ property.evaluate-conditionals $(rproperties) ] ;
|
||||
local rproperties = [ $(property-set).refine $(self.requirements) ] ;
|
||||
|
||||
if $(rproperties[1]) != "@error"
|
||||
{
|
||||
@@ -503,9 +499,12 @@ rule basic-target ( name : project
|
||||
# requirements may also code from dependencies. However, when they
|
||||
# come from dependencies, the value is not target id, but rather
|
||||
# virtual target names, so generators.construct can use them.
|
||||
|
||||
rproperties = [ $(rproperties).evaluate-conditionals ] ;
|
||||
|
||||
local xproperties =
|
||||
[ targets.generate-dependencies $(rproperties) : $(self.project) ] ;
|
||||
[ targets.generate-dependencies $(rproperties) : $(self.project)
|
||||
: $(rproperties) ] ;
|
||||
|
||||
|
||||
local source-targets ;
|
||||
@@ -513,7 +512,7 @@ rule basic-target ( name : project
|
||||
{
|
||||
# Try treating this source as reference to main target
|
||||
local more-targets =
|
||||
[ targets.generate $(s) : $(self.project) : $(properties) ] ;
|
||||
[ targets.generate $(s) : $(self.project) : $(property-set) ] ;
|
||||
if $(more-targets)
|
||||
{
|
||||
source-targets += $(more-targets) ;
|
||||
@@ -529,16 +528,19 @@ rule basic-target ( name : project
|
||||
# unqual to project's reference properties. As the
|
||||
# result, we create per-target bin directory while
|
||||
# it's not really needed.
|
||||
xproperties = [ feature.run-actions $(xproperties) ] ;
|
||||
|
||||
|
||||
xproperties = [ $(xproperties).run-actions ] ;
|
||||
|
||||
self.generated.$(property-path) =
|
||||
[ construct $(source-targets) : $(xproperties) ] ;
|
||||
|
||||
# Apply use requirement of this target to all generated
|
||||
# virtual targets.
|
||||
local xusage-requirements =
|
||||
[ targets.generate-dependencies $(self.usage-requirements)
|
||||
[ targets.generate-dependencies
|
||||
$(self.usage-requirements)
|
||||
: $(self.project) : $(rproperties) ] ;
|
||||
xusage-requirements = [ $(xusage-requirements).raw ] ;
|
||||
|
||||
for local e in $(self.generated.$(property-path))
|
||||
{
|
||||
@@ -579,11 +581,11 @@ rule typed-target ( name : project : type
|
||||
|
||||
self.type = $(type) ;
|
||||
|
||||
rule construct ( source-targets * : properties * )
|
||||
rule construct ( source-targets * : property-set )
|
||||
{
|
||||
local r = [ generators.construct $(self.project) $(self.name) : $(self.type)
|
||||
: $(properties) # [ feature.expand
|
||||
<main-target-type>$(self.type)
|
||||
: [ property-set.create [ $(property-set).raw ] # [ feature.expand
|
||||
<main-target-type>$(self.type) ]
|
||||
# ]
|
||||
: $(source-targets)
|
||||
: allow-composing ] ;
|
||||
@@ -609,8 +611,9 @@ rule main-target-requirements (
|
||||
{
|
||||
local loc = [ project.attribute $(project) location ] ;
|
||||
local requirements = [ property.translate-paths $(specification) : $(loc) ] ;
|
||||
local requirements = [ property-set.create $(requirements) ] ;
|
||||
local project-requirements = [ project.attribute $(project) requirements ] ;
|
||||
requirements = [ property.refine $(project-requirements) : $(requirements) ] ;
|
||||
requirements = [ $(project-requirements).refine $(requirements) ] ;
|
||||
if $(requirements[1]) = "@error"
|
||||
{
|
||||
errors.error "Conflicting requirements for target:" $(requirements) ;
|
||||
@@ -629,11 +632,11 @@ rule main-target-usage-requirements (
|
||||
{
|
||||
local loc = [ project.attribute $(project) location ] ;
|
||||
local project-usage-requirements = [ project.attribute $(project) usage-requirements ] ;
|
||||
|
||||
local usage-requirements = [ property.translate-paths $(specification) : $(loc) ] ;
|
||||
usage-requirements += $(project-usage-requirements) ;
|
||||
|
||||
return $(usage-requirements) ;
|
||||
|
||||
local usage-requirements = [ property-set.create
|
||||
[ property.translate-paths $(specification) : $(loc) ] ] ;
|
||||
|
||||
return [ $(project-usage-requirements).add $(usage-requirements) ] ;
|
||||
}
|
||||
|
||||
# Return the default build value to use when declaring a main target,
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
import class : class new ;
|
||||
import type ;
|
||||
import property-set ;
|
||||
import utility ;
|
||||
|
||||
# +--------------------------+
|
||||
# | virtual-target |
|
||||
@@ -349,8 +351,8 @@ rule abstract-file-target ( name
|
||||
local properties ;
|
||||
if $(self.action)
|
||||
{
|
||||
properties = [ property.remove free incidental : [ $(self.action).properties ] ] ;
|
||||
local property-grist = [ property.as-path $(properties) ] ;
|
||||
local ps = [ $(self.action).properties-ps ] ;
|
||||
local property-grist = [ $(ps).as-path ] ;
|
||||
grist = $(location-grist)/$(property-grist) ;
|
||||
}
|
||||
if ! $(grist)
|
||||
@@ -447,21 +449,16 @@ rule file-target (
|
||||
{
|
||||
if $(self.action)
|
||||
{
|
||||
local properties = [ property.take free : [ property.remove incidental :
|
||||
[ $(self.action).properties ] ] ] ;
|
||||
|
||||
local ps = [ $(self.action).properties-ps ] ;
|
||||
|
||||
local main-target = [ $(self.dg).main-target ] ;
|
||||
local project = [ $(main-target).project ] ;
|
||||
local plocation = [ project.attribute $(project) location ] ;
|
||||
local ptarget = [ project.target $(plocation) ] ;
|
||||
local ref = [ $(ptarget).reference-properties [ $(self.dg).properties ] ] ;
|
||||
local ref-ps = [ $(ptarget).reference-properties [ $(self.dg).properties-ps ] ] ;
|
||||
|
||||
properties = [ sequence.insertion-sort
|
||||
[ sequence.unique $(properties) ] ] ;
|
||||
ref = [ sequence.insertion-sort
|
||||
[ sequence.unique $(ref) ] ] ;
|
||||
|
||||
if $(properties) != $(ref)
|
||||
if [ $(ps).free ] != [ $(ref-ps).free ]
|
||||
{
|
||||
self.extra-path = [ sequence.join main-target- [ $(main-target).name ] ] ;
|
||||
}
|
||||
@@ -491,7 +488,7 @@ rule file-target (
|
||||
[ $(self.action).path ]
|
||||
$(self.extra-path)
|
||||
] ;
|
||||
|
||||
|
||||
return [ path.native $(path) ] ;
|
||||
}
|
||||
}
|
||||
@@ -522,13 +519,24 @@ rule remember-binding ( target : bound-path )
|
||||
# rule action-name ( targets + : sources * : properties * )
|
||||
# Targets and sources are passed as actual jam targets. The rule may
|
||||
# not establish dependency relationship, but should do everything else.
|
||||
rule action ( targets + : sources * : action-name : properties * )
|
||||
rule action ( targets + : sources * : action-name : property-set ? )
|
||||
{
|
||||
self.targets = $(targets) ;
|
||||
self.sources = $(sources) ;
|
||||
self.action-name = $(action-name) ;
|
||||
self.properties = $(properties) ;
|
||||
|
||||
|
||||
if ! $(property-set)
|
||||
{
|
||||
property-set = [ property-set.empty ] ;
|
||||
}
|
||||
|
||||
if ! [ class.is-instance $(property-set) ]
|
||||
{
|
||||
errors.error "Property set instance required" ;
|
||||
}
|
||||
|
||||
self.properties = $(property-set) ;
|
||||
|
||||
rule targets ( )
|
||||
{
|
||||
return $(self.targets) ;
|
||||
@@ -544,7 +552,7 @@ rule action ( targets + : sources * : action-name : properties * )
|
||||
return $(self.action-name) ;
|
||||
}
|
||||
|
||||
rule properties ( )
|
||||
rule properties-ps ( )
|
||||
{
|
||||
return $(self.properties) ;
|
||||
}
|
||||
@@ -556,7 +564,8 @@ rule action ( targets + : sources * : action-name : properties * )
|
||||
{
|
||||
self.actualized = true ;
|
||||
|
||||
local properties = [ adjust-properties [ properties ] ] ;
|
||||
local ps = [ properties-ps ] ;
|
||||
local properties = [ adjust-properties [ $(ps).raw ] ] ;
|
||||
|
||||
|
||||
local actual-targets ;
|
||||
@@ -601,12 +610,10 @@ rule action ( targets + : sources * : action-name : properties * )
|
||||
|
||||
rule path ( )
|
||||
{
|
||||
local subvariant = [ property.remove free incidental : $(self.properties) ] ;
|
||||
local pp = [ property.as-path $(subvariant) ] ;
|
||||
return $(pp) ;
|
||||
local p = [ $(self.properties).as-path ] ;
|
||||
return $(p) ;
|
||||
}
|
||||
|
||||
|
||||
# Determined real properties when trying building with 'properties'.
|
||||
# This is last chance to fix properties, for example to adjust includes
|
||||
# to get generated headers correctly. Default implementation returns
|
||||
@@ -678,7 +685,7 @@ rule register ( target )
|
||||
result = $(t) ;
|
||||
}
|
||||
else if $(a1) && $(a2) && [ $(a1).action-name ] = [ $(a2).action-name ]
|
||||
&& [ $(a1).properties ] = [ $(a2).properties ] && [ $(a1).sources ] = [ $(a2).sources ]
|
||||
&& [ $(a1).properties-ps ] = [ $(a2).properties-ps ] && [ $(a1).sources ] = [ $(a2).sources ]
|
||||
{
|
||||
result = $(t) ;
|
||||
}
|
||||
@@ -801,18 +808,19 @@ local rule clone-action-template ( action from cloned-from : new-source )
|
||||
|
||||
local action-class = [ modules.peek $(action) : __class__ ] ;
|
||||
|
||||
local ps = [ $(action).properties-ps ] ;
|
||||
local cloned = [ new $(action-class) [ $(action).targets ] : $(sources)
|
||||
: [ $(action).action-name ] : [ $(action).properties ] ] ;
|
||||
: [ $(action).action-name ] : $(ps) ] ;
|
||||
|
||||
return $(cloned) ;
|
||||
}
|
||||
|
||||
local rule subvariant-dg ( main-target # The instance of main-target class
|
||||
: properties * # Properties requested for this target
|
||||
: property-set # Properties requested for this target
|
||||
: virtual-targets * )
|
||||
{
|
||||
self.main-target = $(main-target) ;
|
||||
self.properties = $(properties) ;
|
||||
self.properties = $(property-set) ;
|
||||
self.virtual-targets = $(virtual-targets) ;
|
||||
|
||||
# Pre-compose the list of other dependency graphs, on which this one
|
||||
@@ -836,19 +844,28 @@ local rule subvariant-dg ( main-target # The instance of main-target class
|
||||
}
|
||||
}
|
||||
self.other-dg = [ sequence.unique $(self.other-dg) ] ;
|
||||
|
||||
|
||||
rule main-target ( )
|
||||
{
|
||||
return $(self.main-target) ;
|
||||
}
|
||||
|
||||
rule properties ( )
|
||||
rule properties-ps ( )
|
||||
{
|
||||
return $(self.properties) ;
|
||||
}
|
||||
|
||||
|
||||
rule all-target-directories ( )
|
||||
{
|
||||
if ! $(self.target-directories)
|
||||
{
|
||||
compute-target-directories ;
|
||||
}
|
||||
return $(self.target-directories) ;
|
||||
}
|
||||
|
||||
rule compute-target-directories ( )
|
||||
{
|
||||
local result ;
|
||||
for local t in $(self.virtual-targets)
|
||||
{
|
||||
@@ -858,8 +875,8 @@ local rule subvariant-dg ( main-target # The instance of main-target class
|
||||
{
|
||||
result += [ $(d).all-target-directories ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
self.target-directories = $(result) ;
|
||||
}
|
||||
}
|
||||
|
||||
class subvariant-dg ;
|
||||
|
||||
@@ -293,8 +293,9 @@ rule lib-generator ( )
|
||||
{
|
||||
composing-generator.__init__ lib-generator : : LIB : <main-target-type>LIB ;
|
||||
|
||||
rule run ( project name ? : properties * : sources * )
|
||||
rule run ( project name ? : property-set : sources * )
|
||||
{
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
# Determine the needed target type
|
||||
local actual-type ;
|
||||
if <search> in $(properties:G) || <name> in $(properties:G)
|
||||
@@ -311,8 +312,8 @@ rule lib-generator ( )
|
||||
}
|
||||
# Construct the target. Pass 'allow-composing', since generators for
|
||||
# library types are composing and we need to find them.
|
||||
return [ generators.construct $(project) $(name) : $(actual-type) : $(properties)
|
||||
: $(sources) : allow-composing ] ;
|
||||
return [ generators.construct $(project) $(name) : $(actual-type)
|
||||
: $(property-set) : $(sources) : allow-composing ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,21 +12,23 @@ import property ;
|
||||
import errors : error ;
|
||||
import type : type ;
|
||||
import regex ;
|
||||
import property-set ;
|
||||
|
||||
rule make-target-class ( name : project : sources * : requirements *
|
||||
: make-rule + : default-build * )
|
||||
{
|
||||
basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements)
|
||||
: $(default-build) ;
|
||||
|
||||
self.make-rule = $(make-rule) ;
|
||||
|
||||
rule construct ( source-targets * : properties * )
|
||||
rule construct ( source-targets * : property-set )
|
||||
{
|
||||
local t = [ new file-target $(self.name:S=) : [ type.type $(self.name:S) ]
|
||||
: $(self.project) ] ;
|
||||
$(t).suffix [ regex.match .(.*) : $(self.name:S) ] ;
|
||||
local a = [ new action $(t) : $(source-targets) : $(self.make-rule)
|
||||
: $(properties) ] ;
|
||||
: $(property-set) ] ;
|
||||
$(t).action $(a) ;
|
||||
return $(t) ;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ rule prebuilt-file-generator
|
||||
{
|
||||
generator.__init__ prebuilt-file-generator : : * : <file> ;
|
||||
|
||||
rule run ( project name ? : properties * : sources * )
|
||||
rule run ( project name ? : property-set : sources * )
|
||||
{
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
local name = [ feature.get-values <file> : $(properties) ] ;
|
||||
local type = [ type.type $(name:S) ] ;
|
||||
if ! $(type)
|
||||
@@ -42,7 +43,7 @@ rule prebuilt-file-generator
|
||||
# Therefore, we encode properties via 'extra-grist', which is ugly.
|
||||
# Maybe, we should just introduce 'do-nothing-action', which only
|
||||
# keps properties.
|
||||
$(t).extra-grist [ property.as-path $(properties) ] ;
|
||||
$(t).extra-grist [ $(property-set).as-path ] ;
|
||||
$(t).suffix [ MATCH .(.*) : $(name:S) ] ;
|
||||
return $(t) ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user