mirror of
https://github.com/boostorg/build.git
synced 2026-02-09 23:12:23 +00:00
When adding the default value of a feature, also add the default values of its subfeatures. Fixes #308. Closes #310.
* Rework the test case expansion.py to avoid interference from user-config.jam and toolsets which previously masked this problem. Also add a test case specifically for this issue. * Remove the test case for BB60. I have no idea what BB60 is, but the test case doesn't seem particularly important for the current implementation given that project requirements are merged into the target requirements long before conditionals are evaluated.
This commit is contained in:
@@ -1092,7 +1092,7 @@ rule add-defaults ( properties * )
|
||||
}
|
||||
}
|
||||
|
||||
local worklist = $(properties) ;
|
||||
local worklist = $(properties) $(more) ;
|
||||
local expanded-from-composite ;
|
||||
local to-expand = $(more) ;
|
||||
while $(worklist)
|
||||
|
||||
@@ -7,87 +7,92 @@
|
||||
|
||||
import BoostBuild
|
||||
|
||||
t = BoostBuild.Tester(use_test_config=False)
|
||||
t = BoostBuild.Tester(arguments=["--config="], pass_toolset=0)
|
||||
|
||||
t.write("a.cpp", """
|
||||
#ifdef CF_IS_OFF
|
||||
int main() {}
|
||||
#endif
|
||||
""")
|
||||
t.write("source.input", "")
|
||||
|
||||
t.write("b.cpp", """
|
||||
#if defined(CF_1) && !defined(CF_IS_OFF)
|
||||
int main() {}
|
||||
#endif
|
||||
""")
|
||||
t.write("test-properties.jam", """
|
||||
import feature : feature ;
|
||||
import generators ;
|
||||
import toolset ;
|
||||
import type ;
|
||||
|
||||
t.write("c.cpp", """
|
||||
#ifdef FOO
|
||||
int main() {}
|
||||
#endif
|
||||
""")
|
||||
# We're not using the toolset at all, and we want to
|
||||
# suppress toolset initialization to avoid surprises.
|
||||
feature.extend toolset : null ;
|
||||
|
||||
t.write("d.cpp", """
|
||||
#ifndef CF_IS_OFF
|
||||
int main() {}
|
||||
#endif
|
||||
""")
|
||||
|
||||
t.write("e.cpp", """
|
||||
#if !defined(CF_IS_OFF) && defined(CF_2) && !defined(CF_1)
|
||||
int main() {}
|
||||
#endif
|
||||
""")
|
||||
|
||||
t.write("f.cpp", """
|
||||
#if defined(CF_1)
|
||||
int main() {}
|
||||
#endif
|
||||
""")
|
||||
|
||||
t.write("g.cpp", """
|
||||
#if defined(FOPT_2)
|
||||
int main() {}
|
||||
#endif
|
||||
""")
|
||||
|
||||
t.write("h.cpp", """
|
||||
#if defined(CX_2)
|
||||
int main() {}
|
||||
#endif
|
||||
type.register CHECK : check ;
|
||||
type.register INPUT : input ;
|
||||
feature expected-define : : free ;
|
||||
feature unexpected-define : : free ;
|
||||
toolset.flags test-properties DEFINES : <define> ;
|
||||
toolset.flags test-properties EXPECTED : <expected-define> ;
|
||||
toolset.flags test-properties UNEXPECTED : <unexpected-define> ;
|
||||
generators.register-standard test-properties.check : INPUT : CHECK ;
|
||||
rule check ( target : source : properties * )
|
||||
{
|
||||
local defines = [ on $(target) return $(DEFINES) ] ;
|
||||
for local macro in [ on $(target) return $(EXPECTED) ]
|
||||
{
|
||||
if ! ( $(macro) in $(defines) )
|
||||
{
|
||||
EXIT expected $(macro) for $(target) in $(properties) : 1 ;
|
||||
}
|
||||
}
|
||||
for local macro in [ on $(target) return $(UNEXPECTED) ]
|
||||
{
|
||||
if $(macro) in $(defines)
|
||||
{
|
||||
EXIT unexpected $(macro) for $(target) in $(properties) : 1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
actions check
|
||||
{
|
||||
echo okay > $(<)
|
||||
}
|
||||
""")
|
||||
|
||||
t.write("jamfile.jam", """
|
||||
import test-properties ;
|
||||
# See if default value of composite feature 'cf' will be expanded to
|
||||
# <define>CF_IS_OFF.
|
||||
exe a : a.cpp ;
|
||||
check a : source.input : <expected-define>CF_IS_OFF ;
|
||||
|
||||
# See if subfeature in requirements in expanded.
|
||||
exe b : b.cpp : <cf>on-1 ;
|
||||
check b : source.input : <cf>on-1
|
||||
<expected-define>CF_1 <unexpected-define>CF_IS_OFF ;
|
||||
|
||||
# See if conditional requirements are recursively expanded.
|
||||
exe c : c.cpp : <toolset>$toolset:<variant>release <variant>release:<define>FOO
|
||||
check c : source.input : <toolset>null:<variant>release
|
||||
<variant>release:<define>FOO <expected-define>FOO
|
||||
;
|
||||
|
||||
# Composites specified in the default build should not
|
||||
# be expanded if they are overridden in the the requirements.
|
||||
exe d : d.cpp : <cf>on : <cf>off ;
|
||||
check d : source.input : <cf>on <unexpected-define>CF_IS_OFF : <cf>off ;
|
||||
|
||||
# Overriding a feature should clear subfeatures and
|
||||
# apply default values of subfeatures.
|
||||
exe e : e.cpp : <cf>always : <cf>on-1 ;
|
||||
check e : source.input : <cf>always
|
||||
<unexpected-define>CF_IS_OFF <expected-define>CF_2 <unexpected-define>CF_1
|
||||
: <cf>on-1 ;
|
||||
|
||||
# Subfeatures should not be changed if the parent feature doesn't change
|
||||
exe f : f.cpp : <cf>on : <cf>on-1 ;
|
||||
check f : source.input : <cf>on <expected-define>CF_1 : <cf>on-1 ;
|
||||
|
||||
# If a subfeature is not specific to the value of the parent feature,
|
||||
# then changing the parent value should not clear the subfeature.
|
||||
exe g : g.cpp : <fopt>off : <fopt>on-2 ;
|
||||
check g : source.input : <fopt>off <expected-define>FOPT_2 : <fopt>on-2 ;
|
||||
|
||||
# If the default value of a composite feature adds an optional
|
||||
# feature which has a subfeature with a default, then that
|
||||
# default should be added.
|
||||
exe h : h.cpp ;
|
||||
check h : source.input : <expected-define>CX_2 ;
|
||||
|
||||
# If the default value of a feature is used, then the
|
||||
# default value of its subfeatures should also be used.
|
||||
check i : source.input : <expected-define>SF_1 ;
|
||||
""")
|
||||
|
||||
t.write("jamroot.jam", """
|
||||
@@ -107,40 +112,23 @@ feature.feature cx2 : on : optional incidental ;
|
||||
feature.subfeature cx2 on : sub : 1 : composite incidental ;
|
||||
feature.compose <cx1>on : <cx2>on ;
|
||||
feature.compose <cx2-on:sub>1 : <define>CX_2 ;
|
||||
|
||||
feature.feature sf : a : incidental ;
|
||||
feature.subfeature sf a : sub : 1 : composite incidental ;
|
||||
feature.compose <sf-a:sub>1 : <define>SF_1 ;
|
||||
""")
|
||||
|
||||
t.expand_toolset("jamfile.jam")
|
||||
|
||||
t.run_build_system()
|
||||
t.expect_addition(["bin/$toolset/debug*/a.exe",
|
||||
"bin/$toolset/debug*/b.exe",
|
||||
"bin/$toolset/release*/c.exe",
|
||||
"bin/$toolset/debug*/d.exe",
|
||||
"bin/$toolset/debug*/e.exe",
|
||||
"bin/$toolset/debug*/f.exe",
|
||||
"bin/$toolset/debug*/g.exe",
|
||||
"bin/$toolset/debug*/h.exe"])
|
||||
|
||||
t.rm("bin")
|
||||
|
||||
|
||||
# Test for issue BB60.
|
||||
|
||||
t.write("test.cpp", """
|
||||
#include "header.h"
|
||||
int main() {}
|
||||
""")
|
||||
|
||||
t.write("jamfile.jam", """
|
||||
project : requirements <toolset>$toolset:<include>foo ;
|
||||
exe test : test.cpp : <toolset>$toolset ;
|
||||
""")
|
||||
|
||||
t.expand_toolset("jamfile.jam")
|
||||
t.write("foo/header.h", "\n")
|
||||
t.write("jamroot.jam", "")
|
||||
|
||||
t.run_build_system()
|
||||
t.expect_addition("bin/$toolset/debug*/test.exe")
|
||||
t.expect_addition(["bin/debug/a.check",
|
||||
"bin/debug/b.check",
|
||||
"bin/null/release/c.check",
|
||||
"bin/debug/d.check",
|
||||
"bin/debug/e.check",
|
||||
"bin/debug/f.check",
|
||||
"bin/debug/g.check",
|
||||
"bin/debug/h.check",
|
||||
"bin/debug/i.check"])
|
||||
|
||||
t.cleanup()
|
||||
|
||||
Reference in New Issue
Block a user