diff --git a/src/build-system.jam b/src/build-system.jam index 51f253bcd..0c9cbf481 100755 --- a/src/build-system.jam +++ b/src/build-system.jam @@ -22,6 +22,7 @@ import build-request ; import errors : error ; import virtual-target ; import "class" : new ; +import toolset ; import builtin ; import make ; @@ -44,9 +45,12 @@ rule location ( ) # ignore user configs. local test-config = [ GLOB [ os.environ BOOST_BUILD_PATH ] : test-config.jam ] ; + +local debug-config = [ MATCH ^(--debug-configuration)$ : [ modules.peek : ARGV ] ] ; + if $(test-config) { - if --debug-configuration in [ modules.peek : ARGV ] + if $(debug-config) { ECHO "notice: loading test-config.jam from" [ NORMALIZE_PATH $(test-config[1]) ] ; @@ -68,65 +72,123 @@ if $(test-config) || --ignore-config in [ modules.peek : ARGV ] local user-path = [ os.home-directories ] [ os.environ BOOST_BUILD_PATH ] ; +# Unless ignore-config is set, load the configuration file in +# $(path)/$(basename).jam +local rule load-config ( basename : path + ) +{ + if ! $(ignore-config) + { + if $(debug-config) + { + local where = [ GLOB $(path) : $(basename).jam ] ; + if $(where) + { + ECHO notice: loading $(basename).jam from + [ NORMALIZE_PATH $(where[1]) ] ; + } + } + + modules.load $(basename) : : $(path) ; + project.load-used-projects $(basename) ; + } +} + +# # Load site-config. +# module site-config { import project : initialize ; initialize site-config ; } - -if ! $(ignore-config) -{ - local path ; - if [ os.name ] in NT CYGWIN - { - path = [ modules.peek : SystemRoot ] $(user-path) ; - } - else - { - path = /etc $(user-path) ; - } - - - if --debug-configuration in [ modules.peek : ARGV ] - { - local where = [ GLOB $(path) : site-config.jam ] ; - if $(where) - { - ECHO "notice: loading site-config.jam from" - [ NORMALIZE_PATH $(where[1]) ] ; - } - } - - modules.load site-config : : $(path) ; - project.load-used-projects site-config ; + +local site-path = /etc $(user-path) ; + +if [ os.name ] in NT CYGWIN +{ + site-path = [ modules.peek : SystemRoot ] $(user-path) ; } +load-config site-config : $(site-path) ; +# # Load user-config. +# module user-config { import project : initialize ; initialize user-config ; } -if ! $(ignore-config) -{ - if --debug-configuration in [ modules.peek : ARGV ] +load-config user-config : $(user-path) ; + +# +# Autoconfigure toolsets based on any instances of --toolset=xxx or +# toolset=xxx in the command line +# +local argv = [ modules.peek : ARGV ] ; +local x-toolset-version = [ MATCH ^(--)?toolset=(.*) : $(argv) ] ; + +if $(x-toolset-version) +{ + local toolset-version = $(x-toolset-version[2]) ; + local toolset = [ MATCH ([^-]+).* : $(toolset-version) ] ; + local version = [ MATCH [^-]+-(.+) : $(toolset-version) ] ; + + if $(debug-config) { - local where = [ GLOB $(user-path) : user-config.jam ] ; - if $(where) + ECHO notice: [cmdline-cfg] Detected command-line request for + $(toolset-version): toolset= \"$(toolset)\" "version= \""$(version)\" ; + } + + local known ; + + # if the toolset isn't known, configure it now. + if $(toolset) in [ feature.values ] + { + known = true ; + } + + if $(known) && $(version) + && ! [ feature.is-subvalue toolset : $(toolset) : version : $(version) ] + { + known = ; + } + + if ! $(known) + { + if $(debug-config) { - ECHO "notice: loading user-config.jam from" - [ NORMALIZE_PATH $(where[1]) ] ; - } - } + ECHO notice: [cmdline-cfg] toolset $(toolset-version) + not previously configured; configuring now ; + } + toolset.using $(toolset) : $(version) ; + } + else + { + if $(debug-config) + { + ECHO notice: [cmdline-cfg] toolset $(toolset-version) already configured ; + } + } + + # make sure we get an appropriate property in the build request into + # case the user used the "--toolset=..." form + local toolset-option = [ MATCH ^--toolset=(.*) : $(argv) ] ; + if $(toolset-option) + && ! $(toolset-option) in $(argv) + && ! toolset=$(toolset-option) in $(argv) + { + if $(debug-config) + { + ECHO notice: [cmdline-cfg] adding toolset=$(toolset-option) "to build request." ; + } - modules.load user-config : : $(user-path) ; - project.load-used-projects user-config ; -} - - + argv += $(toolset-option) ; + modules.poke : ARGV : $(argv) ; + } +} + if USER_MODULE in [ RULENAMES ] { USER_MODULE site-config user-config ; @@ -152,11 +214,22 @@ if [ project.find "." : "." ] if ! [ feature.values ] { - ECHO "warning: no toolsets are configured." ; - ECHO "warning: you won't be able to build C++ programs." ; - ECHO "warning: please consult the documentation at" ; - ECHO "warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" ; - ECHO ; + local default-toolset = gcc ; + if [ os.name ] = NT + { + default-toolset = msvc ; + } + + ECHO "warning: * No toolsets are configured." ; + ECHO "warning: * Configuring default toolset" \"$(default-toolset)\". ; + ECHO "warning: * If the default is wrong, you may not be able to" ; + ECHO "warning: build C++ programs." ; + ECHO "warning: * Use the \"--toolset=xxxxx\" option to override our guess." ; + ECHO "warning: * Please consult the documentation at" ; + ECHO "warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" ; + ECHO "warning: for more configuration options" ; + + toolset.using $(default-toolset) ; } diff --git a/src/build/feature.jam b/src/build/feature.jam index b9b9e8822..2e0f91a78 100644 --- a/src/build/feature.jam +++ b/src/build/feature.jam @@ -439,6 +439,38 @@ rule validate-value-string ( feature value-string ) } } +# A helper that computes: +# * the name(s) of the module-local variable(s) used to record the +# correspondence between subvalue(s) and a subfeature +# +# * the value of that variable when such a subfeature/subvalue has +# been defined +# +# Returns a list consisting of the latter followed by the former +local rule subvalue-var ( + feature # Main feature name + + value-string ? # If supplied, specifies a specific value of the + # main feature for which the subfeature values + # are valid + + : subfeature # The name of the subfeature + : subvalues * # The subfeature values +) +{ + feature = [ grist $(feature) ] ; + validate-feature $(feature) ; + if $(value-string) + { + validate-value-string $(feature) $(value-string) ; + } + + local subfeature-name = [ get-subfeature-name $(subfeature) $(value-string) ] ; + + return $(subfeature-name) + $(feature)$(value-string:E="")<>$(subvalues).subfeature ; +} + # Extends the given subfeature with the subvalues. If the optional # value-string is provided, the subvalues are only valid for the given # value of the feature. Thus, you could say that @@ -457,21 +489,29 @@ rule extend-subfeature ( : subvalues * # The additional values of the subfeature being defined. ) { - feature = [ grist $(feature) ] ; - validate-feature $(feature) ; - if $(value-string) - { - validate-value-string $(feature) $(value-string) ; - } - - local subfeature-name = [ get-subfeature-name $(subfeature) $(value-string) ] ; + local subfeature-vars = [ + subvalue-var $(feature) $(value-string) : $(subfeature) : $(subvalues) ] ; - local f = [ utility.ungrist $(feature) ] ; - extend $(f)-$(subfeature-name) : $(subvalues) ; + local f = [ utility.ungrist [ grist $(feature) ] ] ; + extend $(f)-$(subfeature-vars[1]) : $(subvalues) ; # provide a way to get from the given feature or property and # subfeature value to the subfeature name. - $(feature)$(value-string:E="")<>$(subvalues).subfeature = $(subfeature-name) ; + $(subfeature-vars[2-]) = $(subfeature-vars[1]) ; +} + +# Returns true iff the subvalues are valid for the feature. When the +# optional value-string is provided, returns true iff the subvalues +# are valid for the given value of the feature. +rule is-subvalue ( feature : value-string ? : subfeature : subvalue ) +{ + local subfeature-vars = [ + subvalue-var $(feature) $(value-string) : $(subfeature) : $(subvalues) ] ; + + if $($(subfeature-vars[2])) = $(subfeature-vars[1]) + { + return true ; + } } # Can be called three ways: @@ -1021,6 +1061,13 @@ local rule __test__ ( ) subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4 3.0 3.0.1 3.0.2 ; + assert.true is-subvalue toolset : gcc : version : 2.95.3 ; + assert.false is-subvalue toolset : gcc : version : 1.1 ; + + assert.false is-subvalue toolset : notool : version : 2.95.3 ; + assert.true is-subvalue toolset : : version : 2.95.3 ; + assert.false is-subvalue toolset : : version : yabba ; + subfeature toolset gcc : platform : linux cygwin : optional ; assert.result