blob: 6732fa3551e6469a1729ad7b3328814b8501d659 [file] [log] [blame]
# Copyright 2006 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# Declares main target 'generate' used to produce targets by calling a
# user-provided rule that takes and produces virtual targets.
import "class" : new ;
import errors ;
import feature ;
import project ;
import property ;
import property-set ;
import targets ;
import regex ;
feature.feature generating-rule : : free ;
class generated-target-class : basic-target
{
import errors ;
import indirect ;
import virtual-target ;
rule __init__ ( name : project : sources * : requirements *
: default-build * : usage-requirements * )
{
basic-target.__init__ $(name) : $(project) : $(sources)
: $(requirements) : $(default-build) : $(usage-requirements) ;
if ! [ $(self.requirements).get <generating-rule> ]
{
errors.user-error "The generate rule requires the <generating-rule>"
"property to be set" ;
}
}
rule construct ( name : sources * : property-set )
{
local result ;
local gr = [ $(property-set).get <generating-rule> ] ;
# FIXME: this is a copy-paste from virtual-target.jam. We should add a
# utility rule to call a rule like this.
local rule-name = [ MATCH ^@(.*) : $(gr) ] ;
if $(rule-name)
{
if $(gr[2])
{
local target-name = [ full-name ] ;
errors.user-error "Multiple <generating-rule> properties"
"encountered for target $(target-name)." ;
}
result = [ indirect.call $(rule-name) $(self.project) $(name)
: $(property-set) : $(sources) ] ;
if ! $(result)
{
ECHO "warning: Unable to construct" [ full-name ] ;
}
}
local ur ;
local targets ;
if $(result)
{
if [ class.is-a $(result[1]) : property-set ]
{
ur = $(result[1]) ;
targets = $(result[2-]) ;
}
else
{
ur = [ property-set.empty ] ;
targets = $(result) ;
}
}
# FIXME: the following loop should be doable using sequence.transform or
# some similar utility rule.
local rt ;
for local t in $(targets)
{
rt += [ virtual-target.register $(t) ] ;
}
return $(ur) $(rt) ;
}
}
rule generate ( name : sources * : requirements * : default-build *
: usage-requirements * )
{
local project = [ project.current ] ;
targets.main-target-alternative
[ new generated-target-class $(name) : $(project)
: [ targets.main-target-sources $(sources) : $(name) ]
: [ targets.main-target-requirements $(requirements) : $(project) ]
: [ targets.main-target-default-build $(default-build) : $(project) ]
: [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
] ;
}
IMPORT $(__name__) : generate : : generate ;