2
0
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:
Vladimir Prus
2002-10-09 11:33:22 +00:00
parent ef5eff03d0
commit b55dc66bf3
8 changed files with 129 additions and 14 deletions

View File

@@ -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 ;

View File

@@ -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) ] ;

View File

@@ -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) ;

View File

@@ -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)
;
}

View File

@@ -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 ? )

View File

@@ -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) ;
}

View File

@@ -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
View 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()