From 577511be1a72fd5fcbdb16a904ec8b6bf7e7d807 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Nov 2002 14:37:43 +0000 Subject: [PATCH] Attempt to handle derived target types [SVN r16213] --- new/builtin.jam | 46 +++++++++++---------- new/gcc.jam | 4 +- new/generators.jam | 92 ++++++++++++++++++++++++++++++++++------- new/targets.jam | 14 +++---- new/type.jam | 81 ++++++++++++++++++++++++------------ v2/build/generators.jam | 92 ++++++++++++++++++++++++++++++++++------- v2/build/targets.jam | 14 +++---- v2/build/type.jam | 81 ++++++++++++++++++++++++------------ v2/gcc.jam | 4 +- v2/tools/builtin.jam | 46 +++++++++++---------- 10 files changed, 328 insertions(+), 146 deletions(-) diff --git a/new/builtin.jam b/new/builtin.jam index a57970fd6..c21f274a8 100644 --- a/new/builtin.jam +++ b/new/builtin.jam @@ -17,6 +17,7 @@ import os ; import stage ; import prebuilt ; import toolset ; +import errors : error ; feature toolset : gcc : implicit propagated link-incompatible ; feature shared : false true : propagated ; @@ -60,8 +61,7 @@ rule variant ( name : parents-or-properties * : tool-properties * ) # between base variants. if $(parents[2]) { - print.wrapped-text "error: multiple base variants are not yet supported" ; - EXIT ; + error "multiple base variants are not yet supported" ; } # Record explicitly specified properties for this variant @@ -107,26 +107,30 @@ variant release : on off ; type.register LIB : : : main ; -if [ os.name ] in NT CYGWIN +# register the given type on the specified OSes, or on remaining OSes +# if os is not specified. +local rule declare-type ( os * : type : suffixes * : base-type ? : main ? ) { - type.register EXE : exe : : main ; - type.register SHARED-LIB : dll : LIB : main ; - - if [ os.name ] = CYGWIN + if ! [ type.registered $(type) ] { - type.register STATIC-LIB : a : LIB : main ; - } - else - { - type.register STATIC-LIB : lib : LIB : main ; + if ( ! $(os) ) || [ os.name ] in $(os) + { + type.register $(type) : $(suffixes) : $(base-type) : $(main) ; + } } } -else -{ - type.register EXE : : : main ; - type.register SHARED-LIB : so : LIB : main ; - type.register STATIC-LIB : a : LIB : main ; -} + +declare-type NT : STATIC_LIB : a : LIB : main ; +declare-type : STATIC_LIB : a : LIB : main ; + +declare-type NT : SHARED_LIB : dll : LIB : main ; +declare-type : SHARED_LIB : so : LIB : main ; + +declare-type NT CYGWIN : EXE : exe : : main ; +declare-type : EXE : : : main ; + +declare-type NT CYGWIN : PYTHON_EXTENSION : dll : SHARED_LIB : main ; +declare-type : PYTHON_EXTENSION : so : SHARED_LIB : main ; type.register CPP : cpp cxx ; @@ -209,18 +213,18 @@ type.register OBJ : o : : main ; rule lib-generator ( ) { - composing-generator.__init__ lib-generator : unknown-source-type : LIB ; + composing-generator.__init__ lib-generator : unknown-source-type : LIB : LIB ; rule run ( project name ? : properties * : sources + ) { local actual-type ; if true in $(properties) { - actual-type = SHARED-LIB ; + actual-type = SHARED_LIB ; } else { - actual-type = STATIC-LIB ; + actual-type = STATIC_LIB ; } return [ generators.construct $(project) $(name) : $(actual-type) : $(properties) : $(sources) : allow-composing-generators ] ; diff --git a/new/gcc.jam b/new/gcc.jam index 65d7d9064..5c4e8a261 100644 --- a/new/gcc.jam +++ b/new/gcc.jam @@ -4,8 +4,8 @@ import generators ; import os ; generators.register-composing gcc.link : LIB OBJ : EXE : gcc ; -generators.register-composing gcc.archive : OBJ : STATIC-LIB : gcc ; -generators.register-composing gcc.link-dll : OBJ : SHARED-LIB : gcc ; +generators.register-composing gcc.archive : OBJ : STATIC_LIB : gcc ; +generators.register-composing gcc.link-dll : OBJ : SHARED_LIB : gcc ; generators.register-c-compiler gcc.compile : CPP : OBJ : gcc ; generators.register-c-compiler gcc.compile : C : OBJ : gcc ; diff --git a/new/generators.jam b/new/generators.jam index 2dd09e8b5..81f76ac1e 100644 --- a/new/generators.jam +++ b/new/generators.jam @@ -124,6 +124,10 @@ rule generator ( self.name-pre-post.$(m[1]) = $(m[3]) $(m[4]) ; } + self.optional-properties + = [ feature.expand $(self.target-types) ] + ; + rule id ( ) { return $(self.id) ; @@ -154,6 +158,7 @@ rule generator ( # TODO: comment is out of date. rule optional-properties ( ) { + return $(self.optional-properties) ; } # Tries to invoke this generator on the given sources. Returns a @@ -558,24 +563,79 @@ local rule find-viable-generators ( target-type : properties * ) # Select generators that can create the required target type. local viable-generators = ; local generator-rank = ; - # TODO: rank generators by optional properties. - for local g in $(.generators.$(target-type)) + + import type ; + local t = [ type.all-bases $(target-type) ] ; + + while $(t[1]) { - # Avoid trying the same generator twice on different levels. - if ! $(g) in $(.active-generators) - && ! ( [ is-a $(g) : composing-generator ] && $(.had-composing-generator) ) - { - if [ $(g).requirements ] in $(properties) - { - viable-generators += $(g) ; - generator-rank += [ sequence.length [ set.intersection - [ $(g).optional-properties ] : $(properties) ] ] ; + for local g in $(.generators.$(t)) + { + # Avoid trying the same generator twice on different levels. + if ! $(g) in $(.active-generators) + && ! ( [ is-a $(g) : composing-generator ] && $(.had-composing-generator) ) + { + if [ $(g).requirements ] in $(properties) + { + viable-generators += $(g) ; + generator-rank += [ sequence.length [ set.intersection + [ $(g).optional-properties ] : $(properties) ] ] ; + t = ; + } } - } + } + t = $(t[2-]) ; } return [ sequence.select-highest-ranked $(viable-generators) : $(generator-rank) ] ; } + +# currently unused. Sorry for the cruft. Delete at will +local rule find-viable-generators.new ( target-type : properties * ) +{ + # Select generators that can create the required target type. + local viable-generators = ; + local generator-rank = ; + + import type ; + local t = [ type.all-bases $(target-type) ] ; + + while $(t[1]) + { + generators.dout [ indent ] " ...checking type" [ $(t[1]) ] ; + + for local g in $(.generators.$(t[1])) + { + generators.dout [ indent ] " ...checking" [ $(g).id ] ; + # Avoid trying the same generator twice on different levels. + if ! $(g) in $(.active-generators) + && ! ( [ is-a $(g) : composing-generator ] && $(.had-composing-generator) ) + { + local requirements = [ $(g).requirements ] ; + generators.dout [ indent ] " ...requirements:" $(requirements) ; + + if $(requirements) in $(properties) + { + local optional = [ $(g).optional-properties ] ; + local match = $(requirements) [ set.intersection $(optional) : $(properties) ] ; + + if $(match) + { + viable-generators += $(g) ; + generator-rank += [ sequence.length $(match) ] ; + generators.dout [ indent ] " ...matched" [ $(g).id ] + "with rank $(generator-rank[-1]) :" $(match) ; + t = ; + } + } + } + } + t = $(t[2-]) ; + } + + + return [ sequence.select-highest-ranked $(viable-generators) : $(generator-rank) ] ; +} # Given a vector of vectors, of of them represents results of running some # generator, returns the 'best' result, it it exists. Otherwise, exit with @@ -669,7 +729,7 @@ rule construct ( project name ? : target-type multiple ? : properties * : source generators.dout [ indent ] " from" [ $(s).str ] ; } generators.dout [ indent ] " properties:" $(properties) ; - + local .had-composing-generator = $(.had-composing-generator) ; if $(allow-composing-generators) { @@ -728,7 +788,7 @@ rule construct ( project name ? : target-type multiple ? : properties * : source local results = [ new vector ] ; generators.dout [ indent ] "*** " [ sequence.length $(viable-generators) ] - " viable generators " ; + " viable generators" ; for local g in $(viable-generators) { @@ -785,8 +845,8 @@ rule construct ( project name ? : target-type multiple ? : properties * : source } else { - error [ $(results).size ] "possible generations for " - $(target-types) "Can't handle this now." ; + error [ $(results).size ] "possible generations for " $(target-types) + : "generations:" [ $(results).str ] ; } } diff --git a/new/targets.jam b/new/targets.jam index b97fbabfc..32a1b6f0e 100644 --- a/new/targets.jam +++ b/new/targets.jam @@ -34,7 +34,6 @@ import regex ; import property ; import errors ; import common ; -import errors ; # Base class for all abstract targets. @@ -337,9 +336,7 @@ rule basic-target ( name : project if $(sources:G) { - print.wrapped-text "error: gristed element in sources for " - [ full-name ] ; - EXIT ; + errors.error "gristed element in sources for" [ full-name ] ; } @@ -495,7 +492,6 @@ rule basic-target ( name : project { return $(self.requirements) ; } - } class basic-target : abstract-target ; @@ -577,11 +573,13 @@ rule typed-target ( name : project : type rule construct ( source-targets * : properties * ) { local r = [ generators.construct $(self.project) $(self.name) : $(self.type) - : $(properties) $(self.type) : $(source-targets) ] ; + : $(properties) # [ feature.expand + $(self.type) + # ] + : $(source-targets) ] ; if ! $(r) { - print.wrapped-text "error: unable to construct" [ full-name ] ; - EXIT ; + errors.error "unable to construct" [ full-name ] ; } return $(r) ; diff --git a/new/type.jam b/new/type.jam index fcd7c6bbb..8661d60b9 100644 --- a/new/type.jam +++ b/new/type.jam @@ -9,11 +9,14 @@ import feature ; import generators : * ; import class : class new ; - +import errors ; feature.feature target-type : : composite optional ; -feature.feature base-target-type : : composite optional ; + +# feature.feature base-target-type : : composite optional ; feature.feature main-target-type : : optional incidental ; +feature.feature base-target-type : : composite optional free ; +# feature.feature main-target-type : : composite optional incidental ; # 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'. @@ -25,9 +28,17 @@ feature.feature main-target-type : : optional incidental ; # will be added to the global scope. rule register ( type : suffixes * : base-type ? : main ? ) { + # Type names cannot contain hyphens, because when used as + # feature-values they will be interpreted as composite features + # which need to be decomposed. + switch $(type) + { + case *-* : errors.error "type name \"$(type)\" contains a hyphen" ; + } + if $(type) in $(.types) { - error "Type $(type) is already registered." ; + errors.error "Type $(type) is already registered." ; } else { @@ -36,16 +47,36 @@ rule register ( type : suffixes * : base-type ? : main ? ) .suffix.$(type) = $(suffixes[1]) ; .type.$(suffixes) = $(type) ; feature.extend target-type : $(type) ; - feature.compose $(type) : $(base-type:G=) ; - feature.compose $(type) : $(base-type:G=) ; + + feature.compose $(type) : $(base-type:G=) ; + feature.extend base-target-type : $(type) ; +# feature.compose $(type) : $(type) ; + feature.compose $(type) : $(base-type) ; if $(main) - { - IMPORT $(__name__) : main-target-rule : : $(type:L) ; + { + # Convert the type name to lowercase and convert all + # underscores to hyphens to get the main target rule name. + import regex ; + local n = [ regex.split $(type:L) "_" ] ; + n = $(n:J=-) ; + .main-target-type.$(n) = $(type) ; + + IMPORT $(__name__) : main-target-rule : : $(n) ; +# feature.compose $(type) : $(type) ; } } } +# Returns true iff type has been registered. +rule registered ( type ) +{ + if $(type) in $(.types) + { + return true ; + } +} + # Sets a scanner class that will be used for this 'type'. rule set-scanner ( type : scanner ) { @@ -64,30 +95,28 @@ rule get-scanner ( type : properties * ) } } +# returns type and all of its bases in order of their distance from type. +rule all-bases ( type ) +{ + local result = $(type) ; + while $(type) + { + type = $(.bases.$(type)) ; + result += $(type) ; + } + return $(result) ; +} + # Returns true if 'type' has 'base' as its direct or # indirect base. rule is-derived ( type base ) { - if $(base) in $(.bases.$(type)) + if $(base) in [ all-bases $(type) ] { return true ; } - else - { - # CONSIDER: maybe break when 'found' is true - local found ; - for local e in $(.bases.$(type)) - { - if [ is-derived $(e) $(base) ] - { - found = true ; - } - } - return $(found) ; - } } - # Returns suffix that should be used when generating target of 'type'. rule generated-target-suffix ( type ) { @@ -105,13 +134,13 @@ rule type ( suffix ) rule main-target-rule ( name : sources * : requirements * : default-build * : use-requirements * ) { - # First find requuired target type, which is equal to the name used to - # invoke us. + # First find required target type, which is equal to the name used + # to invoke us. local bt = [ BACKTRACE 1 ] ; - local type = $(bt[4]) ; + local rulename = $(bt[4]) ; targets.main-target-alternative $(name) [ CALLER_MODULE ] typed-target : 3 : 5 : 4 - : $(type:U) : $(sources) : $(requirements) : $(default-build) : $(use-requirements) + : $(.main-target-type.$(rulename)) : $(sources) : $(requirements) : $(default-build) : $(use-requirements) ; } diff --git a/v2/build/generators.jam b/v2/build/generators.jam index 2dd09e8b5..81f76ac1e 100644 --- a/v2/build/generators.jam +++ b/v2/build/generators.jam @@ -124,6 +124,10 @@ rule generator ( self.name-pre-post.$(m[1]) = $(m[3]) $(m[4]) ; } + self.optional-properties + = [ feature.expand $(self.target-types) ] + ; + rule id ( ) { return $(self.id) ; @@ -154,6 +158,7 @@ rule generator ( # TODO: comment is out of date. rule optional-properties ( ) { + return $(self.optional-properties) ; } # Tries to invoke this generator on the given sources. Returns a @@ -558,24 +563,79 @@ local rule find-viable-generators ( target-type : properties * ) # Select generators that can create the required target type. local viable-generators = ; local generator-rank = ; - # TODO: rank generators by optional properties. - for local g in $(.generators.$(target-type)) + + import type ; + local t = [ type.all-bases $(target-type) ] ; + + while $(t[1]) { - # Avoid trying the same generator twice on different levels. - if ! $(g) in $(.active-generators) - && ! ( [ is-a $(g) : composing-generator ] && $(.had-composing-generator) ) - { - if [ $(g).requirements ] in $(properties) - { - viable-generators += $(g) ; - generator-rank += [ sequence.length [ set.intersection - [ $(g).optional-properties ] : $(properties) ] ] ; + for local g in $(.generators.$(t)) + { + # Avoid trying the same generator twice on different levels. + if ! $(g) in $(.active-generators) + && ! ( [ is-a $(g) : composing-generator ] && $(.had-composing-generator) ) + { + if [ $(g).requirements ] in $(properties) + { + viable-generators += $(g) ; + generator-rank += [ sequence.length [ set.intersection + [ $(g).optional-properties ] : $(properties) ] ] ; + t = ; + } } - } + } + t = $(t[2-]) ; } return [ sequence.select-highest-ranked $(viable-generators) : $(generator-rank) ] ; } + +# currently unused. Sorry for the cruft. Delete at will +local rule find-viable-generators.new ( target-type : properties * ) +{ + # Select generators that can create the required target type. + local viable-generators = ; + local generator-rank = ; + + import type ; + local t = [ type.all-bases $(target-type) ] ; + + while $(t[1]) + { + generators.dout [ indent ] " ...checking type" [ $(t[1]) ] ; + + for local g in $(.generators.$(t[1])) + { + generators.dout [ indent ] " ...checking" [ $(g).id ] ; + # Avoid trying the same generator twice on different levels. + if ! $(g) in $(.active-generators) + && ! ( [ is-a $(g) : composing-generator ] && $(.had-composing-generator) ) + { + local requirements = [ $(g).requirements ] ; + generators.dout [ indent ] " ...requirements:" $(requirements) ; + + if $(requirements) in $(properties) + { + local optional = [ $(g).optional-properties ] ; + local match = $(requirements) [ set.intersection $(optional) : $(properties) ] ; + + if $(match) + { + viable-generators += $(g) ; + generator-rank += [ sequence.length $(match) ] ; + generators.dout [ indent ] " ...matched" [ $(g).id ] + "with rank $(generator-rank[-1]) :" $(match) ; + t = ; + } + } + } + } + t = $(t[2-]) ; + } + + + return [ sequence.select-highest-ranked $(viable-generators) : $(generator-rank) ] ; +} # Given a vector of vectors, of of them represents results of running some # generator, returns the 'best' result, it it exists. Otherwise, exit with @@ -669,7 +729,7 @@ rule construct ( project name ? : target-type multiple ? : properties * : source generators.dout [ indent ] " from" [ $(s).str ] ; } generators.dout [ indent ] " properties:" $(properties) ; - + local .had-composing-generator = $(.had-composing-generator) ; if $(allow-composing-generators) { @@ -728,7 +788,7 @@ rule construct ( project name ? : target-type multiple ? : properties * : source local results = [ new vector ] ; generators.dout [ indent ] "*** " [ sequence.length $(viable-generators) ] - " viable generators " ; + " viable generators" ; for local g in $(viable-generators) { @@ -785,8 +845,8 @@ rule construct ( project name ? : target-type multiple ? : properties * : source } else { - error [ $(results).size ] "possible generations for " - $(target-types) "Can't handle this now." ; + error [ $(results).size ] "possible generations for " $(target-types) + : "generations:" [ $(results).str ] ; } } diff --git a/v2/build/targets.jam b/v2/build/targets.jam index b97fbabfc..32a1b6f0e 100644 --- a/v2/build/targets.jam +++ b/v2/build/targets.jam @@ -34,7 +34,6 @@ import regex ; import property ; import errors ; import common ; -import errors ; # Base class for all abstract targets. @@ -337,9 +336,7 @@ rule basic-target ( name : project if $(sources:G) { - print.wrapped-text "error: gristed element in sources for " - [ full-name ] ; - EXIT ; + errors.error "gristed element in sources for" [ full-name ] ; } @@ -495,7 +492,6 @@ rule basic-target ( name : project { return $(self.requirements) ; } - } class basic-target : abstract-target ; @@ -577,11 +573,13 @@ rule typed-target ( name : project : type rule construct ( source-targets * : properties * ) { local r = [ generators.construct $(self.project) $(self.name) : $(self.type) - : $(properties) $(self.type) : $(source-targets) ] ; + : $(properties) # [ feature.expand + $(self.type) + # ] + : $(source-targets) ] ; if ! $(r) { - print.wrapped-text "error: unable to construct" [ full-name ] ; - EXIT ; + errors.error "unable to construct" [ full-name ] ; } return $(r) ; diff --git a/v2/build/type.jam b/v2/build/type.jam index fcd7c6bbb..8661d60b9 100644 --- a/v2/build/type.jam +++ b/v2/build/type.jam @@ -9,11 +9,14 @@ import feature ; import generators : * ; import class : class new ; - +import errors ; feature.feature target-type : : composite optional ; -feature.feature base-target-type : : composite optional ; + +# feature.feature base-target-type : : composite optional ; feature.feature main-target-type : : optional incidental ; +feature.feature base-target-type : : composite optional free ; +# feature.feature main-target-type : : composite optional incidental ; # 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'. @@ -25,9 +28,17 @@ feature.feature main-target-type : : optional incidental ; # will be added to the global scope. rule register ( type : suffixes * : base-type ? : main ? ) { + # Type names cannot contain hyphens, because when used as + # feature-values they will be interpreted as composite features + # which need to be decomposed. + switch $(type) + { + case *-* : errors.error "type name \"$(type)\" contains a hyphen" ; + } + if $(type) in $(.types) { - error "Type $(type) is already registered." ; + errors.error "Type $(type) is already registered." ; } else { @@ -36,16 +47,36 @@ rule register ( type : suffixes * : base-type ? : main ? ) .suffix.$(type) = $(suffixes[1]) ; .type.$(suffixes) = $(type) ; feature.extend target-type : $(type) ; - feature.compose $(type) : $(base-type:G=) ; - feature.compose $(type) : $(base-type:G=) ; + + feature.compose $(type) : $(base-type:G=) ; + feature.extend base-target-type : $(type) ; +# feature.compose $(type) : $(type) ; + feature.compose $(type) : $(base-type) ; if $(main) - { - IMPORT $(__name__) : main-target-rule : : $(type:L) ; + { + # Convert the type name to lowercase and convert all + # underscores to hyphens to get the main target rule name. + import regex ; + local n = [ regex.split $(type:L) "_" ] ; + n = $(n:J=-) ; + .main-target-type.$(n) = $(type) ; + + IMPORT $(__name__) : main-target-rule : : $(n) ; +# feature.compose $(type) : $(type) ; } } } +# Returns true iff type has been registered. +rule registered ( type ) +{ + if $(type) in $(.types) + { + return true ; + } +} + # Sets a scanner class that will be used for this 'type'. rule set-scanner ( type : scanner ) { @@ -64,30 +95,28 @@ rule get-scanner ( type : properties * ) } } +# returns type and all of its bases in order of their distance from type. +rule all-bases ( type ) +{ + local result = $(type) ; + while $(type) + { + type = $(.bases.$(type)) ; + result += $(type) ; + } + return $(result) ; +} + # Returns true if 'type' has 'base' as its direct or # indirect base. rule is-derived ( type base ) { - if $(base) in $(.bases.$(type)) + if $(base) in [ all-bases $(type) ] { return true ; } - else - { - # CONSIDER: maybe break when 'found' is true - local found ; - for local e in $(.bases.$(type)) - { - if [ is-derived $(e) $(base) ] - { - found = true ; - } - } - return $(found) ; - } } - # Returns suffix that should be used when generating target of 'type'. rule generated-target-suffix ( type ) { @@ -105,13 +134,13 @@ rule type ( suffix ) rule main-target-rule ( name : sources * : requirements * : default-build * : use-requirements * ) { - # First find requuired target type, which is equal to the name used to - # invoke us. + # First find required target type, which is equal to the name used + # to invoke us. local bt = [ BACKTRACE 1 ] ; - local type = $(bt[4]) ; + local rulename = $(bt[4]) ; targets.main-target-alternative $(name) [ CALLER_MODULE ] typed-target : 3 : 5 : 4 - : $(type:U) : $(sources) : $(requirements) : $(default-build) : $(use-requirements) + : $(.main-target-type.$(rulename)) : $(sources) : $(requirements) : $(default-build) : $(use-requirements) ; } diff --git a/v2/gcc.jam b/v2/gcc.jam index 65d7d9064..5c4e8a261 100644 --- a/v2/gcc.jam +++ b/v2/gcc.jam @@ -4,8 +4,8 @@ import generators ; import os ; generators.register-composing gcc.link : LIB OBJ : EXE : gcc ; -generators.register-composing gcc.archive : OBJ : STATIC-LIB : gcc ; -generators.register-composing gcc.link-dll : OBJ : SHARED-LIB : gcc ; +generators.register-composing gcc.archive : OBJ : STATIC_LIB : gcc ; +generators.register-composing gcc.link-dll : OBJ : SHARED_LIB : gcc ; generators.register-c-compiler gcc.compile : CPP : OBJ : gcc ; generators.register-c-compiler gcc.compile : C : OBJ : gcc ; diff --git a/v2/tools/builtin.jam b/v2/tools/builtin.jam index a57970fd6..c21f274a8 100644 --- a/v2/tools/builtin.jam +++ b/v2/tools/builtin.jam @@ -17,6 +17,7 @@ import os ; import stage ; import prebuilt ; import toolset ; +import errors : error ; feature toolset : gcc : implicit propagated link-incompatible ; feature shared : false true : propagated ; @@ -60,8 +61,7 @@ rule variant ( name : parents-or-properties * : tool-properties * ) # between base variants. if $(parents[2]) { - print.wrapped-text "error: multiple base variants are not yet supported" ; - EXIT ; + error "multiple base variants are not yet supported" ; } # Record explicitly specified properties for this variant @@ -107,26 +107,30 @@ variant release : on off ; type.register LIB : : : main ; -if [ os.name ] in NT CYGWIN +# register the given type on the specified OSes, or on remaining OSes +# if os is not specified. +local rule declare-type ( os * : type : suffixes * : base-type ? : main ? ) { - type.register EXE : exe : : main ; - type.register SHARED-LIB : dll : LIB : main ; - - if [ os.name ] = CYGWIN + if ! [ type.registered $(type) ] { - type.register STATIC-LIB : a : LIB : main ; - } - else - { - type.register STATIC-LIB : lib : LIB : main ; + if ( ! $(os) ) || [ os.name ] in $(os) + { + type.register $(type) : $(suffixes) : $(base-type) : $(main) ; + } } } -else -{ - type.register EXE : : : main ; - type.register SHARED-LIB : so : LIB : main ; - type.register STATIC-LIB : a : LIB : main ; -} + +declare-type NT : STATIC_LIB : a : LIB : main ; +declare-type : STATIC_LIB : a : LIB : main ; + +declare-type NT : SHARED_LIB : dll : LIB : main ; +declare-type : SHARED_LIB : so : LIB : main ; + +declare-type NT CYGWIN : EXE : exe : : main ; +declare-type : EXE : : : main ; + +declare-type NT CYGWIN : PYTHON_EXTENSION : dll : SHARED_LIB : main ; +declare-type : PYTHON_EXTENSION : so : SHARED_LIB : main ; type.register CPP : cpp cxx ; @@ -209,18 +213,18 @@ type.register OBJ : o : : main ; rule lib-generator ( ) { - composing-generator.__init__ lib-generator : unknown-source-type : LIB ; + composing-generator.__init__ lib-generator : unknown-source-type : LIB : LIB ; rule run ( project name ? : properties * : sources + ) { local actual-type ; if true in $(properties) { - actual-type = SHARED-LIB ; + actual-type = SHARED_LIB ; } else { - actual-type = STATIC-LIB ; + actual-type = STATIC_LIB ; } return [ generators.construct $(project) $(name) : $(actual-type) : $(properties) : $(sources) : allow-composing-generators ] ;