mirror of
https://github.com/boostorg/build.git
synced 2026-02-16 01:12:13 +00:00
Minor stylistic changes throughout several Boost Build modules. Added several todo comments.
[SVN r48644]
This commit is contained in:
@@ -91,8 +91,8 @@ rule command-line-free-features ( )
|
||||
|
||||
|
||||
# Returns the location of the build system. The primary use case is building
|
||||
# Boost where it's sometimes needed to get the location of other components
|
||||
# (e.g. BoostBook files) and it's convenient to use locations relative to the
|
||||
# Boost where it is sometimes needed to get the location of other components
|
||||
# (e.g. BoostBook files) and it is convenient to use locations relative to the
|
||||
# Boost Build path.
|
||||
#
|
||||
rule location ( )
|
||||
@@ -139,7 +139,7 @@ local rule actual-clean-targets ( )
|
||||
local targets-to-clean ;
|
||||
for local t in $(.results-of-main-targets)
|
||||
{
|
||||
# Don't include roots or sources.
|
||||
# Do not include roots or sources.
|
||||
targets-to-clean += [ virtual-target.traverse $(t) ] ;
|
||||
}
|
||||
targets-to-clean = [ sequence.unique $(targets-to-clean) ] ;
|
||||
@@ -170,8 +170,8 @@ local rule actual-clean-targets ( )
|
||||
|
||||
|
||||
# Given a target id, try to find and return the corresponding target. This is
|
||||
# only invoked when there's no Jamfile in ".". This code somewhat duplicates
|
||||
# code in project-target.find but we can't reuse that code without a
|
||||
# only invoked when there is no Jamfile in ".". This code somewhat duplicates
|
||||
# code in project-target.find but we can not reuse that code without a
|
||||
# project-targets instance.
|
||||
#
|
||||
local rule find-target ( target-id )
|
||||
@@ -655,7 +655,7 @@ local rule should-clean-project ( project )
|
||||
if ! $(t)
|
||||
{
|
||||
ECHO "notice: could not find main target" $(id) ;
|
||||
ECHO "notice: assuming it's a name of file to create." ;
|
||||
ECHO "notice: assuming it is a name of file to create." ;
|
||||
explicitly-requested-files += $(id) ;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -67,11 +67,7 @@ if "--debug-generators" in [ modules.peek : ARGV ]
|
||||
#
|
||||
rule update-viable-source-target-type-cache-with-derived-type ( type )
|
||||
{
|
||||
# TODO: There really ought be an interface to ask for a direct base target
|
||||
# type without having to go through a list of all the base target types.
|
||||
local all-base-types = [ type.all-bases $(type) ] ;
|
||||
local base-type = $(all-base-types[2]) ;
|
||||
|
||||
local base-type = [ type.base $(type) ] ;
|
||||
if $(base-type)
|
||||
{
|
||||
for local g in $(.vstg-cached-generators)
|
||||
|
||||
@@ -103,14 +103,13 @@ JAMROOT ?= project-root.jam [Jj]amroot [Jj]amroot.jam ;
|
||||
#
|
||||
rule load-parent ( location )
|
||||
{
|
||||
local found = [ path.glob-in-parents $(location) :
|
||||
$(JAMROOT) $(JAMFILE) ] ;
|
||||
local found = [ path.glob-in-parents $(location) : $(JAMROOT) $(JAMFILE) ] ;
|
||||
|
||||
if ! $(found)
|
||||
{
|
||||
ECHO "error: Could not find parent for project at '$(location)'" ;
|
||||
ECHO "error: Did not find Jamfile.jam or Jamroot.jam in any parent directory." ;
|
||||
EXIT ;
|
||||
ECHO error: Could not find parent for project at '$(location)' ;
|
||||
EXIT error: Did not find Jamfile.jam or Jamroot.jam in any parent
|
||||
directory. ;
|
||||
}
|
||||
|
||||
return [ load $(found[1]:D) ] ;
|
||||
@@ -153,8 +152,8 @@ rule find ( name : current-location )
|
||||
|
||||
if ! $(project-module)
|
||||
{
|
||||
local location = [ path.root
|
||||
[ path.make $(name) ] $(current-location) ] ;
|
||||
local location = [ path.root [ path.make $(name) ] $(current-location) ]
|
||||
;
|
||||
|
||||
# If no project is registered for the given location, try to load it.
|
||||
# First see if we have a Jamfile. If not, then see if we might have a
|
||||
@@ -220,8 +219,8 @@ rule find-jamfile (
|
||||
{
|
||||
if ! $(.parent-jamfile.$(dir))
|
||||
{
|
||||
.parent-jamfile.$(dir) =
|
||||
[ path.glob-in-parents $(dir) : $(JAMFILE) ] ;
|
||||
.parent-jamfile.$(dir) = [ path.glob-in-parents $(dir) : $(JAMFILE)
|
||||
] ;
|
||||
}
|
||||
jamfile-glob = $(.parent-jamfile.$(dir)) ;
|
||||
}
|
||||
@@ -237,7 +236,7 @@ rule find-jamfile (
|
||||
|
||||
local jamfile-to-load = $(jamfile-glob) ;
|
||||
# Multiple Jamfiles found in the same place. Warn about this and ensure we
|
||||
# use only one of them. As a temporary convenience measure, if there's
|
||||
# use only one of them. As a temporary convenience measure, if there is
|
||||
# Jamfile.v2 among found files, suppress the warning and use it.
|
||||
#
|
||||
if $(jamfile-to-load[2-])
|
||||
@@ -262,11 +261,10 @@ rule find-jamfile (
|
||||
#
|
||||
if ! $(no-errors) && ! $(jamfile-to-load)
|
||||
{
|
||||
errors.error
|
||||
"Unable to load Jamfile." :
|
||||
"Could not find a Jamfile in directory '$(dir)'". :
|
||||
"Attempted to find it with pattern '"$(JAMFILE:J=" ")"'." :
|
||||
"Please consult the documentation at 'http://www.boost.org'." ;
|
||||
errors.error Unable to load Jamfile.
|
||||
: Could not find a Jamfile in directory '$(dir)'.
|
||||
: Attempted to find it with pattern '"$(JAMFILE:J=" ")"'.
|
||||
: Please consult the documentation at 'http://www.boost.org'. ;
|
||||
}
|
||||
|
||||
return $(jamfile-to-load) ;
|
||||
@@ -319,13 +317,12 @@ local rule load-jamfile (
|
||||
# Now do some checks.
|
||||
if $(.current-project) != $(saved-project)
|
||||
{
|
||||
errors.error "The value of the .current-project variable"
|
||||
: "has magically changed after loading a Jamfile."
|
||||
: "This means some of the targets might be defined in the wrong project."
|
||||
: "after loading" $(jamfile-module)
|
||||
: "expected value" $(saved-project)
|
||||
: "actual value" $(.current-project)
|
||||
;
|
||||
errors.error "The value of the .current-project variable has magically"
|
||||
: "changed after loading a Jamfile. This means some of the targets"
|
||||
: "might be defined in the wrong project."
|
||||
: "after loading" $(jamfile-module)
|
||||
: "expected value" $(saved-project)
|
||||
: "actual value" $(.current-project) ;
|
||||
}
|
||||
|
||||
if $(.global-build-dir)
|
||||
@@ -578,10 +575,8 @@ class project-attributes
|
||||
|
||||
if $(result[1]) = "@error"
|
||||
{
|
||||
errors.error
|
||||
"Requirements for project at '$(self.location)'"
|
||||
"conflict with parent's." :
|
||||
"Explanation: " $(result[2-]) ;
|
||||
errors.error Requirements for project at '$(self.location)'
|
||||
conflict with parent's. : Explanation: $(result[2-]) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -601,7 +596,8 @@ class project-attributes
|
||||
local non-free = [ property.remove free : $(unconditional) ] ;
|
||||
if $(non-free)
|
||||
{
|
||||
errors.error "usage-requirements" $(specification) "have non-free properties" $(non-free) ;
|
||||
errors.error usage-requirements $(specification) have non-free
|
||||
properties $(non-free) ;
|
||||
}
|
||||
local t = [ property.translate-paths $(specification)
|
||||
: $(self.location) ] ;
|
||||
@@ -624,8 +620,8 @@ class project-attributes
|
||||
self.source-location = ;
|
||||
for local src-path in $(specification)
|
||||
{
|
||||
self.source-location += [ path.root
|
||||
[ path.make $(src-path) ] $(self.location) ] ;
|
||||
self.source-location += [ path.root [ path.make $(src-path) ]
|
||||
$(self.location) ] ;
|
||||
}
|
||||
}
|
||||
else if $(attribute) = "build-dir"
|
||||
@@ -642,8 +638,8 @@ class project-attributes
|
||||
else if ! $(attribute) in "default-build" "location" "parent"
|
||||
"projects-to-build" "project-root" "source-location"
|
||||
{
|
||||
errors.error "Invalid project attribute '$(attribute)' specified"
|
||||
"for project at '$(self.location)'" ;
|
||||
errors.error Invalid project attribute '$(attribute)' specified for
|
||||
project at '$(self.location)' ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -744,11 +740,11 @@ rule use ( id : location )
|
||||
{
|
||||
# The project at 'location' either has no id or that id is not equal to
|
||||
# the 'id' parameter.
|
||||
if $($(id).jamfile-module)
|
||||
&& $($(id).jamfile-module) != $(project-module)
|
||||
if $($(id).jamfile-module) && ( $($(id).jamfile-module) !=
|
||||
$(project-module) )
|
||||
{
|
||||
errors.user-error
|
||||
"Attempt to redeclare already existing project id '$(id)'" ;
|
||||
errors.user-error Attempt to redeclare already existing project id
|
||||
'$(id)' ;
|
||||
}
|
||||
$(id).jamfile-module = $(project-module) ;
|
||||
}
|
||||
@@ -783,12 +779,13 @@ rule extension ( id : options * : * )
|
||||
|
||||
# Create the project data, and bring in the project rules into the
|
||||
# module.
|
||||
project.initialize $(__name__) :
|
||||
[ path.join [ project.attribute $(root-project) location ] ext $(1:L) ] ;
|
||||
project.initialize $(__name__) : [ path.join [ project.attribute
|
||||
$(root-project) location ] ext $(1:L) ] ;
|
||||
|
||||
# Create the project itself, i.e. the attributes. All extensions are
|
||||
# created in the "/ext" project space.
|
||||
project /ext/$(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
|
||||
project /ext/$(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) :
|
||||
$(9) ;
|
||||
local attributes = [ project.attributes $(__name__) ] ;
|
||||
|
||||
# Inherit from the root project of whomever is defining us.
|
||||
@@ -803,12 +800,12 @@ rule glob-internal ( project : wildcards + : excludes * : rule-name )
|
||||
local location = [ $(project).get source-location ] ;
|
||||
|
||||
local result ;
|
||||
local paths = [ path.$(rule-name) $(location)
|
||||
: [ sequence.transform path.make : $(wildcards) ]
|
||||
: [ sequence.transform path.make : $(excludes) ] ] ;
|
||||
local paths = [ path.$(rule-name) $(location) :
|
||||
[ sequence.transform path.make : $(wildcards) ] :
|
||||
[ sequence.transform path.make : $(excludes) ] ] ;
|
||||
if $(wildcards:D) || $(rule-name) != glob
|
||||
{
|
||||
# The paths we've found are relative to the current directory, but the
|
||||
# The paths we have found are relative to the current directory, but the
|
||||
# names specified in the sources list are assumed to be relative to the
|
||||
# source directory of the corresponding project. So, just make the names
|
||||
# absolute.
|
||||
@@ -906,8 +903,8 @@ module project-rules
|
||||
local location = [ $(attributes).get location ] ;
|
||||
# Project with an empty location is a 'standalone' project such as
|
||||
# user-config or qt. It has no build dir. If we try to set build dir
|
||||
# for user-config, we'll then try to inherit it, with either weird
|
||||
# or wrong consequences.
|
||||
# for user-config, we shall then try to inherit it, with either
|
||||
# weird or wrong consequences.
|
||||
if $(location) && $(location) = [ $(attributes).get project-root ]
|
||||
{
|
||||
# Re-read the project id, since it might have been changed in
|
||||
@@ -916,12 +913,12 @@ module project-rules
|
||||
# This is Jamroot.
|
||||
if $(id)
|
||||
{
|
||||
if $(explicit-build-dir)
|
||||
&& [ path.is-rooted $(explicit-build-dir) ]
|
||||
if $(explicit-build-dir) &&
|
||||
[ path.is-rooted $(explicit-build-dir) ]
|
||||
{
|
||||
errors.user-error "Absolute directory specified via 'build-dir' project attribute"
|
||||
: "Don't know how to combine that with the --build-dir option."
|
||||
;
|
||||
errors.user-error Absolute directory specified via
|
||||
'build-dir' project attribute : Do not know how to
|
||||
combine that with the --build-dir option. ;
|
||||
}
|
||||
# Strip the leading slash from id.
|
||||
local rid = [ MATCH /(.*) : $(id) ] ;
|
||||
@@ -933,11 +930,12 @@ module project-rules
|
||||
}
|
||||
else
|
||||
{
|
||||
# Not Jamroot
|
||||
# Not Jamroot.
|
||||
if $(explicit-build-dir)
|
||||
{
|
||||
errors.user-error "When --build-dir is specified, the 'build-dir' project"
|
||||
: "attribute is allowed only for top-level 'project' invocations" ;
|
||||
errors.user-error When --build-dir is specified, the
|
||||
'build-dir' project : attribute is allowed only for
|
||||
top-level 'project' invocations ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -950,7 +948,7 @@ module project-rules
|
||||
rule constant (
|
||||
name # Variable name of the constant.
|
||||
: value + # Value of the constant.
|
||||
)
|
||||
)
|
||||
{
|
||||
import project ;
|
||||
local p = [ project.target $(__name__) ] ;
|
||||
@@ -1012,10 +1010,11 @@ module project-rules
|
||||
|
||||
if $(wildcards:D) || $(excludes:D)
|
||||
{
|
||||
errors.user-error "The patterns to 'glob-tree' may not include directory" ;
|
||||
errors.user-error The patterns to 'glob-tree' may not include
|
||||
directory ;
|
||||
}
|
||||
return [ project.glob-internal [ project.current ]
|
||||
: $(wildcards) : $(excludes) : glob-tree ] ;
|
||||
return [ project.glob-internal [ project.current ] : $(wildcards) :
|
||||
$(excludes) : glob-tree ] ;
|
||||
}
|
||||
|
||||
# Calculates conditional requirements for multiple requirements at once.
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
# each Jamfile, and can be obtained by the 'target' rule in the Jamfile's module
|
||||
# (see project.jam).
|
||||
#
|
||||
# Project targets keep a list of 'main-target' instances. A main target is
|
||||
# what the user explicitly defines in a Jamfile. It is possible to have several
|
||||
# Project targets keep a list of 'main-target' instances. A main target is what
|
||||
# the user explicitly defines in a Jamfile. It is possible to have several
|
||||
# definitions for a main target, for example to have different lists of sources
|
||||
# for different platforms. So, main targets keep a list of alternatives.
|
||||
#
|
||||
@@ -89,8 +89,8 @@ class abstract-target
|
||||
import "class" ;
|
||||
import errors ;
|
||||
|
||||
rule __init__ ( name # name of the target in Jamfile
|
||||
: project-target # the project target to which this one belongs
|
||||
rule __init__ ( name # Name of the target in Jamfile.
|
||||
: project-target # The project target to which this one belongs.
|
||||
)
|
||||
{
|
||||
# Note: it might seem that we don't need either name or project at all.
|
||||
@@ -232,10 +232,8 @@ class project-target : abstract-target
|
||||
self.build-dir = [ get build-dir ] ;
|
||||
if ! $(self.build-dir)
|
||||
{
|
||||
self.build-dir = [ path.join
|
||||
[ $(self.project).get location ]
|
||||
bin
|
||||
] ;
|
||||
self.build-dir = [ path.join [ $(self.project).get location ]
|
||||
bin ] ;
|
||||
}
|
||||
}
|
||||
return $(self.build-dir) ;
|
||||
@@ -300,8 +298,8 @@ class project-target : abstract-target
|
||||
#
|
||||
rule mark-target-as-explicit ( target-name )
|
||||
{
|
||||
# Record the name of the target, not instance, since this
|
||||
# rule is called before main target instaces are created.
|
||||
# Record the name of the target, not instance, since this rule is called
|
||||
# before main target instances are created.
|
||||
self.explicit-targets += $(target-name) ;
|
||||
}
|
||||
|
||||
@@ -311,13 +309,13 @@ class project-target : abstract-target
|
||||
{
|
||||
if $(self.built-main-targets)
|
||||
{
|
||||
errors.error "add-alternative called when main targets are already created."
|
||||
: "in project" [ full-name ] ;
|
||||
errors.error add-alternative called when main targets are already
|
||||
created. : in project [ full-name ] ;
|
||||
}
|
||||
self.alternatives += $(target-instance) ;
|
||||
}
|
||||
|
||||
# Returns a 'main-target' class instance corresponding to the 'name'.
|
||||
# Returns a 'main-target' class instance corresponding to 'name'.
|
||||
#
|
||||
rule main-target ( name )
|
||||
{
|
||||
@@ -325,11 +323,10 @@ class project-target : abstract-target
|
||||
{
|
||||
build-main-targets ;
|
||||
}
|
||||
|
||||
return $(self.main-target.$(name)) ;
|
||||
}
|
||||
|
||||
# Tells if a main target with the specified name exists.
|
||||
# Returns whether a main target with the specified name exists.
|
||||
#
|
||||
rule has-main-target ( name )
|
||||
{
|
||||
@@ -344,13 +341,12 @@ class project-target : abstract-target
|
||||
}
|
||||
}
|
||||
|
||||
# Find and return the target with the specified id, treated relative to
|
||||
# self.
|
||||
# Worker function for the find rule not implementing any caching and simply
|
||||
# returning nothing in case the target can not be found.
|
||||
#
|
||||
rule find-really ( id )
|
||||
{
|
||||
local result ;
|
||||
local project = $(self.project) ;
|
||||
local current-location = [ get location ] ;
|
||||
|
||||
local split = [ MATCH (.*)//(.*) : $(id) ] ;
|
||||
@@ -360,8 +356,8 @@ class project-target : abstract-target
|
||||
local extra-error-message ;
|
||||
if $(project-part)
|
||||
{
|
||||
# There's explicit project part in id. Looks up the project and
|
||||
# passes the request to it.
|
||||
# There is an explicitly specified project part in id. Looks up the
|
||||
# project and passes the request to it.
|
||||
local pm = [ project.find $(project-part) : $(current-location) ] ;
|
||||
if $(pm)
|
||||
{
|
||||
@@ -370,37 +366,44 @@ class project-target : abstract-target
|
||||
}
|
||||
else
|
||||
{
|
||||
extra-error-message = "error: could not find project '$(project-part)'" ;
|
||||
# TODO: This extra error message will not get displayed most
|
||||
# likely due to some buggy refactoring. Refactor the code so the
|
||||
# message gets diplayed again.
|
||||
extra-error-message = error: could not find project
|
||||
'$(project-part)' ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# Interpret target-name as name of main target. Need to do this
|
||||
# before checking for file. Consider this:
|
||||
# before checking for file. Consider the following scenario with a
|
||||
# toolset not modifying its executable's names, e.g. gcc on
|
||||
# Unix-like platforms:
|
||||
#
|
||||
# exe test : test.cpp ;
|
||||
# install s : test : <location>. ;
|
||||
#
|
||||
# After first build we'll have target 'test' in Jamfile and file
|
||||
# 'test' on the disk. We need target to override the file.
|
||||
# After the first build we would have a target named 'test' in the
|
||||
# Jamfile and a file named 'test' on the disk. We need the target to
|
||||
# override the file.
|
||||
result = [ main-target $(id) ] ;
|
||||
|
||||
|
||||
# Interpret id as an existing file reference.
|
||||
if ! $(result)
|
||||
{
|
||||
result = [ new file-reference [ path.make $(id) ] : $(project) ] ;
|
||||
|
||||
result = [ new file-reference [ path.make $(id) ] :
|
||||
$(self.project) ] ;
|
||||
if ! [ $(result).exists ]
|
||||
{
|
||||
# File actually does not exist. Reset 'target' so that an
|
||||
# error is issued.
|
||||
result = ;
|
||||
}
|
||||
}
|
||||
|
||||
# Interpret id as project-id
|
||||
# Interpret id as project-id.
|
||||
if ! $(result)
|
||||
{
|
||||
local project-module = [ project.find $(id) : $(current-location) ] ;
|
||||
local project-module = [ project.find $(id) :
|
||||
$(current-location) ] ;
|
||||
if $(project-module)
|
||||
{
|
||||
result = [ project.target $(project-module) ] ;
|
||||
@@ -411,6 +414,11 @@ class project-target : abstract-target
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
# Find and return the target with the specified id, treated relative to
|
||||
# self. Id may specify either a target or a file name with the target taking
|
||||
# priority. May report an error or return nothing if the target is not found
|
||||
# depending on the 'no-error' parameter.
|
||||
#
|
||||
rule find ( id : no-error ? )
|
||||
{
|
||||
local v = $(.id.$(id)) ;
|
||||
@@ -771,7 +779,7 @@ class main-target : abstract-target
|
||||
}
|
||||
|
||||
|
||||
# Abstract target which refers to a source file. This is an artificial entity
|
||||
# Abstract target refering to a source file. This is an artificial entity
|
||||
# allowing sources to a target to be represented using a list of abstract target
|
||||
# instances.
|
||||
#
|
||||
@@ -788,11 +796,8 @@ class file-reference : abstract-target
|
||||
|
||||
rule generate ( properties )
|
||||
{
|
||||
location ;
|
||||
return [ property-set.empty ]
|
||||
[ virtual-target.from-file $(self.name)
|
||||
: $(self.file-location)
|
||||
: $(self.project) ] ;
|
||||
return [ property-set.empty ] [ virtual-target.from-file $(self.name) :
|
||||
[ location ] : $(self.project) ] ;
|
||||
}
|
||||
|
||||
# Returns true if the referred file really exists.
|
||||
@@ -1075,7 +1080,8 @@ class basic-target : abstract-target
|
||||
|
||||
if $(sources:G)
|
||||
{
|
||||
errors.user-error "properties found in the 'sources' parameter for" [ full-name ] ;
|
||||
errors.user-error properties found in the 'sources' parameter for
|
||||
[ full-name ] ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1199,7 +1205,8 @@ class basic-target : abstract-target
|
||||
ECHO [ targets.indent ] "Common properties: " [ $(rproperties).raw ] ;
|
||||
}
|
||||
|
||||
if $(rproperties[1]) != "@error" && [ $(rproperties).get <build> ] != no
|
||||
if ( $(rproperties[1]) != "@error" ) && ( [ $(rproperties).get
|
||||
<build> ] != no )
|
||||
{
|
||||
local source-targets ;
|
||||
local properties = [ $(rproperties).non-dependency ] ;
|
||||
@@ -1418,8 +1425,7 @@ class typed-target : basic-target
|
||||
|
||||
rule construct ( name : source-targets * : property-set )
|
||||
{
|
||||
local r = [ generators.construct $(self.project) $(name:S=)
|
||||
: $(self.type)
|
||||
local r = [ generators.construct $(self.project) $(name:S=) : $(self.type)
|
||||
: [ property-set.create [ $(property-set).raw ]
|
||||
<main-target-type>$(self.type) ]
|
||||
: $(source-targets) ] ;
|
||||
|
||||
@@ -14,6 +14,7 @@ import project ;
|
||||
import property ;
|
||||
import scanner ;
|
||||
|
||||
|
||||
# The following import would create a circular dependency:
|
||||
# project -> project-root -> builtin -> type -> targets -> project
|
||||
# import targets ;
|
||||
@@ -48,15 +49,15 @@ rule register ( type : suffixes * : base-type ? )
|
||||
else
|
||||
{
|
||||
.types += $(type) ;
|
||||
.bases.$(type) = $(base-type) ;
|
||||
.base.$(type) = $(base-type) ;
|
||||
.derived.$(base-type) += $(type) ;
|
||||
|
||||
if $(suffixes)-is-not-empty
|
||||
{
|
||||
# Specify mapping from suffixes to type.
|
||||
register-suffixes $(suffixes) : $(type) ;
|
||||
# Generated targets of 'type' will use the first of 'suffixes'. This
|
||||
# may be overriden.
|
||||
# By default generated targets of 'type' will use the first of
|
||||
#'suffixes'. This may be overriden.
|
||||
set-generated-target-suffix $(type) : : $(suffixes[1]) ;
|
||||
}
|
||||
|
||||
@@ -68,23 +69,17 @@ rule register ( type : suffixes * : base-type ? )
|
||||
feature.compose <base-target-type>$(type) : <base-target-type>$(base-type) ;
|
||||
|
||||
# We used to declare the main target rule only when a 'main' parameter
|
||||
# was specified. However, it is hard to decide that a type will *never*
|
||||
# need a main target rule and so from time to time we needed to make yet
|
||||
# another type 'main'. So now a main target rule is defined for each
|
||||
# type.
|
||||
# has been specified. However, it is hard to decide that a type will
|
||||
# *never* need a main target rule and so from time to time we needed to
|
||||
# make yet another type 'main'. So now a main target rule is defined for
|
||||
# each type.
|
||||
main-rule-name = [ type-to-rule-name $(type) ] ;
|
||||
.main-target-type.$(main-rule-name) = $(type) ;
|
||||
|
||||
IMPORT $(__name__) : main-target-rule : : $(main-rule-name) ;
|
||||
|
||||
# This is a hack to invalidate generator selection related cached viable
|
||||
# source target type information because it adding a new derived target
|
||||
# type logically adds the new type to the any viable source target type
|
||||
# lists already containing its base type.
|
||||
#
|
||||
# We can improve the current implementation by not clearing the whole
|
||||
# cache but simply updating the cached values. That might be more
|
||||
# performant but needs to be tested and implemented at a later time.
|
||||
# Adding a new derived type affects generator selection so we need to
|
||||
# make the generator selection module update any of its cached
|
||||
# information related to a new derived type being defined.
|
||||
if $(base-type)
|
||||
{
|
||||
generators.update-viable-source-target-type-cache-with-derived-type
|
||||
@@ -128,8 +123,8 @@ rule register-suffixes ( suffixes + : type )
|
||||
}
|
||||
else if $(.type.$(s)) != type
|
||||
{
|
||||
errors.error Attempting to specify multiple types for suffix \"$(s)\"
|
||||
: "Old type $(.type.$(s)), New type $(type)" ;
|
||||
errors.error Attempting to specify multiple types for suffix
|
||||
\"$(s)\" : "Old type $(.type.$(s)), New type $(type)" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +145,7 @@ rule registered ( type )
|
||||
#
|
||||
rule validate ( type )
|
||||
{
|
||||
if ! $(type) in $(.types)
|
||||
if ! [ registered $(type) ]
|
||||
{
|
||||
errors.error "Unknown target type $(type)" ;
|
||||
}
|
||||
@@ -161,10 +156,7 @@ rule validate ( type )
|
||||
#
|
||||
rule set-scanner ( type : scanner )
|
||||
{
|
||||
if ! $(type) in $(.types)
|
||||
{
|
||||
error "Type" $(type) "is not declared" ;
|
||||
}
|
||||
validate $(type) ;
|
||||
.scanner.$(type) = $(scanner) ;
|
||||
}
|
||||
|
||||
@@ -180,6 +172,15 @@ rule get-scanner ( type : property-set )
|
||||
}
|
||||
|
||||
|
||||
# Returns a base type for the given type or nothing in case the given type is
|
||||
# not derived.
|
||||
#
|
||||
rule base ( type )
|
||||
{
|
||||
return $(.base.$(type)) ;
|
||||
}
|
||||
|
||||
|
||||
# Returns the given type and all of its base types in order of their distance
|
||||
# from type.
|
||||
#
|
||||
@@ -188,13 +189,16 @@ rule all-bases ( type )
|
||||
local result = $(type) ;
|
||||
while $(type)
|
||||
{
|
||||
type = $(.bases.$(type)) ;
|
||||
type = [ base $(type) ] ;
|
||||
result += $(type) ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
|
||||
# Returns the given type and all of its derived types in order of their distance
|
||||
# from type.
|
||||
#
|
||||
rule all-derived ( type )
|
||||
{
|
||||
local result = $(type) ;
|
||||
@@ -206,7 +210,8 @@ rule all-derived ( type )
|
||||
}
|
||||
|
||||
|
||||
# Returns true if 'type' has 'base' as its direct or indirect base.
|
||||
# Returns true if 'type' is equal to 'base' or has 'base' as its direct or
|
||||
# indirect base.
|
||||
#
|
||||
rule is-derived ( type base )
|
||||
{
|
||||
@@ -216,19 +221,15 @@ rule is-derived ( type base )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Returns true if 'type' is either derived from or is equal to 'base'.
|
||||
#
|
||||
# TODO: It might be that is-derived and is-subtype were meant to be different
|
||||
# rules - one returning true for type = base and one not, but as currently
|
||||
# implemented they are actually the same. Clean this up.
|
||||
#
|
||||
rule is-subtype ( type base )
|
||||
{
|
||||
if $(type) = $(base)
|
||||
{
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [ is-derived $(type) $(base) ] ;
|
||||
}
|
||||
return [ is-derived $(type) $(base) ] ;
|
||||
}
|
||||
|
||||
|
||||
@@ -343,7 +344,7 @@ local rule generated-target-ps-real ( ps : type : properties * )
|
||||
{
|
||||
found = true ;
|
||||
}
|
||||
type = $(.bases.$(type)) ;
|
||||
type = $(.base.$(type)) ;
|
||||
}
|
||||
if $(result) = ""
|
||||
{
|
||||
@@ -359,8 +360,8 @@ local rule generated-target-ps ( ps : type : property-set )
|
||||
local v = $($(key)) ;
|
||||
if ! $(v)
|
||||
{
|
||||
v = [ generated-target-ps-real $(ps) : $(type)
|
||||
: [ $(property-set).raw ] ] ;
|
||||
v = [ generated-target-ps-real $(ps) : $(type) : [ $(property-set).raw ]
|
||||
] ;
|
||||
if ! $(v)
|
||||
{
|
||||
v = none ;
|
||||
@@ -393,23 +394,32 @@ rule type ( filename )
|
||||
|
||||
|
||||
# Rule used to construct all main targets. Note that this rule gets imported
|
||||
# into the global namespace under different alias names and exactly what type of
|
||||
# target it is supposed to construct is read from the name of the alias rule
|
||||
# actually used to invoke it.
|
||||
# into the global namespace under different alias names and the exact target
|
||||
# type to construct is selected based on the alias used to actually invoke this
|
||||
# rule.
|
||||
#
|
||||
rule main-target-rule ( name : sources * : requirements * : default-build *
|
||||
: usage-requirements * )
|
||||
rule main-target-rule ( name : sources * : requirements * : default-build * :
|
||||
usage-requirements * )
|
||||
{
|
||||
# First discover the required target type, which is equal to the rule name
|
||||
# used to invoke us.
|
||||
# First discover the required target type based on the exact alias used to
|
||||
# invoke this rule.
|
||||
local bt = [ BACKTRACE 1 ] ;
|
||||
local rulename = $(bt[4]) ;
|
||||
local target-type = [ type-from-rule-name $(rulename) ] ;
|
||||
|
||||
local project = [ project.current ] ;
|
||||
|
||||
# This is a circular module dependency so it must be imported here.
|
||||
# This is a circular module dependency and so must be imported here.
|
||||
import targets ;
|
||||
return [ targets.create-typed-target $(.main-target-type.$(rulename))
|
||||
: $(project) : $(name) : $(sources) : $(requirements)
|
||||
: $(default-build) : $(usage-requirements) ] ;
|
||||
|
||||
return [ targets.create-typed-target $(target-type) : [ project.current ] :
|
||||
$(name) : $(sources) : $(requirements) : $(default-build) :
|
||||
$(usage-requirements) ] ;
|
||||
}
|
||||
|
||||
|
||||
rule __test__ ( )
|
||||
{
|
||||
import assert ;
|
||||
|
||||
# TODO: Add tests for all the is-derived, is-base & related type relation
|
||||
# checking rules.
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
# Implements virtual targets, which correspond to actual files created during a
|
||||
# build, but are not yet targets in Jam sense. They are needed, for example,
|
||||
# when searching for possible transformation sequences, when it's not yet known
|
||||
# when searching for possible transformation sequences, when it is not yet known
|
||||
# whether a particular target should be created at all.
|
||||
|
||||
import "class" : new ;
|
||||
@@ -17,6 +17,7 @@ import set ;
|
||||
import type ;
|
||||
import utility ;
|
||||
|
||||
|
||||
# +--------------------------+
|
||||
# | virtual-target |
|
||||
# +==========================+
|
||||
@@ -88,18 +89,24 @@ class virtual-target
|
||||
|
||||
# Name of this target.
|
||||
#
|
||||
rule name ( ) { return $(self.name) ; }
|
||||
rule name ( )
|
||||
{
|
||||
return $(self.name) ;
|
||||
}
|
||||
|
||||
# Project of this target.
|
||||
#
|
||||
rule project ( ) { return $(self.project) ; }
|
||||
rule project ( )
|
||||
{
|
||||
return $(self.project) ;
|
||||
}
|
||||
|
||||
# Adds additional 'virtual-target' instances this one depends on.
|
||||
#
|
||||
rule depends ( d + )
|
||||
{
|
||||
self.dependencies = [ sequence.merge $(self.dependencies)
|
||||
: [ sequence.insertion-sort $(d) ] ] ;
|
||||
self.dependencies = [ sequence.merge $(self.dependencies) :
|
||||
[ sequence.insertion-sort $(d) ] ] ;
|
||||
}
|
||||
|
||||
rule dependencies ( )
|
||||
@@ -185,7 +192,8 @@ class virtual-target
|
||||
{
|
||||
# In fact, we just need to merge virtual-target with
|
||||
# abstract-file-target as the latter is the only class derived from the
|
||||
# former. But that's for later.
|
||||
# former. But that has been left for later.
|
||||
|
||||
errors.error "method should be defined in derived classes" ;
|
||||
}
|
||||
}
|
||||
@@ -197,8 +205,9 @@ class virtual-target
|
||||
# May be a source file (when no action is specified) or a derived file
|
||||
# (otherwise).
|
||||
#
|
||||
# The target's grist is concatenation of its project's location, properties of
|
||||
# action (for derived files) and, optionally, value identifying the main target.
|
||||
# The target's grist is a concatenation of its project's location, action
|
||||
# properties (for derived targets) and, optionally, value identifying the main
|
||||
# target.
|
||||
#
|
||||
class abstract-file-target : virtual-target
|
||||
{
|
||||
@@ -236,7 +245,10 @@ class abstract-file-target : virtual-target
|
||||
}
|
||||
}
|
||||
|
||||
rule type ( ) { return $(self.type) ; }
|
||||
rule type ( )
|
||||
{
|
||||
return $(self.type) ;
|
||||
}
|
||||
|
||||
# Sets the path. When generating target name, it will override any path
|
||||
# computation from properties.
|
||||
@@ -291,11 +303,11 @@ class abstract-file-target : virtual-target
|
||||
}
|
||||
|
||||
# Return a human-readable representation of this target. If this target has
|
||||
# an action, that's:
|
||||
# an action, that is:
|
||||
#
|
||||
# { <action-name>-<self.name>.<self.type> <action-sources>... }
|
||||
#
|
||||
# otherwise, it's:
|
||||
# otherwise, it is:
|
||||
#
|
||||
# { <self.name>.<self.type> }
|
||||
#
|
||||
@@ -441,7 +453,7 @@ class abstract-file-target : virtual-target
|
||||
}
|
||||
}
|
||||
|
||||
# If there's no tag or the tag rule returned nothing.
|
||||
# If there is no tag or the tag rule returned nothing.
|
||||
if ! $(tag) || ! $(self.name)
|
||||
{
|
||||
self.name = [ virtual-target.add-prefix-and-suffix $(specified-name)
|
||||
@@ -460,7 +472,7 @@ class abstract-file-target : virtual-target
|
||||
|
||||
if $(self.action)
|
||||
{
|
||||
# For non-derived target, we don't care if there are several
|
||||
# For non-derived target, we do not care if there are several
|
||||
# virtual targets that refer to the same name. One case when
|
||||
# this is unavoidable is when the file name is main.cpp and two
|
||||
# targets have types CPP (for compiling) and MOCCABLE_CPP (for
|
||||
@@ -531,23 +543,23 @@ class file-target : abstract-file-target
|
||||
import errors ;
|
||||
|
||||
rule __init__ (
|
||||
name exact ?
|
||||
: type ? # Optional type for this target
|
||||
name exact ?
|
||||
: type ? # Optional type for this target.
|
||||
: project
|
||||
: action ?
|
||||
: path ?
|
||||
)
|
||||
{
|
||||
abstract-file-target.__init__ $(name) $(exact) : $(type) : $(project)
|
||||
: $(action) ;
|
||||
abstract-file-target.__init__ $(name) $(exact) : $(type) : $(project) :
|
||||
$(action) ;
|
||||
|
||||
self.path = $(path) ;
|
||||
}
|
||||
|
||||
rule clone-with-different-type ( new-type )
|
||||
{
|
||||
return [ new file-target $(self.name) exact : $(new-type)
|
||||
: $(self.project) : $(self.action) : $(self.path) ] ;
|
||||
return [ new file-target $(self.name) exact : $(new-type) :
|
||||
$(self.project) : $(self.action) : $(self.path) ] ;
|
||||
}
|
||||
|
||||
rule actualize-location ( target )
|
||||
@@ -581,14 +593,14 @@ class file-target : abstract-file-target
|
||||
# target has no directory name and uses a special <e> grist.
|
||||
#
|
||||
# First, that means that "bjam hello.o" will build all known hello.o
|
||||
# targets. Second, the <e> grist makes sure this target won't be
|
||||
# targets. Second, the <e> grist makes sure this target will not be
|
||||
# confused with other targets, for example, if we have subdir 'test'
|
||||
# with target 'test' in it that includes a 'test.o' file, then the
|
||||
# target for directory will be just 'test' the target for test.o
|
||||
# will be <ptest/bin/gcc/debug>test.o and the target we create below
|
||||
# will be <e>test.o
|
||||
DEPENDS $(target:G=e) : $(target) ;
|
||||
# Allow bjam <path-to-file>/<file> to work. This won't catch all
|
||||
# Allow bjam <path-to-file>/<file> to work. This will not catch all
|
||||
# possible ways to refer to the path (relative/absolute, extra ".",
|
||||
# various "..", but should help in obvious cases.
|
||||
DEPENDS $(target:G=e:R=$(path)) : $(target) ;
|
||||
@@ -608,13 +620,13 @@ class file-target : abstract-file-target
|
||||
if $(self.action)
|
||||
{
|
||||
local p = [ $(self.action).properties ] ;
|
||||
local path = [ $(p).target-path ] ;
|
||||
local path,relative-to-build-dir = [ $(p).target-path ] ;
|
||||
local path = $(path,relative-to-build-dir[1]) ;
|
||||
local relative-to-build-dir = $(path,relative-to-build-dir[2]) ;
|
||||
|
||||
if $(path[2]) = true
|
||||
if $(relative-to-build-dir)
|
||||
{
|
||||
# Indicates that the path is relative to the build dir.
|
||||
path = [ path.join [ $(self.project).build-dir ]
|
||||
$(path[1]) ] ;
|
||||
path = [ path.join [ $(self.project).build-dir ] $(path) ] ;
|
||||
}
|
||||
|
||||
self.path = [ path.native $(path) ] ;
|
||||
@@ -727,7 +739,8 @@ class action
|
||||
|
||||
actualize-sources [ sources ] : $(properties) ;
|
||||
|
||||
DEPENDS $(actual-targets) : $(self.actual-sources) $(self.dependency-only-sources) ;
|
||||
DEPENDS $(actual-targets) : $(self.actual-sources)
|
||||
$(self.dependency-only-sources) ;
|
||||
|
||||
# Action name can include additional argument to rule, which should
|
||||
# not be passed to 'set-target-variables'
|
||||
@@ -794,8 +807,8 @@ class action
|
||||
#
|
||||
# For bjam to find the dependency the generated target must be
|
||||
# actualized (i.e. have its Jam target constructed). In the above case,
|
||||
# if we're building just hello ("bjam hello"), 'a.h' won't be actualized
|
||||
# unless we do it here.
|
||||
# if we are building just hello ("bjam hello"), 'a.h' will not be
|
||||
# actualized unless we do it here.
|
||||
local implicit = [ $(self.properties).get <implicit-dependency> ] ;
|
||||
for local i in $(implicit)
|
||||
{
|
||||
@@ -816,7 +829,7 @@ class action
|
||||
|
||||
|
||||
# Action class which does nothing --- it produces the targets with specific
|
||||
# properties out of nowhere. It's needed to distinguish virtual targets with
|
||||
# properties out of nowhere. It is needed to distinguish virtual targets with
|
||||
# different properties that are known to exist and have no actions which create
|
||||
# them.
|
||||
#
|
||||
@@ -866,16 +879,21 @@ class non-scanning-action : action
|
||||
# Creates a virtual target with an appropriate name and type from 'file'. If a
|
||||
# target with that name in that project already exists, returns that already
|
||||
# created target.
|
||||
#
|
||||
# FIXME: a more correct way would be to compute the path to the file, based on
|
||||
# name and source location for the project, and use that path to determine if
|
||||
# the target was already created.
|
||||
# the target has already been created. This logic should be shared with how we
|
||||
# usually find targets identified by a specific target id. It should also be
|
||||
# updated to work correctly when the file is specified using both relative and
|
||||
# absolute paths.
|
||||
#
|
||||
# TODO: passing a project with all virtual targets is starting to be annoying.
|
||||
#
|
||||
rule from-file ( file : file-loc : project )
|
||||
{
|
||||
import type ; # Had to do this here to break a circular dependency.
|
||||
|
||||
# Check if we've created a target corresponding to this file.
|
||||
# Check whether we already created a target corresponding to this file.
|
||||
local path = [ path.root [ path.root $(file) $(file-loc) ] [ path.pwd ] ] ;
|
||||
|
||||
if $(.files.$(path))
|
||||
@@ -888,11 +906,8 @@ rule from-file ( file : file-loc : project )
|
||||
local type = [ type.type $(file) ] ;
|
||||
local result ;
|
||||
|
||||
result = [ new file-target $(file)
|
||||
: $(type)
|
||||
: $(project)
|
||||
: #action
|
||||
: $(file-loc) ] ;
|
||||
result = [ new file-target $(file) : $(type) : $(project) : :
|
||||
$(file-loc) ] ;
|
||||
|
||||
.files.$(path) = $(result) ;
|
||||
return $(result) ;
|
||||
@@ -900,7 +915,7 @@ rule from-file ( file : file-loc : project )
|
||||
}
|
||||
|
||||
|
||||
# Registers a new virtual target. Checks if there's already a registered target
|
||||
# Registers a new virtual target. Checks if there is already a registered target
|
||||
# with the same name, type, project and subvariant properties as well as the
|
||||
# same sources and equal action. If such target is found it is returned and a
|
||||
# new 'target' is not registered. Otherwise, 'target' is registered and
|
||||
@@ -926,15 +941,15 @@ rule register ( target )
|
||||
else
|
||||
{
|
||||
if $(a1) && $(a2) &&
|
||||
[ $(a1).action-name ] = [ $(a2).action-name ] &&
|
||||
[ $(a1).sources ] = [ $(a2).sources ]
|
||||
( [ $(a1).action-name ] = [ $(a2).action-name ] ) &&
|
||||
( [ $(a1).sources ] = [ $(a2).sources ] )
|
||||
{
|
||||
local ps1 = [ $(a1).properties ] ;
|
||||
local ps2 = [ $(a2).properties ] ;
|
||||
local p1 = [ $(ps1).base ] [ $(ps1).free ]
|
||||
[ set.difference [ $(ps1).dependency ] : [ $(ps1).incidental ] ] ;
|
||||
local p2 = [ $(ps2).base ] [ $(ps2).free ]
|
||||
[ set.difference [ $(ps2).dependency ] : [ $(ps2).incidental ] ] ;
|
||||
local p1 = [ $(ps1).base ] [ $(ps1).free ] [ set.difference
|
||||
[ $(ps1).dependency ] : [ $(ps1).incidental ] ] ;
|
||||
local p2 = [ $(ps2).base ] [ $(ps2).free ] [ set.difference
|
||||
[ $(ps2).dependency ] : [ $(ps2).incidental ] ] ;
|
||||
if $(p1) = $(p2)
|
||||
{
|
||||
result = $(t) ;
|
||||
@@ -957,10 +972,10 @@ rule register ( target )
|
||||
}
|
||||
|
||||
|
||||
# Each target returned by 'register' is added to a .recent-targets list,
|
||||
# Each target returned by 'register' is added to the .recent-targets list,
|
||||
# returned by this function. This allows us to find all virtual targets created
|
||||
# when building a given main target, even those constructed only as intermediate
|
||||
# targets.
|
||||
# when building a specific main target, even those constructed only as
|
||||
# intermediate targets.
|
||||
#
|
||||
rule recent-targets ( )
|
||||
{
|
||||
@@ -1040,9 +1055,9 @@ rule register-actual-name ( actual-name : virtual-target )
|
||||
|
||||
# Traverses the dependency graph of 'target' and return all targets that will be
|
||||
# created before this one is created. If the root of some dependency graph is
|
||||
# found during traversal, it's either included or not, depending on the value of
|
||||
# 'include-roots'. In either case traversal stops at root targets, i.e. sources
|
||||
# of root targets are not traversed.
|
||||
# found during traversal, it is either included or not, depending on the
|
||||
# 'include-roots' value. In either case traversal stops at root targets, i.e.
|
||||
# root target sources are not traversed.
|
||||
#
|
||||
rule traverse ( target : include-roots ? : include-sources ? )
|
||||
{
|
||||
@@ -1097,9 +1112,9 @@ rule clone-action ( action : new-project : new-action-name ? : new-properties ?
|
||||
for local target in [ $(action).targets ]
|
||||
{
|
||||
local n = [ $(target).name ] ;
|
||||
# Don't modify produced targets names.
|
||||
local cloned-target = [ class.new file-target $(n) exact
|
||||
: [ $(target).type ] : $(new-project) : $(cloned-action) ] ;
|
||||
# Do not modify produced target names.
|
||||
local cloned-target = [ class.new file-target $(n) exact :
|
||||
[ $(target).type ] : $(new-project) : $(cloned-action) ] ;
|
||||
local d = [ $(target).dependencies ] ;
|
||||
if $(d)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,6 @@ os.remove("jamroot.jam")
|
||||
t.run_build_system(status=1, stdout=
|
||||
"""error: Could not find parent for project at '.'
|
||||
error: Did not find Jamfile.jam or Jamroot.jam in any parent directory.
|
||||
|
||||
""")
|
||||
|
||||
t.set_tree("project-test3")
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Defines standard features and rules.
|
||||
# Defines standard features and rules.
|
||||
|
||||
import alias ;
|
||||
import "class" : new ;
|
||||
@@ -445,9 +445,9 @@ class c-scanner : scanner
|
||||
# Attach binding of including file to included targets. When a target is
|
||||
# directly created from virtual target this extra information is
|
||||
# unnecessary. But in other cases, it allows us to distinguish between
|
||||
# two headers of the same name included from different places. We don't
|
||||
# two headers of the same name included from different places. We do not
|
||||
# need this extra information for angle includes, since they should not
|
||||
# depend on including file (we can't get literal "." in include path).
|
||||
# depend on including file (we can not get literal "." in include path).
|
||||
local g2 = $(g)"#"$(b) ;
|
||||
|
||||
angle = $(angle:G=$(g)) ;
|
||||
@@ -510,7 +510,7 @@ class lib-generator : generator
|
||||
# Determine the needed target type.
|
||||
local actual-type ;
|
||||
# <source>files can be generated by <conditional>@rule feature
|
||||
# in which case we don't consider it a SEARCHED_LIB type.
|
||||
# in which case we do not consider it a SEARCHED_LIB type.
|
||||
if ! <source> in $(properties:G) &&
|
||||
( <search> in $(properties:G) || <name> in $(properties:G) )
|
||||
{
|
||||
@@ -556,12 +556,12 @@ rule lib ( names + : sources * : requirements * : default-build * :
|
||||
if <name> in $(requirements:G)
|
||||
{
|
||||
errors.user-error "When several names are given to the 'lib' rule" :
|
||||
"it's not allowed to specify the <name> feature." ;
|
||||
"it is not allowed to specify the <name> feature." ;
|
||||
}
|
||||
if $(sources)
|
||||
{
|
||||
errors.user-error "When several names are given to the 'lib' rule" :
|
||||
"it's not allowed to specify sources." ;
|
||||
"it is not allowed to specify sources." ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,7 +629,7 @@ class searched-lib-generator : generator
|
||||
lib-name ?= $(name) ;
|
||||
local t = [ new searched-lib-target $(lib-name) : $(project)
|
||||
: $(shared) : $(search) : $(a) ] ;
|
||||
# We return sources for a simple reason. If there's
|
||||
# We return sources for a simple reason. If there is
|
||||
# lib png : z : <name>png ;
|
||||
# the 'z' target should be returned, so that apps linking to 'png'
|
||||
# will link to 'z', too.
|
||||
@@ -707,11 +707,11 @@ class C-compiling-generator : generator
|
||||
rule register-c-compiler ( id : source-types + : target-types + : requirements *
|
||||
: optional-properties * )
|
||||
{
|
||||
generators.register [ new C-compiling-generator $(id) : $(source-types)
|
||||
: $(target-types) : $(requirements) : $(optional-properties) ] ;
|
||||
generators.register [ new C-compiling-generator $(id) : $(source-types) :
|
||||
$(target-types) : $(requirements) : $(optional-properties) ] ;
|
||||
}
|
||||
|
||||
# FIXME: this is ugly, should find a better way (we'd like client code to
|
||||
# FIXME: this is ugly, should find a better way (we would like client code to
|
||||
# register all generators as "generators.some-rule" instead of
|
||||
# "some-module.some-rule".)
|
||||
#
|
||||
@@ -756,18 +756,22 @@ class linking-generator : generator
|
||||
}
|
||||
}
|
||||
|
||||
# It's possible that sources include shared libraries that did not came
|
||||
# It is possible that sources include shared libraries that did not came
|
||||
# from 'lib' targets, e.g. .so files specified as sources. In this case
|
||||
# we have to add extra dll-path properties and propagate extra xdll-path
|
||||
# properties so that application linking to use will get xdll-path to
|
||||
# properties so that application linking to us will get xdll-path to
|
||||
# those libraries.
|
||||
local extra-xdll-paths ;
|
||||
for local s in $(sources)
|
||||
{
|
||||
if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ]
|
||||
{
|
||||
# Unfortunately, we don't have a good way to find the path to a
|
||||
# Unfortunately, we do not have a good way to find the path to a
|
||||
# file, so use this nasty approach.
|
||||
#
|
||||
# TODO: This needs to be done better. One thing that is really
|
||||
# broken with this is that it does not work correctly with
|
||||
# projects having multiple source locations.
|
||||
local p = [ $(s).project ] ;
|
||||
local location = [ path.root [ $(s).name ]
|
||||
[ $(p).get source-location ] ] ;
|
||||
@@ -776,8 +780,8 @@ class linking-generator : generator
|
||||
}
|
||||
|
||||
# Hardcode DLL paths only when linking executables.
|
||||
# Pros: don't need to relink libraries when installing.
|
||||
# Cons: "standalone" libraries (plugins, python extensions) can't
|
||||
# Pros: do not need to relink libraries when installing.
|
||||
# Cons: "standalone" libraries (plugins, python extensions) can not
|
||||
# hardcode paths to dependent libraries.
|
||||
if [ $(property-set).get <hardcode-dll-paths> ] = true
|
||||
&& [ type.is-derived $(self.target-types[1]) EXE ]
|
||||
@@ -830,9 +834,9 @@ class linking-generator : generator
|
||||
# to other shared libraries this one depends on in order to be able to
|
||||
# find them all at runtime.
|
||||
|
||||
# Just pass all features in property-set, it's theorically possible that
|
||||
# we'll propagate <xdll-path> features explicitly specified by the user,
|
||||
# but then the user's to blaim for using an internal feature.
|
||||
# Just pass all features in property-set, it is theorically possible
|
||||
# that we will propagate <xdll-path> features explicitly specified by
|
||||
# the user, but then the user is to blaim for using an internal feature.
|
||||
local values = [ $(property-set).get <xdll-path> ] ;
|
||||
extra += $(values:G=<xdll-path>) ;
|
||||
|
||||
@@ -911,7 +915,7 @@ class archive-generator : generator
|
||||
local result = [ generator.run $(project) $(name) : $(property-set)
|
||||
: $(sources) ] ;
|
||||
|
||||
# For static linking, if we get a library in source, we can't directly
|
||||
# For static linking, if we get a library in source, we can not directly
|
||||
# link to it so we need to cause our dependencies to link to that
|
||||
# library. There are two approaches:
|
||||
# - adding the library to the list of returned targets.
|
||||
@@ -922,11 +926,11 @@ class archive-generator : generator
|
||||
# lib a2 : a2.cpp a1 : <link>static ;
|
||||
# install dist : a2 ;
|
||||
#
|
||||
# here we'll try to install 'a1', even though it's not necessary in the
|
||||
# general case. With the second approach, even indirect dependants will
|
||||
# link to the library, but it should not cause any harm. So, return all
|
||||
# LIB sources together with created targets, so that dependants link to
|
||||
# them.
|
||||
# here we will try to install 'a1', even though it is not necessary in
|
||||
# the general case. With the second approach, even indirect dependants
|
||||
# will link to the library, but it should not cause any harm. So, return
|
||||
# all LIB sources together with created targets, so that dependants link
|
||||
# to them.
|
||||
local usage-requirements ;
|
||||
if [ $(property-set).get <link> ] = static
|
||||
{
|
||||
|
||||
@@ -3,24 +3,25 @@
|
||||
# accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Defines main target 'cast', used to change type for target. For example,
|
||||
# in Qt library one wants two kinds of CPP files -- those that just compiled
|
||||
# and those that are passed via the MOC tool.
|
||||
# Defines main target 'cast', used to change type for target. For example, in Qt
|
||||
# library one wants two kinds of CPP files -- those that just compiled and those
|
||||
# that are passed via the MOC tool.
|
||||
#
|
||||
# This is done with:
|
||||
#
|
||||
# exe main : main.cpp [ cast _ moccable-cpp : widget.cpp ] ;
|
||||
#
|
||||
# Boost.Build will assing target type CPP to both main.cpp and widget.cpp.
|
||||
# Then, the cast rule will change target type of widget.cpp to
|
||||
# MOCCABLE-CPP, and Qt support will run MOC tool as part of build process.
|
||||
# Boost.Build will assing target type CPP to both main.cpp and widget.cpp. Then,
|
||||
# the cast rule will change target type of widget.cpp to MOCCABLE-CPP, and Qt
|
||||
# support will run the MOC tool as part of the build process.
|
||||
#
|
||||
# At the moment, the 'cast' rule only works for non-derived (source) targets.
|
||||
#
|
||||
# Another solution would be to add separate main target 'moc-them' that
|
||||
# will moc all the passed sources, not matter what's the type, but I prefer
|
||||
# cast, as defining new target type + generator for that type is somewhat
|
||||
# simpler then defining main target rule.
|
||||
# TODO: The following comment is unclear or incorrect. Clean it up.
|
||||
# > Another solution would be to add a separate main target 'moc-them' that
|
||||
# > would moc all the passed sources, no matter what their type is, but I prefer
|
||||
# > cast, as defining a new target type + generator for that type is somewhat
|
||||
# > simpler than defining a main target rule.
|
||||
|
||||
import "class" : new ;
|
||||
import errors ;
|
||||
@@ -34,11 +35,11 @@ class cast-target-class : typed-target
|
||||
{
|
||||
import type ;
|
||||
|
||||
rule __init__ ( name : project : type : sources * : requirements *
|
||||
: default-build * : usage-requirements * )
|
||||
rule __init__ ( name : project : type : sources * : requirements * :
|
||||
default-build * : usage-requirements * )
|
||||
{
|
||||
typed-target.__init__ $(name) : $(project) : $(type) : $(sources)
|
||||
: $(requirements) : $(default-build) : $(usage-requirements) ;
|
||||
typed-target.__init__ $(name) : $(project) : $(type) : $(sources) :
|
||||
$(requirements) : $(default-build) : $(usage-requirements) ;
|
||||
}
|
||||
|
||||
rule construct ( name : source-targets * : property-set )
|
||||
@@ -48,14 +49,14 @@ class cast-target-class : typed-target
|
||||
{
|
||||
if ! [ class.is-a $(s) : file-target ]
|
||||
{
|
||||
ECHO "error: source to the 'cast' rule is not a file!" ;
|
||||
EXIT ;
|
||||
import errors ;
|
||||
errors.user-error Source to the 'cast' rule is not a file! ;
|
||||
}
|
||||
if [ $(s).action ]
|
||||
{
|
||||
ECHO "error: only non-derived target are allowed for 'cast'." ;
|
||||
ECHO "error: when building " [ full-name ] ;
|
||||
EXIT ;
|
||||
import errors ;
|
||||
errors.user-error Only non-derived target are allowed for
|
||||
'cast'. : when building [ full-name ] ;
|
||||
}
|
||||
local r = [ $(s).clone-with-different-type $(self.type) ] ;
|
||||
result += [ virtual-target.register $(r) ] ;
|
||||
@@ -65,27 +66,26 @@ class cast-target-class : typed-target
|
||||
}
|
||||
|
||||
|
||||
rule cast ( name type : sources * : requirements * : default-build *
|
||||
: usage-requirements * )
|
||||
rule cast ( name type : sources * : requirements * : default-build * :
|
||||
usage-requirements * )
|
||||
{
|
||||
local project = [ project.current ] ;
|
||||
|
||||
local real-type = [ type.type-from-rule-name $(type) ] ;
|
||||
if ! $(real-type)
|
||||
{
|
||||
errors.user-error "No type corresponds to main target rule name '$(type)'"
|
||||
: "Hint: try lowercase name" ;
|
||||
errors.user-error No type corresponds to the main target rule name
|
||||
'$(type)' : "Hint: try a lowercase name" ;
|
||||
}
|
||||
|
||||
# This is a circular module dependency so it must be imported here.
|
||||
import targets ;
|
||||
targets.main-target-alternative
|
||||
[ new cast-target-class $(name) : $(project) : $(real-type)
|
||||
: [ targets.main-target-sources $(sources) : $(name) ]
|
||||
: [ targets.main-target-requirements $(requirements) : $(project) ]
|
||||
: [ targets.main-target-default-build $(default-build) : $(project) ]
|
||||
: [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
|
||||
] ;
|
||||
targets.main-target-alternative [ new cast-target-class $(name) : $(project)
|
||||
: $(real-type)
|
||||
: [ targets.main-target-sources $(sources) : $(name) ]
|
||||
: [ targets.main-target-requirements $(requirements) : $(project) ]
|
||||
: [ targets.main-target-default-build $(default-build) : $(project) ]
|
||||
: [ targets.main-target-usage-requirements $(usage-requirements) :
|
||||
$(project) ] ] ;
|
||||
}
|
||||
|
||||
|
||||
IMPORT $(__name__) : cast : : cast ;
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
|
||||
# This module defines the 'make' main target rule.
|
||||
|
||||
import targets ;
|
||||
import "class" : new ;
|
||||
import property ;
|
||||
import errors : error ;
|
||||
import type : type ;
|
||||
import regex ;
|
||||
import property-set ;
|
||||
import project ;
|
||||
import property ;
|
||||
import property-set ;
|
||||
import regex ;
|
||||
import targets ;
|
||||
|
||||
|
||||
class make-target-class : basic-target
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
|
||||
import alias ;
|
||||
import "class" : new ;
|
||||
import "class" ;
|
||||
import common ;
|
||||
import errors ;
|
||||
import feature ;
|
||||
@@ -98,11 +98,9 @@ rule make-test ( target-type : sources + : requirements * : target-name ? )
|
||||
# The <location-prefix> forces the build system for generate paths in the
|
||||
# form '$build_dir/array1.test/gcc/debug'. This is necessary to allow
|
||||
# post-processing tools to work.
|
||||
local t =
|
||||
[ targets.create-typed-target
|
||||
[ type.type-from-rule-name $(target-type) ] : $(project)
|
||||
: $(real-name) : $(sources)
|
||||
: $(requirements) <location-prefix>$(real-name).test ] ;
|
||||
local t = [ targets.create-typed-target [ type.type-from-rule-name
|
||||
$(target-type) ] : $(project) : $(real-name) : $(sources) :
|
||||
$(requirements) <location-prefix>$(real-name).test ] ;
|
||||
|
||||
# The alias to the real target, per period replacement above.
|
||||
if $(real-name) != $(target-name)
|
||||
@@ -121,15 +119,18 @@ rule make-test ( target-type : sources + : requirements * : target-name ? )
|
||||
|
||||
# Note: passing more that one cpp file here is known to fail. Passing a cpp file
|
||||
# and a library target works.
|
||||
#
|
||||
rule compile ( sources + : requirements * : target-name ? )
|
||||
{
|
||||
return [ make-test compile : $(sources) : $(requirements) : $(target-name) ] ;
|
||||
return [ make-test compile : $(sources) : $(requirements) : $(target-name) ]
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
rule compile-fail ( sources + : requirements * : target-name ? )
|
||||
{
|
||||
return [ make-test compile-fail : $(sources) : $(requirements) : $(target-name) ] ;
|
||||
return [ make-test compile-fail : $(sources) : $(requirements) :
|
||||
$(target-name) ] ;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +142,8 @@ rule link ( sources + : requirements * : target-name ? )
|
||||
|
||||
rule link-fail ( sources + : requirements * : target-name ? )
|
||||
{
|
||||
return [ make-test link-fail : $(sources) : $(requirements) : $(target-name) ] ;
|
||||
return [ make-test link-fail : $(sources) : $(requirements) : $(target-name)
|
||||
] ;
|
||||
}
|
||||
|
||||
|
||||
@@ -161,8 +163,8 @@ rule handle-input-files ( input-files * )
|
||||
}
|
||||
|
||||
|
||||
rule run ( sources + : args * : input-files * : requirements * : target-name ?
|
||||
: default-build * )
|
||||
rule run ( sources + : args * : input-files * : requirements * : target-name ? :
|
||||
default-build * )
|
||||
{
|
||||
requirements += <testing.arg>$(args:J=" ") ;
|
||||
requirements += [ handle-input-files $(input-files) ] ;
|
||||
@@ -170,12 +172,13 @@ rule run ( sources + : args * : input-files * : requirements * : target-name ?
|
||||
}
|
||||
|
||||
|
||||
rule run-fail ( sources + : args * : input-files * : requirements *
|
||||
: target-name ? : default-build * )
|
||||
rule run-fail ( sources + : args * : input-files * : requirements * :
|
||||
target-name ? : default-build * )
|
||||
{
|
||||
requirements += <testing.arg>$(args:J=" ") ;
|
||||
requirements += [ handle-input-files $(input-files) ] ;
|
||||
return [ make-test run-fail : $(sources) : $(requirements) : $(target-name) ] ;
|
||||
return [ make-test run-fail : $(sources) : $(requirements) : $(target-name)
|
||||
] ;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +189,7 @@ IMPORT : alias : : test-suite ;
|
||||
# For all main targets in 'project-module', which are typed targets with type
|
||||
# derived from 'TEST', produce some interesting information.
|
||||
#
|
||||
rule dump-tests # ( project-module )
|
||||
rule dump-tests
|
||||
{
|
||||
for local t in $(.all-tests)
|
||||
{
|
||||
@@ -247,19 +250,16 @@ rule dump-test ( target )
|
||||
{
|
||||
if [ class.is-a $(s) : file-reference ]
|
||||
{
|
||||
local location =
|
||||
[ path.root
|
||||
[ path.root [ $(s).name ] [ $(s).location ] ]
|
||||
[ path.pwd ] ] ;
|
||||
local location = [ path.root [ path.root [ $(s).name ]
|
||||
[ $(s).location ] ] [ path.pwd ] ] ;
|
||||
|
||||
source-files +=
|
||||
[ path.relative-to
|
||||
[ path.root $(project-root) [ path.pwd ] ]
|
||||
$(location) ] ;
|
||||
source-files += [ path.relative-to [ path.root $(project-root)
|
||||
[ path.pwd ] ] $(location) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
local target-name = [ $(project).get location ] // [ $(target).name ] .test ;
|
||||
local target-name = [ $(project).get location ] // [ $(target).name ] .test
|
||||
;
|
||||
target-name = $(target-name:J=) ;
|
||||
|
||||
local r = [ $(target).requirements ] ;
|
||||
@@ -285,9 +285,8 @@ rule dump-test ( target )
|
||||
# Format them into a single string of quoted strings.
|
||||
test-info = \"$(test-info:J=\"\ \")\" ;
|
||||
|
||||
ECHO boost-test($(type)) \"$(name)\"
|
||||
[$(test-info)]
|
||||
":" \"$(source-files)\" ;
|
||||
ECHO boost-test($(type)) \"$(name)\" [$(test-info)] ":"
|
||||
\"$(source-files)\" ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,14 +338,14 @@ rule expect-failure ( target : dependency + : properties * )
|
||||
}
|
||||
|
||||
|
||||
# The rule/action combination used to report successfull passing of a test.
|
||||
# The rule/action combination used to report successful passing of a test.
|
||||
#
|
||||
rule **passed**
|
||||
{
|
||||
# Dump all the tests, if needed. We do it here, since dump should happen
|
||||
# only after all Jamfiles have been read, and there is no such place
|
||||
# currently defined (but there should be).
|
||||
if ! $(.dumped-tests) && --dump-tests in [ modules.peek : ARGV ]
|
||||
if ! $(.dumped-tests) && ( --dump-tests in [ modules.peek : ARGV ] )
|
||||
{
|
||||
.dumped-tests = true ;
|
||||
dump-tests ;
|
||||
|
||||
@@ -213,15 +213,11 @@ rule root ( path root )
|
||||
#
|
||||
rule pwd ( )
|
||||
{
|
||||
if $(.pwd)
|
||||
{
|
||||
return $(.pwd) ;
|
||||
}
|
||||
else
|
||||
if ! $(.pwd)
|
||||
{
|
||||
.pwd = [ make [ PWD ] ] ;
|
||||
return $(.pwd) ;
|
||||
}
|
||||
return $(.pwd) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,8 +260,8 @@ rule glob ( dirs * : patterns + : exclude-patterns * )
|
||||
local exc = [ GLOB-RECURSIVELY $(real-exclude-patterns) ] ;
|
||||
exc = [ sequence.transform NORMALIZE_PATH : $(exc) ] ;
|
||||
|
||||
return [ sequence.transform path.make :
|
||||
[ set.difference $(inc) : $(exc) ] ] ;
|
||||
return [ sequence.transform path.make : [ set.difference $(inc) : $(exc) ] ]
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,11 +273,8 @@ rule glob ( dirs * : patterns + : exclude-patterns * )
|
||||
#
|
||||
rule glob-tree ( roots * : patterns + : exclude-patterns * )
|
||||
{
|
||||
return [ sequence.transform path.make : [ .glob-tree
|
||||
[ sequence.transform path.native : $(roots) ]
|
||||
: $(patterns)
|
||||
: $(exclude-patterns)
|
||||
] ] ;
|
||||
return [ sequence.transform path.make : [ .glob-tree [ sequence.transform
|
||||
path.native : $(roots) ] : $(patterns) : $(exclude-patterns) ] ] ;
|
||||
}
|
||||
|
||||
|
||||
@@ -304,7 +297,8 @@ local rule .glob-tree ( roots * : patterns * : exclude-patterns * )
|
||||
}
|
||||
if $(subdirs)
|
||||
{
|
||||
result += [ .glob-tree $(subdirs) : $(patterns) : $(exclude-patterns) ] ;
|
||||
result += [ .glob-tree $(subdirs) : $(patterns) : $(exclude-patterns) ]
|
||||
;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
@@ -328,32 +322,33 @@ rule all-parents ( path : upper_limit ? : cwd ? )
|
||||
cwd ?= [ pwd ] ;
|
||||
local path_ele = [ regex.split [ root $(path) $(cwd) ] "/" ] ;
|
||||
|
||||
if ! $(upper_limit) {
|
||||
if ! $(upper_limit)
|
||||
{
|
||||
upper_limit = / ;
|
||||
}
|
||||
local upper_ele = [ regex.split [ root $(upper_limit) $(cwd) ] "/" ] ;
|
||||
|
||||
# Leave only elements in 'path_ele' below 'upper_ele'
|
||||
while $(path_ele) && $(upper_ele[1]) = $(path_ele[1]) {
|
||||
# Leave only elements in 'path_ele' below 'upper_ele'.
|
||||
while $(path_ele) && ( $(upper_ele[1]) = $(path_ele[1]) )
|
||||
{
|
||||
upper_ele = $(upper_ele[2-]) ;
|
||||
path_ele = $(path_ele[2-]) ;
|
||||
}
|
||||
|
||||
# All upper elements removed ?
|
||||
if ! $(upper_ele)
|
||||
{
|
||||
# Create the relative paths to parents, number of elements in 'path_ele'
|
||||
local result ;
|
||||
for local i in $(path_ele) {
|
||||
path = [ parent $(path) ] ;
|
||||
result += $(path) ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
else
|
||||
# Have all upper elements been removed ?
|
||||
if $(upper_ele)
|
||||
{
|
||||
errors.error "$(upper_limit) is not prefix of $(path)" ;
|
||||
}
|
||||
|
||||
# Create the relative paths to parents, number of elements in 'path_ele'.
|
||||
local result ;
|
||||
for local i in $(path_ele)
|
||||
{
|
||||
path = [ parent $(path) ] ;
|
||||
result += $(path) ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user