mirror of
https://github.com/boostorg/build.git
synced 2026-02-14 00:32:11 +00:00
Add a new rule configure.choose that adds properties associated with the first target from a list that successfully builds.
This commit is contained in:
@@ -222,6 +222,89 @@ rule try-build ( targets * : ps : what : retry ? )
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
# Attempts to build several sets of virtual targets. Returns the
|
||||
# the index of the first set that builds.
|
||||
rule try-find-build ( ps : what : * )
|
||||
{
|
||||
local args = 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ;
|
||||
# The outer layer only needs to check $(what), but we
|
||||
# also need to check the individual elements, in case
|
||||
# the set of targets has changed since the last build.
|
||||
local cache-name = $(what) $($(args)[1]) [ $(ps).raw ] ;
|
||||
cache-name = $(cache-name:J=-) ;
|
||||
local value = [ config-cache.get $(cache-name) ] ;
|
||||
|
||||
local result ;
|
||||
local jam-targets ;
|
||||
|
||||
|
||||
# Check whether we need to force rebuild configure targets
|
||||
if --reconfigure in [ modules.peek : ARGV ]
|
||||
{
|
||||
local all-targets ;
|
||||
for local t in $($(args)[2-])
|
||||
{
|
||||
all-targets += [ virtual-target.traverse $(t) ] ;
|
||||
}
|
||||
for local t in [ sequence.unique $(all-targets) ]
|
||||
{
|
||||
$(t).always ;
|
||||
}
|
||||
}
|
||||
|
||||
if $(value)
|
||||
{
|
||||
local none = none ; # What to show when the argument
|
||||
local name = $(value) ;
|
||||
if $(name) != none
|
||||
{
|
||||
name = [ CALC $(name) + 2 ] ;
|
||||
}
|
||||
local x = [ PAD " - $(what)" : $(.width) ] ;
|
||||
local y = [ PAD $($(name)[1]) : 3 ] ;
|
||||
result = $(value) ;
|
||||
log-check-result "$(x) : $(y) (cached)" ;
|
||||
}
|
||||
else
|
||||
{
|
||||
local x = [ PAD " - $(what)" : $(.width) ] ;
|
||||
for local i in $(args)
|
||||
{
|
||||
local jam-targets ;
|
||||
for local t in $($(i)[2-])
|
||||
{
|
||||
jam-targets += [ $(t).actualize ] ;
|
||||
}
|
||||
if [ UPDATE_NOW $(jam-targets) :
|
||||
$(.log-fd) : ignore-minus-n : ignore-minus-q ]
|
||||
{
|
||||
result = [ CALC $(i) - 2 ] ;
|
||||
log-check-result "$(x) : $($(i)[1])" ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ! $(result)
|
||||
{
|
||||
result = none ;
|
||||
}
|
||||
}
|
||||
if ! $(value)
|
||||
{
|
||||
if $(result)
|
||||
{
|
||||
config-cache.set $(cache-name) : $(result) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
config-cache.set $(cache-name) : $(result) ;
|
||||
}
|
||||
}
|
||||
if $(result) != none
|
||||
{
|
||||
return $(result) ;
|
||||
}
|
||||
}
|
||||
|
||||
# Attempt to build a metatarget named by 'metatarget-reference'
|
||||
# in context of 'project' with properties 'ps'.
|
||||
# Returns non-empty value if build is OK.
|
||||
@@ -248,6 +331,68 @@ rule builds-raw ( metatarget-reference : project : ps : what : retry ? )
|
||||
}
|
||||
}
|
||||
|
||||
# Attempt to build a metatarget named by 'metatarget-reference'
|
||||
# in context of 'project' with properties 'ps'.
|
||||
# Returns the 1-based index of the first target
|
||||
# that builds.
|
||||
rule find-builds-raw ( project : ps : what : * )
|
||||
{
|
||||
local result ;
|
||||
local args = 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ;
|
||||
|
||||
if ! $(.$(what)-tested.$(ps))
|
||||
{
|
||||
.$(what)-tested.$(ps) = true ;
|
||||
local targets.$(i) what.$(i) ;
|
||||
for local i in $(args)
|
||||
{
|
||||
if ! $($(i))
|
||||
{
|
||||
break ;
|
||||
}
|
||||
targets.$(i) = [ targets.generate-from-reference
|
||||
$($(i)[1]) : $(project) : $(ps) ] ;
|
||||
# ignore usage requirements
|
||||
targets.$(i) = $(targets.$(i)[2-]) ;
|
||||
if $($(i)[2])
|
||||
{
|
||||
what.$(i) = $($(i)[2]) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
local t = [ targets.resolve-reference
|
||||
$($(i)[1]) : $(project) ] ;
|
||||
what.$(i) = [ $(t[1]).name ] ;
|
||||
}
|
||||
}
|
||||
|
||||
result = [ try-find-build $(ps) : $(what)
|
||||
: $(what.4) $(targets.4)
|
||||
: $(what.5) $(targets.5)
|
||||
: $(what.6) $(targets.6)
|
||||
: $(what.7) $(targets.7)
|
||||
: $(what.8) $(targets.8)
|
||||
: $(what.9) $(targets.9)
|
||||
: $(what.10) $(targets.10)
|
||||
: $(what.11) $(targets.11)
|
||||
: $(what.12) $(targets.12)
|
||||
: $(what.13) $(targets.13)
|
||||
: $(what.14) $(targets.14)
|
||||
: $(what.15) $(targets.15)
|
||||
: $(what.16) $(targets.16)
|
||||
: $(what.17) $(targets.17)
|
||||
: $(what.18) $(targets.18)
|
||||
: $(what.19) $(targets.19) ] ;
|
||||
.$(what)-result.$(ps) = $(result) ;
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $(.$(what)-result.$(ps)) ;
|
||||
}
|
||||
}
|
||||
|
||||
local rule get-relevant-features ( )
|
||||
{
|
||||
local relevant = [ feature.expand <configure> ] ;
|
||||
@@ -286,6 +431,19 @@ rule builds ( metatarget-reference : properties * : what ? : retry ? )
|
||||
$(retry) ] ;
|
||||
}
|
||||
|
||||
rule find-builds ( what : properties * : * )
|
||||
{
|
||||
local relevant = [ property.select [ get-relevant-features ] : $(properties) ] ;
|
||||
local ps = [ property-set.create $(relevant) ] ;
|
||||
local t = [ targets.current ] ;
|
||||
local p = [ $(t).project ] ;
|
||||
|
||||
return [ find-builds-raw $(p) : $(ps) : $(what) :
|
||||
$(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) :
|
||||
$(10) : $(11) : $(12) : $(13) : $(14) : $(15) :
|
||||
$(16) : $(17) : $(18) : $(19) ] ;
|
||||
}
|
||||
|
||||
|
||||
# Called by Boost.Build startup code to specify the file to receive the
|
||||
# configuration check results. Should never be called by user code.
|
||||
@@ -330,6 +488,57 @@ class check-target-builds-worker
|
||||
}
|
||||
}
|
||||
|
||||
class configure-choose-worker
|
||||
{
|
||||
import configure ;
|
||||
import property ;
|
||||
rule __init__ ( message : * )
|
||||
{
|
||||
self.message = $(message) ;
|
||||
for i in 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
{
|
||||
local name = [ CALC $(i) - 1 ] ;
|
||||
self.targets.$(name) = $($(i)[1]) ;
|
||||
if ! $($(i)[2]:G) # Check whether the second argument is a property
|
||||
{
|
||||
self.what.$(name) = $($(i)[2]) ;
|
||||
self.props.$(name) = $($(i)[3-]) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.props.$(name) = $($(i)[2-]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
rule check ( properties * )
|
||||
{
|
||||
local i = [ configure.find-builds $(self.message) : $(properties)
|
||||
: $(self.targets.1) $(self.what.1)
|
||||
: $(self.targets.2) $(self.what.2)
|
||||
: $(self.targets.3) $(self.what.3)
|
||||
: $(self.targets.4) $(self.what.4)
|
||||
: $(self.targets.5) $(self.what.5)
|
||||
: $(self.targets.6) $(self.what.6)
|
||||
: $(self.targets.7) $(self.what.7)
|
||||
: $(self.targets.8) $(self.what.8)
|
||||
: $(self.targets.9) $(self.what.9)
|
||||
: $(self.targets.10) $(self.what.10)
|
||||
: $(self.targets.11) $(self.what.11)
|
||||
: $(self.targets.12) $(self.what.12)
|
||||
: $(self.targets.13) $(self.what.13)
|
||||
: $(self.targets.14) $(self.what.14)
|
||||
: $(self.targets.15) $(self.what.15)
|
||||
: $(self.targets.16) $(self.what.16)
|
||||
: $(self.targets.17) $(self.what.17)
|
||||
: $(self.targets.18) $(self.what.18)
|
||||
: $(self.targets.19) $(self.what.19) ] ;
|
||||
if $(self.props.$(i))
|
||||
{
|
||||
return [ property.evaluate-conditionals-in-context $(self.props.$(i)) : $(properties) ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rule check-target-builds ( target message ? : true-properties * :
|
||||
false-properties * )
|
||||
@@ -339,5 +548,19 @@ rule check-target-builds ( target message ? : true-properties * :
|
||||
return <conditional>@$(instance).check ;
|
||||
}
|
||||
|
||||
# Usage:
|
||||
# [ configure.choose "architecture"
|
||||
# : /config//x86 x86 <architecture>x86
|
||||
# : /config//mips mips <architecture>mips
|
||||
# ]
|
||||
rule choose ( message : * )
|
||||
{
|
||||
local instance = [ new configure-choose-worker $(message)
|
||||
: $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9)
|
||||
: $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16)
|
||||
: $(17) : $(18) : $(19) ] ;
|
||||
return <conditional>@$(instance).check ;
|
||||
}
|
||||
|
||||
|
||||
IMPORT $(__name__) : check-target-builds : : check-target-builds ;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import BoostBuild
|
||||
|
||||
def test_basic():
|
||||
def test_check_target_builds():
|
||||
t = BoostBuild.Tester(use_test_config=0)
|
||||
t.write("Jamroot", """
|
||||
import configure ;
|
||||
@@ -67,4 +67,55 @@ obj bar : foo.cpp :
|
||||
|
||||
t.cleanup()
|
||||
|
||||
test_basic()
|
||||
def test_choose():
|
||||
t = BoostBuild.Tester(use_test_config=0)
|
||||
t.write("Jamroot", """
|
||||
import configure ;
|
||||
obj pass : pass.cpp ;
|
||||
obj fail : fail.cpp ;
|
||||
explicit pass fail ;
|
||||
obj foo : foo.cpp :
|
||||
[ configure.choose "which one?" : fail <define>FAIL : pass <define>PASS ] ;
|
||||
""")
|
||||
t.write("pass.cpp", "void f() {}\n")
|
||||
t.write("fail.cpp", "#error fail.cpp\n")
|
||||
t.write("foo.cpp", """
|
||||
#ifndef PASS
|
||||
#error PASS not defined
|
||||
#endif
|
||||
#ifdef FAIL
|
||||
#error FAIL is defined
|
||||
#endif
|
||||
""")
|
||||
t.run_build_system()
|
||||
t.expect_output_lines([
|
||||
" - which one? : pass"])
|
||||
t.expect_addition("bin/$toolset/debug*/pass.obj")
|
||||
t.expect_addition("bin/$toolset/debug*/foo.obj")
|
||||
t.expect_nothing_more()
|
||||
|
||||
# An up-to-date build should use the cache
|
||||
t.run_build_system()
|
||||
t.expect_output_lines([
|
||||
" - which one? : pass (cached)"])
|
||||
t.expect_nothing_more()
|
||||
|
||||
# -a should re-run everything, including configuration checks
|
||||
t.run_build_system(["-a"])
|
||||
t.expect_output_lines([
|
||||
" - which one? : pass"])
|
||||
t.expect_touch("bin/$toolset/debug*/pass.obj")
|
||||
t.expect_touch("bin/$toolset/debug*/foo.obj")
|
||||
t.expect_nothing_more()
|
||||
|
||||
# --reconfigure should re-run configuration checks only
|
||||
t.run_build_system(["--reconfigure"])
|
||||
t.expect_output_lines([
|
||||
" - which one? : pass"])
|
||||
t.expect_touch("bin/$toolset/debug*/pass.obj")
|
||||
t.expect_nothing_more()
|
||||
|
||||
t.cleanup()
|
||||
|
||||
test_check_target_builds()
|
||||
test_choose()
|
||||
|
||||
Reference in New Issue
Block a user