2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 01:12:13 +00:00

Allow the 'stage' rule to traverse dependencies.

* build/virtual-target.jam
  (subvariant.__init__): New parameter 'sources'.
  (subvariant.all-referenced-targets): New method.

* build/targets.jam
  (basic-target.create-subvariant): New parameter 'sources'.

* built/type.jam
  (is-subtype): New rule.

* tools/stage.jam
  (stage-target-class.construct): Traverse dependencies when requested.
  (stage-target-class.collect-targets): New method.


[SVN r20534]
This commit is contained in:
Vladimir Prus
2003-10-29 06:08:44 +00:00
parent 9776888f81
commit 88783cf4e3
5 changed files with 162 additions and 5 deletions

View File

@@ -917,7 +917,7 @@ class basic-target : abstract-target
check-for-unused-sources
$(result) : $(source-target-groups) ;
local s = [ create-subvariant $(result) : $(property-set)
local s = [ create-subvariant $(result) : $(property-set) : $(source-targets)
: $(rproperties) : $(usage-requirements) ] ;
self.generated.$(property-set) =
@@ -954,7 +954,8 @@ class basic-target : abstract-target
}
# Creates a new subvariant-dg instances for 'targets'
local rule create-subvariant ( targets * : build-request : rproperties
local rule create-subvariant ( targets * : build-request : sources * :
rproperties
: usage-requirements )
{
for local e in $(targets)
@@ -966,7 +967,7 @@ class basic-target : abstract-target
# is created.
local all-targets =
[ sequence.transform virtual-target.traverse : $(targets) ] ;
local dg = [ new subvariant $(__name__) : $(build-request)
local dg = [ new subvariant $(__name__) : $(build-request) : $(sources)
: $(rproperties) : $(usage-requirements) : $(all-targets) ] ;
for local v in $(all-targets)
{

View File

@@ -183,6 +183,21 @@ rule is-derived ( type base )
}
}
# Returns true if 'type' is either derived from 'base',
# or 'type' is equal to 'base'.
rule is-subtype ( type base )
{
if $(type) = $(base)
{
return true ;
}
else
{
return [ is-derived $(type) $(base) ] ;
}
}
# Sets a target suffix that should be used when generating target
# of 'type' with the specified properties. Can be called with
# empty properties if no suffix for 'type' was specified yet.

View File

@@ -895,12 +895,14 @@ class subvariant
rule __init__ ( main-target # The instance of main-target class
: property-set # Properties requested for this target
: sources *
: build-properties # Actually used properties
: sources-usage-requirements # Properties propagated from sources
: created-targets * ) # Top-level created targets
{
self.main-target = $(main-target) ;
self.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) ;
@@ -941,6 +943,33 @@ class subvariant
{
return $(self.sources-usage-requirements) ;
}
# Returns all targets referenced by this subvariant,
# either directly or indirectly, and
# either as sources, or as dependency properties.
rule all-referenced-targets ( )
{
# Find directly referenced targets.
local deps = [ $(self.build-properties).dependency ] ;
local all-targets = $(self.sources) $(deps:G=) ;
# Find other subvariants.
local r ;
for local t in $(all-targets)
{
r += [ $(t).dg ] ;
}
r = [ sequence.unique $(r) ] ;
for local s in $(r)
{
if $(s) != $(__name__)
{
all-targets += [ $(s).all-referenced-targets ] ;
}
}
return $(all-targets) ;
}
# Returns a list of properties which contain implicit includes,
# needed to handle dependencies of generated headers.

View File

@@ -110,4 +110,34 @@ myexe a : a.cpp ;
t.run_build_system()
t.expect_addition("dist/a.myexe")
# Test 'stage's ability to traverse dependencies.
t.write("a.cpp", """
int main() { return 0; }
""")
t.write("l.cpp", """
void
#if defined(_WIN32)
__declspec(dllexport)
#endif
foo() { }
""")
t.write("Jamfile", """
lib l : l.cpp ;
exe a : a.cpp l ;
stage dist : a : <traverse-dependencies>on <include-type>EXE <include-type>LIB ;
""")
t.write("project-root.jam", "")
t.rm("dist")
t.run_build_system()
t.expect_addition("dist/a.exe")
t.expect_addition("dist/l.dll")
t.cleanup()

View File

@@ -26,6 +26,26 @@
#
# - <name> tells the new name of the staged target. In this case, only
# one target can be specified in sources.
#
# The stage rule can also traverse dependencies, for example to install a
# program an all required libraries. Two properties affect this.
#
# - <traverse-dependencies>on tells that dependencies should be traversed.
# For each target in 'stage' sources, all sources to that target and all
# dependency properties are traversed. Sources and dependecy properties of
# those target are traversed recursively.
#
# - <include-type>SOME_TYPE tells that targets of SOME_TYPE or a type derived
# from SOME_TYPE, should be included.
# If no such property is specified, then all found targets will be staged.
# Otherwise, only targets with types mentioned in <include-type> property
# will be included.
#
# Example usage::
#
# stage dist : hello_world :
# <traverse-dependencies>on <include-type>EXE <include-type>SHARED_LIB ;
#
import targets ;
import "class" : new ;
@@ -35,6 +55,10 @@ import type : type ;
import type ;
import regex ;
import generators ;
import feature ;
feature.feature <traverse-dependencies> : off on : incidental ;
feature.feature <include-type> : : free incidental ;
class stage-target-class : basic-target
{
@@ -54,7 +78,13 @@ class stage-target-class : basic-target
{
errors.error "<name> property cannot be specified when staging several targets" ;
}
if [ $(property-set).get <traverse-dependencies> ] = "on"
{
source-targets = [ collect-targets $(source-targets)
: [ $(property-set).get <include-type> ] ] ;
}
local location = [ feature.get-values <location> :
[ $(property-set).raw ] ] ;
if ! $(location)
@@ -115,11 +145,63 @@ class stage-target-class : basic-target
return $(result) ;
}
rule collect-targets ( targets * : types-to-include * )
{
# Find subvariants
local s ;
for local t in $(targets)
{
s += [ $(t).dg ] ;
}
s = [ sequence.unique $(s) ] ;
local result = $(targets) ;
for local i in $(s)
{
result += [ $(i).all-referenced-targets ] ;
}
result = [ sequence.unique $(result) ] ;
if $(types-to-include)
{
local result2 ;
for local r in $(result)
{
if [ include-type [ $(r).type ] : $(types-to-include) ]
{
result2 += $(r) ;
}
}
return $(result2) ;
}
else
{
return $(result) ;
}
}
# Don't do nothing.
rule check-for-unused-sources ( result * : sources * )
{
}
# Returns true iff 'type' is subtype of some element of 'types-to-include'.
local rule include-type ( type : types-to-include * )
{
local found ;
while $(types-to-include) && ! $(found)
{
if [ type.is-subtype $(type) $(types-to-include[1]) ]
{
found = true ;
}
types-to-include = $(types-to-include[2-]) ;
}
return $(found) ;
}
}
# Declare staged version of the EXE type. Generator for this type will