# Copyright (c) 2010 Vladimir Prus. # # Use, modification and distribution is subject to the Boost Software # License Version 1.0. (See accompanying file LICENSE_1_0.txt or # http://www.boost.org/LICENSE_1_0.txt) # This module defines function to help with two main tasks: # # - Discovering build-time configuration for the purposes of adjusting # build process. # - Reporting what is built, and how it is configured. import targets ; import errors ; import targets ; import sequence ; import property ; import property-set ; import "class" : new ; import common ; import path ; rule log-summary ( ) { } .width = 30 ; rule set-width ( width ) { .width = $(width) ; } # Declare that the components specified by the parameter exist. rule register-components ( components * ) { .components += $(components) ; } # Declare that the components specified by the parameters will # be build. rule components-building ( components * ) { .built-components += $(components) ; } # Report something about component configuration that the # user should better know. rule log-component-configuration ( component : message ) { # FIXME: implement per-property-set logs .component-logs.$(component) += $(message) ; } rule log-check-result ( result ) { if ! $(.announced-checks) { ECHO "Performing configuration checks\n" ; .announced-checks = 1 ; } ECHO $(result) ; #.check-results += $(result) ; } rule log-library-search-result ( library : result ) { local x = [ PAD " - $(library) : $(result)" : $(.width) ] ; log-check-result "$(x)" ; } rule print-component-configuration ( ) { local c = [ sequence.unique $(.components) ] ; ECHO "\nComponent configuration:\n" ; for c in $(.components) { local s ; if $(c) in $(.built-components) { s = "building" ; } else { s = "not building" ; } ECHO [ PAD " - $(c)" : $(.width) ] ": $(s)" ; for local m in $(.component-logs.$(c)) { ECHO " -" $(m) ; } } ECHO ; } rule print-configure-checks-summary ( ) { # FIXME: the problem with that approach is tha # the user sees checks summary when all checks are # done, and has no progress reporting while the # checks are being executed. if $(.check-results) { ECHO "Configuration checks summary\n" ; for local r in $(.check-results) { ECHO $(r) ; } ECHO ; } } # Attempt to build a metatarget named by 'metatarget-reference' # in context of 'project' with properties 'ps'. # Returns non-empty value if build is OK. rule builds-raw ( metatarget-reference : project : ps : what : retry ? ) { local result ; if ! $(retry) && ! $(.$(what)-tested.$(ps)) { .$(what)-tested.$(ps) = true ; local targets = [ targets.generate-from-reference $(metatarget-reference) : $(project) : $(ps) ] ; local jam-targets ; for local t in $(targets[2-]) { jam-targets += [ $(t).actualize ] ; } if ! UPDATE_NOW in [ RULENAMES ] { # Cannot determine. Assume existance. } else { local x = [ PAD " - $(what)" : $(.width) ] ; if [ UPDATE_NOW $(jam-targets) : $(.log-fd) : ignore-minus-n : ignore-minus-q ] { .$(what)-supported.$(ps) = yes ; result = true ; log-check-result "$(x) : yes" ; } else { log-check-result "$(x) : no" ; } } return $(result) ; } else { return $(.$(what)-supported.$(ps)) ; } } rule builds ( metatarget-reference : properties * : what ? : retry ? ) { what ?= "$(metatarget-reference) builds" ; # FIXME: this should not be hardcoded. Other checks might # want to consider different set of features as relevant. local toolset = [ property.select : $(properties) ] ; local toolset-version-property = "" ; local relevant = [ property.select $(toolset-version-property) : $(properties) ] ; local ps = [ property-set.create $(relevant) ] ; local t = [ targets.current ] ; local p = [ $(t).project ] ; return [ builds-raw $(metatarget-reference) : $(p) : $(ps) : $(what) : $(retry) ] ; } # Called by Boost.Build startup code to specify name of a file # that will receive results of configure checks. This # should never be called by users. rule set-log-file ( log-file ) { path.makedirs [ path.parent $(log-file) ] ; .log-fd = [ FILE_OPEN $(log-file) : "w" ] ; } # Frontend rules class check-target-builds-worker { import configure ; import property-set ; import targets ; import property ; rule __init__ ( target message ? : true-properties * : false-properties * ) { self.target = $(target) ; self.message = $(message) ; self.true-properties = $(true-properties) ; self.false-properties = $(false-properties) ; } rule check ( properties * ) { local choosen ; if [ configure.builds $(self.target) : $(properties) : $(self.message) ] { choosen = $(self.true-properties) ; } else { choosen = $(self.false-properties) ; } return [ property.evaluate-conditionals-in-context $(choosen) : $(properties) ] ; } } rule check-target-builds ( target message ? : true-properties * : false-properties * ) { local instance = [ new check-target-builds-worker $(target) $(message) : $(true-properties) : $(false-properties) ] ; return @$(instance).check ; } IMPORT $(__name__) : check-target-builds : : check-target-builds ;