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

Allow to specify target ids in command line.

* project.jam (lookup-with-load): New rule.
      (find-target): Try interperting target id as project first.

    * build-request.jam (from-command-line): Don't grab
      unconditionally elements which have slashes -- they may be target
      ids.

    * build-system.jam: Allow target ids is command
      line. Accept --clean option.

    * BoostBuild.py (run_build_system): Call 'ignore_directoies' on diff.

    * tree.py (Trees_different.ignore_directoies): New method.


[SVN r15768]
This commit is contained in:
Vladimir Prus
2002-10-07 13:18:27 +00:00
parent 742e30850e
commit 4b5d5cc6e4
11 changed files with 268 additions and 75 deletions

View File

@@ -139,11 +139,11 @@ rule from-command-line ( command-line * : feature-space ? )
{
if ! [ MATCH "^(-).*" : $(e) ]
{
# Build request spec either contains slashes, or has "=" in it,
# or is the name of an implicit property.
# Build request spec either has "=" in it, or completely
# consists of implicit feature values.
local fs = feature-space ;
if [ MATCH "(.*/.*)" : $(e) ] || [ MATCH "(.*=.*)" : $(e) ] ||
[ $(feature-space).is-implicit-value $(e) ]
if [ MATCH "(.*=.*)" : $(e) ]
|| [ $(feature-space).is-implicit-value $(e:D=) ]
{
properties += [ convert-command-line-element $(e) : $(feature-space) ] ;
}

View File

@@ -22,7 +22,6 @@ if [ MATCH (--dump-projects) : [ modules.peek : ARGV ] ]
build-request = [ build-request.from-command-line [ modules.peek : ARGV ] ] ;
targets = [ $(build-request).get-at 1 ] ;
properties = [ $(build-request).get-at 2 ] ;
# For the time being, just stick toolset to the build request. We'd need to
# find a way to select default toolset collection and a method to override
@@ -30,24 +29,67 @@ properties = [ $(build-request).get-at 2 ] ;
expanded = [ build-request.expand $(properties) <toolset>gcc ] ;
root-target = [ project.target "." ] ;
local target-ids = [ $(build-request).get-at 1 ] ;
local targets
local clean ;
if "--clean" in [ modules.peek : ARGV ]
{
clean = true ;
}
for local id in $(target-ids)
{
if $(id) = clean
{
clean = true ;
}
else
{
local t = [ project.find-target $(id) : "." ] ;
if ! $(t)
{
print.wrapped-text "error: target" $(id) "does not exist" ;
EXIT ;
}
else
{
targets += $(t) ;
}
}
}
if ! $(targets)
{
targets += [ project.target "." ] ;
}
virtual-targets = ;
if $(expanded)
{
for local p in $(expanded)
{
$(root-target).direct-build-request [ feature.split $(p) ] ;
for local t in $(targets)
{
$(t).direct-build-request [ feature.split $(p) ] ;
}
}
for local p in $(expanded)
{
virtual-targets += [ $(root-target).generate [ feature.split $(p) ] ] ;
for local t in $(targets)
{
virtual-targets += [ $(t).generate [ feature.split $(p) ] ] ;
}
}
}
else
{
virtual-targets = [ $(root-target).generate ] ;
for local t in $(targets)
{
virtual-targets += [ $(t).generate ] ;
}
}
@@ -59,7 +101,14 @@ for t in $(virtual-targets)
NOTFILE all ;
DEPENDS all : $(actual-targets) ;
# If there are any targets in the command line, cause them to be updated
UPDATE $(targets) ;
if $(clean)
{
UPDATE clean ;
}
else
{
UPDATE all ;
}

View File

@@ -107,6 +107,33 @@ rule lookup ( id : current-location )
}
}
# Agressively tries to lookup target: if it's not found, loads
# project at location specified by target-id and tries again
rule lookup-with-load ( id : current-location )
{
local location = [ lookup $(id) : $(current-location) ] ;
if ! $(location)
{
# Try to load the project at the specified location
location = [ MATCH (.*)@(.*) : $(project-id) ] ;
location = [ path.root $(location[1]) $(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.
location = [ lookup $(id) : $(current-location) ] ;
}
else
{
location = ;
}
}
return $(location) ;
}
# Helper for 'find-target'
local rule remove-trailing-slash ( string )
{
@@ -120,8 +147,8 @@ local rule remove-trailing-slash ( string )
}
}
# Given an 'id' for a target, return an instance of 'main-target' that
# corresponds to it. If there's no such main-target, returns empty string.
# 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 )
{
@@ -154,38 +181,46 @@ rule find-target ( id : current-location )
target-id = $(split[3]) ;
}
local location = [ lookup $(project-id) : $(current-location) ] ;
if ! $(location)
# First check if there's a project with such id. In that case, we'll
# return project target for it.
local location ;
if [ MATCH (@) : $(id) ]
{
# Try to load the project at the specified location
location = [ MATCH (.*)@(.*) : $(project-id) ] ;
if [ find-jamfile $(location[1]) ]
{
load $(location[1]) ;
# If there's project-id relative to the 'location' the
# jamfile at 'location' should made those available somehow.
location = [ lookup $(project-id) : $(current-location) ] ;
}
else
{
location = ;
}
location = [ lookup-with-load $(id)
: $(current-location) ] ;
}
else
{
# When id has no "@" and we're looking for a project, treat id
# as path.
location = [ lookup-with-load $(id)@ : $(current-location) ] ;
}
if $(location) {
local project-target = [ project.target $(location) ] ;
if [ $(project-target).has-main-target $(target-id) ]
{
return [ $(project-target).main-target $(target-id) ] ;
}
}
else if $(explicit)
if $(location)
{
print.wrapped-text
"The target id" $(id) " specified by project at" $(current-location)
"is invalid" ;
EXIT ;
return [ project.target $(location) ] ;
}
else
{
# Now treat 'id' as referring to a main target
location = [ lookup-with-load $(project-id) : $(current-location) ] ;
if $(location) {
local project-target = [ project.target $(location) ] ;
if [ $(project-target).has-main-target $(target-id) ]
{
return [ $(project-target).main-target $(target-id) ] ;
}
}
else if $(explicit)
{
print.wrapped-text
"The target id" $(id) " specified by project at" $(current-location)
"is invalid" ;
EXIT ;
}
}
}
#

