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

Implement toolset inheritance. Add Kylix toolset. Still need

to inherit "init" rule and test all this.

* new/borland.jam
    Use COMPILER_NAME and LINKER_NAME vars.

* new/generators.jam
    (generator.clone): New method.
    (register-composing): Use 'register'
    (generators-for-toolset): New rule.

* new/property.jam
    (change): New rule

* new/toolset.jam
    (add-flag): New rule
    (flags): Use the above.
    (register): New rule.
    (inherit): New rule
    (inherit-generators,inherit-flags,inherit-rules): New rules.


[SVN r16979]
This commit is contained in:
Vladimir Prus
2003-01-21 16:10:37 +00:00
parent 1241832b20
commit 0f58dd79ab
12 changed files with 372 additions and 50 deletions

View File

@@ -8,8 +8,13 @@
import property ;
import generators ;
import os ;
import toolset ;
toolset.register borland ;
COMPILER_NAME = bcc32 ;
LINKER_NAME = bcc32 ;
feature.extend toolset : borland ;
# A borland-specific target type
type.register BORLAND.TDS : tds ;
@@ -34,7 +39,7 @@ toolset.flags borland.compile INCLUDES <include> ;
actions compile
{
bcc32 $(OPTIONS) -q -D$(DEFINES) -I$(INCLUDES) -c -o$(<) $(>)
$(COMPILER_NAME) $(OPTIONS) -q -D$(DEFINES) -I$(INCLUDES) -c -o$(<) $(>)
}
# Declare flags and action for linking
@@ -46,7 +51,7 @@ toolset.flags borland.link LIBRARIES <library> ;
actions link bind LIBRARIES
{
bcc32 $(OPTIONS) -q -L$(LINKPATH) -e$(<[1]) $(>) $(LIBRARIES) -l$(FINDLIBS)
$(LINKER_NAME) $(OPTIONS) -q -L$(LINKPATH) -e$(<[1]) $(>) $(LIBRARIES) -l$(FINDLIBS)
}
# Declare action for archives

View File

