mirror of
https://github.com/boostorg/build.git
synced 2026-02-18 01:52:17 +00:00
Implement simple form of use requirements.
* new/virtual-target.jam
(virtual-target.use-requirements): New rule.
(virtual-target.set-use-requirements): New rule.
* new/generators.jam (construct): Use 'use-requirements' of sources.
* new/targets.jam (basic-target.generate): Store use requirements for
generated targets.
(main-target-alternative): Process use requirements.
* new/project.jam: Support 'use-requirements' project attribute.
[SVN r15821]
This commit is contained in:
@@ -624,10 +624,17 @@ local rule select-dependency-graph ( options )
|
||||
rule construct ( project name ? : target-type multiple ? : properties * : sources +
|
||||
: allow-composing-generators ? )
|
||||
{
|
||||
local use-requirements ;
|
||||
if (.construct-stack)
|
||||
{
|
||||
ensure-type $(sources) ;
|
||||
for local e in $(sources)
|
||||
{
|
||||
use-requirements += [ $(e).use-requirements ] ;
|
||||
}
|
||||
}
|
||||
properties += $(use-requirements) ;
|
||||
properties = [ sequence.unique $(properties) ] ;
|
||||
|
||||
.construct-stack += 1 ;
|
||||
|
||||
|
||||
@@ -381,6 +381,8 @@ local rule initialize (
|
||||
: [ $(pattributes).get default-build ] ;
|
||||
$(attributes).set requirements
|
||||
: [ $(pattributes).get requirements ] : exact ;
|
||||
$(attributes).set use-requirements
|
||||
: [ $(pattributes).get use-requirements ] : exact ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,6 +432,15 @@ rule project-attributes ( location )
|
||||
self.requirements = $(result) ;
|
||||
}
|
||||
}
|
||||
else if $(attribute) = "use-requirements"
|
||||
{
|
||||
if [ property.remove free : $(specification) ]
|
||||
{
|
||||
errors.error "use-requirements" $($(real-pos2)) "have non-free properties" ;
|
||||
}
|
||||
self.use-requirements += [ property.translate-paths $(specification)
|
||||
: $(self.location) ] ;
|
||||
}
|
||||
else if $(attribute) = "source-location"
|
||||
{
|
||||
self.source-location = [ path.join $(self.location) $(specification) ] ;
|
||||
|
||||
@@ -34,6 +34,7 @@ import regex ;
|
||||
import property ;
|
||||
import errors ;
|
||||
import common ;
|
||||
import errors ;
|
||||
|
||||
|
||||
# Base class for all abstract targets.
|
||||
@@ -331,7 +332,7 @@ class main-target : abstract-target ;
|
||||
# The second variant specifies additional properties that should be used
|
||||
# when building the target.
|
||||
rule basic-target ( name : project
|
||||
: sources * : requirements * : default-build * )
|
||||
: sources * : requirements * : default-build * : use-requirements * )
|
||||
{
|
||||
import build-request ;
|
||||
import virtual-target ;
|
||||
@@ -341,6 +342,7 @@ rule basic-target ( name : project
|
||||
self.sources = $(sources) ;
|
||||
self.requirements = $(requirements) ;
|
||||
self.default-build = $(default-build) ;
|
||||
self.use-requirements = $(use-requirements) ;
|
||||
|
||||
# Applies default-build if 'properties' are empty or
|
||||
# have only single <toolset> element.
|
||||
@@ -396,9 +398,13 @@ rule basic-target ( name : project
|
||||
# Just a source file
|
||||
source-targets += [ virtual-target.from-file $(s) : $(self.project) ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.generated.$(property-path) =
|
||||
[ construct $(source-targets) : $(rproperties) ] ;
|
||||
for local e in $(self.generated.$(property-path))
|
||||
{
|
||||
$(e).set-use-requirements $(self.use-requirements) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -460,14 +466,14 @@ rule basic-target ( name : project
|
||||
|
||||
class basic-target : abstract-target ;
|
||||
|
||||
.args = 4 5 6 7 8 9 ;
|
||||
.args = 5 6 7 8 9 ;
|
||||
|
||||
# Creates a main target alternative of type 'class-name'. The ctor will be
|
||||
# passed 'target-name', 'project' and all trailing arguments.
|
||||
# If 'requirements-pos' and 'default-build-pos' are specified, the corresponding
|
||||
# trailing arguments will be specially processed.
|
||||
rule main-target-alternative ( target-name project class-name
|
||||
: requirements-pos ? : default-build-pos ?
|
||||
: requirements-pos ? : use-requirements-pos ? : default-build-pos ?
|
||||
: * )
|
||||
{
|
||||
for local i in $(.args)
|
||||
@@ -478,10 +484,22 @@ rule main-target-alternative ( target-name project class-name
|
||||
if $(requirements-pos)
|
||||
{
|
||||
local real-pos = $(.args[$(requirements-pos)]) ;
|
||||
local real-pos2 = $(.args[$(use-requirements-pos)]) ;
|
||||
local project-requirements = [ project.attribute $(project) requirements ] ;
|
||||
local project-use-requirements = [ project.attribute $(project) use-requirements ] ;
|
||||
|
||||
local loc = [ project.attribute $(project) location ] ;
|
||||
local requirements = [ property.translate-paths $($(real-pos)) : $(loc) ] ;
|
||||
local requirements =
|
||||
[ property.translate-paths $($(real-pos)) : $(loc) ] ;
|
||||
# Should have only free properties
|
||||
if [ property.remove free : $($(real-pos2)) ]
|
||||
{
|
||||
errors.error "use-requirements" $($(real-pos2)) "have non-free properties" ;
|
||||
}
|
||||
|
||||
local use-requirements =
|
||||
[ property.translate-paths $($(real-pos2)) : $(loc) ] ;
|
||||
use-requirements += $(project-use-requirements) ;
|
||||
|
||||
requirements = [ property.refine $(project-requirements) : $(requirements) ] ;
|
||||
if $(requirements[1]) = "@error"
|
||||
@@ -490,8 +508,9 @@ rule main-target-alternative ( target-name project class-name
|
||||
}
|
||||
else
|
||||
{
|
||||
a$(real-pos) = $(requirements) ;
|
||||
a$(real-pos) = $(requirements) $(use-requirements) ;
|
||||
}
|
||||
a$(real-pos2) = $(use-requirements) ;
|
||||
}
|
||||
|
||||
if $(default-build-pos)
|
||||
@@ -509,15 +528,15 @@ rule main-target-alternative ( target-name project class-name
|
||||
|
||||
$(target).add-alternative
|
||||
[ new $(class-name) $(target-name) : $(project)
|
||||
: $(a4) : $(a5) : $(a6) : $(a7) : $(a8) : $(a9) ] ;
|
||||
: $(a5) : $(a6) : $(a7) : $(a8) : $(a9) ] ;
|
||||
}
|
||||
|
||||
|
||||
rule typed-target ( name : project : type
|
||||
: sources * : requirements * : default-build * )
|
||||
: sources * : requirements * : default-build * : use-requirements * )
|
||||
{
|
||||
basic-target.__init__ $(name) : $(project)
|
||||
: $(sources) : $(requirements) : $(default-build) ;
|
||||
: $(sources) : $(requirements) : $(default-build) : $(use-requirements) ;
|
||||
|
||||
self.type = $(type) ;
|
||||
|
||||
|
||||
@@ -102,15 +102,16 @@ rule type ( suffix )
|
||||
}
|
||||
|
||||
|
||||
rule main-target-rule ( name : sources * : requirements * : default-build * )
|
||||
rule main-target-rule ( name : sources * : requirements * : default-build *
|
||||
: use-requirements * )
|
||||
{
|
||||
# First find requuired target type, which is equal to the name used to
|
||||
# invoke us.
|
||||
local bt = [ BACKTRACE 1 ] ;
|
||||
local type = $(bt[4]) ;
|
||||
|
||||
targets.main-target-alternative $(name) [ CALLER_MODULE ] typed-target : 3 : 4
|
||||
: $(type:U) : $(sources) : $(requirements) : $(default-build)
|
||||
targets.main-target-alternative $(name) [ CALLER_MODULE ] typed-target : 3 : 5 : 4
|
||||
: $(type:U) : $(sources) : $(requirements) : $(default-build) : $(use-requirements)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,18 @@ rule virtual-target ( name : type ? : project
|
||||
return $(self.root) ;
|
||||
}
|
||||
|
||||
|
||||
# Gets 'use' requirements.
|
||||
rule use-requirements ( )
|
||||
{
|
||||
return $(self.use-requirements) ;
|
||||
}
|
||||
|
||||
# Sets 'use' requirements
|
||||
rule set-use-requirements ( requirements * )
|
||||
{
|
||||
self.use-requirements = $(requirements) ;
|
||||
}
|
||||
|
||||
# Sets the dependency graph this target is part of.
|
||||
# 'dg' is an instance of 'subvariant-dg' class.
|
||||
rule dg ( dg ? )
|
||||
|
||||
@@ -39,7 +39,7 @@ rule make ( target-name : sources * : generating-rule : requirements * )
|
||||
# Default build is not specified: 'main-target-alternative' will take
|
||||
# care of it.
|
||||
targets.main-target-alternative
|
||||
$(target-name) [ CALLER_MODULE ] make-target-class : 2 : 4
|
||||
$(target-name) [ CALLER_MODULE ] make-target-class : 2 : : 4
|
||||
: $(sources) : $(requirements) : $(generating-rule) : $(default-build) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,3 +28,5 @@ import no_type
|
||||
import chain
|
||||
import default_build
|
||||
import main_properties
|
||||
import use_requirements
|
||||
|
||||
|
||||
64
test/use_requirements.py
Normal file
64
test/use_requirements.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from BoostBuild import Tester
|
||||
t = Tester()
|
||||
|
||||
# Test that use requirements on main target work
|
||||
t.write("project-root.jam", "import gcc ;")
|
||||
t.write("Jamfile", """
|
||||
lib b : b.cpp : : : <define>FOO ;
|
||||
exe a : a.cpp b ;
|
||||
""")
|
||||
t.write("b.cpp", "void foo() {}")
|
||||
t.write("a.cpp", """
|
||||
#ifdef FOO
|
||||
void foo() {}
|
||||
#endif
|
||||
int main() { foo(); }
|
||||
""")
|
||||
|
||||
t.run_build_system()
|
||||
|
||||
t.run_build_system("--clean")
|
||||
|
||||
# Test that use requirement on project work
|
||||
t.write("Jamfile", "exe a : a.cpp lib/b ;")
|
||||
t.write("lib/Jamfile", """
|
||||
project :
|
||||
use-requirements <define>FOO
|
||||
;
|
||||
lib b : b.cpp ;
|
||||
""")
|
||||
t.write("lib/b.cpp", "void foo() {}")
|
||||
t.run_build_system()
|
||||
|
||||
# Test that use requirements are inherited correctly
|
||||
|
||||
t.write("Jamfile", "exe a : a.cpp lib/1/b ;")
|
||||
|
||||
t.write("a.cpp", """
|
||||
#if defined(FOO) && defined(ZOO)
|
||||
void foo() {}
|
||||
#endif
|
||||
int main() { foo(); }
|
||||
""")
|
||||
|
||||
t.write("lib/Jamfile", """
|
||||
project :
|
||||
use-requirements <define>FOO
|
||||
;
|
||||
""")
|
||||
|
||||
t.write("lib/1/Jamfile", """
|
||||
project :
|
||||
use-requirements <define>ZOO
|
||||
;
|
||||
lib b : b.cpp ;
|
||||
""")
|
||||
t.write("lib/1/b.cpp", "void foo() {}")
|
||||
|
||||
t.run_build_system()
|
||||
|
||||
|
||||
|
||||
t.cleanup()
|
||||
Reference in New Issue
Block a user