View File

@@ -179,6 +179,7 @@ class Tester(TestCmd.TestCmd):
self.tree = build_tree(self.workdir)
self.difference = trees_difference(self.previous_tree, self.tree)
self.difference.ignore_directories()
self.unexpected_difference = copy.deepcopy(self.difference)
self.last_build_time = time.time()

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python
from BoostBuild import Tester
from BoostBuild import Tester, List
import os
from string import strip
@@ -101,4 +101,30 @@ t.expect_removal(["bin/gcc/debug/a.obj",
"lib3/bin/gcc/debug/f.obj",
])
# Now test target ids in command line
t.set_tree("project-test3")
t.run_build_system("lib/b.obj")
t.expect_addition("lib/bin/gcc/debug/b.obj")
t.expect_nothing_more()
t.run_build_system("clean lib/b.obj")
t.expect_removal("lib/bin/gcc/debug/b.obj")
t.expect_nothing_more()
t.run_build_system("release lib2@helper/e.obj @/lib3/f.obj")
t.expect_addition("lib2/helper/bin/gcc/release/e.obj")
t.expect_addition("lib3/bin/gcc/release/f.obj")
t.expect_nothing_more()
# Test project ids in command line work as well
t.set_tree("project-test3")
t.run_build_system("@/lib2")
t.expect_addition("lib2/bin/gcc/debug/" * List("c.obj d.obj l.exe"))
t.expect_addition("bin/gcc/debug/a.obj")
t.expect_nothing_more()
t.run_build_system("lib")
t.expect_addition("lib/bin/gcc/debug/" * List("b.obj m.exe"))
t.expect_nothing_more()
t.cleanup()

View File

@@ -21,6 +21,16 @@ class Trees_difference:
self.removed_files.extend(other.removed_files)
self.modified_files.extend(other.modified_files)
self.touched_files.extend(other.touched_files)
def ignore_directories(self):
"Removes directories for list of found differences"
def not_dir(x):
return x[-1] != "/"
self.added_files = filter(not_dir, self.added_files)
self.removed_files = filter(not_dir, self.removed_files)
self.modified_files = filter(not_dir, self.modified_files)
self.touched_files = filter(not_dir, self.touched_files)
def pprint(self):
print "Added files :", self.added_files

View File

