diff --git a/v2/build-system.jam b/v2/build-system.jam index 59de52cfe..37d57614a 100755 --- a/v2/build-system.jam +++ b/v2/build-system.jam @@ -72,7 +72,7 @@ if --version in [ modules.peek : ARGV ] # We always load project in "." so that 'use-project' directives has # any chance of been seen. Otherwise, we won't be able to refer to # subprojects using target ids. -current-project = [ project.load "." ] ; +current-project = [ project.target [ project.load "." ] ] ; if [ MATCH (--dump-projects) : [ modules.peek : ARGV ] ] { diff --git a/v2/build/project.jam b/v2/build/project.jam index 0dbce3278..17ec345d5 100644 --- a/v2/build/project.jam +++ b/v2/build/project.jam @@ -305,7 +305,7 @@ rule initialize ( inherit-attributes $(module-name) : $(project-root-module) : $(parent-module) ; } - .current-project = $(module-name) ; + .current-project = [ target $(module-name) ] ; } # Make 'project-module' inherit attributes of project root and parent module. @@ -513,16 +513,6 @@ rule target ( project-module ) return $(.target.$(project-module)) ; } -# If 'path' is absolute, returns it. -# Oherwise, returns the location of 'project', joined -# with 'path' -rule path-relative-to-project-location ( path project ) -{ - local project-location = [ attribute $(project) location ] ; - return [ path.root $(path) $(project-location) ] ; -} - - # Use/load a project. rule use ( id : location ) { diff --git a/v2/build/targets.jam b/v2/build/targets.jam index ab650d497..5e3393053 100644 --- a/v2/build/targets.jam +++ b/v2/build/targets.jam @@ -78,23 +78,25 @@ import feature ; import virtual-target ; import path ; import set ; +import assert ; # Base class for all abstract targets. class abstract-target { - import project ; - + import project assert "class" ; + rule __init__ ( name # name of the target in Jamfile - : project # the project module where the target is declared + : project-target # the project target to which this one belongs ) { + assert.true class.is-a $(project-target) : project-target ; # Note: it might seem that we don't need either name or project at all. # However, there are places where we really need it. One example is error # messages which should name problematic targets. Another is setting correct # paths for sources and generated files. self.name = $(name) ; - self.project = $(project) ; + self.project = $(project-target) ; } # Returns the name of this target. @@ -112,7 +114,7 @@ class abstract-target # Returns a user-readable name for this target. rule full-name ( ) { - local location = [ project.attribute $(self.project) location ] ; + local location = [ $(self.project).get location ] ; return $(location)/$(self.name) ; } @@ -160,13 +162,27 @@ class project-target : abstract-target import sequence ; import "class" : new ; - rule __init__ ( name : project : requirements * : default-build * ) + rule __init__ ( name : project-module : requirements * : default-build * ) { - abstract-target.__init__ $(name) : $(project) ; + abstract-target.__init__ $(name) : $(__name__) ; + self.project-module = $(project-module) ; self.requirements = $(requirements) ; self.default-build = $(default-build) ; } + + # This is needed only by the 'make' rule. Need to find the + # way to make 'make' work without this method. + rule project-module ( ) + { + return $(self.project-module) ; + } + + rule get ( attribute ) + { + return [ project.attribute $(self.project-module) $(attribute) ] ; + } + # Generates all possible targets contained in this project. rule generate ( property-set * ) @@ -204,8 +220,8 @@ class project-target : abstract-target } # Collect all projects referenced via "projects-to-build" attribute. - local self-location = [ project.attribute $(self.project) location ] ; - for local pn in [ project.attribute $(self.project) projects-to-build ] + local self-location = [ get location ] ; + for local pn in [ get projects-to-build ] { local p = [ project.module-name [ path.join $(self-location) $(pn) ] ] ; result += [ project.target $(p) ] ; @@ -561,7 +577,7 @@ class file-reference : abstract-target rule exists ( ) { local location = [ path.root $(self.name) - [ project.attribute $(self.project) source-location ] ] ; + [ $(self.project).get source-location ] ] ; return [ path.exists [ path.native $(location) ] ] ; } } @@ -575,7 +591,7 @@ if "--quiet" in [ modules.peek : ARGV ] rule find ( id : project ) { - local current-location = [ project.attribute $(project) location ] ; + local current-location = [ $(project).get location ] ; local target ; local split = [ MATCH (.*)//(.*) : $(id) ] ; @@ -595,7 +611,8 @@ rule find ( id : project ) local base-project ; if $(project-part) { - base-project = [ project.find $(project-part) : $(current-location) ] ; + base-project = [ project.target + [ project.find $(project-part) : $(current-location) ] ] ; } else { @@ -618,10 +635,9 @@ rule find ( id : project ) # Interpret target-name as name of main target if ! $(target) && $(base-project) { - local project-target = [ project.target $(base-project) ] ; - if [ $(project-target).has-main-target $(target-part) ] + if [ $(base-project).has-main-target $(target-part) ] { - target = [ $(project-target).main-target $(target-part) ] ; + target = [ $(base-project).main-target $(target-part) ] ; } } @@ -1157,12 +1173,12 @@ rule main-target-requirements ( : project # Project where the main target is to be declared ) { - local loc = [ project.attribute $(project) location ] ; + local loc = [ $(project).get location ] ; local requirements = [ property.translate-paths $(specification) : $(loc) ] ; local requirements = [ property.expand-subfeatures-in-conditions $(requirements) ] ; local requirements = [ property-set.create $(requirements) ] ; - local project-requirements = [ project.attribute $(project) requirements ] ; + local project-requirements = [ $(project).get requirements ] ; requirements = [ $(project-requirements).refine $(requirements) ] ; if $(requirements[1]) = "@error" { @@ -1180,8 +1196,8 @@ rule main-target-usage-requirements ( : project # Project where the main target is to be declared ) { - local loc = [ project.attribute $(project) location ] ; - local project-usage-requirements = [ project.attribute $(project) usage-requirements ] ; + local loc = [ $(project).get location ] ; + local project-usage-requirements = [ $(project).get usage-requirements ] ; local usage-requirements = [ property-set.create [ property.translate-paths $(specification) : $(loc) ] ] ; @@ -1204,7 +1220,7 @@ rule main-target-default-build ( } else { - result = [ project.attribute $(project) default-build ] ; + result = [ $(project).get default-build ] ; } return [ property-set.create-with-validation $(result) ] ; } @@ -1213,7 +1229,7 @@ rule main-target-default-build ( # Returns 'target'. rule main-target-alternative ( target ) { - local ptarget = [ project.target [ $(target).project ] ] ; + local ptarget = [ $(target).project ] ; $(ptarget).add-alternative $(target) ; return $(target) ; diff --git a/v2/build/virtual-target.jam b/v2/build/virtual-target.jam index 2767ae3df..e614e4a11 100644 --- a/v2/build/virtual-target.jam +++ b/v2/build/virtual-target.jam @@ -387,7 +387,7 @@ class abstract-file-target : virtual-target { # File is either source, which will be searched for, or is not a file at # all. Use the location of project for distinguishing. - local project-location = [ project.attribute $(self.project) location ] ; + local project-location = [ $(self.project).get location ] ; local location-grist = [ sequence.join [ regex.split $(project-location) "/" ] : "!" ] ; @@ -476,7 +476,7 @@ class file-target : abstract-file-target { # This is a source file. SEARCH on $(target) = - [ path.native [ project.attribute $(self.project) source-location ] ] ; + [ path.native [ $(self.project).get source-location ] ] ; } } @@ -487,11 +487,11 @@ class file-target : abstract-file-target { if $(self.action) { - local build-dir = [ project.attribute $(self.project) build-dir ] ; + local build-dir = [ $(self.project).get build-dir ] ; if ! $(build-dir) { build-dir = [ path.join - [ project.attribute $(self.project) location ] + [ $(self.project).get location ] bin ] ; } diff --git a/v2/tools/make.jam b/v2/tools/make.jam index ede777d91..9411f7484 100644 --- a/v2/tools/make.jam +++ b/v2/tools/make.jam @@ -45,17 +45,18 @@ rule make ( target-name : sources * : generating-rule + : requirements * : caller ? ) { caller ?= [ project.current ] ; - local rules = [ RULENAMES $(caller) ] ; + caller-module = [ $(caller).project-module ] ; + local rules = [ RULENAMES $(caller-module) ] ; if $(generating-rule[1]) in $(rules) { # This is local rule, make it global - local n = $(caller).$(generating-rule[1]) ; - IMPORT $(caller) : $(generating-rule[1]) : : $(n) ; + local n = $(caller-module).$(generating-rule[1]) ; + IMPORT $(caller-module) : $(generating-rule[1]) : : $(n) ; generating-rule = $(n) $(generating-rule[2-]) ; } targets.main-target-alternative - [ new make-target-class $(target-name) : $(caller) + [ new make-target-class $(target-name) : $(caller) : [ targets.main-target-sources $(sources) : $(target-name) ] : [ targets.main-target-requirements $(requirements) : $(caller) ] : $(generating-rule) diff --git a/v2/tools/stage.jam b/v2/tools/stage.jam index b5f5e2fc5..f0fb6f1f8 100644 --- a/v2/tools/stage.jam +++ b/v2/tools/stage.jam @@ -63,7 +63,7 @@ feature.feature : : free incidental ; class stage-target-class : basic-target { - import feature project type errors generators ; + import feature project type errors generators path ; import "class" : new ; rule __init__ ( name-and-dir : project : sources * : requirements * : default-build * ) @@ -78,8 +78,7 @@ class stage-target-class : basic-target local loc = [ $(property-set).get ] ; if ! $(loc) { - loc = [ project.path-relative-to-project-location $(self.name) - $(self.project) ] ; + loc = [ path.root $(self.name) [ $(self.project).get location ] ] ; property-set = [ $(property-set).add-raw $(loc:G=) ] ; } diff --git a/v2/tools/symlink.jam b/v2/tools/symlink.jam index c48c86aa8..41daaee16 100644 --- a/v2/tools/symlink.jam +++ b/v2/tools/symlink.jam @@ -16,7 +16,7 @@ feature.feature symlink-location : project-relative build-relative : incidental # class symlink-targets : basic-target { - import numbers modules class property project ; + import numbers modules class property project path ; rule __init__ ( project @@ -64,8 +64,7 @@ class symlink-targets : basic-target # location, instead of placing it in the build directory. if [ property.select : [ $(property-set).raw ] ] = project-relative { - $(vt).set-path [ project.path-relative-to-project-location - $(s:D) $(self.project) ] ; + $(vt).set-path [ path.root $(s:D) [ $(self.project).get location ] ] ; } self.virtual-targets += $(vt) ; diff --git a/v2/tools/testing.jam b/v2/tools/testing.jam index c8cb2c7a0..e0e4cbeb2 100644 --- a/v2/tools/testing.jam +++ b/v2/tools/testing.jam @@ -161,6 +161,10 @@ rule dump-test ( target ) { local type = [ $(target).type ] ; local name = [ $(target).name ] ; + local project = [ $(target).project ] ; + local project-root = [ project.attribute $(project) project-root-module ] ; + local project-root-location = [ $(project-root).location ] ; + local sources = [ $(target).sources ] ; local source-files ; for local s in $(sources) @@ -170,7 +174,7 @@ rule dump-test ( target ) source-files += [ path.relative [ path.root [ $(s).location ] [ path.pwd ] ] - /home/ghost/Work/boost ] ; + $(project-root-location) ] ; } }