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:
@@ -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) ] ;
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
10
test/tree.py
10
test/tree.py
@@ -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
|
||||
|
||||
@@ -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) ] ;
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user