@@ -139,11 +139,11 @@ rule from-command-line ( command-line * : feature-space ? )
{
if ! [ MATCH "^(-).*" : $(e) ]
{
# Build request spec either contains slashes, or has "=" in it,
# or is the name of an implicit property.
# Build request spec either has "=" in it, or completely
# consists of implicit feature values.
local fs = feature-space ;
if [ MATCH "(.*/.*)" : $(e) ] || [ MATCH "(.*=.*)" : $(e) ] ||
[ $(feature-space).is-implicit-value $(e) ]
if [ MATCH "(.*=.*)" : $(e) ]
|| [ $(feature-space).is-implicit-value $(e:D=) ]
{
properties += [ convert-command-line-element $(e) : $(feature-space) ] ;
}

View File

@@ -107,6 +107,33 @@ rule lookup ( id : current-location )
}
}
# Agressively tries to lookup target: if it's not found, loads
# project at location specified by target-id and tries again
rule lookup-with-load ( id : current-location )
{
local location = [ lookup $(id) : $(current-location) ] ;
if ! $(location)
{
# Try to load the project at the specified location
location = [ MATCH (.*)@(.*) : $(project-id) ] ;
location = [ path.root $(location[1]) $(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.
location = [ lookup $(id) : $(current-location) ] ;
}
else
{
location = ;
}
}
return $(location) ;
}
# Helper for 'find-target'
local rule remove-trailing-slash ( string )
{
@@ -120,8 +147,8 @@ local rule remove-trailing-slash ( string )
}
}
# Given an 'id' for a target, return an instance of 'main-target' that
# corresponds to it. If there's no such main-target, returns empty string.
# 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 )
{
@@ -154,38 +181,46 @@ rule find-target ( id : current-location )
target-id = $(split[3]) ;
}
local location = [ lookup $(project-id) : $(current-location) ] ;
if ! $(location)
# First check if there's a project with such id. In that case, we'll
# return project target for it.
local location ;
if [ MATCH (@) : $(id) ]
{
# Try to load the project at the specified location
location = [ MATCH (.*)@(.*) : $(project-id) ] ;
if [ find-jamfile $(location[1]) ]
{
load $(location[1]) ;
# If there's project-id relative to the 'location' the
# jamfile at 'location' should made those available somehow.
location = [ lookup $(project-id) : $(current-location) ] ;
}
else
{
location = ;
}
location = [ lookup-with-load $(id)
: $(current-location) ] ;
}
else
{
# When id has no "@" and we're looking for a project, treat id
# as path.
location = [ lookup-with-load $(id)@ : $(current-location) ] ;
}
if $(location) {
local project-target = [ project.target $(location) ] ;
if [ $(project-target).has-main-target $(target-id) ]
{
return [ $(project-target).main-target $(target-id) ] ;
}
}
else if $(explicit)
if $(location)
{
print.wrapped-text
"The target id" $(id) " specified by project at" $(current-location)
"is invalid" ;
EXIT ;
return [ project.target $(location) ] ;
}
else
{
# Now treat 'id' as referring to a main target
location = [ lookup-with-load $(project-id) : $(current-location) ] ;
if $(location) {
local project-target = [ project.target $(location) ] ;
if [ $(project-target).has-main-target $(target-id) ]
{
return [ $(project-target).main-target $(target-id) ] ;
}
}
else if $(explicit)
{
print.wrapped-text
"The target id" $(id) " specified by project at" $(current-location)
"is invalid" ;
EXIT ;
}
}
}
#

View File

@@ -179,6 +179,7 @@ class Tester(TestCmd.TestCmd):
self.tree = build_tree(self.workdir)
self.difference = trees_difference(self.previous_tree, self.tree)
self.difference.ignore_directories()
self.unexpected_difference = copy.deepcopy(self.difference)
self.last_build_time = time.time()

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python
from BoostBuild import Tester
from BoostBuild import Tester, List
import os
from string import strip
@@ -101,4 +101,30 @@ t.expect_removal(["bin/gcc/debug/a.obj",
"lib3/bin/gcc/debug/f.obj",
])
# Now test target ids in command line
t.set_tree("project-test3")
t.run_build_system("lib/b.obj")
t.expect_addition("lib/bin/gcc/debug/b.obj")
t.expect_nothing_more()
t.run_build_system("clean lib/b.obj")
t.expect_removal("lib/bin/gcc/debug/b.obj")
t.expect_nothing_more()
t.run_build_system("release lib2@helper/e.obj @/lib3/f.obj")
t.expect_addition("lib2/helper/bin/gcc/release/e.obj")
t.expect_addition("lib3/bin/gcc/release/f.obj")
t.expect_nothing_more()
# Test project ids in command line work as well
t.set_tree("project-test3")
t.run_build_system("@/lib2")
t.expect_addition("lib2/bin/gcc/debug/" * List("c.obj d.obj l.exe"))
t.expect_addition("bin/gcc/debug/a.obj")
t.expect_nothing_more()
t.run_build_system("lib")
t.expect_addition("lib/bin/gcc/debug/" * List("b.obj m.exe"))
t.expect_nothing_more()
t.cleanup()

View File

@@ -21,6 +21,16 @@ class Trees_difference:
self.removed_files.extend(other.removed_files)
self.modified_files.extend(other.modified_files)
self.touched_files.extend(other.touched_files)
def ignore_directories(self):
"Removes directories for list of found differences"
def not_dir(x):
return x[-1] != "/"
self.added_files = filter(not_dir, self.added_files)
self.removed_files = filter(not_dir, self.removed_files)
self.modified_files = filter(not_dir, self.modified_files)
self.touched_files = filter(not_dir, self.touched_files)
def pprint(self):
print "Added files :", self.added_files