|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import "class" : new ; |
|
import errors ; |
|
import path ; |
|
import sequence ; |
|
import set ; |
|
import type ; |
|
import utility ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class virtual-target |
|
{ |
|
import scanner ; |
|
import sequence ; |
|
import utility ; |
|
import virtual-target ; |
|
|
|
rule __init__ ( |
|
name |
|
: project |
|
) |
|
{ |
|
self.name = $(name) ; |
|
self.project = $(project) ; |
|
self.dependencies = ; |
|
} |
|
|
|
|
|
|
|
rule name ( ) |
|
{ |
|
return $(self.name) ; |
|
} |
|
|
|
|
|
|
|
rule project ( ) |
|
{ |
|
return $(self.project) ; |
|
} |
|
|
|
|
|
|
|
rule depends ( d + ) |
|
{ |
|
self.dependencies = [ sequence.merge $(self.dependencies) : |
|
[ sequence.insertion-sort $(d) ] ] ; |
|
} |
|
|
|
rule dependencies ( ) |
|
{ |
|
return $(self.dependencies) ; |
|
} |
|
|
|
rule always ( ) |
|
{ |
|
.always = 1 ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule actualize ( scanner ? ) |
|
{ |
|
local actual-name = [ actualize-no-scanner ] ; |
|
|
|
if $(.always) |
|
{ |
|
ALWAYS $(actual-name) ; |
|
} |
|
|
|
if ! $(scanner) |
|
{ |
|
return $(actual-name) ; |
|
} |
|
else |
|
{ |
|
|
|
local g = [ sequence.join |
|
[ utility.ungrist $(actual-name:G) ] $(scanner) : - ] ; |
|
local name = $(actual-name:G=$(g)) ; |
|
|
|
if ! $(self.made.$(name)) |
|
{ |
|
self.made.$(name) = true ; |
|
|
|
DEPENDS $(name) : $(actual-name) ; |
|
|
|
actualize-location $(name) ; |
|
|
|
scanner.install $(scanner) : $(name) $(__name__) ; |
|
} |
|
return $(name) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
rule actualize-action ( target ) |
|
{ |
|
errors.error "method should be defined in derived classes" ; |
|
} |
|
|
|
|
|
|
|
rule actualize-location ( target ) |
|
{ |
|
errors.error "method should be defined in derived classes" ; |
|
} |
|
|
|
|
|
|
|
|
|
rule path ( ) |
|
{ |
|
errors.error "method should be defined in derived classes" ; |
|
} |
|
|
|
|
|
|
|
|
|
rule actual-name ( ) |
|
{ |
|
errors.error "method should be defined in derived classes" ; |
|
} |
|
|
|
|
|
rule actualize-no-scanner ( ) |
|
{ |
|
|
|
|
|
|
|
|
|
errors.error "method should be defined in derived classes" ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class abstract-file-target : virtual-target |
|
{ |
|
import project ; |
|
import regex ; |
|
import sequence ; |
|
import path ; |
|
import type ; |
|
import property-set ; |
|
import indirect ; |
|
|
|
rule __init__ ( |
|
name |
|
exact ? |
|
|
|
|
|
|
|
: type ? |
|
: project |
|
: action ? |
|
) |
|
{ |
|
virtual-target.__init__ $(name) : $(project) ; |
|
|
|
self.type = $(type) ; |
|
self.action = $(action) ; |
|
if $(action) |
|
{ |
|
$(action).add-targets $(__name__) ; |
|
|
|
if $(self.type) && ! $(exact) |
|
{ |
|
_adjust-name $(name) ; |
|
} |
|
} |
|
} |
|
|
|
rule type ( ) |
|
{ |
|
return $(self.type) ; |
|
} |
|
|
|
|
|
|
|
|
|
rule set-path ( path ) |
|
{ |
|
self.path = [ path.native $(path) ] ; |
|
} |
|
|
|
|
|
|
|
rule action ( ) |
|
{ |
|
return $(self.action) ; |
|
} |
|
|
|
|
|
|
|
|
|
rule root ( set ? ) |
|
{ |
|
if $(set) |
|
{ |
|
self.root = true ; |
|
} |
|
return $(self.root) ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
rule creating-subvariant ( s ? |
|
|
|
|
|
) |
|
{ |
|
if $(s) && ! $(self.creating-subvariant) |
|
{ |
|
self.creating-subvariant = $(s) ; |
|
} |
|
return $(self.creating-subvariant) ; |
|
} |
|
|
|
rule actualize-action ( target ) |
|
{ |
|
if $(self.action) |
|
{ |
|
$(self.action).actualize ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule str ( ) |
|
{ |
|
local action = [ action ] ; |
|
local name-dot-type = [ sequence.join $(self.name) "." $(self.type) ] ; |
|
|
|
if $(action) |
|
{ |
|
local sources = [ $(action).sources ] ; |
|
local action-name = [ $(action).action-name ] ; |
|
|
|
local ss ; |
|
for local s in $(sources) |
|
{ |
|
ss += [ $(s).str ] ; |
|
} |
|
|
|
return "{" $(action-name)-$(name-dot-type) $(ss) "}" ; |
|
} |
|
else |
|
{ |
|
return "{" $(name-dot-type) "}" ; |
|
} |
|
} |
|
|
|
rule less ( a ) |
|
{ |
|
if [ str ] < [ $(a).str ] |
|
{ |
|
return true ; |
|
} |
|
} |
|
|
|
rule equal ( a ) |
|
{ |
|
if [ str ] = [ $(a).str ] |
|
{ |
|
return true ; |
|
} |
|
} |
|
|
|
|
|
rule actual-name ( ) |
|
{ |
|
if ! $(self.actual-name) |
|
{ |
|
local grist = [ grist ] ; |
|
local basename = [ path.native $(self.name) ] ; |
|
self.actual-name = <$(grist)>$(basename) ; |
|
} |
|
return $(self.actual-name) ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
rule grist ( ) |
|
{ |
|
|
|
|
|
|
|
local path = [ path ] ; |
|
if $(path) |
|
{ |
|
|
|
|
|
return p$(path) ; |
|
} |
|
else |
|
{ |
|
|
|
|
|
local project-location = [ $(self.project).get location ] ; |
|
local location-grist = [ sequence.join [ regex.split |
|
$(project-location) "/" ] : "!" ] ; |
|
|
|
if $(self.action) |
|
{ |
|
local ps = [ $(self.action).properties ] ; |
|
local property-grist = [ $(ps).as-path ] ; |
|
|
|
|
|
if $(property-grist) |
|
{ |
|
location-grist = $(location-grist)/$(property-grist) ; |
|
} |
|
} |
|
|
|
return l$(location-grist) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule _adjust-name ( specified-name ) |
|
{ |
|
local ps ; |
|
if $(self.action) |
|
{ |
|
ps = [ $(self.action).properties ] ; |
|
} |
|
else |
|
{ |
|
ps = [ property-set.empty ] ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
ps = [ property-set.create [ $(ps).raw ] <target>$(__name__) ] ; |
|
|
|
local tag = [ $(ps).get <tag> ] ; |
|
|
|
if $(tag) |
|
{ |
|
local rule-name = [ MATCH ^@(.*) : $(tag) ] ; |
|
if $(rule-name) |
|
{ |
|
if $(tag[2]) |
|
{ |
|
errors.error "<tag>@rulename is present but is not the only" |
|
"<tag> feature" ; |
|
} |
|
|
|
self.name = [ indirect.call $(rule-name) $(specified-name) |
|
: $(self.type) : $(ps) ] ; |
|
} |
|
else |
|
{ |
|
errors.error |
|
"The value of the <tag> feature must be '@rule-name'" ; |
|
} |
|
} |
|
|
|
|
|
if ! $(tag) || ! $(self.name) |
|
{ |
|
self.name = [ virtual-target.add-prefix-and-suffix $(specified-name) |
|
: $(self.type) : $(ps) ] ; |
|
} |
|
} |
|
|
|
rule actualize-no-scanner ( ) |
|
{ |
|
local name = [ actual-name ] ; |
|
|
|
|
|
if ! $(self.made.$(name)) |
|
{ |
|
self.made.$(name) = true ; |
|
|
|
if $(self.action) |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
virtual-target.register-actual-name $(name) : $(__name__) ; |
|
} |
|
|
|
for local i in $(self.dependencies) |
|
{ |
|
DEPENDS $(name) : [ $(i).actualize ] ; |
|
} |
|
|
|
actualize-location $(name) ; |
|
actualize-action $(name) ; |
|
} |
|
return $(name) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
rule add-prefix-and-suffix ( specified-name : type ? : property-set ) |
|
{ |
|
local suffix = [ type.generated-target-suffix $(type) : $(property-set) ] ; |
|
|
|
|
|
|
|
|
|
if $(suffix:G) |
|
{ |
|
suffix = [ utility.ungrist $(suffix) ] ; |
|
} |
|
else |
|
{ |
|
suffix = .$(suffix) ; |
|
} |
|
|
|
local prefix = [ type.generated-target-prefix $(type) : $(property-set) ] ; |
|
|
|
if [ MATCH ^($(prefix)) : $(specified-name) ] |
|
{ |
|
prefix = ; |
|
} |
|
return $(prefix:E="")$(specified-name)$(suffix:E="") ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class file-target : abstract-file-target |
|
{ |
|
import "class" : new ; |
|
import common ; |
|
import errors ; |
|
|
|
rule __init__ ( |
|
name exact ? |
|
: type ? |
|
: project |
|
: action ? |
|
: path ? |
|
) |
|
{ |
|
abstract-file-target.__init__ $(name) $(exact) : $(type) : $(project) : |
|
$(action) ; |
|
|
|
self.path = $(path) ; |
|
} |
|
|
|
rule clone-with-different-type ( new-type ) |
|
{ |
|
return [ new file-target $(self.name) exact : $(new-type) : |
|
$(self.project) : $(self.action) : $(self.path) ] ; |
|
} |
|
|
|
rule actualize-location ( target ) |
|
{ |
|
if $(self.action) |
|
{ |
|
|
|
local path = [ path ] ; |
|
LOCATE on $(target) = $(path) ; |
|
|
|
|
|
DEPENDS $(target) : $(path) ; |
|
common.MkDir $(path) ; |
|
|
|
|
|
|
|
if $(target:D) |
|
{ |
|
local d = $(target:D) ; |
|
d = $(d:R=$(path)) ; |
|
DEPENDS $(target) : $(d) ; |
|
common.MkDir $(d) ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEPENDS $(target:G=e) : $(target) ; |
|
|
|
|
|
|
|
DEPENDS $(target:G=e:R=$(path)) : $(target) ; |
|
} |
|
else |
|
{ |
|
SEARCH on $(target) = [ path.native $(self.path) ] ; |
|
} |
|
} |
|
|
|
|
|
|
|
rule path ( ) |
|
{ |
|
if ! $(self.path) |
|
{ |
|
if $(self.action) |
|
{ |
|
local p = [ $(self.action).properties ] ; |
|
local path,relative-to-build-dir = [ $(p).target-path ] ; |
|
local path = $(path,relative-to-build-dir[1]) ; |
|
local relative-to-build-dir = $(path,relative-to-build-dir[2]) ; |
|
|
|
if $(relative-to-build-dir) |
|
{ |
|
path = [ path.join [ $(self.project).build-dir ] $(path) ] ; |
|
} |
|
|
|
self.path = [ path.native $(path) ] ; |
|
} |
|
} |
|
return $(self.path) ; |
|
} |
|
} |
|
|
|
|
|
class notfile-target : abstract-file-target |
|
{ |
|
rule __init__ ( name : project : action ? ) |
|
{ |
|
abstract-file-target.__init__ $(name) : : $(project) : $(action) ; |
|
} |
|
|
|
|
|
|
|
rule path ( ) |
|
{ |
|
return ; |
|
} |
|
|
|
rule actualize-location ( target ) |
|
{ |
|
NOTFILE $(target) ; |
|
ALWAYS $(target) ; |
|
|
|
NOUPDATE $(target) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class action |
|
{ |
|
import "class" ; |
|
import errors ; |
|
import type ; |
|
import toolset ; |
|
import property-set ; |
|
import indirect ; |
|
import path ; |
|
import set : difference ; |
|
|
|
rule __init__ ( sources * : action-name + : property-set ? ) |
|
{ |
|
self.sources = $(sources) ; |
|
|
|
self.action-name = [ indirect.make-qualified $(action-name) ] ; |
|
|
|
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 add-targets ( targets * ) |
|
{ |
|
self.targets += $(targets) ; |
|
} |
|
|
|
rule replace-targets ( old-targets * : new-targets * ) |
|
{ |
|
self.targets = [ set.difference $(self.targets) : $(old-targets) ] ; |
|
self.targets += $(new-targets) ; |
|
} |
|
|
|
rule targets ( ) |
|
{ |
|
return $(self.targets) ; |
|
} |
|
|
|
rule sources ( ) |
|
{ |
|
return $(self.sources) ; |
|
} |
|
|
|
rule action-name ( ) |
|
{ |
|
return $(self.action-name) ; |
|
} |
|
|
|
rule properties ( ) |
|
{ |
|
return $(self.properties) ; |
|
} |
|
|
|
|
|
|
|
rule actualize ( ) |
|
{ |
|
if ! $(self.actualized) |
|
{ |
|
self.actualized = true ; |
|
|
|
local ps = [ properties ] ; |
|
local properties = [ adjust-properties $(ps) ] ; |
|
|
|
local actual-targets ; |
|
for local i in [ targets ] |
|
{ |
|
actual-targets += [ $(i).actualize ] ; |
|
} |
|
|
|
actualize-sources [ sources ] : $(properties) ; |
|
|
|
DEPENDS $(actual-targets) : $(self.actual-sources) |
|
$(self.dependency-only-sources) ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if $(actual-targets[2]) |
|
{ |
|
INCLUDES $(actual-targets) : $(actual-targets) ; |
|
} |
|
|
|
|
|
|
|
toolset.set-target-variables |
|
[ indirect.get-rule $(self.action-name[1]) ] $(actual-targets) |
|
: $(properties) ; |
|
|
|
|
|
|
|
|
|
|
|
.action on $(actual-targets) = $(__name__) ; |
|
|
|
indirect.call $(self.action-name) $(actual-targets) |
|
: $(self.actual-sources) : [ $(properties).raw ] ; |
|
|
|
|
|
|
|
common.Clean clean-all : $(actual-targets) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
rule actualize-source-type ( sources * : property-set ) |
|
{ |
|
local result = ; |
|
for local i in $(sources) |
|
{ |
|
local scanner ; |
|
if [ $(i).type ] |
|
{ |
|
scanner = [ type.get-scanner [ $(i).type ] : $(property-set) ] ; |
|
} |
|
result += [ $(i).actualize $(scanner) ] ; |
|
} |
|
return $(result) ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule actualize-sources ( sources * : property-set ) |
|
{ |
|
local dependencies = [ $(self.properties).get <dependency> ] ; |
|
|
|
self.dependency-only-sources += |
|
[ actualize-source-type $(dependencies) : $(property-set) ] ; |
|
self.actual-sources += |
|
[ actualize-source-type $(sources) : $(property-set) ] ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local implicit = [ $(self.properties).get <implicit-dependency> ] ; |
|
for local i in $(implicit) |
|
{ |
|
$(i:G=).actualize ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
rule adjust-properties ( property-set ) |
|
{ |
|
return $(property-set) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class null-action : action |
|
{ |
|
rule __init__ ( property-set ? ) |
|
{ |
|
action.__init__ : .no-action : $(property-set) ; |
|
} |
|
|
|
rule actualize ( ) |
|
{ |
|
if ! $(self.actualized) |
|
{ |
|
self.actualized = true ; |
|
for local i in [ targets ] |
|
{ |
|
$(i).actualize ; |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
class non-scanning-action : action |
|
{ |
|
rule __init__ ( sources * : action-name + : property-set ? ) |
|
{ |
|
action.__init__ $(sources) : $(action-name) : $(property-set) ; |
|
} |
|
|
|
rule actualize-source-type ( sources * : property-set ) |
|
{ |
|
local result ; |
|
for local i in $(sources) |
|
{ |
|
result += [ $(i).actualize ] ; |
|
} |
|
return $(result) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule from-file ( file : file-loc : project ) |
|
{ |
|
import type ; |
|
|
|
|
|
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) : : |
|
$(file-loc) ] ; |
|
|
|
.files.$(path) = $(result) ; |
|
return $(result) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule register ( target ) |
|
{ |
|
local signature = [ sequence.join |
|
[ $(target).path ] [ $(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 ] [ set.difference |
|
[ $(ps1).dependency ] : [ $(ps1).incidental ] ] ; |
|
local p2 = [ $(ps2).base ] [ $(ps2).free ] [ set.difference |
|
[ $(ps2).dependency ] : [ $(ps2).incidental ] ] ; |
|
if $(p1) = $(p2) |
|
{ |
|
result = $(t) ; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ! $(result) |
|
{ |
|
.cache.$(signature) += $(target) ; |
|
result = $(target) ; |
|
} |
|
|
|
.recent-targets += $(result) ; |
|
.all-targets += $(result) ; |
|
|
|
return $(result) ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule recent-targets ( ) |
|
{ |
|
return $(.recent-targets) ; |
|
} |
|
|
|
|
|
rule clear-recent-targets ( ) |
|
{ |
|
.recent-targets = ; |
|
} |
|
|
|
|
|
|
|
|
|
rule all-targets ( ) |
|
{ |
|
return $(.all-targets) ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
rule select-by-type ( type : targets * ) |
|
{ |
|
local result ; |
|
for local t in $(targets) |
|
{ |
|
if [ type.is-subtype [ $(t).type ] $(type) ] |
|
{ |
|
result += $(t) ; |
|
} |
|
} |
|
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) ; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule traverse ( target : include-roots ? : include-sources ? ) |
|
{ |
|
local result ; |
|
if [ $(target).action ] |
|
{ |
|
local action = [ $(target).action ] ; |
|
|
|
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) ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 ] ; |
|
|
|
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 |
|
: property-set |
|
: sources * |
|
: build-properties |
|
: sources-usage-requirements |
|
: 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) ; |
|
|
|
|
|
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) ; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
rule all-referenced-targets ( theset ) |
|
{ |
|
|
|
local deps = [ $(self.build-properties).dependency ] ; |
|
local all-targets = $(self.sources) $(deps) ; |
|
|
|
|
|
local r ; |
|
for local t in $(all-targets) |
|
{ |
|
if ! [ $(theset).contains $(t) ] |
|
{ |
|
$(theset).add $(t) ; |
|
r += [ $(t:G=).creating-subvariant ] ; |
|
} |
|
} |
|
r = [ sequence.unique $(r) ] ; |
|
for local s in $(r) |
|
{ |
|
if $(s) != $(__name__) |
|
{ |
|
$(s).all-referenced-targets $(theset) ; |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rule implicit-includes ( feature : target-type ? ) |
|
{ |
|
local key = ii$(feature)-$(target-type:E="") ; |
|
if ! $($(key))-is-not-empty |
|
{ |
|
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) ] |
|
{ |
|
result = [ sequence.merge $(result) : [ $(t).path ] ] ; |
|
} |
|
} |
|
for local d in $(self.other-dg) |
|
{ |
|
result += [ $(d).all-target-directories $(target-type) ] ; |
|
} |
|
self.target-directories = $(result) ; |
|
} |
|
} |
|
|