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

Work on BB14: allow target suffixes to depend

on build properties.

* new/builtin.jam
    Introduce "os" feature.

* new/gcc.jam
    Make object suffix "o" on all platforms.

* new/property.jam
    (property-map): New class.

* new/type.jam
    (.suffixes): Global propety-map instance, to
	keep properties->suffix mapping.
    (set-generated-target-suffix): New rule
    (generated-target-suffix): New argument
	'properties'.

* new/virtual-target.jam
    (abstract-file-target.actual-name): Pass
	properties to type.generated-target-suffix.

* test/project_test4.py
    Don't specify expected list of build properties,
    since it's not stable. Check head of error message
    only.


[SVN r16700]
This commit is contained in:
Vladimir Prus
2002-12-25 07:18:34 +00:00
parent 5f624c98af
commit c55ca9170f
12 changed files with 222 additions and 34 deletions

View File

@@ -20,6 +20,11 @@ import toolset ;
import errors : error ;
import symlink ;
# This feature is used to determine which OS we're on.
# In future, this may become <target-os> and <host-os>
local os = [ modules.peek : OS ] ;
feature os : $(os) : propagated link-incompatible ;
feature toolset : : implicit propagated link-incompatible symmetric ;
feature link : shared static : propagated ;
feature link-runtime : shared static : propagated ;

View File

@@ -2,10 +2,16 @@
import property ;
import generators ;
import os ;
import type ;
feature.extend toolset : gcc ;
feature.subfeature toolset gcc : version : : optional ;
# Make the "o" suffix used for gcc toolset on all
# platforms
type.set-generated-target-suffix OBJ : <toolset>gcc : o ;
# Initializes the gcc toolset
# Each argument has the form:
# version binary-name [path]

View File

@@ -7,6 +7,8 @@ import feature ;
import utility : ungrist ;
import sequence : unique ;
import errors : error ;
import class : class ;
# Refines 'properties' by overriding any elements for which a different
# value is specified in 'requirements'. If the resulting property set
@@ -312,6 +314,51 @@ rule translate-paths ( properties * : path )
return $(result) ;
}
# Class which maintains a property set -> string
# mapping
rule property-map ( )
{
self.next-flag = 1 ;
# Associate 'value' with 'properties'
rule insert ( properties + : value )
{
self.all-flags += $(self.next-flag) ;
self.properties.$(self.next-flag) = $(properties) ;
self.value.$(self.next-flag) = $(value) ;
self.next-flag = [ numbers.increment $(self.next-flag) ] ;
}
# Return the value associated with 'properties'
# or any subset of it. If more than one
# subset has value assigned to it, return the
# value for the longest subset, if it's unique.
rule find ( properties + )
{
# First find all matches
local matches ;
local match-ranks ;
for local i in $(self.all-flags)
{
if $(self.properties.$(i)) in $(properties)
{
matches += $(i) ;
match-ranks += [ sequence.length
$(self.properties.$(i)) ] ;
}
}
local best = [ sequence.select-highest-ranked
$(matches) : $(match-ranks) ] ;
if $(best[2])
{
errors.error "Ambiguous key" ;
}
return $(self.value.$(best)) ;
}
}
class property-map ;
local rule __test__ ( )
@@ -402,5 +449,22 @@ local rule __test__ ( )
assert.result <include>a
: select include : <include>a <toolset>gcc ;
pm = [ new property-map ] ;
$(pm).insert <toolset>gcc : o ;
$(pm).insert <toolset>gcc <os>NT : obj ;
$(pm).insert <toolset>gcc <os>CYGWIN : obj ;
assert.equal o
: [ $(pm).find <toolset>gcc ] ;
assert.equal obj
: [ $(pm).find <toolset>gcc <os>NT ] ;
try ;
$(pm).find <toolset>gcc <os>NT <os>CYGWIN ;
catch "Ambiguous key" ;
}

View File

@@ -10,6 +10,7 @@ import feature ;
import generators : * ;
import class : class new ;
import errors ;
import property ;
feature.feature target-type : : composite optional ;
@@ -18,6 +19,9 @@ feature.feature main-target-type : : optional incidental ;
feature.feature base-target-type : : composite optional free ;
# feature.feature main-target-type : : composite optional incidental ;
# Store suffixes for generated targets
.suffixes = [ new property-map ] ;
# Registers a target type, possible derived from a 'base-type'.
# If 'suffixes' are provided, they given all the suffixes that mean a file is of 'type'.
# Also, the first element gives the suffix to be used when constructing and object of
@@ -44,7 +48,13 @@ rule register ( type : suffixes * : base-type ? : main ? )
{
.types += $(type) ;
.bases.$(type) = $(base-type) ;
.suffix.$(type) = $(suffixes[1]) ;
if $(suffixes)
{
$(.suffixes).insert <type>$(type) : $(suffixes[1]) ;
}
.type.$(suffixes) = $(type) ;
feature.extend target-type : $(type) ;
@@ -117,10 +127,20 @@ rule is-derived ( type base )
}
}
# Returns suffix that should be used when generating target of 'type'.
rule generated-target-suffix ( type )
# Sets a target suffix that should be used when
# generating target of 'type' with the specified
# properties
rule set-generated-target-suffix ( type : properties + : suffix )
{
return $(.suffix.$(type)) ;
$(.suffixes).insert <type>$(type) $(properties) : $(suffix) ;
}
# Returns suffix that should be used when generating target of 'type',
# with the specified properties.
rule generated-target-suffix ( type : properties * )
{
return [ $(.suffixes).find <type>$(type) $(properties) ] ;
}
# Returns file type given its suffix. The 'suffix' parameter should include