@@ -381,7 +381,7 @@ rule C-compiling-generator ( id : source-types + : target-types + :
{
generator.__init__ $(id) : $(source-types) : $(target-types) :
$(requirements) ;
rule action-class ( )
{
return compile-action ;

View File

@@ -79,6 +79,7 @@ rule generator (
self.id = $(id) ;
self.source-types = $(source-types) ;
self.target-types-and-names = $(target-types-and-names) ;
self.requirements = $(requirements) ;
for local e in $(target-types-and-names)
@@ -127,7 +128,19 @@ rule generator (
{
return $(self.optional-properties) ;
}
# Returns another generator which differers from $(self) in
# - id
# - value to <toolset> feature in properties
rule clone ( new-id : new-toolset-name )
{
return [ new $(__class__) $(new-id) : $(self.source-types)
: $(self.target-types-and-names)
: [ property.change $(self.requirements)
: toolset $(new-toolset-name) ]
] ;
}
# Tries to invoke this generator on the given sources. Returns a
# list of generated targets (instances of 'virtual-target').
rule run ( project # Project for which the targets are generated
@@ -463,8 +476,11 @@ rule register ( g )
for local t in [ $(g).target-types ]
{
.generators.$(t) += $(g) ;
}
}
# Update the set of generators for toolset
local id = [ $(g).id ] ;
.generators-for-toolset.$(id:S=) += $(g) ;
}
@@ -479,13 +495,16 @@ rule register-composing ( id : source-types + : target-types + : requirements *
{
local g = [ new composing-generator $(id) : $(source-types)
: $(target-types) : $(requirements) ] ;
.generators += $(g) ;
for local t in [ $(g).target-types ]
{
.generators.$(t) += $(g) ;
}
register $(g) ;
}
# Returns all generators which belong to 'toolset', i.e. which
# ids are $(toolset).<something>
rule generators-for-toolset ( toolset )
{
return $(.generators-for-toolset.$(toolset)) ;
}
# Set if results of the current generators search are going to be cached
# This means no futher attempts to cache generators search should be

16
new/kylix.jam Normal file
View File

@@ -0,0 +1,16 @@
# Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears in
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
# Support for the Borland's Kylix command line compiler
import toolset ;
toolset.register kylix ;
toolset.inherit kylix : borland ;
COMPILER_NAME = bc++ ;
LINKER_NAME = bc++ ;

View File

@@ -3,7 +3,7 @@
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
import feature ;
import feature : grist ;
import utility : ungrist ;
import sequence : unique ;
import errors : error ;
@@ -308,6 +308,27 @@ rule select ( features * : properties * )
return $(result) ;
}
# Changes the value of 'feature' to 'value', or adds it.
rule change ( properties * : feature value )
{
local result ;
feature = [ grist $(feature) ] ;
for local p in $(properties)
{
if $(p:G) = $(feature)
{
result += $(value:G=$(feature)) ;
}
else
{
result += $(p) ;
}
}
return $(result) ;
}
# Interpret all path properties in 'properties' as relative to 'path'
rule translate-paths ( properties * : path )
{
@@ -475,6 +496,9 @@ local rule __test__ ( )
assert.result <include>a <toolset>gcc
: select include <bar> <toolset> : <include>a <toolset>gcc ;
assert.result <toolset>kylix <include>a
: change <toolset>gcc <include>a : toolset kylix ;
pm = [ new property-map ] ;
$(pm).insert <toolset>gcc : o ;

View File

@@ -69,14 +69,10 @@ rule flags ( rule-or-module # If contains dot, should be a rule name.
# unconditionally
values * )
{
.$(rule-or-module).flags += $(.flag-no) ;
.$(rule-or-module).variable.$(.flag-no) += $(variable-name) ;
.$(rule-or-module).values.$(.flag-no) += $(values) ;
local match-type ;
if $(condition[1]:G=)
{
.$(rule-or-module).match-type.$(.flag-no) += property-set ;
match-type = property-set ;
property.validate-property-sets $(condition) ;
if ! $(values)
{
@@ -87,7 +83,7 @@ rule flags ( rule-or-module # If contains dot, should be a rule name.
}
else if $(condition)
{
.$(rule-or-module).match-type.$(.flag-no) += feature ;
match-type += feature ;
if $(values)
{
error non-empty value set used with feature match criterion ;
@@ -95,14 +91,35 @@ rule flags ( rule-or-module # If contains dot, should be a rule name.
}
else
{
.$(rule-or-module).match-type.$(.flag-no) += unconditional ;
# CONSIDER: Why setting match type and calling error?
match-type += unconditional ;
error empty value set used with unconditional match criterion ;
}
.$(rule-or-module).condition.$(.flag-no) += $(condition) ;
}
add-flag $(rule-or-module) : $(match-type) : $(variable-name)
: $(condition) : $(values) ;
}
# Adds new flag setting with the specified values
# Does no checking
local rule add-flag ( rule-or-module : match-type :
variable-name : condition * : values * )
{
.$(rule-or-module).flags += $(.flag-no) ;
# Store all flags for a module
local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ;
.module-flags.$(module_) += $(.flag-no) ;
# Store flag-no -> rule-or-module mapping
.rule-or-module.$(.flag-no) = $(rule-or-module) ;
.$(rule-or-module).match-type.$(.flag-no) = $(match-type) ;
.$(rule-or-module).variable.$(.flag-no) += $(variable-name) ;
.$(rule-or-module).values.$(.flag-no) += $(values) ;
.$(rule-or-module).condition.$(.flag-no) += $(condition) ;
.flag-no = [ numbers.increment $(.flag-no) ] ;
}
# Returns the first element of 'property-sets' which is a subset of
# 'properties', or an empty list if no such element exists.
@@ -170,6 +187,86 @@ rule set-target-variables ( rule-or-module target : properties * )
}
}
.toolsets += $(toolset) ;
# Registers a new toolset
rule register ( toolset )
{
feature.extend toolset : $(toolset) ;
.toolsets += $(toolset) ;
}
# Make toolset 'toolset', defined in a module of the same name,
# inherit from 'base'
# 1. The 'init' rule from 'base' is imported into 'toolset' with full
# name. Another 'init' is called, which forwards to the base one.
# 2. All generators from 'base' are cloned. The ids are adjusted and
# <toolset> property in requires is adjusted too
# 3. All flags are inherited
# 4. All rules are imported.
rule inherit ( toolset : base )
{
import $(base) ;
inherit-generators $(toolset) : $(base) ;
inherit-flags $(toolset) : $(base) ;
inherit-rules $(toolset) : $(base) ;
}
rule inherit-generators ( toolset : base )
{
local base-generators = [ generators.generators-for-toolset $(base) ] ;
for local g in $(base-generators)
{
local id = [ $(g).id ] ;
local new-id = $(id:B=$(toolset)) ;
generators.register [ $(g).clone $(new-id) : $(toolset) ] ;
}
}
rule inherit-flags ( toolset : base )
{
for local f in $(.module-flags.$(base))
{
local rule-or-module = $(.rule-or-module.$(f)) ;
local rule_ = [ MATCH "[^.]*\.(.*)" : $(rule-or-module) ] ;
local new-rule-or-module ;
if $(rule_)
{
new-rule-or-module = $(toolset).$(rule_) ;
}
else
{
new-rule-or-module = $(toolset) ;
}
add-flag
$(new-rule-or-module)
: $(.$(rule-or-module).match-type.$(f))
: $(.$(rule-or-module).variable.$(f))
: $(.$(rule-or-module).condition.$(f))
: $(.$(rule-or-module).values.$(f))
;
}
}
rule inherit-rules ( toolset : base )
{
# It appears that "action" creates local rule...
local base-generators = [ generators.generators-for-toolset $(base) ] ;
local rules ;
for local g in $(base-generators)
{
local id = [ MATCH "[^.]*\.(.*)" : [ $(g).id ] ] ;
rules += $(id) ;
}
IMPORT $(base) : $(rules) : $(toolset) : $(rules) : localized ;
# Import the rules to the global scope
IMPORT $(toolset) : $(rules) : : $(toolset).$(rules) ;
}
local rule __test__ ( )
{
import assert ;

View File

@@ -8,8 +8,13 @@
import property ;
import generators ;
import os ;
import toolset ;
toolset.register borland ;
COMPILER_NAME = bcc32 ;
LINKER_NAME = bcc32 ;
feature.extend toolset : borland ;
# A borland-specific target type
type.register BORLAND.TDS : tds ;
@@ -34,7 +39,7 @@ toolset.flags borland.compile INCLUDES <include> ;
actions compile
{
bcc32 $(OPTIONS) -q -D$(DEFINES) -I$(INCLUDES) -c -o$(<) $(>)
$(COMPILER_NAME) $(OPTIONS) -q -D$(DEFINES) -I$(INCLUDES) -c -o$(<) $(>)
}
# Declare flags and action for linking
@@ -46,7 +51,7 @@ toolset.flags borland.link LIBRARIES <library> ;
actions link bind LIBRARIES
{
bcc32 $(OPTIONS) -q -L$(LINKPATH) -e$(<[1]) $(>) $(LIBRARIES) -l$(FINDLIBS)
$(LINKER_NAME) $(OPTIONS) -q -L$(LINKPATH) -e$(<[1]) $(>) $(LIBRARIES) -l$(FINDLIBS)
}
# Declare action for archives

View File

@@ -79,6 +79,7 @@ rule generator (
self.id = $(id) ;
self.source-types = $(source-types) ;
self.target-types-and-names = $(target-types-and-names) ;
self.requirements = $(requirements) ;
for local e in $(target-types-and-names)
@@ -127,7 +128,19 @@ rule generator (
{
return $(self.optional-properties) ;
}
# Returns another generator which differers from $(self) in
# - id
# - value to <toolset> feature in properties
rule clone ( new-id : new-toolset-name )
{
return [ new $(__class__) $(new-id) : $(self.source-types)
: $(self.target-types-and-names)
: [ property.change $(self.requirements)
: toolset $(new-toolset-name) ]
] ;
}
# Tries to invoke this generator on the given sources. Returns a
# list of generated targets (instances of 'virtual-target').
rule run ( project # Project for which the targets are generated
@@ -463,8 +476,11 @@ rule register ( g )
for local t in [ $(g).target-types ]
{
.generators.$(t) += $(g) ;
}
}
# Update the set of generators for toolset
local id = [ $(g).id ] ;
.generators-for-toolset.$(id:S=) += $(g) ;
}
@@ -479,13 +495,16 @@ rule register-composing ( id : source-types + : target-types + : requirements *
{
local g = [ new composing-generator $(id) : $(source-types)
: $(target-types) : $(requirements) ] ;
.generators += $(g) ;
for local t in [ $(g).target-types ]
{
.generators.$(t) += $(g) ;
}
register $(g) ;
}
# Returns all generators which belong to 'toolset', i.e. which
# ids are $(toolset).<something>
rule generators-for-toolset ( toolset )
{
return $(.generators-for-toolset.$(toolset)) ;
}
# Set if results of the current generators search are going to be cached
# This means no futher attempts to cache generators search should be

View File

@@ -3,7 +3,7 @@
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
import feature ;
import feature : grist ;
import utility : ungrist ;
import sequence : unique ;
import errors : error ;
@@ -308,6 +308,27 @@ rule select ( features * : properties * )
return $(result) ;
}
# Changes the value of 'feature' to 'value', or adds it.
rule change ( properties * : feature value )
{
local result ;
feature = [ grist $(feature) ] ;
for local p in $(properties)
{
if $(p:G) = $(feature)
{
result += $(value:G=$(feature)) ;
}
else
{
result += $(p) ;
}
}
return $(result) ;
}
# Interpret all path properties in 'properties' as relative to 'path'
rule translate-paths ( properties * : path )
{
@@ -475,6 +496,9 @@ local rule __test__ ( )
assert.result <include>a <toolset>gcc
: select include <bar> <toolset> : <include>a <toolset>gcc ;
assert.result <toolset>kylix <include>a
: change <toolset>gcc <include>a : toolset kylix ;
pm = [ new property-map ] ;
$(pm).insert <toolset>gcc : o ;

View File

@@ -69,14 +69,10 @@ rule flags ( rule-or-module # If contains dot, should be a rule name.
# unconditionally
values * )
{
.$(rule-or-module).flags += $(.flag-no) ;
.$(rule-or-module).variable.$(.flag-no) += $(variable-name) ;
.$(rule-or-module).values.$(.flag-no) += $(values) ;
local match-type ;
if $(condition[1]:G=)
{
.$(rule-or-module).match-type.$(.flag-no) += property-set ;
match-type = property-set ;
property.validate-property-sets $(condition) ;
if ! $(values)
{
@@ -87,7 +83,7 @@ rule flags ( rule-or-module # If contains dot, should be a rule name.
}
else if $(condition)
{
.$(rule-or-module).match-type.$(.flag-no) += feature ;
match-type += feature ;
if $(values)
{
error non-empty value set used with feature match criterion ;
@@ -95,14 +91,35 @@ rule flags ( rule-or-module # If contains dot, should be a rule name.
}
else
{
.$(rule-or-module).match-type.$(.flag-no) += unconditional ;
# CONSIDER: Why setting match type and calling error?
match-type += unconditional ;
error empty value set used with unconditional match criterion ;
}
.$(rule-or-module).condition.$(.flag-no) += $(condition) ;
}
add-flag $(rule-or-module) : $(match-type) : $(variable-name)
: $(condition) : $(values) ;
}
# Adds new flag setting with the specified values
# Does no checking
local rule add-flag ( rule-or-module : match-type :
variable-name : condition * : values * )
{
.$(rule-or-module).flags += $(.flag-no) ;
# Store all flags for a module
local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ;
.module-flags.$(module_) += $(.flag-no) ;
# Store flag-no -> rule-or-module mapping
.rule-or-module.$(.flag-no) = $(rule-or-module) ;
.$(rule-or-module).match-type.$(.flag-no) = $(match-type) ;
.$(rule-or-module).variable.$(.flag-no) += $(variable-name) ;
.$(rule-or-module).values.$(.flag-no) += $(values) ;
.$(rule-or-module).condition.$(.flag-no) += $(condition) ;
.flag-no = [ numbers.increment $(.flag-no) ] ;
}
# Returns the first element of 'property-sets' which is a subset of
# 'properties', or an empty list if no such element exists.
@@ -170,6 +187,86 @@ rule set-target-variables ( rule-or-module target : properties * )
}
}
.toolsets += $(toolset) ;
# Registers a new toolset
rule register ( toolset )
{
feature.extend toolset : $(toolset) ;
.toolsets += $(toolset) ;
}
# Make toolset 'toolset', defined in a module of the same name,
# inherit from 'base'
# 1. The 'init' rule from 'base' is imported into 'toolset' with full
# name. Another 'init' is called, which forwards to the base one.
# 2. All generators from 'base' are cloned. The ids are adjusted and
# <toolset> property in requires is adjusted too
# 3. All flags are inherited
# 4. All rules are imported.
rule inherit ( toolset : base )
{
import $(base) ;
inherit-generators $(toolset) : $(base) ;
inherit-flags $(toolset) : $(base) ;
inherit-rules $(toolset) : $(base) ;
}
rule inherit-generators ( toolset : base )
{
local base-generators = [ generators.generators-for-toolset $(base) ] ;
for local g in $(base-generators)
{
local id = [ $(g).id ] ;
local new-id = $(id:B=$(toolset)) ;
generators.register [ $(g).clone $(new-id) : $(toolset) ] ;
}
}
rule inherit-flags ( toolset : base )
{
for local f in $(.module-flags.$(base))
{
local rule-or-module = $(.rule-or-module.$(f)) ;
local rule_ = [ MATCH "[^.]*\.(.*)" : $(rule-or-module) ] ;
local new-rule-or-module ;
if $(rule_)
{
new-rule-or-module = $(toolset).$(rule_) ;
}
else
{
new-rule-or-module = $(toolset) ;
}
add-flag
$(new-rule-or-module)
: $(.$(rule-or-module).match-type.$(f))
: $(.$(rule-or-module).variable.$(f))
: $(.$(rule-or-module).condition.$(f))
: $(.$(rule-or-module).values.$(f))
;
}
}
rule inherit-rules ( toolset : base )
{
# It appears that "action" creates local rule...
local base-generators = [ generators.generators-for-toolset $(base) ] ;
local rules ;
for local g in $(base-generators)
{
local id = [ MATCH "[^.]*\.(.*)" : [ $(g).id ] ] ;
rules += $(id) ;
}
IMPORT $(base) : $(rules) : $(toolset) : $(rules) : localized ;
# Import the rules to the global scope
IMPORT $(toolset) : $(rules) : : $(toolset).$(rules) ;
}
local rule __test__ ( )
{
import assert ;

16
v2/kylix.jam Normal file
View File

@@ -0,0 +1,16 @@
# Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears in
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
# Support for the Borland's Kylix command line compiler
import toolset ;
toolset.register kylix ;
toolset.inherit kylix : borland ;
COMPILER_NAME = bc++ ;
LINKER_NAME = bc++ ;

View File

@@ -381,7 +381,7 @@ rule C-compiling-generator ( id : source-types + : target-types + :
{
generator.__init__ $(id) : $(source-types) : $(target-types) :
$(requirements) ;
rule action-class ( )
{
return compile-action ;