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:
@@ -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 ;
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
28
new/type.jam
28
new/type.jam
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
Reference in New Issue
Block a user