2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 01:12:13 +00:00

Simplify project-id and target-id handling.

* new/project.jam
  (lookup) Don't support project location in front of "@".
  (lookup-with-load): Remove.
  (find): New rule.
  (find-target): move to...

* new/target.jam
  (find): Here. And simplify.


[SVN r18667]
This commit is contained in:
Vladimir Prus
2003-06-04 13:30:45 +00:00
parent f98371b844
commit ecbc945e8e
12 changed files with 182 additions and 310 deletions

View File

@@ -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 <project-id> 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

View File

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

View File

@@ -8,8 +8,6 @@ import project-roots ;
project-roots.print ;
assert.result Jamfile<project-test1/dir2> : project.lookup @/cool-library : "." ;
assert.result Jamfile<project-test1/dir2> : project.lookup project-test1@/cool-library : "." ;
assert.result Jamfile<project-test1/dir> : project.lookup project-test1@dir : "." ;
assert.result Jamfile<project-test1/dir> : project.lookup @dir : "project-test1" ;
assert.result Jamfile<project-test1> : project.lookup @ : "project-test1" ;

View File

@@ -10,7 +10,6 @@ import standalone-project ;
project-roots.print ;
assert.result Jamfile<dir2> : project.lookup @/cool-library : "." ;
assert.result Jamfile<dir> : project.lookup dir@ : "." ;
assert.result Jamfile<dir> : project.lookup @dir : "." ;
assert.result standalone-project : project.lookup @/teeest : "." ;

View File

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

View File

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

View File

@@ -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 <project-id> 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

View File

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

View File

@@ -8,8 +8,6 @@ import project-roots ;
project-roots.print ;
assert.result Jamfile<project-test1/dir2> : project.lookup @/cool-library : "." ;
assert.result Jamfile<project-test1/dir2> : project.lookup project-test1@/cool-library : "." ;
assert.result Jamfile<project-test1/dir> : project.lookup project-test1@dir : "." ;
assert.result Jamfile<project-test1/dir> : project.lookup @dir : "project-test1" ;
assert.result Jamfile<project-test1> : project.lookup @ : "project-test1" ;

View File

@@ -10,7 +10,6 @@ import standalone-project ;
project-roots.print ;
assert.result Jamfile<dir2> : project.lookup @/cool-library : "." ;
assert.result Jamfile<dir> : project.lookup dir@ : "." ;
assert.result Jamfile<dir> : project.lookup @dir : "." ;
assert.result standalone-project : project.lookup @/teeest : "." ;

View File

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

View File

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