diff --git a/new/project.jam b/new/project.jam index 0797839f6..95c2e3820 100644 --- a/new/project.jam +++ b/new/project.jam @@ -46,6 +46,7 @@ import project-roots ; import print ; import class : class new ; import errors ; +import assert ; import property-set ; # @@ -64,7 +65,6 @@ rule load ( jamfile-location ) if ! $(jamfile-location) in $(.project-locations) { .project-locations += $(jamfile-location) ; - load-jamfile $(jamfile-location) ; @@ -97,102 +97,74 @@ rule act-as-jamfile ( module : location ) # Returns the project module, given its id. -# Projects can be referred using path@project-id notation. In it, 'path' -# selects jamfile location relatively to 'current-location' and 'project-id' -# names project relatively to the selected jamfile. -# Rooted 'project-id' is possible: -# "@/boost" will refer to the top-level project called "boost". -# +# Projects can be referred using @project-id notation. +# Where is a path. When this path is not absolute, it's relative +# to the project in 'current-location'. rule lookup ( id : current-location ) { - local split = [ MATCH (.*)@(.*) : $(id) ] ; - local location = $(split[1]) ; - # A jam quirk: if there's no part before "@", 'location' will be empty - # string, and ?= won't change it. - if $(location) + local split = [ MATCH ^(@)(.*) : $(id) ] ; + if ! $(split) { - location = - [ path.root $(location) $(current-location) ] ; + error "Project id '$(id)' is invalid" ; } - else - { - location = $(current-location) ; - } - + local project-id = $(split[2]) ; + + local location = $(current-location) ; if [ path.is-rooted $(project-id) ] { return $($(project-id).jamfile-module) ; } - else + else { - if ! $(location) + # Find the project module for this location + assert.in $(location) : $(.project-locations) ; + local module-name = [ module-name $(location) ] ; + + if ! $(project-id) { - error Jamfile location must be specified for relative project-id $(id) ; + return $(module-name) ; } - - if $(location) in $(.project-locations) + else { - local module-name = [ module-name $(location) ] ; - - if $(module-name) - { - if ! $(project-id) - { - return $(module-name) ; - } - else - { - local base-id = [ attribute $(module-name) id ] ; - - if ! $(base-id) - { - error "Project in $(location) has no project id" ; - } - else - { - local rooted-id = $(base-id)/$(project-id) ; - return $($(rooted-id).jamfile-module) ; - } - } + local base-id = [ attribute $(module-name) id ] ; + + if ! $(base-id) + { + error "Project in $(location) has no project id" ; } + else + { + local rooted-id = $(base-id)/$(project-id) ; + return $($(rooted-id).jamfile-module) ; + } } } } -# Returns a project module given its id. If target cannot be -# found, loads the project at project at location specified by -# target-id and tries again. -rule lookup-with-load ( id : current-location ) +# Given 'name' which can be project-id or plain directory name, +# return project module corresponding to that id or directory. +# Returns nothing of project is not found. +rule find ( name : current-location ) { - local project-module = [ lookup $(id) : $(current-location) ] ; - if ! $(project-module) + local project-module ; + if [ MATCH (@) : $(name) ] + { + project-module = [ lookup $(name) : $(current-location) ] ; + } + else { - # Try to load the project at the specified location - location = [ MATCH (.*)@(.*) : $(id) ] ; - if ! $(location) - { - location = "." ; - } - location = [ path.root $(location[1]) $(current-location) ] ; + local location = [ path.root $(name) $(current-location) ] ; if [ find-jamfile $(location) ] { - load $(location) ; - # If there's project-id relative to the 'location' the - # jamfile at 'location' should made those available somehow. - project-module = [ lookup $(id) : $(current-location) ] ; - } - else - { - location = ; - } + project-module = [ load $(location) ] ; + } } return $(project-module) ; } - # Helper for 'find-target' local rule remove-trailing-slash ( string ) { @@ -201,81 +173,6 @@ local rule remove-trailing-slash ( string ) return $(stripped) ; } -# Given an 'id' for a target, return an instance of 'abstract-target' that -# corresponds to it. If there's no such target, returns empty string. -# The project referred to by id is loaded if it is not already loaded. -rule find-target ( id : current-location ) -{ - # Find the project first - local project-id ; - local target-id ; - local explicit ; - if [ MATCH (.*)@(.*) : $(id) ] - { - explicit = 1 ; - # Take the last "/" separated component after "@" as target id. - local split = [ MATCH (.*@(.*/)*)([^/]*) : $(id) ] ; - project-id = [ remove-trailing-slash $(split[1]) ] ; - target-id = $(split[3]) ; - } - else - { - # This is not @-id. Treat it as path -- the last "/" separated component - # is target id, everything else denote project location. - local split = [ MATCH ((.*/)*)([^/]*) : $(id) ] ; - if $(split[1]) - { - project-id = [ remove-trailing-slash $(split[1]) ] ; - project-id = $(project-id)@ ; - } - else - { - project-id = @ ; - } - target-id = $(split[3]) ; - } - - # Handle the case where id refers to a project. We just try to - # pass it through lookup-with-load and if it succedes, we return - # the project. - - local project-module ; - if [ MATCH (@) : $(id) ] - { - project-module = [ lookup-with-load $(id) : $(current-location) ] ; - } - else - { - # When id has no "@" and we're looking for a project, treat id - # as path. - project-module = [ lookup-with-load $(id)@ : $(current-location) ] ; - } - - if $(project-module) - { - return [ project.target $(project-module) ] ; - } - else - { - # Now treat 'id' as referring to a main target - project-module = [ lookup-with-load $(project-id) : $(current-location) ] ; - - if $(project-module) { - local project-target = [ project.target $(project-module) ] ; - if [ $(project-target).has-main-target $(target-id) ] - { - return [ $(project-target).main-target $(target-id) ] ; - } - } - else if $(explicit) - { - errors.error - The target id \"$(id)\", specified by project at \"$(current-location)\" - is invalid (missing 'use-project'?) ; - } - } -} - # # Returns the name of module corresponding to 'jamfile-location'. # If no module corresponds to location yet, associates default diff --git a/new/targets.jam b/new/targets.jam index 64f666bd6..edf948887 100644 --- a/new/targets.jam +++ b/new/targets.jam @@ -403,6 +403,48 @@ rule main-target ( name : project ) class main-target : abstract-target ; +# Given an 'id' for a target, return an instance of 'abstract-target' that +# corresponds to it. If there's no such target, returns empty string. +# The project referred to by id is loaded if it is not already loaded. +rule find ( id : current-location ) +{ + local target ; + # Find if this is project + local project-module = [ find $(id) : $(current-location) ] ; + if $(project-module) + { + target = [ project.target $(project-module) ] ; + } + else + { + # Split 'id' into project and target. + + local split = [ MATCH ((@?)(.*/)*)([^/]*) : $(id) ] ; + local project-name = [ remove-trailing-slash $(split[1]) ] ; + local has-project-id = $(split[2]) ; + local target-name = $(split[4]) ; + + local project-module = [ find $(project-name) : $(current-location) ] ; + + if $(project-module) { + local project-target = [ project.target $(project-module) ] ; + if [ $(project-target).has-main-target $(target-name) ] + { + target = [ $(project-target).main-target $(target-name) ] ; + } + } + else if $(has-project-id) + { + # This error checking should be moved somewhere. + errors.error + The target id \"$(id)\", specified by project at \"$(current-location)\" + is invalid (missing 'use-project'?) ; + } + } + return $(target) ; +} + + # Attempts to generate the target given by target # reference. Either returns all the virtual targets # generated (possible none), or string "@main target not found" @@ -424,7 +466,7 @@ rule generate ( target-reference # Target reference # Check if such target exists local main-target = - [ project.find-target $(id) : [ project.attribute $(project) location ] ] ; + [ find $(id) : [ project.attribute $(project) location ] ] ; if $(main-target) { # Take properties which should be propagated and refine them @@ -461,10 +503,10 @@ rule generate-dependencies ( property-set : project : generation-ps ) for local p in [ $(property-set).dependency ] { local g = [ targets.generate $(p:TG=) : $(project) : $(generation-ps) ] ; - if ! $(g) - { - errors.error "cannot generate dependency " $(p) ; - } + #if ! $(g) + #{ + # errors.error "cannot generate dependency " $(p) ; + #} xproperties += $(p:G)$(g) ; } local r = [ property-set.create @@ -594,7 +636,7 @@ rule basic-target ( name : project for local e in $(targets-or-properties) { result += [ $(e:G=).usage-requirements ] ; - } + } return $(result) ; } diff --git a/test/project-test1.jam b/test/project-test1.jam index 4e743eee3..80f93f5dd 100644 --- a/test/project-test1.jam +++ b/test/project-test1.jam @@ -8,8 +8,6 @@ import project-roots ; project-roots.print ; assert.result Jamfile : project.lookup @/cool-library : "." ; -assert.result Jamfile : project.lookup project-test1@/cool-library : "." ; -assert.result Jamfile : project.lookup project-test1@dir : "." ; assert.result Jamfile : project.lookup @dir : "project-test1" ; assert.result Jamfile : project.lookup @ : "project-test1" ; diff --git a/test/project-test1/project-test1.jam b/test/project-test1/project-test1.jam index b3bba402c..e6fcd5ae9 100644 --- a/test/project-test1/project-test1.jam +++ b/test/project-test1/project-test1.jam @@ -10,7 +10,6 @@ import standalone-project ; project-roots.print ; assert.result Jamfile : project.lookup @/cool-library : "." ; -assert.result Jamfile : project.lookup dir@ : "." ; assert.result Jamfile : project.lookup @dir : "." ; assert.result standalone-project : project.lookup @/teeest : "." ; diff --git a/test/project-test3/Jamfile b/test/project-test3/Jamfile index d11250e7f..ae581e783 100644 --- a/test/project-test3/Jamfile +++ b/test/project-test3/Jamfile @@ -2,7 +2,7 @@ use-project /lib2 : lib2 ; use-project /lib3 : lib3 ; -make a.exe : a.obj lib/b.obj @/lib2/c.obj lib2@d.obj lib2@helper/e.obj @/lib3/f.obj : yfc-link ; +make a.exe : a.obj lib/b.obj @/lib2/c.obj lib2/d.obj lib2/helper/e.obj @/lib3/f.obj : yfc-link ; make a.obj : a.cpp : yfc-compile ; build-project lib2 ; diff --git a/test/project_test3.py b/test/project_test3.py index f891377b6..fd52663d3 100644 --- a/test/project_test3.py +++ b/test/project_test3.py @@ -110,7 +110,7 @@ t.run_build_system("clean lib/b.obj") t.expect_removal("lib/bin/$toolset/debug/b.obj") t.expect_nothing_more() -t.run_build_system("release lib2@helper/e.obj @/lib3/f.obj") +t.run_build_system("release lib2/helper/e.obj @/lib3/f.obj") t.expect_addition("lib2/helper/bin/$toolset/release/e.obj") t.expect_addition("lib3/bin/$toolset/release/f.obj") t.expect_nothing_more() diff --git a/v2/build/project.jam b/v2/build/project.jam index 0797839f6..95c2e3820 100644 --- a/v2/build/project.jam +++ b/v2/build/project.jam @@ -46,6 +46,7 @@ import project-roots ; import print ; import class : class new ; import errors ; +import assert ; import property-set ; # @@ -64,7 +65,6 @@ rule load ( jamfile-location ) if ! $(jamfile-location) in $(.project-locations) { .project-locations += $(jamfile-location) ; - load-jamfile $(jamfile-location) ; @@ -97,102 +97,74 @@ rule act-as-jamfile ( module : location ) # Returns the project module, given its id. -# Projects can be referred using path@project-id notation. In it, 'path' -# selects jamfile location relatively to 'current-location' and 'project-id' -# names project relatively to the selected jamfile. -# Rooted 'project-id' is possible: -# "@/boost" will refer to the top-level project called "boost". -# +# Projects can be referred using @project-id notation. +# Where is a path. When this path is not absolute, it's relative +# to the project in 'current-location'. rule lookup ( id : current-location ) { - local split = [ MATCH (.*)@(.*) : $(id) ] ; - local location = $(split[1]) ; - # A jam quirk: if there's no part before "@", 'location' will be empty - # string, and ?= won't change it. - if $(location) + local split = [ MATCH ^(@)(.*) : $(id) ] ; + if ! $(split) { - location = - [ path.root $(location) $(current-location) ] ; + error "Project id '$(id)' is invalid" ; } - else - { - location = $(current-location) ; - } - + local project-id = $(split[2]) ; + + local location = $(current-location) ; if [ path.is-rooted $(project-id) ] { return $($(project-id).jamfile-module) ; } - else + else { - if ! $(location) + # Find the project module for this location + assert.in $(location) : $(.project-locations) ; + local module-name = [ module-name $(location) ] ; + + if ! $(project-id) { - error Jamfile location must be specified for relative project-id $(id) ; + return $(module-name) ; } - - if $(location) in $(.project-locations) + else { - local module-name = [ module-name $(location) ] ; - - if $(module-name) - { - if ! $(project-id) - { - return $(module-name) ; - } - else - { - local base-id = [ attribute $(module-name) id ] ; - - if ! $(base-id) - { - error "Project in $(location) has no project id" ; - } - else - { - local rooted-id = $(base-id)/$(project-id) ; - return $($(rooted-id).jamfile-module) ; - } - } + local base-id = [ attribute $(module-name) id ] ; + + if ! $(base-id) + { + error "Project in $(location) has no project id" ; } + else + { + local rooted-id = $(base-id)/$(project-id) ; + return $($(rooted-id).jamfile-module) ; + } } } } -# Returns a project module given its id. If target cannot be -# found, loads the project at project at location specified by -# target-id and tries again. -rule lookup-with-load ( id : current-location ) +# Given 'name' which can be project-id or plain directory name, +# return project module corresponding to that id or directory. +# Returns nothing of project is not found. +rule find ( name : current-location ) { - local project-module = [ lookup $(id) : $(current-location) ] ; - if ! $(project-module) + local project-module ; + if [ MATCH (@) : $(name) ] + { + project-module = [ lookup $(name) : $(current-location) ] ; + } + else { - # Try to load the project at the specified location - location = [ MATCH (.*)@(.*) : $(id) ] ; - if ! $(location) - { - location = "." ; - } - location = [ path.root $(location[1]) $(current-location) ] ; + local location = [ path.root $(name) $(current-location) ] ; if [ find-jamfile $(location) ] { - load $(location) ; - # If there's project-id relative to the 'location' the - # jamfile at 'location' should made those available somehow. - project-module = [ lookup $(id) : $(current-location) ] ; - } - else - { - location = ; - } + project-module = [ load $(location) ] ; + } } return $(project-module) ; } - # Helper for 'find-target' local rule remove-trailing-slash ( string ) { @@ -201,81 +173,6 @@ local rule remove-trailing-slash ( string ) return $(stripped) ; } -# Given an 'id' for a target, return an instance of 'abstract-target' that -# corresponds to it. If there's no such target, returns empty string. -# The project referred to by id is loaded if it is not already loaded. -rule find-target ( id : current-location ) -{ - # Find the project first - local project-id ; - local target-id ; - local explicit ; - if [ MATCH (.*)@(.*) : $(id) ] - { - explicit = 1 ; - # Take the last "/" separated component after "@" as target id. - local split = [ MATCH (.*@(.*/)*)([^/]*) : $(id) ] ; - project-id = [ remove-trailing-slash $(split[1]) ] ; - target-id = $(split[3]) ; - } - else - { - # This is not @-id. Treat it as path -- the last "/" separated component - # is target id, everything else denote project location. - local split = [ MATCH ((.*/)*)([^/]*) : $(id) ] ; - if $(split[1]) - { - project-id = [ remove-trailing-slash $(split[1]) ] ; - project-id = $(project-id)@ ; - } - else - { - project-id = @ ; - } - target-id = $(split[3]) ; - } - - # Handle the case where id refers to a project. We just try to - # pass it through lookup-with-load and if it succedes, we return - # the project. - - local project-module ; - if [ MATCH (@) : $(id) ] - { - project-module = [ lookup-with-load $(id) : $(current-location) ] ; - } - else - { - # When id has no "@" and we're looking for a project, treat id - # as path. - project-module = [ lookup-with-load $(id)@ : $(current-location) ] ; - } - - if $(project-module) - { - return [ project.target $(project-module) ] ; - } - else - { - # Now treat 'id' as referring to a main target - project-module = [ lookup-with-load $(project-id) : $(current-location) ] ; - - if $(project-module) { - local project-target = [ project.target $(project-module) ] ; - if [ $(project-target).has-main-target $(target-id) ] - { - return [ $(project-target).main-target $(target-id) ] ; - } - } - else if $(explicit) - { - errors.error - The target id \"$(id)\", specified by project at \"$(current-location)\" - is invalid (missing 'use-project'?) ; - } - } -} - # # Returns the name of module corresponding to 'jamfile-location'. # If no module corresponds to location yet, associates default diff --git a/v2/build/targets.jam b/v2/build/targets.jam index 64f666bd6..edf948887 100644 --- a/v2/build/targets.jam +++ b/v2/build/targets.jam @@ -403,6 +403,48 @@ rule main-target ( name : project ) class main-target : abstract-target ; +# Given an 'id' for a target, return an instance of 'abstract-target' that +# corresponds to it. If there's no such target, returns empty string. +# The project referred to by id is loaded if it is not already loaded. +rule find ( id : current-location ) +{ + local target ; + # Find if this is project + local project-module = [ find $(id) : $(current-location) ] ; + if $(project-module) + { + target = [ project.target $(project-module) ] ; + } + else + { + # Split 'id' into project and target. + + local split = [ MATCH ((@?)(.*/)*)([^/]*) : $(id) ] ; + local project-name = [ remove-trailing-slash $(split[1]) ] ; + local has-project-id = $(split[2]) ; + local target-name = $(split[4]) ; + + local project-module = [ find $(project-name) : $(current-location) ] ; + + if $(project-module) { + local project-target = [ project.target $(project-module) ] ; + if [ $(project-target).has-main-target $(target-name) ] + { + target = [ $(project-target).main-target $(target-name) ] ; + } + } + else if $(has-project-id) + { + # This error checking should be moved somewhere. + errors.error + The target id \"$(id)\", specified by project at \"$(current-location)\" + is invalid (missing 'use-project'?) ; + } + } + return $(target) ; +} + + # Attempts to generate the target given by target # reference. Either returns all the virtual targets # generated (possible none), or string "@main target not found" @@ -424,7 +466,7 @@ rule generate ( target-reference # Target reference # Check if such target exists local main-target = - [ project.find-target $(id) : [ project.attribute $(project) location ] ] ; + [ find $(id) : [ project.attribute $(project) location ] ] ; if $(main-target) { # Take properties which should be propagated and refine them @@ -461,10 +503,10 @@ rule generate-dependencies ( property-set : project : generation-ps ) for local p in [ $(property-set).dependency ] { local g = [ targets.generate $(p:TG=) : $(project) : $(generation-ps) ] ; - if ! $(g) - { - errors.error "cannot generate dependency " $(p) ; - } + #if ! $(g) + #{ + # errors.error "cannot generate dependency " $(p) ; + #} xproperties += $(p:G)$(g) ; } local r = [ property-set.create @@ -594,7 +636,7 @@ rule basic-target ( name : project for local e in $(targets-or-properties) { result += [ $(e:G=).usage-requirements ] ; - } + } return $(result) ; } diff --git a/v2/test/project-test1.jam b/v2/test/project-test1.jam index 4e743eee3..80f93f5dd 100644 --- a/v2/test/project-test1.jam +++ b/v2/test/project-test1.jam @@ -8,8 +8,6 @@ import project-roots ; project-roots.print ; assert.result Jamfile : project.lookup @/cool-library : "." ; -assert.result Jamfile : project.lookup project-test1@/cool-library : "." ; -assert.result Jamfile : project.lookup project-test1@dir : "." ; assert.result Jamfile : project.lookup @dir : "project-test1" ; assert.result Jamfile : project.lookup @ : "project-test1" ; diff --git a/v2/test/project-test1/project-test1.jam b/v2/test/project-test1/project-test1.jam index b3bba402c..e6fcd5ae9 100644 --- a/v2/test/project-test1/project-test1.jam +++ b/v2/test/project-test1/project-test1.jam @@ -10,7 +10,6 @@ import standalone-project ; project-roots.print ; assert.result Jamfile : project.lookup @/cool-library : "." ; -assert.result Jamfile : project.lookup dir@ : "." ; assert.result Jamfile : project.lookup @dir : "." ; assert.result standalone-project : project.lookup @/teeest : "." ; diff --git a/v2/test/project-test3/Jamfile b/v2/test/project-test3/Jamfile index d11250e7f..ae581e783 100644 --- a/v2/test/project-test3/Jamfile +++ b/v2/test/project-test3/Jamfile @@ -2,7 +2,7 @@ use-project /lib2 : lib2 ; use-project /lib3 : lib3 ; -make a.exe : a.obj lib/b.obj @/lib2/c.obj lib2@d.obj lib2@helper/e.obj @/lib3/f.obj : yfc-link ; +make a.exe : a.obj lib/b.obj @/lib2/c.obj lib2/d.obj lib2/helper/e.obj @/lib3/f.obj : yfc-link ; make a.obj : a.cpp : yfc-compile ; build-project lib2 ; diff --git a/v2/test/project_test3.py b/v2/test/project_test3.py index f891377b6..fd52663d3 100644 --- a/v2/test/project_test3.py +++ b/v2/test/project_test3.py @@ -110,7 +110,7 @@ t.run_build_system("clean lib/b.obj") t.expect_removal("lib/bin/$toolset/debug/b.obj") t.expect_nothing_more() -t.run_build_system("release lib2@helper/e.obj @/lib3/f.obj") +t.run_build_system("release lib2/helper/e.obj @/lib3/f.obj") t.expect_addition("lib2/helper/bin/$toolset/release/e.obj") t.expect_addition("lib3/bin/$toolset/release/f.obj") t.expect_nothing_more()