View File

@@ -297,10 +297,12 @@ rule abstract-file-target ( name
local location-grist =
[ sequence.join [ regex.split $(project-location) "/" ] : "!" ] ;
local grist ;
local properties ;
if $(self.action)
{
local p = [ property.remove free incidental : [ $(self.action).properties ] ] ;
local property-grist = [ property.as-path $(p) ] ;
properties = [ property.remove free incidental : [ $(self.action).properties ] ] ;
local property-grist = [ property.as-path $(properties) ] ;
grist = $(location-grist)/$(property-grist) ;
}
@@ -321,7 +323,9 @@ rule abstract-file-target ( name
else if $(self.type)
{
self.actual-name = [ sequence.join <$(grist)>$(self.name)
[ type.generated-target-suffix $(self.type) ] : "." ] ;
[ type.generated-target-suffix $(self.type) :
$(properties)
] : "." ] ;
}
else
{

View File

@@ -2,7 +2,7 @@
from BoostBuild import Tester
import os
from string import strip
from string import strip, find
t = Tester()
@@ -45,14 +45,9 @@ t.run_build_system("--no-error-backtrace", stdout=expected, status=None)
t.copy("lib/Jamfile3", "lib/Jamfile")
expected="""warning: skipped build of lib/b.obj with properties <toolset>gcc <link>shared
<link-runtime>shared <optimization>on <threading>single <rtti>on
<debug-symbols>on <hardcode-dll-paths>false <variant>debug
don't know how to make <.>lib/b.obj/<optimization>on
...skipped <./gcc/debug>a.exe for lack of <.>lib/b.obj/<optimization>on...
"""
t.run_build_system(stdout=expected, status=None)
t.run_build_system(status=None)
t.fail_test(find(t.stdout(), "warning: skipped build of lib/b.obj with properties") \
!= 0)
# Check that project can be skipped as well
t.copy("Jamfile4", "Jamfile")
@@ -70,7 +65,7 @@ t.run_build_system("rtti=on", stdout=expected, status=None)
# We don't yet make targets depend on Jamfile, so need to start from scratch
# The following test is disabled, because of problems related to
# issue 634319
# issue BB10
#t.set_tree("project-test4")
#t.copy("Jamfile2", "Jamfile")

View File

@@ -7,6 +7,8 @@ import feature ;
import utility : ungrist ;
import sequence : unique ;
import errors : error ;
import class : class ;
# Refines 'properties' by overriding any elements for which a different
# value is specified in 'requirements'. If the resulting property set
@@ -312,6 +314,51 @@ rule translate-paths ( properties * : path )
return $(result) ;
}
# Class which maintains a property set -> string
# mapping
rule property-map ( )
{
self.next-flag = 1 ;
# Associate 'value' with 'properties'
rule insert ( properties + : value )
{
self.all-flags += $(self.next-flag) ;
self.properties.$(self.next-flag) = $(properties) ;
self.value.$(self.next-flag) = $(value) ;
self.next-flag = [ numbers.increment $(self.next-flag) ] ;
}
# Return the value associated with 'properties'
# or any subset of it. If more than one
# subset has value assigned to it, return the
# value for the longest subset, if it's unique.
rule find ( properties + )
{
# First find all matches
local matches ;
local match-ranks ;
for local i in $(self.all-flags)
{
if $(self.properties.$(i)) in $(properties)
{
matches += $(i) ;
match-ranks += [ sequence.length
$(self.properties.$(i)) ] ;
}
}
local best = [ sequence.select-highest-ranked
$(matches) : $(match-ranks) ] ;
if $(best[2])
{
errors.error "Ambiguous key" ;
}
return $(self.value.$(best)) ;
}
}
class property-map ;
local rule __test__ ( )
@@ -402,5 +449,22 @@ local rule __test__ ( )
assert.result <include>a
: select include : <include>a <toolset>gcc ;
pm = [ new property-map ] ;
$(pm).insert <toolset>gcc : o ;
$(pm).insert <toolset>gcc <os>NT : obj ;
$(pm).insert <toolset>gcc <os>CYGWIN : obj ;
assert.equal o
: [ $(pm).find <toolset>gcc ] ;
assert.equal obj
: [ $(pm).find <toolset>gcc <os>NT ] ;
try ;
$(pm).find <toolset>gcc <os>NT <os>CYGWIN ;
catch "Ambiguous key" ;
}

