diff --git a/new/borland.jam b/new/borland.jam index 275d92acd..41f36afd2 100644 --- a/new/borland.jam +++ b/new/borland.jam @@ -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 ; 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 ; 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 diff --git a/new/builtin.jam b/new/builtin.jam index f16010832..ce443f66b 100644 --- a/new/builtin.jam +++ b/new/builtin.jam @@ -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 ; diff --git a/new/generators.jam b/new/generators.jam index 105082e2d..4b764a683 100644 --- a/new/generators.jam +++ b/new/generators.jam @@ -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 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). +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 diff --git a/new/kylix.jam b/new/kylix.jam new file mode 100644 index 000000000..fe108f941 --- /dev/null +++ b/new/kylix.jam @@ -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++ ; + diff --git a/new/property.jam b/new/property.jam index 75e8febdc..ef5c25b81 100644 --- a/new/property.jam +++ b/new/property.jam @@ -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 a gcc : select include : a gcc ; + + assert.result kylix a + : change gcc a : toolset kylix ; pm = [ new property-map ] ; $(pm).insert gcc : o ; diff --git a/new/toolset.jam b/new/toolset.jam index d04609389..f5f0292e7 100644 --- a/new/toolset.jam +++ b/new/toolset.jam @@ -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 +# 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 ; diff --git a/v2/borland.jam b/v2/borland.jam index 275d92acd..41f36afd2 100644 --- a/v2/borland.jam +++ b/v2/borland.jam @@ -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 ; 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 ; 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 diff --git a/v2/build/generators.jam b/v2/build/generators.jam index 105082e2d..4b764a683 100644 --- a/v2/build/generators.jam +++ b/v2/build/generators.jam @@ -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 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). +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 diff --git a/v2/build/property.jam b/v2/build/property.jam index 75e8febdc..ef5c25b81 100644 --- a/v2/build/property.jam +++ b/v2/build/property.jam @@ -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 a gcc : select include : a gcc ; + + assert.result kylix a + : change gcc a : toolset kylix ; pm = [ new property-map ] ; $(pm).insert gcc : o ; diff --git a/v2/build/toolset.jam b/v2/build/toolset.jam index d04609389..f5f0292e7 100644 --- a/v2/build/toolset.jam +++ b/v2/build/toolset.jam @@ -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 +# 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 ; diff --git a/v2/kylix.jam b/v2/kylix.jam new file mode 100644 index 000000000..fe108f941 --- /dev/null +++ b/v2/kylix.jam @@ -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++ ; + diff --git a/v2/tools/builtin.jam b/v2/tools/builtin.jam index f16010832..ce443f66b 100644 --- a/v2/tools/builtin.jam +++ b/v2/tools/builtin.jam @@ -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 ;