mirror of
https://github.com/boostorg/build.git
synced 2026-02-16 01:12:13 +00:00
Propagate free properties in build request to all directly requested targets.
* targets.jam
(abstract-target.direct-build-request): New rule.
(project-target.direct-build-request): New rule.
(main-target.direct-build-request): New rule.
(main-target.generate): Use data stored by
'direct-build-request' to adjust build properties.
* build-system.jam: Call 'direct-build-request' on project
target in "."
* feature.jam (feature): Don't allow propagated free features.
[SVN r15677]
This commit is contained in:
@@ -32,6 +32,11 @@ virtual-targets = ;
|
||||
|
||||
if $(expanded)
|
||||
{
|
||||
for local p in $(expanded)
|
||||
{
|
||||
$(root-target).direct-build-request [ feature.split $(p) ] ;
|
||||
}
|
||||
|
||||
for local p in $(expanded)
|
||||
{
|
||||
virtual-targets += [ $(root-target).generate [ feature.split $(p) ] ] ;
|
||||
|
||||
@@ -65,13 +65,15 @@ rule feature (
|
||||
{
|
||||
error = feature already defined: ;
|
||||
}
|
||||
else if implicit in $(attributes)
|
||||
else if implicit in $(attributes) && free in $(attributes)
|
||||
{
|
||||
if free in $(attributes)
|
||||
{
|
||||
error = free features cannot also be implicit ;
|
||||
}
|
||||
error = free features cannot also be implicit ;
|
||||
}
|
||||
else if free in $(attributes) && propagated in $(attributes)
|
||||
{
|
||||
error = free features cannot be propagated ;
|
||||
}
|
||||
|
||||
|
||||
if $(error)
|
||||
{
|
||||
@@ -846,6 +848,12 @@ local rule __test__ ( )
|
||||
}
|
||||
catch free features cannot also be implicit ;
|
||||
|
||||
try ;
|
||||
{
|
||||
feature feature3 : : free propagated ;
|
||||
}
|
||||
catch free features cannot be propagated ;
|
||||
|
||||
try ;
|
||||
{
|
||||
implied-feature lackluster ;
|
||||
|
||||
@@ -56,6 +56,13 @@ rule abstract-target ( name # name of the target in Jamfile
|
||||
return $(location)/$(self.name) ;
|
||||
}
|
||||
|
||||
# Adds one more direct build request for this targets. If later generate
|
||||
# is called with the same non-free non-incidental properties as in one
|
||||
# of direct build requests, then that build request is used instead.
|
||||
rule direct-build-request ( properties * )
|
||||
{
|
||||
}
|
||||
|
||||
# Takes properties in split form ("<feature1>foo <feature2>bar").
|
||||
# Generates virtual targets for this abstract targets which are matching
|
||||
# 'properties' as closely as possible. It 'properties' are not specified,
|
||||
@@ -78,15 +85,30 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
self.requirements = $(requirements) ;
|
||||
self.default-build = $(default-build) ;
|
||||
|
||||
rule direct-build-request ( properties * )
|
||||
{
|
||||
for local name in $(self.main-targets)
|
||||
{
|
||||
local t = [ main-target $(name) ] ;
|
||||
result += [ $(t).direct-build-request $(properties) ] ;
|
||||
}
|
||||
for local pn in [ project.attribute $(self.project) projects-to-build ]
|
||||
{
|
||||
local p = [ project.module-name $(pn) ] ;
|
||||
local t = [ project.target [ project.attribute $(p) location ] ] ;
|
||||
result += [ $(t).direct-build-request $(properties) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# Generates all possible targets contained in this project.
|
||||
rule generate ( properties * )
|
||||
{
|
||||
# Project properties are directly imposed on all main targets.
|
||||
# However, we'd need to check if this project can be build at
|
||||
# all.
|
||||
local properties =
|
||||
local xproperties =
|
||||
[ property.refine $(properties) : $(self.requirements) ] ;
|
||||
if $(properties[1]) = "@error"
|
||||
if $(xproperties[1]) = "@error"
|
||||
{
|
||||
local id = [ project.attribute $(self.project) id ] ;
|
||||
if $(id)
|
||||
@@ -156,12 +178,34 @@ rule main-target ( name : project )
|
||||
self.alternatives += $(target) ;
|
||||
}
|
||||
|
||||
rule direct-build-request ( properties * )
|
||||
{
|
||||
local base = [ property.remove free incidental : $(properties) ] ;
|
||||
local ep = $(self.direct-request.$(base:J=-)) ;
|
||||
if $(ep) && $(ep) != $(properties)
|
||||
{
|
||||
error "Conflicting direct build requests" $(ep) "and" $(properties) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.direct-request.$(base:J=-) = $(properties) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Select an alternative for this main target, by finding all alternatives
|
||||
# which requirements are satisfied by 'properties' and picking the one with
|
||||
# longest requirements set.
|
||||
# Returns the result of calling 'generate' on that alternative.
|
||||
rule generate ( properties * )
|
||||
{
|
||||
local base = [ property.remove free incidental : $(properties) ] ;
|
||||
local ep = $(self.direct-request.$(base:J=-)) ;
|
||||
if $(ep)
|
||||
{
|
||||
properties = $(ep) ;
|
||||
}
|
||||
|
||||
# Try to generate all the alternatives.
|
||||
local alternatives = [ new vector ] ;
|
||||
|
||||
@@ -228,8 +272,16 @@ rule main-target ( name : project )
|
||||
}
|
||||
|
||||
# Add additional subvariant element for the targets which free,
|
||||
# non-incidental properties are not equal to project's.
|
||||
|
||||
# non-incidental properties are not equal to project's, plus
|
||||
# those in build request
|
||||
|
||||
# Note that free properties can appear on 'properties' only
|
||||
# from direct build request, because free properties are not
|
||||
# allowed to be propagated.
|
||||
local ref = [ project.attribute $(self.project) requirements ]
|
||||
$(properties) ;
|
||||
ref = [ property.take free : [ property.remove incidental : $(ref) ] ] ;
|
||||
|
||||
local pr = [ property.take free : [ property.remove incidental :
|
||||
[ project.attribute $(self.project) requirements ] ] ] ;
|
||||
|
||||
@@ -248,7 +300,7 @@ rule main-target ( name : project )
|
||||
local properties = [ property.take free : [ property.remove incidental :
|
||||
[ $(action).properties ] ] ] ;
|
||||
|
||||
if $(properties) != $(pr)
|
||||
if $(properties) != $(ref)
|
||||
{
|
||||
$(v).extra-path [ sequence.join main-target- $(self.name) ] ;
|
||||
}
|
||||
@@ -305,7 +357,8 @@ rule basic-target ( name : project
|
||||
return $(result) ;
|
||||
} else {
|
||||
|
||||
property-path = [ property.as-path $(properties) ] ;
|
||||
property-path = [ property.as-path
|
||||
[ property.remove free incidental : $(properties) ] ] ;
|
||||
if ! $(property-path)
|
||||
{
|
||||
property-path = X ;
|
||||
|
||||
9
test/direct-request-test/Jamfile
Normal file
9
test/direct-request-test/Jamfile
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
# This will link correctly only if symbol MACROS is defined when compiling
|
||||
# b.cpp. However, this is only possible if that symbol is requested
|
||||
# on command line and b.cpp is compiled with directly requested
|
||||
# properties.
|
||||
|
||||
exe a : a.cpp b ;
|
||||
|
||||
lib b : b.cpp ;
|
||||
7
test/direct-request-test/a.cpp
Normal file
7
test/direct-request-test/a.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
void foo();
|
||||
|
||||
int main()
|
||||
{
|
||||
foo();
|
||||
}
|
||||
4
test/direct-request-test/b.cpp
Normal file
4
test/direct-request-test/b.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
#ifdef MACROS
|
||||
void foo() {}
|
||||
#endif
|
||||
2
test/direct-request-test/project-root.jam
Normal file
2
test/direct-request-test/project-root.jam
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
import gcc ;
|
||||
15
test/direct_request_test.py
Normal file
15
test/direct_request_test.py
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from BoostBuild import Tester, List
|
||||
import os
|
||||
from string import strip
|
||||
|
||||
t = Tester()
|
||||
|
||||
# First check some startup
|
||||
t.set_tree("direct-request-test")
|
||||
t.run_build_system(extra_args="define=MACROS")
|
||||
|
||||
t.expect_addition("bin/gcc/debug/shared-false/threading-single/" * List("a.o b.o b.a a"))
|
||||
|
||||
t.cleanup()
|
||||
@@ -20,3 +20,4 @@ import project_test3
|
||||
import project_test4
|
||||
import generators_test
|
||||
import dependency_test
|
||||
import direct_request_test
|
||||
|
||||
@@ -65,13 +65,15 @@ rule feature (
|
||||
{
|
||||
error = feature already defined: ;
|
||||
}
|
||||
else if implicit in $(attributes)
|
||||
else if implicit in $(attributes) && free in $(attributes)
|
||||
{
|
||||
if free in $(attributes)
|
||||
{
|
||||
error = free features cannot also be implicit ;
|
||||
}
|
||||
error = free features cannot also be implicit ;
|
||||
}
|
||||
else if free in $(attributes) && propagated in $(attributes)
|
||||
{
|
||||
error = free features cannot be propagated ;
|
||||
}
|
||||
|
||||
|
||||
if $(error)
|
||||
{
|
||||
@@ -846,6 +848,12 @@ local rule __test__ ( )
|
||||
}
|
||||
catch free features cannot also be implicit ;
|
||||
|
||||
try ;
|
||||
{
|
||||
feature feature3 : : free propagated ;
|
||||
}
|
||||
catch free features cannot be propagated ;
|
||||
|
||||
try ;
|
||||
{
|
||||
implied-feature lackluster ;
|
||||
|
||||
@@ -56,6 +56,13 @@ rule abstract-target ( name # name of the target in Jamfile
|
||||
return $(location)/$(self.name) ;
|
||||
}
|
||||
|
||||
# Adds one more direct build request for this targets. If later generate
|
||||
# is called with the same non-free non-incidental properties as in one
|
||||
# of direct build requests, then that build request is used instead.
|
||||
rule direct-build-request ( properties * )
|
||||
{
|
||||
}
|
||||
|
||||
# Takes properties in split form ("<feature1>foo <feature2>bar").
|
||||
# Generates virtual targets for this abstract targets which are matching
|
||||
# 'properties' as closely as possible. It 'properties' are not specified,
|
||||
@@ -78,15 +85,30 @@ rule project-target ( name : project : requirements * : default-build * )
|
||||
self.requirements = $(requirements) ;
|
||||
self.default-build = $(default-build) ;
|
||||
|
||||
rule direct-build-request ( properties * )
|
||||
{
|
||||
for local name in $(self.main-targets)
|
||||
{
|
||||
local t = [ main-target $(name) ] ;
|
||||
result += [ $(t).direct-build-request $(properties) ] ;
|
||||
}
|
||||
for local pn in [ project.attribute $(self.project) projects-to-build ]
|
||||
{
|
||||
local p = [ project.module-name $(pn) ] ;
|
||||
local t = [ project.target [ project.attribute $(p) location ] ] ;
|
||||
result += [ $(t).direct-build-request $(properties) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# Generates all possible targets contained in this project.
|
||||
rule generate ( properties * )
|
||||
{
|
||||
# Project properties are directly imposed on all main targets.
|
||||
# However, we'd need to check if this project can be build at
|
||||
# all.
|
||||
local properties =
|
||||
local xproperties =
|
||||
[ property.refine $(properties) : $(self.requirements) ] ;
|
||||
if $(properties[1]) = "@error"
|
||||
if $(xproperties[1]) = "@error"
|
||||
{
|
||||
local id = [ project.attribute $(self.project) id ] ;
|
||||
if $(id)
|
||||
@@ -156,12 +178,34 @@ rule main-target ( name : project )
|
||||
self.alternatives += $(target) ;
|
||||
}
|
||||
|
||||
rule direct-build-request ( properties * )
|
||||
{
|
||||
local base = [ property.remove free incidental : $(properties) ] ;
|
||||
local ep = $(self.direct-request.$(base:J=-)) ;
|
||||
if $(ep) && $(ep) != $(properties)
|
||||
{
|
||||
error "Conflicting direct build requests" $(ep) "and" $(properties) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.direct-request.$(base:J=-) = $(properties) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Select an alternative for this main target, by finding all alternatives
|
||||
# which requirements are satisfied by 'properties' and picking the one with
|
||||
# longest requirements set.
|
||||
# Returns the result of calling 'generate' on that alternative.
|
||||
rule generate ( properties * )
|
||||
{
|
||||
local base = [ property.remove free incidental : $(properties) ] ;
|
||||
local ep = $(self.direct-request.$(base:J=-)) ;
|
||||
if $(ep)
|
||||
{
|
||||
properties = $(ep) ;
|
||||
}
|
||||
|
||||
# Try to generate all the alternatives.
|
||||
local alternatives = [ new vector ] ;
|
||||
|
||||
@@ -228,8 +272,16 @@ rule main-target ( name : project )
|
||||
}
|
||||
|
||||
# Add additional subvariant element for the targets which free,
|
||||
# non-incidental properties are not equal to project's.
|
||||
|
||||
# non-incidental properties are not equal to project's, plus
|
||||
# those in build request
|
||||
|
||||
# Note that free properties can appear on 'properties' only
|
||||
# from direct build request, because free properties are not
|
||||
# allowed to be propagated.
|
||||
local ref = [ project.attribute $(self.project) requirements ]
|
||||
$(properties) ;
|
||||
ref = [ property.take free : [ property.remove incidental : $(ref) ] ] ;
|
||||
|
||||
local pr = [ property.take free : [ property.remove incidental :
|
||||
[ project.attribute $(self.project) requirements ] ] ] ;
|
||||
|
||||
@@ -248,7 +300,7 @@ rule main-target ( name : project )
|
||||
local properties = [ property.take free : [ property.remove incidental :
|
||||
[ $(action).properties ] ] ] ;
|
||||
|
||||
if $(properties) != $(pr)
|
||||
if $(properties) != $(ref)
|
||||
{
|
||||
$(v).extra-path [ sequence.join main-target- $(self.name) ] ;
|
||||
}
|
||||
@@ -305,7 +357,8 @@ rule basic-target ( name : project
|
||||
return $(result) ;
|
||||
} else {
|
||||
|
||||
property-path = [ property.as-path $(properties) ] ;
|
||||
property-path = [ property.as-path
|
||||
[ property.remove free incidental : $(properties) ] ] ;
|
||||
if ! $(property-path)
|
||||
{
|
||||
property-path = X ;
|
||||
|
||||
9
v2/test/direct-request-test/Jamfile
Normal file
9
v2/test/direct-request-test/Jamfile
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
# This will link correctly only if symbol MACROS is defined when compiling
|
||||
# b.cpp. However, this is only possible if that symbol is requested
|
||||
# on command line and b.cpp is compiled with directly requested
|
||||
# properties.
|
||||
|
||||
exe a : a.cpp b ;
|
||||
|
||||
lib b : b.cpp ;
|
||||
7
v2/test/direct-request-test/a.cpp
Normal file
7
v2/test/direct-request-test/a.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
void foo();
|
||||
|
||||
int main()
|
||||
{
|
||||
foo();
|
||||
}
|
||||
4
v2/test/direct-request-test/b.cpp
Normal file
4
v2/test/direct-request-test/b.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
#ifdef MACROS
|
||||
void foo() {}
|
||||
#endif
|
||||
2
v2/test/direct-request-test/project-root.jam
Normal file
2
v2/test/direct-request-test/project-root.jam
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
import gcc ;
|
||||
15
v2/test/direct_request_test.py
Normal file
15
v2/test/direct_request_test.py
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from BoostBuild import Tester, List
|
||||
import os
|
||||
from string import strip
|
||||
|
||||
t = Tester()
|
||||
|
||||
# First check some startup
|
||||
t.set_tree("direct-request-test")
|
||||
t.run_build_system(extra_args="define=MACROS")
|
||||
|
||||
t.expect_addition("bin/gcc/debug/shared-false/threading-single/" * List("a.o b.o b.a a"))
|
||||
|
||||
t.cleanup()
|
||||
@@ -20,3 +20,4 @@ import project_test3
|
||||
import project_test4
|
||||
import generators_test
|
||||
import dependency_test
|
||||
import direct_request_test
|
||||
|
||||
Reference in New Issue
Block a user