View File

@@ -10,6 +10,7 @@ import feature ;
import generators : * ;
import class : class new ;
import errors ;
import property ;
feature.feature target-type : : composite optional ;
@@ -18,6 +19,9 @@ feature.feature main-target-type : : optional incidental ;
feature.feature base-target-type : : composite optional free ;
# feature.feature main-target-type : : composite optional incidental ;
# Store suffixes for generated targets
.suffixes = [ new property-map ] ;
# Registers a target type, possible derived from a 'base-type'.
# If 'suffixes' are provided, they given all the suffixes that mean a file is of 'type'.
# Also, the first element gives the suffix to be used when constructing and object of
@@ -44,7 +48,13 @@ rule register ( type : suffixes * : base-type ? : main ? )
{
.types += $(type) ;
.bases.$(type) = $(base-type) ;
.suffix.$(type) = $(suffixes[1]) ;
if $(suffixes)
{
$(.suffixes).insert <type>$(type) : $(suffixes[1]) ;
}
.type.$(suffixes) = $(type) ;
feature.extend target-type : $(type) ;
@@ -117,10 +127,20 @@ rule is-derived ( type base )
}
}
# Returns suffix that should be used when generating target of 'type'.
rule generated-target-suffix ( type )
# Sets a target suffix that should be used when
# generating target of 'type' with the specified
# properties
rule set-generated-target-suffix ( type : properties + : suffix )
{
return $(.suffix.$(type)) ;
$(.suffixes).insert <type>$(type) $(properties) : $(suffix) ;
}
# Returns suffix that should be used when generating target of 'type',
# with the specified properties.
rule generated-target-suffix ( type : properties * )
{
return [ $(.suffixes).find <type>$(type) $(properties) ] ;
}
# Returns file type given its suffix. The 'suffix' parameter should include

View File

@@ -297,10 +297,12 @@ rule abstract-file-target ( name
local location-grist =
[ sequence.join [ regex.split $(project-location) "/" ] : "!" ] ;
local grist ;
local properties ;
if $(self.action)
{
local p = [ property.remove free incidental : [ $(self.action).properties ] ] ;
local property-grist = [ property.as-path $(p) ] ;
properties = [ property.remove free incidental : [ $(self.action).properties ] ] ;
local property-grist = [ property.as-path $(properties) ] ;
grist = $(location-grist)/$(property-grist) ;
}
@@ -321,7 +323,9 @@ rule abstract-file-target ( name
else if $(self.type)
{
self.actual-name = [ sequence.join <$(grist)>$(self.name)
[ type.generated-target-suffix $(self.type) ] : "." ] ;
[ type.generated-target-suffix $(self.type) :
$(properties)
] : "." ] ;
}
else
{

View File

@@ -2,10 +2,16 @@
import property ;
import generators ;
import os ;
import type ;
feature.extend toolset : gcc ;
feature.subfeature toolset gcc : version : : optional ;
# Make the "o" suffix used for gcc toolset on all
# platforms
type.set-generated-target-suffix OBJ : <toolset>gcc : o ;
# Initializes the gcc toolset
# Each argument has the form:
# version binary-name [path]

View File

@@ -2,7 +2,7 @@
from BoostBuild import Tester
import os
from string import strip
from string import strip, find
t = Tester()
@@ -45,14 +45,9 @@ t.run_build_system("--no-error-backtrace", stdout=expected, status=None)
t.copy("lib/Jamfile3", "lib/Jamfile")
expected="""warning: skipped build of lib/b.obj with properties <toolset>gcc <link>shared
<link-runtime>shared <optimization>on <threading>single <rtti>on
<debug-symbols>on <hardcode-dll-paths>false <variant>debug
don't know how to make <.>lib/b.obj/<optimization>on
...skipped <./gcc/debug>a.exe for lack of <.>lib/b.obj/<optimization>on...
"""
t.run_build_system(stdout=expected, status=None)
t.run_build_system(status=None)
t.fail_test(find(t.stdout(), "warning: skipped build of lib/b.obj with properties") \
!= 0)
# Check that project can be skipped as well
t.copy("Jamfile4", "Jamfile")
@@ -70,7 +65,7 @@ t.run_build_system("rtti=on", stdout=expected, status=None)
# We don't yet make targets depend on Jamfile, so need to start from scratch
# The following test is disabled, because of problems related to
# issue 634319
# issue BB10
#t.set_tree("project-test4")
#t.copy("Jamfile2", "Jamfile")

View File

@@ -20,6 +20,11 @@ import toolset ;
import errors : error ;
import symlink ;
# This feature is used to determine which OS we're on.
# In future, this may become <target-os> and <host-os>
local os = [ modules.peek : OS ] ;
feature os : $(os) : propagated link-incompatible ;
feature toolset : : implicit propagated link-incompatible symmetric ;
feature link : shared static : propagated ;
feature link-runtime : shared static : propagated ;