mirror of
https://github.com/boostorg/build.git
synced 2026-02-17 13:42:14 +00:00
Implement feature relevance.
* New feature <relevant> which is automatically deduced in most cases. * Features which are not relevant do not affect target paths and do not prevent merging of virtual targets. * generators.jam: generator.run always returns usage-requirements to allow usage-requirements in non-top-level generators. This is necessary because we're using usage-requirements to track relevance from flags. * New rule toolset.uses-features to specify features that the rule checks manually, instead of using toolset.flags. In the future, we should consider restricting the properties actually passed, to detect errors. * Adjust tests to handle the new paths (verified by inspection). * Add temporary option --ignore-relevance to consider all features relevant to aid migration. * New rule property.evaluate-conditional-relevance which helps tracking relevance in <conditional>. * Widely scattered changes to use the new interfaces.
This commit is contained in:
@@ -856,6 +856,60 @@ path-constant DATA : data/a.txt ;
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry id="bbv2.reference.features.relevant"><term><literal>relevant</literal></term>
|
||||||
|
<listitem>
|
||||||
|
|
||||||
|
<indexterm><primary>features</primary><secondary>relevance</secondary></indexterm>
|
||||||
|
<indexterm><primary>relevant</primary></indexterm>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<emphasis role="bold">Allowed values:</emphasis> the name of any feature.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This feature is used to indicate which other features are relevant for
|
||||||
|
a given target. It is usually not necessary to manage it explicitly,
|
||||||
|
as Boost.Build can deduce it in most cases. Features which are not
|
||||||
|
relevant will not affect target paths, and will not cause conflicts.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A feature will be considered relevant if any of the following are true
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>It is referenced by <literal>toolset.flags</literal> or <literal>toolset.uses-features</literal></listitem>
|
||||||
|
<listitem>It is used by the requirements of a generator</listitem>
|
||||||
|
<listitem>It is a subfeature of a relevant feature</listitem>
|
||||||
|
<listitem>It has a subfeature which is relevant</listitem>
|
||||||
|
<listitem>It is a composite feature, and any composed feature is relevant</listitem>
|
||||||
|
<listitem>It affects target alternative selection for a main target</listitem>
|
||||||
|
<listitem>It is a propagated feature and is relevant for any dependency</listitem>
|
||||||
|
<listitem>It is relevant for any dependency created by the same main target</listitem>
|
||||||
|
<listitem>It is used in the condition of a conditional property and the corresponding value is relevant</listitem>
|
||||||
|
<listitem>It is explicitly named as relevent</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>Relevant features cannot be automatically deduced in the following cases:</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>Indirect conditionals. Solution: return properties of the form
|
||||||
|
<literal><relevant>result-feature:<relevant>condition-feature</literal>
|
||||||
|
<note><para>This isn't really a <link linkend="bbv2.reference.variants.propcond">conditional</link>,
|
||||||
|
although for most purposes it functions like one. In particular, it does not support
|
||||||
|
multiple comma-separated elements in the condition, and it does work correctly even
|
||||||
|
in contexts where conditional properties are not allowed</para></note></listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Action rules that read properties. Solution: add <literal>toolset.uses-features</literal>
|
||||||
|
to tell Boost.Build that the feature is actually used.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Generators and targets that manipulate property-sets directly.
|
||||||
|
Solution: set <literal><relevant></literal> manually.</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</section>
|
</section>
|
||||||
@@ -2539,7 +2593,8 @@ exe a : a.cpp
|
|||||||
the directory bin unless this is overridden by the build-dir project
|
the directory bin unless this is overridden by the build-dir project
|
||||||
attribute. Under bin is a path that depends on the properties
|
attribute. Under bin is a path that depends on the properties
|
||||||
used to build each target. This path is uniquely determined by
|
used to build each target. This path is uniquely determined by
|
||||||
all non-free, non-incidental properties. For example,
|
all <link linkend="bbv2.reference.features.relevant">relevant</link>
|
||||||
|
non-free, non-incidental properties. For example,
|
||||||
given a property set containing:
|
given a property set containing:
|
||||||
<code><toolset>gcc <toolset-gcc:version>4.6.1 <variant>debug
|
<code><toolset>gcc <toolset-gcc:version>4.6.1 <variant>debug
|
||||||
<warnings>all <define>_DEBUG <include>/usr/local/include
|
<warnings>all <define>_DEBUG <include>/usr/local/include
|
||||||
|
|||||||
@@ -316,5 +316,8 @@ rule check-library ( target : true-properties * : false-properties * )
|
|||||||
{
|
{
|
||||||
local instance = [ class.new check-library-worker $(target) :
|
local instance = [ class.new check-library-worker $(target) :
|
||||||
$(true-properties) : $(false-properties) ] ;
|
$(true-properties) : $(false-properties) ] ;
|
||||||
return <conditional>@$(instance).check ;
|
return <conditional>@$(instance).check
|
||||||
|
[ property.evaluate-conditional-relevance
|
||||||
|
$(true-properties) $(false-properties)
|
||||||
|
: [ configure.get-relevant-features ] <link> ] ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -507,6 +507,11 @@ class configure-choose-worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rule all-properties ( )
|
||||||
|
{
|
||||||
|
local i = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ;
|
||||||
|
return $(self.props.$(i)) ;
|
||||||
|
}
|
||||||
rule check ( properties * )
|
rule check ( properties * )
|
||||||
{
|
{
|
||||||
local i = [ configure.find-builds $(self.message) : $(properties)
|
local i = [ configure.find-builds $(self.message) : $(properties)
|
||||||
@@ -542,7 +547,10 @@ rule check-target-builds ( target message ? : true-properties * :
|
|||||||
{
|
{
|
||||||
local instance = [ new check-target-builds-worker $(target) $(message) :
|
local instance = [ new check-target-builds-worker $(target) $(message) :
|
||||||
$(true-properties) : $(false-properties) ] ;
|
$(true-properties) : $(false-properties) ] ;
|
||||||
return <conditional>@$(instance).check ;
|
return <conditional>@$(instance).check
|
||||||
|
[ property.evaluate-conditional-relevance
|
||||||
|
$(true-properties) $(false-properties)
|
||||||
|
: [ configure.get-relevant-features ] ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
@@ -556,7 +564,10 @@ rule choose ( message : * )
|
|||||||
: $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9)
|
: $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9)
|
||||||
: $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16)
|
: $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16)
|
||||||
: $(17) : $(18) : $(19) ] ;
|
: $(17) : $(18) : $(19) ] ;
|
||||||
return <conditional>@$(instance).check ;
|
return <conditional>@$(instance).check
|
||||||
|
[ property.evaluate-conditional-relevance
|
||||||
|
[ $(instance).all-properties ]
|
||||||
|
: [ configure.get-relevant-features ] ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -662,6 +662,10 @@ rule subfeature (
|
|||||||
local f = [ utility.ungrist $(feature) ] ;
|
local f = [ utility.ungrist $(feature) ] ;
|
||||||
feature $(f)-$(subfeature-name) : $(subvalues) : $(attributes) subfeature ;
|
feature $(f)-$(subfeature-name) : $(subvalues) : $(attributes) subfeature ;
|
||||||
|
|
||||||
|
# Features and subfeatures are always relevent as a group
|
||||||
|
.feature-dependencies.$(f) += $(f)-$(subfeature-name) ;
|
||||||
|
.feature-dependencies.$(f)-$(subfeature-name) += $(f) ;
|
||||||
|
|
||||||
# Now make sure the subfeature values are known.
|
# Now make sure the subfeature values are known.
|
||||||
extend-subfeature $(feature) $(value-string) : $(subfeature) : $(subvalues) ;
|
extend-subfeature $(feature) $(value-string) : $(subfeature) : $(subvalues) ;
|
||||||
}
|
}
|
||||||
@@ -692,6 +696,10 @@ rule compose ( composite-property : component-properties * )
|
|||||||
errors.error composite property "$(composite-property)" cannot have itself as a component ;
|
errors.error composite property "$(composite-property)" cannot have itself as a component ;
|
||||||
}
|
}
|
||||||
$(composite-property).components = $(component-properties) ;
|
$(composite-property).components = $(component-properties) ;
|
||||||
|
|
||||||
|
# A composite feature is relevant if any composed feature is relevant
|
||||||
|
local component-features = [ sequence.transform utility.ungrist : $(component-properties:G) ] ;
|
||||||
|
.feature-dependencies.$(component-features) += [ utility.ungrist $(feature) ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1161,6 +1169,41 @@ rule split ( property-set )
|
|||||||
return $(result) ;
|
return $(result) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Returns all the features that also must be relevant when these features are relevant
|
||||||
|
rule expand-relevant ( features * )
|
||||||
|
{
|
||||||
|
local conditional ;
|
||||||
|
local result ;
|
||||||
|
for f in $(features)
|
||||||
|
{
|
||||||
|
# This looks like a conditional, even though it isn't really.
|
||||||
|
# (Free features can never be used in conditionals)
|
||||||
|
local split = [ MATCH "^(.*):<relevant>(.*)$" : $(f) ] ;
|
||||||
|
if $(split)
|
||||||
|
{
|
||||||
|
local-dependencies.$(split[1]) += $(split[2]) ;
|
||||||
|
conditional += local-dependencies.$(split[1]) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result += $(f) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
local queue = $(result) ;
|
||||||
|
while $(queue)
|
||||||
|
{
|
||||||
|
local added = [ set.difference
|
||||||
|
$(.feature-dependencies.$(queue))
|
||||||
|
$(local-dependencies.$(queue))
|
||||||
|
: $(result) ] ;
|
||||||
|
result += $(added) ;
|
||||||
|
queue = $(added) ;
|
||||||
|
}
|
||||||
|
# Clean up local map
|
||||||
|
$(conditional) = ;
|
||||||
|
return $(result) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Tests of module feature.
|
# Tests of module feature.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -167,8 +167,10 @@ class generator
|
|||||||
import utility ;
|
import utility ;
|
||||||
import path ;
|
import path ;
|
||||||
import property ;
|
import property ;
|
||||||
|
import property-set ;
|
||||||
import sequence ;
|
import sequence ;
|
||||||
import set ;
|
import set ;
|
||||||
|
import toolset ;
|
||||||
import type ;
|
import type ;
|
||||||
import virtual-target ;
|
import virtual-target ;
|
||||||
|
|
||||||
@@ -236,6 +238,10 @@ class generator
|
|||||||
# Note that 'transform' here, is the same as 'for_each'.
|
# Note that 'transform' here, is the same as 'for_each'.
|
||||||
sequence.transform type.validate : $(self.source-types) ;
|
sequence.transform type.validate : $(self.source-types) ;
|
||||||
sequence.transform type.validate : $(self.target-types) ;
|
sequence.transform type.validate : $(self.target-types) ;
|
||||||
|
|
||||||
|
local relevant-for-generator =
|
||||||
|
[ sequence.transform utility.ungrist : $(requirements:G) ] ;
|
||||||
|
self.relevant-features = [ property-set.create <relevant>$(relevant-for-generator) ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
################# End of constructor #################
|
################# End of constructor #################
|
||||||
@@ -406,10 +412,10 @@ class generator
|
|||||||
}
|
}
|
||||||
|
|
||||||
local result ;
|
local result ;
|
||||||
if $(consumed)
|
if $(consumed[2])
|
||||||
{
|
{
|
||||||
result = [ construct-result $(consumed) : $(project) $(name) :
|
result = [ construct-result $(consumed[2-]) : $(project) $(name) :
|
||||||
$(property-set) ] ;
|
[ $(property-set).add $(consumed[1]) ] ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if $(result)
|
if $(result)
|
||||||
@@ -421,7 +427,11 @@ class generator
|
|||||||
generators.dout [ indent ] " FAILURE" ;
|
generators.dout [ indent ] " FAILURE" ;
|
||||||
}
|
}
|
||||||
generators.dout ;
|
generators.dout ;
|
||||||
return $(result) ;
|
if $(result)
|
||||||
|
{
|
||||||
|
# Make sure that we propagate usage-requirements up the stack.
|
||||||
|
return [ $(result[1]).add $(consumed[1]) ] $(result[2-]) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Constructs the dependency graph to be returned by this generator.
|
# Constructs the dependency graph to be returned by this generator.
|
||||||
@@ -443,6 +453,11 @@ class generator
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
local result ;
|
local result ;
|
||||||
|
|
||||||
|
local relevant = [ toolset.relevant $(self.rule-name) ] ;
|
||||||
|
relevant = [ $(relevant).add $(self.relevant-features) ] ;
|
||||||
|
property-set = [ $(property-set).add $(relevant) ] ;
|
||||||
|
|
||||||
# If this is a 1->1 transformation, apply it to all consumed targets in
|
# If this is a 1->1 transformation, apply it to all consumed targets in
|
||||||
# order.
|
# order.
|
||||||
if ! $(self.source-types[2]) && ! $(self.composing)
|
if ! $(self.source-types[2]) && ! $(self.composing)
|
||||||
@@ -458,7 +473,10 @@ class generator
|
|||||||
result += [ generated-targets $(consumed) : $(property-set) :
|
result += [ generated-targets $(consumed) : $(property-set) :
|
||||||
$(project) $(name) ] ;
|
$(project) $(name) ] ;
|
||||||
}
|
}
|
||||||
return $(result) ;
|
if $(result)
|
||||||
|
{
|
||||||
|
return $(relevant) $(result) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Determine target name from fullname (maybe including path components)
|
# Determine target name from fullname (maybe including path components)
|
||||||
@@ -576,6 +594,7 @@ class generator
|
|||||||
{
|
{
|
||||||
local _consumed ;
|
local _consumed ;
|
||||||
local missing-types ;
|
local missing-types ;
|
||||||
|
local usage-requirements ;
|
||||||
|
|
||||||
if $(sources[2])
|
if $(sources[2])
|
||||||
{
|
{
|
||||||
@@ -588,6 +607,7 @@ class generator
|
|||||||
local temp = [ consume-directly $(sources) ] ;
|
local temp = [ consume-directly $(sources) ] ;
|
||||||
if $(temp[1])
|
if $(temp[1])
|
||||||
{
|
{
|
||||||
|
usage-requirements = [ property-set.empty ] ;
|
||||||
_consumed = $(temp[1]) ;
|
_consumed = $(temp[1]) ;
|
||||||
}
|
}
|
||||||
missing-types = $(temp[2-]) ;
|
missing-types = $(temp[2-]) ;
|
||||||
@@ -613,7 +633,7 @@ class generator
|
|||||||
# everything to the required type. There is no need to rerun it on
|
# everything to the required type. There is no need to rerun it on
|
||||||
# targets of different types.
|
# targets of different types.
|
||||||
|
|
||||||
# NOTE: ignoring usage requirements.
|
usage-requirements = $(transformed[1]) ;
|
||||||
for local t in $(transformed[2-])
|
for local t in $(transformed[2-])
|
||||||
{
|
{
|
||||||
if [ $(t).type ] in $(missing-types)
|
if [ $(t).type ] in $(missing-types)
|
||||||
@@ -623,7 +643,7 @@ class generator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [ sequence.unique $(_consumed) ] ;
|
return $(usage-requirements) [ sequence.unique $(_consumed) ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Converts several files to consumable types. Called for composing
|
# Converts several files to consumable types. Called for composing
|
||||||
@@ -638,10 +658,11 @@ class generator
|
|||||||
if ! $(self.source-types)
|
if ! $(self.source-types)
|
||||||
{
|
{
|
||||||
# Anything is acceptible
|
# Anything is acceptible
|
||||||
return $(sources) ;
|
return [ property-set.empty ] $(sources) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
local usage-requirements = [ property-set.empty ] ;
|
||||||
local acceptible-types = [ sequence.unique
|
local acceptible-types = [ sequence.unique
|
||||||
[ sequence.transform type.all-derived : $(self.source-types) ] ] ;
|
[ sequence.transform type.all-derived : $(self.source-types) ] ] ;
|
||||||
for local source in $(sources)
|
for local source in $(sources)
|
||||||
@@ -661,13 +682,17 @@ class generator
|
|||||||
{
|
{
|
||||||
generators.dout [ indent ] " failed to convert " $(source) ;
|
generators.dout [ indent ] " failed to convert " $(source) ;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usage-requirements = [ $(usage-requirements).add $(transformed[1]) ] ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result += $(source) ;
|
result += $(source) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [ sequence.unique $(result) : stable ] ;
|
return $(usage-requirements) [ sequence.unique $(result) : stable ] ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class property-set
|
|||||||
{
|
{
|
||||||
import errors ;
|
import errors ;
|
||||||
import feature ;
|
import feature ;
|
||||||
|
import modules ;
|
||||||
import path ;
|
import path ;
|
||||||
import property ;
|
import property ;
|
||||||
import property-set ;
|
import property-set ;
|
||||||
@@ -86,6 +87,26 @@ class property-set
|
|||||||
return $(self.free) ;
|
return $(self.free) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Returns relevant base properties
|
||||||
|
rule base-relevant ( )
|
||||||
|
{
|
||||||
|
if ! $(self.relevant-initialized)
|
||||||
|
{
|
||||||
|
init-relevant ;
|
||||||
|
}
|
||||||
|
return $(self.base-relevant) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns all relevant properties
|
||||||
|
rule relevant
|
||||||
|
{
|
||||||
|
if ! $(self.relevant-initialized)
|
||||||
|
{
|
||||||
|
init-relevant ;
|
||||||
|
}
|
||||||
|
return $(self.relevant) ;
|
||||||
|
}
|
||||||
|
|
||||||
# Returns dependency properties.
|
# Returns dependency properties.
|
||||||
#
|
#
|
||||||
rule dependency ( )
|
rule dependency ( )
|
||||||
@@ -215,7 +236,7 @@ class property-set
|
|||||||
{
|
{
|
||||||
if ! $(self.as-path)
|
if ! $(self.as-path)
|
||||||
{
|
{
|
||||||
self.as-path = [ property.as-path [ base ] ] ;
|
self.as-path = [ property.as-path [ base-relevant ] ] ;
|
||||||
}
|
}
|
||||||
return $(self.as-path) ;
|
return $(self.as-path) ;
|
||||||
}
|
}
|
||||||
@@ -345,6 +366,30 @@ class property-set
|
|||||||
self.base-initialized = true ;
|
self.base-initialized = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rule init-relevant ( )
|
||||||
|
{
|
||||||
|
local relevant-features = [ get <relevant> ] ;
|
||||||
|
relevant-features = [ feature.expand-relevant $(relevant-features) ] ;
|
||||||
|
relevant-features = <$(relevant-features)> ;
|
||||||
|
ignore-relevance = [ modules.peek property-set : .ignore-relevance ] ;
|
||||||
|
for local p in $(self.raw)
|
||||||
|
{
|
||||||
|
if $(ignore-relevance) || $(p:G) in $(relevant-features)
|
||||||
|
{
|
||||||
|
local att = [ feature.attributes $(p:G) ] ;
|
||||||
|
if ! ( incidental in $(att) )
|
||||||
|
{
|
||||||
|
self.relevant += $(p) ;
|
||||||
|
if ! ( free in $(att) )
|
||||||
|
{
|
||||||
|
self.base-relevant += $(p) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.relevant-initialized = true ;
|
||||||
|
}
|
||||||
|
|
||||||
rule init-dependency ( )
|
rule init-dependency ( )
|
||||||
{
|
{
|
||||||
for local p in $(self.raw)
|
for local p in $(self.raw)
|
||||||
@@ -369,7 +414,7 @@ class property-set
|
|||||||
# characters as well, e.g. free or indirect properties. Indirect
|
# characters as well, e.g. free or indirect properties. Indirect
|
||||||
# properties for example contain a full Jamfile path in their value
|
# properties for example contain a full Jamfile path in their value
|
||||||
# which on Windows file systems contains ':' as the drive separator.
|
# which on Windows file systems contains ':' as the drive separator.
|
||||||
if [ MATCH (:) : $(p:G=) ] || $(p:G) = <conditional>
|
if ( [ MATCH (:) : $(p:G=) ] && ! ( free in [ feature.attributes $(p:G) ] ) ) || $(p:G) = <conditional>
|
||||||
{
|
{
|
||||||
self.conditional += $(p) ;
|
self.conditional += $(p) ;
|
||||||
}
|
}
|
||||||
@@ -382,6 +427,13 @@ class property-set
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# This is a temporary measure to help users work around
|
||||||
|
# any problems. Remove it once we've verified that
|
||||||
|
# everything works.
|
||||||
|
if --ignore-relevance in [ modules.peek : ARGV ]
|
||||||
|
{
|
||||||
|
.ignore-relevance = true ;
|
||||||
|
}
|
||||||
|
|
||||||
# Creates a new 'property-set' instance for the given raw properties or returns
|
# Creates a new 'property-set' instance for the given raw properties or returns
|
||||||
# an already existing ones.
|
# an already existing ones.
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ rule evaluate-conditionals-in-context ( properties * : context * )
|
|||||||
local indirect ;
|
local indirect ;
|
||||||
for local p in $(properties)
|
for local p in $(properties)
|
||||||
{
|
{
|
||||||
if [ MATCH (:<) : $(p) ]
|
if [ MATCH (:<) : $(p) ] && ! free in [ feature.attributes $(p:G) ]
|
||||||
{
|
{
|
||||||
conditionals += $(p) ;
|
conditionals += $(p) ;
|
||||||
}
|
}
|
||||||
@@ -155,6 +155,36 @@ rule evaluate-conditionals-in-context ( properties * : context * )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns <relevant> properties indicating how the conditionals in
|
||||||
|
# properties affect feature relevance. If the optional argument cond
|
||||||
|
# is passed, it is treated as extra conditions for all properties.
|
||||||
|
#
|
||||||
|
rule evaluate-conditional-relevance ( properties * : cond * )
|
||||||
|
{
|
||||||
|
cond = [ sequence.transform utility.ungrist : $(cond:G) ] ;
|
||||||
|
local result ;
|
||||||
|
for local p in $(properties)
|
||||||
|
{
|
||||||
|
# Separate condition and property.
|
||||||
|
local s = [ MATCH ^(.*):(<.*) : $(p) ] ;
|
||||||
|
if ! $(s) || free in [ feature.attributes $(p:G) ]
|
||||||
|
{
|
||||||
|
local value = [ utility.ungrist $(p:G) ] ;
|
||||||
|
result += <relevant>$(value):<relevant>$(cond) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
local condition = [ regex.split $(s[1]) "," ] ;
|
||||||
|
condition = [ MATCH ^!?(.*) : $(condition) ] ;
|
||||||
|
condition = [ sequence.transform utility.ungrist : $(condition:G) ] $(cond) ;
|
||||||
|
local value = [ utility.ungrist $(s[2]:G) ] ;
|
||||||
|
result += <relevant>$(value):<relevant>$(condition) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [ sequence.unique $(result) ] ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rule expand-subfeatures-in-conditions ( properties * )
|
rule expand-subfeatures-in-conditions ( properties * )
|
||||||
{
|
{
|
||||||
local result ;
|
local result ;
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ class project-target : abstract-target
|
|||||||
import property-set ;
|
import property-set ;
|
||||||
import set ;
|
import set ;
|
||||||
import sequence ;
|
import sequence ;
|
||||||
|
import toolset ;
|
||||||
import "class" : new ;
|
import "class" : new ;
|
||||||
|
|
||||||
rule __init__ ( name : project-module parent-project ?
|
rule __init__ ( name : project-module parent-project ?
|
||||||
@@ -584,6 +585,8 @@ class project-target : abstract-target
|
|||||||
IMPORT $(parent-module) : $(user-rules) : $(this-module) : $(user-rules)
|
IMPORT $(parent-module) : $(user-rules) : $(this-module) : $(user-rules)
|
||||||
;
|
;
|
||||||
EXPORT $(this-module) : $(user-rules) ;
|
EXPORT $(this-module) : $(user-rules) ;
|
||||||
|
|
||||||
|
toolset.inherit-flags $(this-module) : $(parent-module) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,10 +624,11 @@ class main-target : abstract-target
|
|||||||
{
|
{
|
||||||
import assert ;
|
import assert ;
|
||||||
import feature ;
|
import feature ;
|
||||||
import print ;
|
|
||||||
import property-set ;
|
import property-set ;
|
||||||
import sequence ;
|
import sequence ;
|
||||||
|
import set ;
|
||||||
import targets : start-building end-building ;
|
import targets : start-building end-building ;
|
||||||
|
import utility ;
|
||||||
|
|
||||||
rule __init__ ( name : project )
|
rule __init__ ( name : project )
|
||||||
{
|
{
|
||||||
@@ -719,6 +723,43 @@ class main-target : abstract-target
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Features are relevant here if they could affect alternative
|
||||||
|
# selection. That is, base, non-conditional properties that
|
||||||
|
# are not identical in all target alternatives.
|
||||||
|
rule relevant-features ( )
|
||||||
|
{
|
||||||
|
if $(self.alternatives[2-])
|
||||||
|
{
|
||||||
|
if $(self.relevant-features)
|
||||||
|
{
|
||||||
|
return $(self.relevant-features) ;
|
||||||
|
}
|
||||||
|
local all-properties ;
|
||||||
|
for t in $(self.alternatives)
|
||||||
|
{
|
||||||
|
local ps = [ $(t).requirements ] ;
|
||||||
|
ps = [ property-set.create [ $(ps).non-conditional ] ] ;
|
||||||
|
all-properties += [ $(ps).base ] ;
|
||||||
|
}
|
||||||
|
all-properties = [ sequence.unique $(all-properties) ] ;
|
||||||
|
local result ;
|
||||||
|
for t in $(self.alternatives)
|
||||||
|
{
|
||||||
|
local ps = [ $(t).requirements ] ;
|
||||||
|
ps = [ property-set.create [ $(ps).non-conditional ] ] ;
|
||||||
|
local properties = [ set.difference $(all-properties) : [ $(ps).base ] ] ;
|
||||||
|
result += $(properties:G) ;
|
||||||
|
}
|
||||||
|
result = [ sequence.transform utility.ungrist : [ sequence.unique $(result) ] ] ;
|
||||||
|
self.relevant-features = [ property-set.create <relevant>$(result) ] ;
|
||||||
|
return $(self.relevant-features) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return [ property-set.empty ] ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rule apply-default-build ( property-set )
|
rule apply-default-build ( property-set )
|
||||||
{
|
{
|
||||||
return [ targets.apply-default-build $(property-set) :
|
return [ targets.apply-default-build $(property-set) :
|
||||||
@@ -735,11 +776,12 @@ class main-target : abstract-target
|
|||||||
start-building $(__name__) ;
|
start-building $(__name__) ;
|
||||||
|
|
||||||
local all-property-sets = [ apply-default-build $(property-set) ] ;
|
local all-property-sets = [ apply-default-build $(property-set) ] ;
|
||||||
|
local relevant = [ relevant-features ] ;
|
||||||
local usage-requirements = [ property-set.empty ] ;
|
local usage-requirements = [ property-set.empty ] ;
|
||||||
local result ;
|
local result ;
|
||||||
for local p in $(all-property-sets)
|
for local p in $(all-property-sets)
|
||||||
{
|
{
|
||||||
local r = [ generate-really $(p) ] ;
|
local r = [ generate-really [ $(p).add $(relevant) ] ] ;
|
||||||
if $(r)
|
if $(r)
|
||||||
{
|
{
|
||||||
usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
|
usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
|
||||||
@@ -1317,6 +1359,15 @@ class basic-target : abstract-target
|
|||||||
local gur = $(result[1]) ;
|
local gur = $(result[1]) ;
|
||||||
result = $(result[2-]) ;
|
result = $(result[2-]) ;
|
||||||
|
|
||||||
|
# Relevant is automatically applied to usage requirements
|
||||||
|
# and only applies for propagated features
|
||||||
|
local relevant = [ propagated-relevant
|
||||||
|
[ $(gur).get <relevant> ]
|
||||||
|
[ $(rproperties).get <relevant> ] ] ;
|
||||||
|
gur = [ property-set.create
|
||||||
|
[ property.change [ $(gur).raw ] : <relevant> ]
|
||||||
|
<relevant>$(relevant) ] ;
|
||||||
|
|
||||||
if $(self.always)
|
if $(self.always)
|
||||||
{
|
{
|
||||||
for local t in $(result)
|
for local t in $(result)
|
||||||
@@ -1409,6 +1460,22 @@ class basic-target : abstract-target
|
|||||||
[ $(self.usage-requirements).evaluate-conditionals
|
[ $(self.usage-requirements).evaluate-conditionals
|
||||||
$(rproperties) ] ;
|
$(rproperties) ] ;
|
||||||
|
|
||||||
|
# Filter out non-propagated <relevant> properties
|
||||||
|
local relevant ;
|
||||||
|
for local r in [ $(xusage-requirements).get <relevant> ]
|
||||||
|
{
|
||||||
|
local check = [ MATCH "(.*):<relevant>(.*)" : $(r) ] ;
|
||||||
|
if $(check) { check = $(check[2]) ; }
|
||||||
|
else { check = $(r) ; }
|
||||||
|
if propagated in [ feature.attributes <$(check)> ]
|
||||||
|
{
|
||||||
|
relevant += $(r) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xusage-requirements = [ property-set.create
|
||||||
|
[ property.change [ $(xusage-requirements).raw ] : <relevant> ]
|
||||||
|
<relevant>$(relevant) ] ;
|
||||||
|
|
||||||
# We generate all dependency properties and add them, as well as their
|
# We generate all dependency properties and add them, as well as their
|
||||||
# usage requirements, to the result.
|
# usage requirements, to the result.
|
||||||
local extra ;
|
local extra ;
|
||||||
@@ -1448,6 +1515,19 @@ class basic-target : abstract-target
|
|||||||
return [ $(result).add [ property-set.create $(raw) ] ] ;
|
return [ $(result).add [ property-set.create $(raw) ] ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local rule propagated-relevant ( values * )
|
||||||
|
{
|
||||||
|
local result ;
|
||||||
|
for local v in [ feature.expand-relevant $(values) ]
|
||||||
|
{
|
||||||
|
if propagated in [ feature.attributes <$(v)> ]
|
||||||
|
{
|
||||||
|
result += $(v) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $(result) ;
|
||||||
|
}
|
||||||
|
|
||||||
# Creates new subvariant instances for 'targets'.
|
# Creates new subvariant instances for 'targets'.
|
||||||
# 'root-targets' - virtual targets to be returned to dependants
|
# 'root-targets' - virtual targets to be returned to dependants
|
||||||
# 'all-targets' - virtual targets created while building this main target
|
# 'all-targets' - virtual targets created while building this main target
|
||||||
@@ -1594,7 +1674,8 @@ rule main-target-requirements (
|
|||||||
import errors ;
|
import errors ;
|
||||||
errors.error "Conflicting requirements for target:" $(requirements) ;
|
errors.error "Conflicting requirements for target:" $(requirements) ;
|
||||||
}
|
}
|
||||||
return [ $(requirements).add [ toolset.requirements ] ] ;
|
local result = [ $(requirements).add [ toolset.requirements ] ] ;
|
||||||
|
return [ $(result).add-raw [ property.evaluate-conditional-relevance [ $(result).raw ] ] ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1617,7 +1698,10 @@ rule main-target-usage-requirements (
|
|||||||
$(specification)
|
$(specification)
|
||||||
: [ $(project).project-module ] [ $(project).get location ] ] ;
|
: [ $(project).project-module ] [ $(project).get location ] ] ;
|
||||||
|
|
||||||
return [ $(project-usage-requirements).add $(usage-requirements) ] ;
|
local result = [ $(project-usage-requirements).add $(usage-requirements) ] ;
|
||||||
|
local relevant =
|
||||||
|
[ property.evaluate-conditional-relevance [ $(result).raw ] ] ;
|
||||||
|
return [ $(result).add-raw $(relevant) ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import set ;
|
|||||||
import property-set ;
|
import property-set ;
|
||||||
import order ;
|
import order ;
|
||||||
import "class" : new ;
|
import "class" : new ;
|
||||||
|
import utility ;
|
||||||
|
|
||||||
|
|
||||||
.flag-no = 1 ;
|
.flag-no = 1 ;
|
||||||
@@ -76,6 +77,36 @@ rule pop-checking-for-flags-module ( )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Specifies features that are referenced by the action rule.
|
||||||
|
# This is necessary in order to detect that these features
|
||||||
|
# are relevant.
|
||||||
|
#
|
||||||
|
rule uses-features ( rule-or-module : features * : unchecked ? )
|
||||||
|
{
|
||||||
|
local caller = [ CALLER_MODULE ] ;
|
||||||
|
if ! [ MATCH ".*([.]).*" : $(rule-or-module) ]
|
||||||
|
&& [ MATCH "(Jamfile<.*)" : $(caller) ]
|
||||||
|
{
|
||||||
|
# Unqualified rule name, used inside Jamfile. Most likely used with
|
||||||
|
# 'make' or 'notfile' rules. This prevents setting flags on the entire
|
||||||
|
# Jamfile module (this will be considered as rule), but who cares?
|
||||||
|
# Probably, 'flags' rule should be split into 'flags' and
|
||||||
|
# 'flags-on-module'.
|
||||||
|
rule-or-module = $(caller).$(rule-or-module) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ;
|
||||||
|
if $(unchecked) != unchecked
|
||||||
|
&& $(.flags-module-checking[1]) != unchecked
|
||||||
|
&& $(module_) != $(caller)
|
||||||
|
{
|
||||||
|
errors.error "Module $(caller) attempted to set flags for module $(module_)" ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.uses-features.$(rule-or-module) += $(features) ;
|
||||||
|
}
|
||||||
|
|
||||||
# Specifies the flags (variables) that must be set on targets under certain
|
# Specifies the flags (variables) that must be set on targets under certain
|
||||||
# conditions, described by arguments.
|
# conditions, described by arguments.
|
||||||
#
|
#
|
||||||
@@ -399,6 +430,34 @@ rule relevant-features ( rule-or-module )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Returns a list of all the features which were
|
||||||
|
# passed to uses-features.
|
||||||
|
local rule used-features ( rule-or-module )
|
||||||
|
{
|
||||||
|
if ! $(.used-features.$(rule-or-module))
|
||||||
|
{
|
||||||
|
local result = $(.uses-features.$(rule-or-module)) ;
|
||||||
|
|
||||||
|
# Strip away last dot separated part and recurse.
|
||||||
|
local next = [ MATCH ^(.+)\\.([^\\.])* : $(rule-or-module) ] ;
|
||||||
|
if $(next)
|
||||||
|
{
|
||||||
|
result += [ used-features $(next[1]) ] ;
|
||||||
|
}
|
||||||
|
result = [ sequence.unique $(result) ] ;
|
||||||
|
if $(result[1]) = ""
|
||||||
|
{
|
||||||
|
result = $(result) ;
|
||||||
|
}
|
||||||
|
.used-features.$(rule-or-module) = $(result) ;
|
||||||
|
return $(result) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $(.used-features.$(rule-or-module)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rule filter-property-set ( rule-or-module : property-set )
|
rule filter-property-set ( rule-or-module : property-set )
|
||||||
{
|
{
|
||||||
local key = .filtered.property-set.$(rule-or-module).$(property-set) ;
|
local key = .filtered.property-set.$(rule-or-module).$(property-set) ;
|
||||||
@@ -454,6 +513,23 @@ rule set-target-variables ( rule-or-module targets + : property-set )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a property-set indicating which features are relevant
|
||||||
|
# for the given rule.
|
||||||
|
#
|
||||||
|
rule relevant ( rule-name )
|
||||||
|
{
|
||||||
|
if ! $(.relevant-features-ps.$(rule-name))
|
||||||
|
{
|
||||||
|
local features = [ sequence.transform utility.ungrist :
|
||||||
|
[ relevant-features $(rule-name) ]
|
||||||
|
[ used-features $(rule-name) ] ] ;
|
||||||
|
.relevant-features-ps.$(rule-name) =
|
||||||
|
[ property-set.create <relevant>$(features) ] ;
|
||||||
|
}
|
||||||
|
return $(.relevant-features-ps.$(rule-name)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Make toolset 'toolset', defined in a module of the same name, inherit from
|
# Make toolset 'toolset', defined in a module of the same name, inherit from
|
||||||
# 'base'.
|
# 'base'.
|
||||||
# 1. The 'init' rule from 'base' is imported into 'toolset' with full name.
|
# 1. The 'init' rule from 'base' is imported into 'toolset' with full name.
|
||||||
|
|||||||
@@ -999,10 +999,8 @@ rule register ( target )
|
|||||||
{
|
{
|
||||||
local ps1 = [ $(a1).properties ] ;
|
local ps1 = [ $(a1).properties ] ;
|
||||||
local ps2 = [ $(a2).properties ] ;
|
local ps2 = [ $(a2).properties ] ;
|
||||||
local p1 = [ $(ps1).base ] [ $(ps1).free ] [ set.difference
|
local p1 = [ $(ps1).relevant ] ;
|
||||||
[ $(ps1).dependency ] : [ $(ps1).incidental ] ] ;
|
local p2 = [ $(ps2).relevant ] ;
|
||||||
local p2 = [ $(ps2).base ] [ $(ps2).free ] [ set.difference
|
|
||||||
[ $(ps2).dependency ] : [ $(ps2).incidental ] ] ;
|
|
||||||
if $(p1) = $(p2)
|
if $(p1) = $(p2)
|
||||||
{
|
{
|
||||||
result = $(t) ;
|
result = $(t) ;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
import generators ;
|
import generators ;
|
||||||
import feature ;
|
import feature ;
|
||||||
|
import toolset : flags ;
|
||||||
import type ;
|
import type ;
|
||||||
import property ;
|
|
||||||
|
|
||||||
feature.feature bison.prefix : : free ;
|
feature.feature bison.prefix : : free ;
|
||||||
type.register Y : y ;
|
type.register Y : y ;
|
||||||
@@ -17,16 +17,10 @@ rule init ( )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
rule bison ( dst dst_header : src : properties * )
|
flags bison.bison PREFIX <bison.prefix> ;
|
||||||
{
|
_ = " " ;
|
||||||
local r = [ property.select bison.prefix : $(properties) ] ;
|
|
||||||
if $(r)
|
|
||||||
{
|
|
||||||
PREFIX_OPT on $(<) = -p $(r:G=) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actions bison
|
actions bison
|
||||||
{
|
{
|
||||||
bison $(PREFIX_OPT) -d -o $(<[1]) $(>)
|
bison -p$(_)$(PREFIX) -d -o $(<[1]) $(>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ rule translate-path ( path )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toolset.uses-features doxygen.headers-to-doxyfile : "<doxygen:param>" ;
|
||||||
|
|
||||||
# Generates a doxygen configuration file (doxyfile) given a set of C++ sources
|
# Generates a doxygen configuration file (doxyfile) given a set of C++ sources
|
||||||
# and a property list that may contain <doxygen:param> features.
|
# and a property list that may contain <doxygen:param> features.
|
||||||
@@ -321,6 +322,7 @@ rule headers-to-doxyfile ( target : sources * : properties * )
|
|||||||
print.text $(text) : true ;
|
print.text $(text) : true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toolset.uses-features doxygen.run : <doxygen.rmdir> "<doxygen:param>" ;
|
||||||
|
|
||||||
# Run Doxygen. See doxygen-action for a description of the strange properties of
|
# Run Doxygen. See doxygen-action for a description of the strange properties of
|
||||||
# this rule.
|
# this rule.
|
||||||
@@ -406,6 +408,7 @@ rule collect ( target : source : properties * )
|
|||||||
: <xsl:param>doxygen.xml.path=$(native-path) ;
|
: <xsl:param>doxygen.xml.path=$(native-path) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toolset.uses-features doxygen.xml-to-boostbook : <prefix> <reftitle> ;
|
||||||
|
|
||||||
# Translate Doxygen XML into BoostBook.
|
# Translate Doxygen XML into BoostBook.
|
||||||
#
|
#
|
||||||
|
|||||||
10
src/tools/features/relevant-feature.jam
Normal file
10
src/tools/features/relevant-feature.jam
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Copyright 2017 Steven Watanabe
|
||||||
|
# Distributed under the Boost Software License, Version 1.0.
|
||||||
|
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
# http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
# Identifies relevant features.
|
||||||
|
|
||||||
|
import feature ;
|
||||||
|
|
||||||
|
feature.feature relevant : : incidental free ;
|
||||||
@@ -25,5 +25,5 @@ rule detect ( properties * )
|
|||||||
local ps = [ property-set.create $(properties) ] ;
|
local ps = [ property-set.create $(properties) ] ;
|
||||||
local api = [ $(ps).get <threadapi> ] ;
|
local api = [ $(ps).get <threadapi> ] ;
|
||||||
if ! $(api) { api = [ get-default $(ps) ] ; }
|
if ! $(api) { api = [ get-default $(ps) ] ; }
|
||||||
return <threadapi>$(api) ;
|
return <threadapi>$(api) <relevant>threadapi:<relevant>target-os ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -550,8 +550,8 @@ class gcc-pch-generator : pch-generator
|
|||||||
# Return result of base class and pch-file property as
|
# Return result of base class and pch-file property as
|
||||||
# usage-requirements.
|
# usage-requirements.
|
||||||
return
|
return
|
||||||
[ property-set.create <pch-file>$(pch-file) <cflags>-Winvalid-pch ]
|
[ $(pch-file[1]).add-raw <pch-file>$(pch-file[2-]) <cflags>-Winvalid-pch ]
|
||||||
$(pch-file)
|
$(pch-file[2-])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import generators ;
|
|||||||
#
|
#
|
||||||
class archive-generator : generator
|
class archive-generator : generator
|
||||||
{
|
{
|
||||||
|
import generators ;
|
||||||
import property-set ;
|
import property-set ;
|
||||||
|
|
||||||
rule __init__ ( id composing ? : source-types + : target-types +
|
rule __init__ ( id composing ? : source-types + : target-types +
|
||||||
@@ -56,9 +57,7 @@ class archive-generator : generator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usage-requirements = [ property-set.create $(usage-requirements) ] ;
|
return [ generators.add-usage-requirements $(result) : $(usage-requirements) ] ;
|
||||||
|
|
||||||
return $(usage-requirements) $(result) ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,8 +54,9 @@ class lib-generator : generator
|
|||||||
}
|
}
|
||||||
property-set = [ $(property-set).add-raw <main-target-type>LIB ] ;
|
property-set = [ $(property-set).add-raw <main-target-type>LIB ] ;
|
||||||
# Construct the target.
|
# Construct the target.
|
||||||
return [ generators.construct $(project) $(name) : $(actual-type)
|
local result = [ generators.construct $(project) $(name) : $(actual-type)
|
||||||
: $(property-set) : $(sources) ] ;
|
: $(property-set) : $(sources) ] ;
|
||||||
|
return [ $(result[1]).add-raw <relevant>link ] $(result[2-]) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,11 +83,12 @@ class linking-generator : generator
|
|||||||
local ur ;
|
local ur ;
|
||||||
if $(result)
|
if $(result)
|
||||||
{
|
{
|
||||||
ur = [ extra-usage-requirements $(result) : $(property-set) ] ;
|
ur = [ extra-usage-requirements $(result[2-]) : $(property-set) ] ;
|
||||||
ur = [ $(ur).add
|
ur = [ $(ur).add
|
||||||
[ property-set.create <xdll-path>$(extra-xdll-paths) ] ] ;
|
[ property-set.create <xdll-path>$(extra-xdll-paths) ] ] ;
|
||||||
|
ur = [ $(ur).add $(result[1]) ] ;
|
||||||
}
|
}
|
||||||
return $(ur) $(result) ;
|
return $(ur) $(result[2-]) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rule extra-usage-requirements ( created-targets * : property-set )
|
rule extra-usage-requirements ( created-targets * : property-set )
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class searched-lib-generator : generator
|
|||||||
|
|
||||||
local search = [ feature.get-values <search> : $(properties) ] ;
|
local search = [ feature.get-values <search> : $(properties) ] ;
|
||||||
|
|
||||||
local a = [ new null-action $(property-set) ] ;
|
local a = [ new null-action [ $(property-set).add-raw <relevant>link ] ] ;
|
||||||
local lib-name = [ feature.get-values <name> : $(properties) ] ;
|
local lib-name = [ feature.get-values <name> : $(properties) ] ;
|
||||||
lib-name ?= $(name) ;
|
lib-name ?= $(name) ;
|
||||||
local t = [ new searched-lib-target $(lib-name) : $(project)
|
local t = [ new searched-lib-target $(lib-name) : $(project)
|
||||||
@@ -47,7 +47,7 @@ class searched-lib-generator : generator
|
|||||||
# lib png : z : <name>png ;
|
# lib png : z : <name>png ;
|
||||||
# the 'z' target should be returned, so that apps linking to 'png'
|
# the 'z' target should be returned, so that apps linking to 'png'
|
||||||
# will link to 'z', too.
|
# will link to 'z', too.
|
||||||
return [ property-set.create <xdll-path>$(search) ]
|
return [ property-set.create <xdll-path>$(search) <relevant>link ]
|
||||||
[ virtual-target.register $(t) ] $(sources) ;
|
[ virtual-target.register $(t) ] $(sources) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
import type ;
|
import type ;
|
||||||
import generators ;
|
import generators ;
|
||||||
import feature ;
|
import feature ;
|
||||||
import property ;
|
import toolset : flags ;
|
||||||
|
|
||||||
|
|
||||||
feature.feature flex.prefix : : free ;
|
feature.feature flex.prefix : : free ;
|
||||||
type.register LEX : l ;
|
type.register LEX : l ;
|
||||||
@@ -18,14 +17,7 @@ rule init ( )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
rule lex ( target : source : properties * )
|
flags lex.lex PREFIX <flex.prefix> ;
|
||||||
{
|
|
||||||
local r = [ property.select flex.prefix : $(properties) ] ;
|
|
||||||
if $(r)
|
|
||||||
{
|
|
||||||
PREFIX on $(<) = $(r:G=) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actions lex
|
actions lex
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import targets ;
|
|||||||
class make-target-class : basic-target
|
class make-target-class : basic-target
|
||||||
{
|
{
|
||||||
import "class" : new ;
|
import "class" : new ;
|
||||||
|
import indirect ;
|
||||||
|
import toolset ;
|
||||||
import type ;
|
import type ;
|
||||||
import virtual-target ;
|
import virtual-target ;
|
||||||
|
|
||||||
@@ -34,10 +36,11 @@ class make-target-class : basic-target
|
|||||||
# below.
|
# below.
|
||||||
local m = [ MATCH ^@(.*) : $(action-name) ] ;
|
local m = [ MATCH ^@(.*) : $(action-name) ] ;
|
||||||
|
|
||||||
local a = [ new action $(source-targets) : $(m[1]) : $(property-set) ] ;
|
local relevant = [ toolset.relevant [ indirect.get-rule $(m[1]) ] ] ;
|
||||||
|
local a = [ new action $(source-targets) : $(m[1]) : [ $(property-set).add $(relevant) ] ] ;
|
||||||
local t = [ new file-target $(self.name) exact : [ type.type
|
local t = [ new file-target $(self.name) exact : [ type.type
|
||||||
$(self.name) ] : $(self.project) : $(a) ] ;
|
$(self.name) ] : $(self.project) : $(a) ] ;
|
||||||
return [ property-set.empty ] [ virtual-target.register $(t) ] ;
|
return $(relevant) [ virtual-target.register $(t) ] ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -595,6 +595,10 @@ feature mpi:processes : : free incidental ;
|
|||||||
# apply to mpi.capture output at the moment.
|
# apply to mpi.capture output at the moment.
|
||||||
# Redo this explicitly.
|
# Redo this explicitly.
|
||||||
toolset.flags mpi.capture-output ARGS <testing.arg> ;
|
toolset.flags mpi.capture-output ARGS <testing.arg> ;
|
||||||
|
toolset.uses-features mpi.capture-output :
|
||||||
|
<testing.launcher> <testing.execute> <dll-path> <xdll-path> <target-os>
|
||||||
|
<mpi:processes> ;
|
||||||
|
|
||||||
rule capture-output ( target : sources * : properties * )
|
rule capture-output ( target : sources * : properties * )
|
||||||
{
|
{
|
||||||
# Use the standard capture-output rule to run the tests
|
# Use the standard capture-output rule to run the tests
|
||||||
|
|||||||
@@ -527,6 +527,7 @@ actions compile.rc
|
|||||||
$(.SETUP) $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
|
$(.SETUP) $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toolset.uses-features msvc.link : <embed-manifest> <embed-manifest-file> ;
|
||||||
|
|
||||||
rule link ( targets + : sources * : properties * )
|
rule link ( targets + : sources * : properties * )
|
||||||
{
|
{
|
||||||
@@ -706,7 +707,7 @@ class msvc-pch-generator : pch-generator
|
|||||||
: $(pch-header) ] ;
|
: $(pch-header) ] ;
|
||||||
|
|
||||||
local pch-file ;
|
local pch-file ;
|
||||||
for local g in $(generated)
|
for local g in $(generated[2-])
|
||||||
{
|
{
|
||||||
if [ type.is-derived [ $(g).type ] PCH ]
|
if [ type.is-derived [ $(g).type ] PCH ]
|
||||||
{
|
{
|
||||||
@@ -714,8 +715,8 @@ class msvc-pch-generator : pch-generator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [ property-set.create <pch-header>$(pch-header)
|
return [ $(generated[1]).add-raw <pch-header>$(pch-header)
|
||||||
<pch-file>$(pch-file) ] $(generated) ;
|
<pch-file>$(pch-file) ] $(generated[2-]) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,7 +879,7 @@ local rule set-setup-command ( targets * : properties * )
|
|||||||
if ! $($(key))
|
if ! $($(key))
|
||||||
{
|
{
|
||||||
properties = [ feature.expand $(properties) ] ;
|
properties = [ feature.expand $(properties) ] ;
|
||||||
properties = [ property.select <toolset> <toolset-msvc:version> <architecture> <address-model> <windows-api> : $(properties) ] ;
|
properties = [ property.select <toolset> <toolset-msvc:version> <architecture> <address-model> <windows-api> <relevant> : $(properties) ] ;
|
||||||
local ps = [ property-set.create $(properties) <msvc.setup-options>$(setup-options) ] ;
|
local ps = [ property-set.create $(properties) <msvc.setup-options>$(setup-options) ] ;
|
||||||
local original = [ virtual-target.from-file $(setup-script) : [ path.pwd ] : $(.project) ] ;
|
local original = [ virtual-target.from-file $(setup-script) : [ path.pwd ] : $(.project) ] ;
|
||||||
local action = [ new non-scanning-action $(original) : msvc.adjust-setup-command : $(ps) ] ;
|
local action = [ new non-scanning-action $(original) : msvc.adjust-setup-command : $(ps) ] ;
|
||||||
@@ -1422,8 +1423,8 @@ class msvc-linking-generator : linking-generator
|
|||||||
|
|
||||||
if $(result)
|
if $(result)
|
||||||
{
|
{
|
||||||
local name-main = [ $(result[0]).name ] ;
|
local name-main = [ $(result[1]).name ] ;
|
||||||
local action = [ $(result[0]).action ] ;
|
local action = [ $(result[1]).action ] ;
|
||||||
|
|
||||||
if [ $(property-set).get <debug-symbols> ] = "on"
|
if [ $(property-set).get <debug-symbols> ] = "on"
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1243,6 +1243,10 @@ local rule pyd-pythonpath ( source )
|
|||||||
toolset.flags python.capture-output ARGS <testing.arg> ;
|
toolset.flags python.capture-output ARGS <testing.arg> ;
|
||||||
toolset.flags python.capture-output INPUT_FILES <testing.input-file> ;
|
toolset.flags python.capture-output INPUT_FILES <testing.input-file> ;
|
||||||
|
|
||||||
|
toolset.uses-features python.capture-output :
|
||||||
|
<testing.launcher> <testing.execute> <dll-path> <xdll-path> <target-os>
|
||||||
|
<pythonpath> ;
|
||||||
|
|
||||||
rule capture-output ( target : sources * : properties * )
|
rule capture-output ( target : sources * : properties * )
|
||||||
{
|
{
|
||||||
# Setup up a proper DLL search path. Here, $(sources[1]) is a python module
|
# Setup up a proper DLL search path. Here, $(sources[1]) is a python module
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ class stlport-target-class : basic-target
|
|||||||
|
|
||||||
local requirements ;
|
local requirements ;
|
||||||
requirements += <stdlib-stlport:version>$(self.version) ;
|
requirements += <stdlib-stlport:version>$(self.version) ;
|
||||||
|
requirements += <relevant>runtime-debugging ;
|
||||||
|
requirements += <relevant>toolset ;
|
||||||
|
requirements += <relevant>runtime-link ;
|
||||||
self.requirements = [ property-set.create $(requirements) ] ;
|
self.requirements = [ property-set.create $(requirements) ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -331,6 +331,8 @@ generators.register-standard testing.capture-output : EXE : RUN_OUTPUT ;
|
|||||||
# http://article.gmane.org/gmane.comp.lib.boost.build/6353).
|
# http://article.gmane.org/gmane.comp.lib.boost.build/6353).
|
||||||
generators.register-standard testing.unit-test : EXE : UNIT_TEST ;
|
generators.register-standard testing.unit-test : EXE : UNIT_TEST ;
|
||||||
|
|
||||||
|
toolset.uses-features testing.expect-success : <preserve-test-targets> ;
|
||||||
|
toolset.uses-features testing.expect-failure : <preserve-test-targets> ;
|
||||||
|
|
||||||
# The action rules called by generators.
|
# The action rules called by generators.
|
||||||
|
|
||||||
@@ -456,6 +458,9 @@ toolset.flags testing.capture-output ARGS <testing.arg> ;
|
|||||||
toolset.flags testing.capture-output INPUT_FILES <testing.input-file> ;
|
toolset.flags testing.capture-output INPUT_FILES <testing.input-file> ;
|
||||||
toolset.flags testing.capture-output LAUNCHER <testing.launcher> ;
|
toolset.flags testing.capture-output LAUNCHER <testing.launcher> ;
|
||||||
|
|
||||||
|
toolset.uses-features testing.capture-output :
|
||||||
|
<testing.launcher> <testing.execute> <dll-path> <xdll-path> <target-os> ;
|
||||||
|
|
||||||
if --remove-test-targets in [ modules.peek : ARGV ]
|
if --remove-test-targets in [ modules.peek : ARGV ]
|
||||||
{
|
{
|
||||||
feature.set-default preserve-test-targets : off ;
|
feature.set-default preserve-test-targets : off ;
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ IMPORT xsltproc : register-generator : : generators.register-xslt ;
|
|||||||
|
|
||||||
rule flags ( rulename )
|
rule flags ( rulename )
|
||||||
{
|
{
|
||||||
|
toolset.uses-features $(rulename) : <xsl:param> <catalog> : unchecked ;
|
||||||
toolset.flags $(rulename) XSL-PATH : <xsl:path> : unchecked ;
|
toolset.flags $(rulename) XSL-PATH : <xsl:path> : unchecked ;
|
||||||
toolset.flags $(rulename) FLAGS : <flags> : unchecked ;
|
toolset.flags $(rulename) FLAGS : <flags> : unchecked ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,8 +214,9 @@ generators.register-linker mock.link : LIB OBJ : EXE : <toolset>mock ;
|
|||||||
generators.register-linker mock.link.dll : LIB OBJ : SHARED_LIB : <toolset>mock ;
|
generators.register-linker mock.link.dll : LIB OBJ : SHARED_LIB : <toolset>mock ;
|
||||||
generators.register-archiver mock.archive : OBJ : STATIC_LIB : <toolset>mock ;
|
generators.register-archiver mock.archive : OBJ : STATIC_LIB : <toolset>mock ;
|
||||||
|
|
||||||
toolset.flags mock.compile INCLUDES <include> ;
|
toolset.flags mock.compile OPTIONS <link>shared : -fPIC ;
|
||||||
toolset.flags mock.compile DEFINES <define> ;
|
toolset.flags mock.compile INCLUDES : <include> ;
|
||||||
|
toolset.flags mock.compile DEFINES : <define> ;
|
||||||
|
|
||||||
actions compile.c
|
actions compile.c
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ def expand_properties(properties):
|
|||||||
result += ["target-os=" + default_target_os]
|
result += ["target-os=" + default_target_os]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def compute_path(properties):
|
def compute_path(properties, target_type):
|
||||||
path = ""
|
path = ""
|
||||||
if "variant=release" in properties:
|
if "variant=release" in properties:
|
||||||
path += "/release"
|
path += "/release"
|
||||||
@@ -74,9 +74,9 @@ def compute_path(properties):
|
|||||||
path += "/cxxstd-latest-iso"
|
path += "/cxxstd-latest-iso"
|
||||||
if "link=static" in properties:
|
if "link=static" in properties:
|
||||||
path += "/link-static"
|
path += "/link-static"
|
||||||
if "runtime-link=static" in properties:
|
if "runtime-link=static" in properties and target_type in ["exe"]:
|
||||||
path += "/runtime-link-static"
|
path += "/runtime-link-static"
|
||||||
if "strip=on" in properties:
|
if "strip=on" in properties and target_type in ["dll", "exe", "obj2"]:
|
||||||
path += "/strip-on"
|
path += "/strip-on"
|
||||||
if get_target_os(properties) != default_target_os:
|
if get_target_os(properties) != default_target_os:
|
||||||
path += "/target-os-" + get_target_os(properties)
|
path += "/target-os-" + get_target_os(properties)
|
||||||
@@ -96,16 +96,17 @@ def test_toolset(toolset, version, property_sets):
|
|||||||
for properties in property_sets:
|
for properties in property_sets:
|
||||||
t.set_toolset(toolset + "-" + version, get_target_os(properties))
|
t.set_toolset(toolset + "-" + version, get_target_os(properties))
|
||||||
properties = adjust_properties(properties)
|
properties = adjust_properties(properties)
|
||||||
path = toolset.split("-")[0] + "-*" + version + compute_path(properties)
|
def path(t):
|
||||||
|
return toolset.split("-")[0] + "-*" + version + compute_path(properties, t)
|
||||||
os.environ["B2_PROPERTIES"] = " ".join(expand_properties(properties))
|
os.environ["B2_PROPERTIES"] = " ".join(expand_properties(properties))
|
||||||
t.run_build_system(["--user-config="] + properties)
|
t.run_build_system(["--user-config="] + properties)
|
||||||
t.expect_addition("bin/%s/lib.obj" % (path))
|
t.expect_addition("bin/%s/lib.obj" % (path("obj")))
|
||||||
if "link=static" not in properties:
|
if "link=static" not in properties:
|
||||||
t.expect_addition("bin/%s/l1.dll" % (path))
|
t.expect_addition("bin/%s/l1.dll" % (path("dll")))
|
||||||
else:
|
else:
|
||||||
t.expect_addition("bin/%s/l1.lib" % (path))
|
t.expect_addition("bin/%s/l1.lib" % (path("lib")))
|
||||||
t.expect_addition("bin/%s/main.obj" % (path))
|
t.expect_addition("bin/%s/main.obj" % (path("obj2")))
|
||||||
t.expect_addition("bin/%s/test.exe" % (path))
|
t.expect_addition("bin/%s/test.exe" % (path("exe")))
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
t.rm("bin")
|
t.rm("bin")
|
||||||
|
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ def test_free():
|
|||||||
actions run { echo $(OPTIONS) > $(<) }
|
actions run { echo $(OPTIONS) > $(<) }
|
||||||
''')
|
''')
|
||||||
t.run_build_system(['f1=x,/:-'])
|
t.run_build_system(['f1=x,/:-'])
|
||||||
t.expect_content("bin/*/output1.txt", "x,/:-")
|
t.expect_content("bin*/output1.txt", "x,/:-")
|
||||||
t.expect_content("bin/*/output2.txt", "x,/:-")
|
t.expect_content("bin*/output2.txt", "x,/:-")
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
|
|
||||||
def test_subfeature():
|
def test_subfeature():
|
||||||
|
|||||||
@@ -61,6 +61,6 @@ t.write("r.rcc", """
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_content("bin/$toolset/debug*/r.obj", "rc-object")
|
t.expect_content("bin/r.obj", "rc-object")
|
||||||
|
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ import sys
|
|||||||
t = BoostBuild.Tester(['example.python.interpreter=%s' % sys.executable])
|
t = BoostBuild.Tester(['example.python.interpreter=%s' % sys.executable])
|
||||||
t.set_tree("../example/make")
|
t.set_tree("../example/make")
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition(["bin/$toolset/debug*/main.cpp"])
|
t.expect_addition(["bin/main.cpp"])
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
|
|||||||
142
test/feature_relevant.py
Normal file
142
test/feature_relevant.py
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# Copyright 2018 Steven Watanabe
|
||||||
|
# Distributed under the Boost Software License, Version 1.0.
|
||||||
|
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
# http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
# Tests the <relevant> feature
|
||||||
|
|
||||||
|
import BoostBuild
|
||||||
|
|
||||||
|
t = BoostBuild.Tester(use_test_config=False)
|
||||||
|
|
||||||
|
t.write("xxx.jam", """
|
||||||
|
import type ;
|
||||||
|
import feature : feature ;
|
||||||
|
import toolset : flags ;
|
||||||
|
import generators ;
|
||||||
|
type.register XXX : xxx ;
|
||||||
|
type.register YYY : yyy ;
|
||||||
|
feature xxxflags : : free ;
|
||||||
|
generators.register-standard xxx.run : YYY : XXX ;
|
||||||
|
# xxxflags is relevant because it is used by flags
|
||||||
|
flags xxx.run OPTIONS : <xxxflags> ;
|
||||||
|
actions run
|
||||||
|
{
|
||||||
|
echo okay > $(<)
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
t.write("zzz.jam", """
|
||||||
|
import xxx ;
|
||||||
|
import type ;
|
||||||
|
import feature : feature ;
|
||||||
|
import generators ;
|
||||||
|
type.register ZZZ : zzz ;
|
||||||
|
feature zzz.enabled : off on : propagated ;
|
||||||
|
# zzz.enabled is relevant because it is used in the generator's
|
||||||
|
# requirements
|
||||||
|
generators.register-standard zzz.run : XXX : ZZZ : <zzz.enabled>on ;
|
||||||
|
actions run
|
||||||
|
{
|
||||||
|
echo okay > $(<)
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
t.write("aaa.jam", """
|
||||||
|
import zzz ;
|
||||||
|
import type ;
|
||||||
|
import feature : feature ;
|
||||||
|
import generators ;
|
||||||
|
import toolset : flags ;
|
||||||
|
type.register AAA : aaa ;
|
||||||
|
feature aaaflags : : free ;
|
||||||
|
generators.register-standard aaa.run : ZZZ : AAA ;
|
||||||
|
flags aaa.run OPTIONS : <aaaflags> ;
|
||||||
|
actions run
|
||||||
|
{
|
||||||
|
echo okay > $(<)
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
t.write("Jamroot.jam", """
|
||||||
|
import xxx ;
|
||||||
|
import zzz ;
|
||||||
|
import aaa ;
|
||||||
|
import feature : feature ;
|
||||||
|
|
||||||
|
# f1 is relevant, because it is composite and <xxxflags> is relevant
|
||||||
|
feature f1 : n y : composite propagated ;
|
||||||
|
feature.compose <f1>y : <xxxflags>-no1 ;
|
||||||
|
# f2 is relevant, because it is used in a conditional
|
||||||
|
feature f2 : n y : propagated ;
|
||||||
|
# f3 is relevant, because it is used to choose the target alternative
|
||||||
|
feature f3 : n y : propagated ;
|
||||||
|
# f4 is relevant, because it is marked as such explicitly
|
||||||
|
feature f4 : n y : propagated ;
|
||||||
|
# f5 is relevant because of the conditional usage-requirements
|
||||||
|
feature f5 : n y : propagated ;
|
||||||
|
# f6 is relevant because the indirect conditional indicates so
|
||||||
|
feature f6 : n y : propagated ;
|
||||||
|
# f7 is relevant because the icond7 says so
|
||||||
|
feature f7 : n y : propagated ;
|
||||||
|
|
||||||
|
# The same as f[n], except not propagated
|
||||||
|
feature g1 : n y : composite ;
|
||||||
|
feature.compose <g1>y : <xxxflags>-no1 ;
|
||||||
|
feature g2 : n y ;
|
||||||
|
feature g3 : n y ;
|
||||||
|
feature g4 : n y ;
|
||||||
|
feature g5 : n y ;
|
||||||
|
feature g6 : n y ;
|
||||||
|
feature g7 : n y ;
|
||||||
|
|
||||||
|
project : default-build
|
||||||
|
<f1>y <f2>y <f3>y <f4>y <f5>y <f6>y <f7>y
|
||||||
|
<g1>y <g2>y <g3>y <g4>y <g5>y <g6>y <g7>y <zzz.enabled>on ;
|
||||||
|
|
||||||
|
rule icond6 ( properties * )
|
||||||
|
{
|
||||||
|
local result ;
|
||||||
|
if <f6>y in $(properties) || <g6>y in $(properties)
|
||||||
|
{
|
||||||
|
result += <xxxflags>-yes6 ;
|
||||||
|
}
|
||||||
|
return $(result)
|
||||||
|
<relevant>xxxflags:<relevant>f6
|
||||||
|
<relevant>xxxflags:<relevant>g6 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
rule icond7 ( properties * )
|
||||||
|
{
|
||||||
|
local result ;
|
||||||
|
if <f7>y in $(properties) || <g7>y in $(properties)
|
||||||
|
{
|
||||||
|
result += <aaaflags>-yes7 ;
|
||||||
|
}
|
||||||
|
return $(result)
|
||||||
|
<relevant>aaaflags:<relevant>f7
|
||||||
|
<relevant>aaaflags:<relevant>g7 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
zzz out : in.yyy
|
||||||
|
: <f2>y:<xxxflags>-no2 <g2>y:<xxxflags>-no2 <relevant>f4 <relevant>g4
|
||||||
|
<conditional>@icond6
|
||||||
|
:
|
||||||
|
: <f5>y:<aaaflags>-yes5 <g5>y:<aaaflags>-yes5 <conditional>@icond7
|
||||||
|
;
|
||||||
|
alias out : : <f3>n ;
|
||||||
|
alias out : : <g3>n ;
|
||||||
|
# Features that are relevant for out are also relevant for check-propagate
|
||||||
|
aaa check-propagate : out ;
|
||||||
|
""")
|
||||||
|
|
||||||
|
t.write("in.yyy", "")
|
||||||
|
|
||||||
|
t.run_build_system()
|
||||||
|
t.expect_addition("bin/f1-y/f2-y/f3-y/f4-y/f6-y/g1-y/g2-y/g3-y/g4-y/g6-y/out.xxx")
|
||||||
|
t.expect_addition("bin/f1-y/f2-y/f3-y/f4-y/f6-y/g1-y/g2-y/g3-y/g4-y/g6-y/zzz.enabled-on/out.zzz")
|
||||||
|
t.expect_addition("bin/f1-y/f2-y/f3-y/f4-y/f5-y/f6-y/f7-y/zzz.enabled-on/check-propagate.aaa")
|
||||||
|
|
||||||
|
t.cleanup()
|
||||||
@@ -20,9 +20,8 @@ t.expect_output_lines("warning: On gcc, DLLs can not be built with "
|
|||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
t.run_build_system(["link=static", "runtime-link=static"])
|
t.run_build_system(["link=static", "runtime-link=static"])
|
||||||
binFolder = "bin/$toolset/debug*/link-static/runtime-link-static"
|
t.expect_addition("bin/$toolset/debug*/link-static/hello.obj")
|
||||||
t.expect_addition("%s/hello.obj" % binFolder)
|
t.expect_addition("bin/$toolset/debug*/link-static/hello.lib")
|
||||||
t.expect_addition("%s/hello.lib" % binFolder)
|
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
|
|||||||
@@ -87,9 +87,9 @@ my-obj other-obj : source.extension ;
|
|||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_output_lines("Generating a CPP file...")
|
t.expect_output_lines("Generating a CPP file...")
|
||||||
t.expect_addition("bin/$toolset/debug*/dummy.my_obj")
|
t.expect_addition("bin/dummy.my_obj")
|
||||||
t.expect_addition("Other/bin/$toolset/debug*/other-obj.cpp")
|
t.expect_addition("Other/bin/other-obj.cpp")
|
||||||
t.expect_addition("Other/bin/$toolset/debug*/other-obj.my_obj")
|
t.expect_addition("Other/bin/other-obj.my_obj")
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
@@ -139,8 +139,8 @@ yyy other : source.xxx2 ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition("bin/$toolset/debug*/dummy.yyy")
|
t.expect_addition("bin/dummy.yyy")
|
||||||
t.expect_addition("Other/bin/$toolset/debug*/other.yyy")
|
t.expect_addition("Other/bin/other.yyy")
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
|
|||||||
@@ -215,17 +215,17 @@ nm-exe e : e.cpp ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition("bin/$toolset/debug*/" * BoostBuild.List("a.my_exe "
|
t.expect_addition("bin/" * BoostBuild.List("a.my_exe "
|
||||||
"a.my_obj b.my_obj c.tui_h c.cpp c.my_obj d_parser.whl d_lexer.dlp "
|
"a.my_obj b.my_obj c.tui_h c.cpp c.my_obj d_parser.whl d_lexer.dlp "
|
||||||
"d_parser.cpp d_lexer.cpp d_lexer.my_obj d_parser.lr0 d_parser.h "
|
"d_parser.cpp d_lexer.cpp d_lexer.my_obj d_parser.lr0 d_parser.h "
|
||||||
"d_parser.my_obj d_parser_symbols.h x.c x.my_obj y.x1 y.x2 y.cpp "
|
"d_parser.my_obj d_parser_symbols.h x.c x.my_obj y.x1 y.x2 y.cpp "
|
||||||
"y.my_obj e.marked_cpp e.positions e.target_cpp e.my_obj e.my_exe "
|
"y.my_obj e.marked_cpp e.positions e.target_cpp e.my_obj e.my_exe "
|
||||||
"f.my_exe obj_1.my_obj obj_2.my_obj"))
|
"f.my_exe obj_1.my_obj obj_2.my_obj"))
|
||||||
t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List("c.my_obj "
|
t.expect_addition("lib/bin/" * BoostBuild.List("c.my_obj "
|
||||||
"auxilliary.my_lib"))
|
"auxilliary.my_lib"))
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
folder = "bin/$toolset/debug*"
|
folder = "bin"
|
||||||
t.expect_content_lines("%s/obj_1.my_obj" % folder, " Sources: 'z.cpp'")
|
t.expect_content_lines("%s/obj_1.my_obj" % folder, " Sources: 'z.cpp'")
|
||||||
t.expect_content_lines("%s/obj_2.my_obj" % folder, " Sources: 'z.cpp'")
|
t.expect_content_lines("%s/obj_2.my_obj" % folder, " Sources: 'z.cpp'")
|
||||||
t.expect_content_lines("%s/a.my_obj" % folder, " Sources: 'a.cpp'")
|
t.expect_content_lines("%s/a.my_obj" % folder, " Sources: 'a.cpp'")
|
||||||
@@ -311,7 +311,7 @@ ddd _xxx : _xxx._a ;
|
|||||||
def suffix(rename):
|
def suffix(rename):
|
||||||
if rename: return "_x"
|
if rename: return "_x"
|
||||||
return ""
|
return ""
|
||||||
name = "bin/$toolset/debug*/_xxx"
|
name = "bin/_xxx"
|
||||||
e = t.expect_addition
|
e = t.expect_addition
|
||||||
e("%s%s._b1" % (name, suffix(rename1)))
|
e("%s%s._b1" % (name, suffix(rename1)))
|
||||||
e("%s%s._b2" % (name, suffix(rename2)))
|
e("%s%s._b2" % (name, suffix(rename2)))
|
||||||
|
|||||||
@@ -21,12 +21,11 @@ int main() {}
|
|||||||
t.write("helper.cpp", "void helper() {}\n")
|
t.write("helper.cpp", "void helper() {}\n")
|
||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib")
|
t.expect_addition("bin/$toolset/debug*/a__helper.lib")
|
||||||
t.rm("bin/$toolset/debug/link-static/a__helper.lib")
|
t.rm("bin/$toolset/debug*/a__helper.lib")
|
||||||
t.rm("bin/$toolset/debug/link-static/*/a__helper.lib")
|
|
||||||
|
|
||||||
t.run_build_system(["a__helper"])
|
t.run_build_system(["a__helper"])
|
||||||
t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib")
|
t.expect_addition("bin/$toolset/debug*/a__helper.lib")
|
||||||
|
|
||||||
t.rm("bin")
|
t.rm("bin")
|
||||||
|
|
||||||
@@ -41,8 +40,8 @@ exe a2 : a.cpp [ lib helper : helper.cpp ] ;
|
|||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition("bin/$toolset/debug/link-static*/a.exe")
|
t.expect_addition("bin/$toolset/debug/link-static*/a.exe")
|
||||||
t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib")
|
t.expect_addition("bin/$toolset/debug*/a__helper.lib")
|
||||||
t.expect_addition("bin/$toolset/debug/link-static*/a2__helper.lib")
|
t.expect_addition("bin/$toolset/debug*/a2__helper.lib")
|
||||||
|
|
||||||
|
|
||||||
# Check that the 'alias' target does not change the name of inline targets, and
|
# Check that the 'alias' target does not change the name of inline targets, and
|
||||||
@@ -58,6 +57,6 @@ t.run_build_system()
|
|||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
t.run_build_system(["a"])
|
t.run_build_system(["a"])
|
||||||
t.expect_addition("bin/$toolset/debug/link-static*/helper.lib")
|
t.expect_addition("bin/$toolset/debug*/helper.lib")
|
||||||
|
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ make foo.bar : : creator : <test_feature>12345678 ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition("bin/$toolset/debug*/foo.bar")
|
t.expect_addition("bin/foo.bar")
|
||||||
t.fail_test(string.find(t.read("bin/$toolset/debug*/foo.bar"), "12345678") == -1)
|
t.fail_test(string.find(t.read("bin/foo.bar"), "12345678") == -1)
|
||||||
|
|
||||||
|
|
||||||
# Regression test. Make sure that if a main target is requested two times, and
|
# Regression test. Make sure that if a main target is requested two times, and
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import os ;
|
import os ;
|
||||||
import gcc ;
|
import gcc ;
|
||||||
import property ;
|
import property ;
|
||||||
|
import toolset ;
|
||||||
|
|
||||||
rule properties-as-path ( properties * )
|
rule properties-as-path ( properties * )
|
||||||
{
|
{
|
||||||
@@ -21,6 +22,9 @@ rule properties-as-path ( properties * )
|
|||||||
[ property.remove incidental : $(r) ] ] ;
|
[ property.remove incidental : $(r) ] ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toolset.flags yfc-compile KNOWN-PROPERTIES : <toolset> <optimization> ;
|
||||||
|
toolset.flags yfc-link KNOWN-PROPERTIES : <toolset> <optimization> ;
|
||||||
|
|
||||||
rule yfc-compile ( target : sources * : property-set * )
|
rule yfc-compile ( target : sources * : property-set * )
|
||||||
{
|
{
|
||||||
PROPERTIES on $(target) = [ properties-as-path $(property-set) ] ;
|
PROPERTIES on $(target) = [ properties-as-path $(property-set) ] ;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import os ;
|
import os ;
|
||||||
import gcc ;
|
import gcc ;
|
||||||
import property ;
|
import property ;
|
||||||
|
import toolset ;
|
||||||
|
|
||||||
rule properties-as-path ( properties * )
|
rule properties-as-path ( properties * )
|
||||||
{
|
{
|
||||||
@@ -21,6 +22,10 @@ rule properties-as-path ( properties * )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
toolset.flags yfc-compile KNOWN-PROPERTIES : <toolset> <optimization> ;
|
||||||
|
toolset.flags yfc-link KNOWN-PROPERTIES : <toolset> <optimization> ;
|
||||||
|
|
||||||
|
|
||||||
rule yfc-compile ( target : sources * : property-set * )
|
rule yfc-compile ( target : sources * : property-set * )
|
||||||
{
|
{
|
||||||
PROPERTIES on $(target) = [ properties-as-path $(property-set) ] ;
|
PROPERTIES on $(target) = [ properties-as-path $(property-set) ] ;
|
||||||
@@ -60,4 +65,4 @@ if [ os.name ] = VMS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPORT $(__name__) : yfc-compile yfc-link : : yfc-compile yfc-link ;
|
#IMPORT $(__name__) : yfc-compile yfc-link : : yfc-compile yfc-link ;
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ project /project-a3 ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition("bin/$toolset/b%d._b" % x for x in range(1, 8))
|
t.expect_addition("bin/b%d._b" % x for x in range(1, 8))
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
@@ -280,7 +280,7 @@ bbb b-invalid-target : /foo//invalid ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system(["b1", "b2"])
|
t.run_build_system(["b1", "b2"])
|
||||||
t.expect_addition("bin/$toolset/debug*/b%d._b" % x for x in range(1, 3))
|
t.expect_addition("bin/b%d._b" % x for x in range(1, 3))
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
t.run_build_system(["b-invalid"], status=1)
|
t.run_build_system(["b-invalid"], status=1)
|
||||||
|
|||||||
@@ -29,6 +29,6 @@ my-lib foo ;
|
|||||||
|
|
||||||
t.run_build_system(subdir="sub")
|
t.run_build_system(subdir="sub")
|
||||||
|
|
||||||
t.expect_addition("sub/bin/$toolset/debug/link-static*/foo.lib")
|
t.expect_addition("sub/bin/$toolset/debug*/foo.lib")
|
||||||
|
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ t = BoostBuild.Tester(use_test_config=False)
|
|||||||
|
|
||||||
t.write("jamroot.jam", """
|
t.write("jamroot.jam", """
|
||||||
project : requirements <threading>multi <variant>debug:<link>static ;
|
project : requirements <threading>multi <variant>debug:<link>static ;
|
||||||
|
# Force link to be relevant
|
||||||
|
project : requirements <link>shared:<define>TEST_DLL ;
|
||||||
|
|
||||||
build-project sub ;
|
build-project sub ;
|
||||||
build-project sub2 ;
|
build-project sub2 ;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ obj test : test.cpp : <implicit-dependency>header3.h ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system(["-j2"])
|
t.run_build_system(["-j2"])
|
||||||
t.expect_addition("bin/$toolset/debug*/header3.h")
|
t.expect_addition("bin/header3.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/test.obj")
|
t.expect_addition("bin/$toolset/debug*/test.obj")
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
@@ -72,9 +72,9 @@ obj test : test.cpp :
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system(["-j2", "test"])
|
t.run_build_system(["-j2", "test"])
|
||||||
t.expect_addition("bin/$toolset/debug*/header1.h")
|
t.expect_addition("bin/header1.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/header2.h")
|
t.expect_addition("bin/header2.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/header3.h")
|
t.expect_addition("bin/header3.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/test.obj")
|
t.expect_addition("bin/$toolset/debug*/test.obj")
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
@@ -122,9 +122,9 @@ obj test : test.cpp :
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system(["-j2", "test"])
|
t.run_build_system(["-j2", "test"])
|
||||||
t.expect_addition("bin/$toolset/debug*/header1.h")
|
t.expect_addition("bin/header1.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/header2.h")
|
t.expect_addition("bin/header2.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/header3.h")
|
t.expect_addition("bin/header3.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/test.obj")
|
t.expect_addition("bin/$toolset/debug*/test.obj")
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ exe test : test2.cpp test1.cpp : <implicit-dependency>header3.h ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system(["-j2", "test"])
|
t.run_build_system(["-j2", "test"])
|
||||||
t.expect_addition("bin/$toolset/debug*/header3.h")
|
t.expect_addition("bin/header3.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/test1.obj")
|
t.expect_addition("bin/$toolset/debug*/test1.obj")
|
||||||
t.expect_addition("bin/$toolset/debug*/test2.obj")
|
t.expect_addition("bin/$toolset/debug*/test2.obj")
|
||||||
t.expect_addition("bin/$toolset/debug*/test.exe")
|
t.expect_addition("bin/$toolset/debug*/test.exe")
|
||||||
@@ -192,7 +192,7 @@ t.expect_nothing_more()
|
|||||||
|
|
||||||
t.touch("header3.in")
|
t.touch("header3.in")
|
||||||
t.run_build_system(["-j2", "test"])
|
t.run_build_system(["-j2", "test"])
|
||||||
t.expect_touch("bin/$toolset/debug*/header3.h")
|
t.expect_touch("bin/header3.h")
|
||||||
t.expect_touch("bin/$toolset/debug*/test1.obj")
|
t.expect_touch("bin/$toolset/debug*/test1.obj")
|
||||||
t.expect_touch("bin/$toolset/debug*/test2.obj")
|
t.expect_touch("bin/$toolset/debug*/test2.obj")
|
||||||
t.expect_touch("bin/$toolset/debug*/test.exe")
|
t.expect_touch("bin/$toolset/debug*/test.exe")
|
||||||
@@ -256,7 +256,7 @@ exe test : test2.cpp test1.cpp : <implicit-dependency>header2.h <include>. ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system(["-j2", "test"])
|
t.run_build_system(["-j2", "test"])
|
||||||
t.expect_addition("bin/$toolset/debug*/header2.h")
|
t.expect_addition("bin/header2.h")
|
||||||
t.expect_addition("bin/$toolset/debug*/test1.obj")
|
t.expect_addition("bin/$toolset/debug*/test1.obj")
|
||||||
t.expect_addition("bin/$toolset/debug*/test2.obj")
|
t.expect_addition("bin/$toolset/debug*/test2.obj")
|
||||||
t.expect_addition("bin/$toolset/debug*/test.exe")
|
t.expect_addition("bin/$toolset/debug*/test.exe")
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ t.write("file2.c", "")
|
|||||||
t.write("file3.c", "")
|
t.write("file3.c", "")
|
||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition("bin/$toolset/debug*/check.order-test")
|
t.expect_addition("bin/check.order-test")
|
||||||
t.expect_content("bin/$toolset/debug*/check.order-test", """\
|
t.expect_content("bin/check.order-test", """\
|
||||||
file2.c
|
file2.c
|
||||||
file1.c
|
file1.c
|
||||||
file3.c
|
file3.c
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ os.environ["TMPDIR"] = tmpdir; # *nix
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
t.run_build_system(["has space"])
|
t.run_build_system(["has space"])
|
||||||
t.expect_addition("has space/bin/$toolset/debug*/test.txt")
|
t.expect_addition("has space/bin/test.txt")
|
||||||
t.expect_addition("has space/bin/$toolset/debug*/test.passed")
|
t.expect_addition("has space/bin/$toolset/debug*/test.passed")
|
||||||
finally:
|
finally:
|
||||||
if oldtmp is not None:
|
if oldtmp is not None:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ t.expect_nothing_more()
|
|||||||
|
|
||||||
reset()
|
reset()
|
||||||
t.run_build_system(["link=static"], subdir="lib")
|
t.run_build_system(["link=static"], subdir="lib")
|
||||||
t.expect_addition("lib/bin/$toolset/debug/link-static*/" * BoostBuild.List(
|
t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List(
|
||||||
"c.obj auxilliary1.lib auxilliary2.lib"))
|
"c.obj auxilliary1.lib auxilliary2.lib"))
|
||||||
t.expect_nothing_more()
|
t.expect_nothing_more()
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,6 @@ second a : a.cpp ;
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
t.run_build_system()
|
t.run_build_system()
|
||||||
t.expect_addition("bin/$toolset/debug*/a")
|
t.expect_addition("bin/a")
|
||||||
|
|
||||||
t.cleanup()
|
t.cleanup()
|
||||||
|
|||||||
@@ -91,11 +91,11 @@ __declspec (dllexport) void x () {}
|
|||||||
BoostBuild.List("bin/$toolset/release*/a_rs.exe") +
|
BoostBuild.List("bin/$toolset/release*/a_rs.exe") +
|
||||||
BoostBuild.List("bin/$toolset/release*/b_rs.dll") +
|
BoostBuild.List("bin/$toolset/release*/b_rs.dll") +
|
||||||
BoostBuild.List("c/a_rs.exe") +
|
BoostBuild.List("c/a_rs.exe") +
|
||||||
BoostBuild.List("bin/$toolset/debug/link-static*/a_dt.exe") +
|
BoostBuild.List("bin/$toolset/debug*/a_dt.exe") +
|
||||||
BoostBuild.List("bin/$toolset/debug/link-static*/b_dt.lib") +
|
BoostBuild.List("bin/$toolset/debug*/b_dt.lib") +
|
||||||
BoostBuild.List("c/a_dt.exe") +
|
BoostBuild.List("c/a_dt.exe") +
|
||||||
BoostBuild.List("bin/$toolset/release/link-static*/a_rt.exe") +
|
BoostBuild.List("bin/$toolset/release*/a_rt.exe") +
|
||||||
BoostBuild.List("bin/$toolset/release/link-static*/b_rt.lib") +
|
BoostBuild.List("bin/$toolset/release*/b_rt.lib") +
|
||||||
BoostBuild.List("c/a_rt.exe"))
|
BoostBuild.List("c/a_rt.exe"))
|
||||||
|
|
||||||
variants = ["debug", "release", "link=static,shared"]
|
variants = ["debug", "release", "link=static,shared"]
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ tests = ["absolute_sources",
|
|||||||
"expansion",
|
"expansion",
|
||||||
"explicit",
|
"explicit",
|
||||||
"feature_cxxflags",
|
"feature_cxxflags",
|
||||||
|
"feature_relevant",
|
||||||
"generator_selection",
|
"generator_selection",
|
||||||
"generators_test",
|
"generators_test",
|
||||||
"implicit_dependency",
|
"implicit_dependency",
|
||||||
|
|||||||
Reference in New Issue
Block a user